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.rs334
1 files changed, 166 insertions, 168 deletions
diff --git a/stockton-render/src/draw/target.rs b/stockton-render/src/draw/target.rs
index 1ee208b..8d308d9 100644
--- a/stockton-render/src/draw/target.rs
+++ b/stockton-render/src/draw/target.rs
@@ -1,14 +1,19 @@
//! Resources needed for drawing on the screen, including sync objects
-use core::{iter::once, mem::ManuallyDrop};
+use std::{
+ array::IntoIter,
+ borrow::Borrow,
+ iter::{empty, once},
+ mem::ManuallyDrop,
+};
use arrayvec::ArrayVec;
use hal::{
- format::{ChannelType, Format, Swizzle},
- image::{Extent, Usage as ImgUsage, ViewKind},
- prelude::*,
+ buffer::SubRange,
+ command::RenderAttachmentInfo,
+ format::{ChannelType, Format},
+ image::{Extent, FramebufferAttachment, Usage as ImgUsage, ViewCapabilities},
pso::Viewport,
- queue::Submission,
window::{CompositeAlphaMode, Extent2D, PresentMode, SwapchainConfig},
};
use na::Mat4;
@@ -22,13 +27,6 @@ use super::{
};
use crate::types::*;
-/// Defines the colour range we use.
-const COLOR_RANGE: hal::image::SubresourceRange = hal::image::SubresourceRange {
- aspects: hal::format::Aspects::COLOR,
- levels: 0..1,
- layers: 0..1,
-};
-
#[derive(Debug, Clone)]
pub struct SwapchainProperties {
pub format: Format,
@@ -49,7 +47,7 @@ pub enum NoSupportedValuesError {
impl SwapchainProperties {
pub fn find_best(
adapter: &Adapter,
- surface: &Surface,
+ surface: &SurfaceT,
) -> Result<SwapchainProperties, NoSupportedValuesError> {
let caps = surface.capabilities(&adapter.physical_device);
let formats = surface.supported_formats(&adapter.physical_device);
@@ -124,8 +122,8 @@ impl SwapchainProperties {
}
pub struct TargetChain {
- /// Swapchain we're targeting
- pub swapchain: ManuallyDrop<Swapchain>,
+ /// Surface we're targeting
+ pub surface: ManuallyDrop<SurfaceT>,
pub properties: SwapchainProperties,
@@ -147,16 +145,14 @@ pub struct TargetChain {
}
impl TargetChain {
- #[allow(clippy::too_many_arguments)]
pub fn new(
- device: &mut Device,
+ device: &mut DeviceT,
adapter: &Adapter,
- surface: &mut Surface,
+ mut surface: SurfaceT,
pipeline: &CompletePipeline,
ui_pipeline: &UiPipeline,
- cmd_pool: &mut CommandPool,
+ cmd_pool: &mut CommandPoolT,
properties: SwapchainProperties,
- old_swapchain: Option<Swapchain>,
) -> Result<TargetChain, TargetChainCreationError> {
let caps = surface.capabilities(&adapter.physical_device);
@@ -181,13 +177,6 @@ impl TargetChain {
image_usage: ImgUsage::COLOR_ATTACHMENT,
};
- // Swapchain
- let (swapchain, mut backbuffer) = unsafe {
- device
- .create_swapchain(surface, swap_config, old_swapchain)
- .map_err(|_| TargetChainCreationError::Todo)?
- };
-
let depth_buffer = {
use hal::format::Aspects;
use hal::image::SubresourceRange;
@@ -199,8 +188,10 @@ impl TargetChain {
ImgUsage::DEPTH_STENCIL_ATTACHMENT,
SubresourceRange {
aspects: Aspects::DEPTH,
- levels: 0..1,
- layers: 0..1,
+ level_start: 0,
+ level_count: Some(1),
+ layer_start: 0,
+ layer_count: Some(1),
},
properties.extent.width as usize,
properties.extent.height as usize,
@@ -208,17 +199,24 @@ impl TargetChain {
.map_err(|_| TargetChainCreationError::Todo)
}?;
- let mut targets: Vec<TargetResources> = Vec::with_capacity(backbuffer.len());
- let mut sync_objects: Vec<SyncObjects> = Vec::with_capacity(backbuffer.len());
- for image in backbuffer.drain(..) {
+ 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(
device,
cmd_pool,
&pipeline.renderpass,
&ui_pipeline.renderpass,
- image,
- &(*depth_buffer.image_view),
+ fat.clone(),
+ FramebufferAttachment {
+ usage: ImgUsage::DEPTH_STENCIL_ATTACHMENT,
+ view_caps: ViewCapabilities::empty(),
+ format: properties.depth_format,
+ },
&properties,
)
.map_err(|_| TargetChainCreationError::Todo)?,
@@ -228,8 +226,15 @@ impl TargetChain {
.push(SyncObjects::new(device).map_err(|_| TargetChainCreationError::Todo)?);
}
+ // Configure Swapchain
+ unsafe {
+ surface
+ .configure_swapchain(device, swap_config)
+ .map_err(|_| TargetChainCreationError::Todo)?;
+ }
+
Ok(TargetChain {
- swapchain: ManuallyDrop::new(swapchain),
+ surface: ManuallyDrop::new(surface),
targets: targets.into_boxed_slice(),
sync_objects: sync_objects.into_boxed_slice(),
depth_buffer: ManuallyDrop::new(depth_buffer),
@@ -239,19 +244,24 @@ impl TargetChain {
})
}
- pub fn deactivate(self, device: &mut Device, cmd_pool: &mut CommandPool) {
- let swapchain = self.deactivate_with_recyling(device, cmd_pool);
+ pub fn deactivate(
+ self,
+ instance: &mut InstanceT,
+ device: &mut DeviceT,
+ cmd_pool: &mut CommandPoolT,
+ ) {
+ let surface = self.deactivate_with_recyling(device, cmd_pool);
unsafe {
- device.destroy_swapchain(swapchain);
+ instance.destroy_surface(surface);
}
}
pub fn deactivate_with_recyling(
- self,
- device: &mut Device,
- cmd_pool: &mut CommandPool,
- ) -> Swapchain {
+ mut self,
+ device: &mut DeviceT,
+ cmd_pool: &mut CommandPoolT,
+ ) -> SurfaceT {
use core::ptr::read;
unsafe {
ManuallyDrop::into_inner(read(&self.depth_buffer)).deactivate(device);
@@ -263,84 +273,102 @@ impl TargetChain {
for i in 0..self.sync_objects.len() {
read(&self.sync_objects[i]).deactivate(device);
}
+
+ self.surface.unconfigure_swapchain(device);
}
- unsafe { ManuallyDrop::into_inner(read(&self.swapchain)) }
+ unsafe { ManuallyDrop::into_inner(read(&self.surface)) }
}
pub fn prep_next_target<'a>(
&'a mut self,
- device: &mut Device,
+ device: &mut DeviceT,
draw_buffers: &mut DrawBuffers<UvPoint>,
pipeline: &CompletePipeline,
vp: &Mat4,
- ) -> Result<&'a mut crate::types::CommandBuffer, &'static str> {
+ ) -> Result<
+ (
+ &'a mut crate::types::CommandBufferT,
+ <SurfaceT as PresentationSurface<back::Backend>>::SwapchainImage,
+ ),
+ &'static str,
+ > {
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 target = &mut self.targets[self.last_image as usize];
+
// Get the image
- let (image_index, _) = unsafe {
- self.swapchain
- .acquire_image(core::u64::MAX, Some(&syncs.get_image), None)
+ let (img, _) = unsafe {
+ self.surface
+ .acquire_image(core::u64::MAX)
.map_err(|_| "FrameError::AcquireError")?
};
- self.last_image = image_index;
-
- let target = &mut self.targets[image_index as usize];
-
// Make sure whatever was last using this has finished
unsafe {
device
.wait_for_fence(&syncs.present_complete, core::u64::MAX)
.map_err(|_| "FrameError::SyncObjectError")?;
device
- .reset_fence(&syncs.present_complete)
+ .reset_fence(&mut syncs.present_complete)
.map_err(|_| "FrameError::SyncObjectError")?;
};
// Record commands
unsafe {
- use hal::buffer::IndexBufferView;
use hal::command::{
ClearColor, ClearDepthStencil, ClearValue, CommandBufferFlags, SubpassContents,
};
use hal::pso::ShaderStageFlags;
- // Colour to clear window to
- let clear_values = [
- ClearValue {
- color: ClearColor {
- float32: [0.0, 0.0, 0.0, 1.0],
- },
- },
- ClearValue {
- depth_stencil: ClearDepthStencil {
- depth: 1.0,
- stencil: 0,
- },
- },
- ];
-
// Get references to our buffers
let (vbufs, ibuf) = {
let vbufref: &<back::Backend as hal::Backend>::Buffer =
draw_buffers.vertex_buffer.get_buffer();
- let vbufs: ArrayVec<[_; 1]> = [(vbufref, 0)].into();
+ let vbufs: ArrayVec<[_; 1]> = [(
+ vbufref,
+ SubRange {
+ offset: 0,
+ size: None,
+ },
+ )]
+ .into();
let ibuf = draw_buffers.index_buffer.get_buffer();
(vbufs, ibuf)
};
- target.cmd_buffer.begin_primary(CommandBufferFlags::EMPTY);
+ target.cmd_buffer.begin_primary(CommandBufferFlags::empty());
// Main render pass / pipeline
target.cmd_buffer.begin_render_pass(
&pipeline.renderpass,
&target.framebuffer,
self.properties.viewport.rect,
- clear_values.iter(),
+ vec![
+ RenderAttachmentInfo {
+ image_view: img.borrow(),
+ clear_value: ClearValue {
+ color: ClearColor {
+ float32: [0.0, 0.0, 0.0, 1.0],
+ },
+ },
+ },
+ RenderAttachmentInfo {
+ image_view: &*self.depth_buffer.image_view,
+ clear_value: ClearValue {
+ depth_stencil: ClearDepthStencil {
+ depth: 1.0,
+ stencil: 0,
+ },
+ },
+ },
+ ]
+ .into_iter(),
SubpassContents::Inline,
);
target.cmd_buffer.bind_graphics_pipeline(&pipeline.pipeline);
@@ -356,22 +384,26 @@ impl TargetChain {
);
// Bind buffers
- target.cmd_buffer.bind_vertex_buffers(0, vbufs);
- target.cmd_buffer.bind_index_buffer(IndexBufferView {
- buffer: ibuf,
- offset: 0,
- index_type: hal::IndexType::U16,
- });
+ target.cmd_buffer.bind_vertex_buffers(0, vbufs.into_iter());
+ target.cmd_buffer.bind_index_buffer(
+ &ibuf,
+ SubRange {
+ offset: 0,
+ size: None,
+ },
+ hal::IndexType::U16,
+ );
};
- Ok(&mut target.cmd_buffer)
+ Ok((&mut target.cmd_buffer, img))
}
pub fn target_2d_pass<'a>(
&'a mut self,
draw_buffers: &mut DrawBuffers<UiPoint>,
+ img: &<SurfaceT as PresentationSurface<back::Backend>>::SwapchainImage,
pipeline: &UiPipeline,
- ) -> Result<&'a mut CommandBuffer, &'static str> {
+ ) -> Result<&'a mut CommandBufferT, &'static str> {
let target = &mut self.targets[self.last_image as usize];
unsafe {
@@ -381,28 +413,27 @@ impl TargetChain {
target.cmd_buffer.pipeline_barrier(
PipelineStage::BOTTOM_OF_PIPE..PipelineStage::TOP_OF_PIPE,
hal::memory::Dependencies::empty(),
- &[],
+ std::iter::empty(),
);
}
// Record commands
unsafe {
- use hal::buffer::IndexBufferView;
use hal::command::{ClearColor, ClearValue, SubpassContents};
- // Colour to clear window to
- let clear_values = [ClearValue {
- color: ClearColor {
- float32: [1.0, 0.0, 0.0, 1.5],
- },
- }];
-
// Get references to our buffers
let (vbufs, ibuf) = {
let vbufref: &<back::Backend as hal::Backend>::Buffer =
draw_buffers.vertex_buffer.get_buffer();
- let vbufs: ArrayVec<[_; 1]> = [(vbufref, 0)].into();
+ let vbufs: ArrayVec<[_; 1]> = [(
+ vbufref,
+ SubRange {
+ offset: 0,
+ size: None,
+ },
+ )]
+ .into();
let ibuf = draw_buffers.index_buffer.get_buffer();
(vbufs, ibuf)
@@ -413,18 +444,29 @@ impl TargetChain {
&pipeline.renderpass,
&target.framebuffer_2d,
self.properties.viewport.rect,
- clear_values.iter(),
+ vec![RenderAttachmentInfo {
+ image_view: img.borrow(),
+ clear_value: ClearValue {
+ color: ClearColor {
+ float32: [0.0, 0.0, 0.0, 1.0],
+ },
+ },
+ }]
+ .into_iter(),
SubpassContents::Inline,
);
target.cmd_buffer.bind_graphics_pipeline(&pipeline.pipeline);
// Bind buffers
- target.cmd_buffer.bind_vertex_buffers(0, vbufs);
- target.cmd_buffer.bind_index_buffer(IndexBufferView {
- buffer: ibuf,
- offset: 0,
- index_type: hal::IndexType::U16,
- });
+ target.cmd_buffer.bind_vertex_buffers(0, vbufs.into_iter());
+ target.cmd_buffer.bind_index_buffer(
+ &ibuf,
+ SubRange {
+ offset: 0,
+ size: None,
+ },
+ hal::IndexType::U16,
+ );
};
Ok(&mut target.cmd_buffer)
@@ -432,7 +474,8 @@ impl TargetChain {
pub fn finish_and_submit_target(
&mut self,
- command_queue: &mut CommandQueue,
+ img: <SurfaceT as PresentationSurface<back::Backend>>::SwapchainImage,
+ command_queue: &mut QueueT,
) -> Result<(), &'static str> {
let syncs = &mut self.sync_objects[self.last_syncs];
let target = &mut self.targets[self.last_image as usize];
@@ -442,31 +485,16 @@ impl TargetChain {
target.cmd_buffer.finish();
}
- // Make submission object
- let command_buffers: std::iter::Once<&CommandBuffer> = once(&target.cmd_buffer);
- let wait_semaphores: std::iter::Once<(&Semaphore, hal::pso::PipelineStage)> = once((
- &syncs.get_image,
- hal::pso::PipelineStage::COLOR_ATTACHMENT_OUTPUT,
- ));
- let signal_semaphores: std::iter::Once<&Semaphore> = once(&syncs.render_complete);
-
- let present_wait_semaphores: std::iter::Once<&Semaphore> = once(&syncs.render_complete);
-
- let submission = Submission {
- command_buffers,
- wait_semaphores,
- signal_semaphores,
- };
-
// Submit it
unsafe {
- command_queue.submit(submission, Some(&syncs.present_complete));
- self.swapchain
- .present(
- command_queue,
- self.last_image as u32,
- present_wait_semaphores,
- )
+ command_queue.submit(
+ once(&*target.cmd_buffer),
+ empty(),
+ once(&*syncs.render_complete),
+ Some(&mut syncs.present_complete),
+ );
+ command_queue
+ .present(&mut self.surface, img, Some(&mut *syncs.render_complete))
.map_err(|_| "FrameError::PresentError")?;
};
@@ -477,53 +505,34 @@ impl TargetChain {
/// Resources for a single target frame, including sync objects
pub struct TargetResources {
/// Command buffer to use when drawing
- pub cmd_buffer: ManuallyDrop<CommandBuffer>,
-
- /// The image for this frame
- pub image: ManuallyDrop<Image>,
-
- /// Imageviews for this frame
- pub imageview: ManuallyDrop<ImageView>,
+ pub cmd_buffer: ManuallyDrop<CommandBufferT>,
/// Framebuffer for this frame
- pub framebuffer: ManuallyDrop<Framebuffer>,
+ pub framebuffer: ManuallyDrop<FramebufferT>,
/// Framebuffer for this frame when drawing in 2D
- pub framebuffer_2d: ManuallyDrop<Framebuffer>,
+ pub framebuffer_2d: ManuallyDrop<FramebufferT>,
}
impl TargetResources {
pub fn new(
- device: &mut Device,
- cmd_pool: &mut CommandPool,
- renderpass: &RenderPass,
- renderpass_2d: &RenderPass,
- image: Image,
- depth_pass: &ImageView,
+ device: &mut DeviceT,
+ cmd_pool: &mut CommandPoolT,
+ renderpass: &RenderPassT,
+ renderpass_2d: &RenderPassT,
+ fat: FramebufferAttachment,
+ dat: FramebufferAttachment,
properties: &SwapchainProperties,
) -> Result<TargetResources, TargetResourcesCreationError> {
// Command Buffer
let cmd_buffer = unsafe { cmd_pool.allocate_one(hal::command::Level::Primary) };
- // ImageView
- let imageview = unsafe {
- device
- .create_image_view(
- &image,
- ViewKind::D2,
- properties.format,
- Swizzle::NO,
- COLOR_RANGE.clone(),
- )
- .map_err(TargetResourcesCreationError::ImageViewError)?
- };
-
// Framebuffer
let framebuffer = unsafe {
device
.create_framebuffer(
&renderpass,
- once(&imageview).chain(once(depth_pass)),
+ IntoIter::new([fat.clone(), dat]),
properties.extent,
)
.map_err(|_| TargetResourcesCreationError::FrameBufferNoMemory)?
@@ -532,48 +541,39 @@ impl TargetResources {
// 2D framebuffer just needs the imageview, not the depth pass
let framebuffer_2d = unsafe {
device
- .create_framebuffer(&renderpass_2d, once(&imageview), properties.extent)
+ .create_framebuffer(&renderpass_2d, once(fat), properties.extent)
.map_err(|_| TargetResourcesCreationError::FrameBufferNoMemory)?
};
Ok(TargetResources {
cmd_buffer: ManuallyDrop::new(cmd_buffer),
- image: ManuallyDrop::new(image),
- imageview: ManuallyDrop::new(imageview),
framebuffer: ManuallyDrop::new(framebuffer),
framebuffer_2d: ManuallyDrop::new(framebuffer_2d),
})
}
- pub fn deactivate(self, device: &mut Device, cmd_pool: &mut CommandPool) {
+ pub fn deactivate(self, device: &mut DeviceT, cmd_pool: &mut CommandPoolT) {
use core::ptr::read;
unsafe {
cmd_pool.free(once(ManuallyDrop::into_inner(read(&self.cmd_buffer))));
device.destroy_framebuffer(ManuallyDrop::into_inner(read(&self.framebuffer)));
device.destroy_framebuffer(ManuallyDrop::into_inner(read(&self.framebuffer_2d)));
- device.destroy_image_view(ManuallyDrop::into_inner(read(&self.imageview)));
}
}
}
pub struct SyncObjects {
- /// Triggered when the image is ready to draw to
- pub get_image: ManuallyDrop<Semaphore>,
-
/// Triggered when rendering is done
- pub render_complete: ManuallyDrop<Semaphore>,
+ pub render_complete: ManuallyDrop<SemaphoreT>,
/// Triggered when the image is on screen
- pub present_complete: ManuallyDrop<Fence>,
+ pub present_complete: ManuallyDrop<FenceT>,
}
impl SyncObjects {
- pub fn new(device: &mut Device) -> Result<Self, TargetResourcesCreationError> {
+ pub fn new(device: &mut DeviceT) -> Result<Self, TargetResourcesCreationError> {
// Sync objects
- let get_image = device
- .create_semaphore()
- .map_err(|_| TargetResourcesCreationError::SyncObjectsNoMemory)?;
let render_complete = device
.create_semaphore()
.map_err(|_| TargetResourcesCreationError::SyncObjectsNoMemory)?;
@@ -582,17 +582,15 @@ impl SyncObjects {
.map_err(|_| TargetResourcesCreationError::SyncObjectsNoMemory)?;
Ok(SyncObjects {
- get_image: ManuallyDrop::new(get_image),
render_complete: ManuallyDrop::new(render_complete),
present_complete: ManuallyDrop::new(present_complete),
})
}
- pub fn deactivate(self, device: &mut Device) {
+ pub fn deactivate(self, device: &mut DeviceT) {
use core::ptr::read;
unsafe {
- device.destroy_semaphore(ManuallyDrop::into_inner(read(&self.get_image)));
device.destroy_semaphore(ManuallyDrop::into_inner(read(&self.render_complete)));
device.destroy_fence(ManuallyDrop::into_inner(read(&self.present_complete)));
}
@@ -606,7 +604,7 @@ pub enum TargetChainCreationError {
#[derive(Debug)]
pub enum TargetResourcesCreationError {
- ImageViewError(hal::image::ViewError),
+ ImageViewError,
FrameBufferNoMemory,
SyncObjectsNoMemory,
}