mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2025-02-18 18:12:32 +00:00
Merge pull request #222 from tomaka/render-pass
Add begin_render_pass(), next_subpass() and end_render_pass() with the new system
This commit is contained in:
commit
82f9c0096b
@ -116,6 +116,11 @@ unsafe impl<'a, L, Pl, S, Pc> StdCommandsList for DispatchCommand<'a, L, Pl, S,
|
||||
self.previous.extract_current_image_state(image)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn buildable_state(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
unsafe fn raw_build<I, F>(self, additional_elements: F, barriers: I,
|
||||
mut final_barrier: PipelineBarrierBuilder) -> Self::Output
|
||||
where F: FnOnce(&mut UnsafeCommandBufferBuilder<L::Pool>),
|
||||
|
@ -85,6 +85,11 @@ unsafe impl<P> StdCommandsList for PrimaryCbBuilder<P> where P: CommandPool {
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn buildable_state(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
unsafe fn raw_build<I, F>(self, additional_elements: F, barriers: I,
|
||||
final_barrier: PipelineBarrierBuilder) -> Self::Output
|
||||
where F: FnOnce(&mut UnsafeCommandBufferBuilder<Self::Pool>),
|
||||
|
@ -17,19 +17,20 @@ use command_buffer::sys::PipelineBarrierBuilder;
|
||||
use command_buffer::sys::UnsafeCommandBufferBuilder;
|
||||
use descriptor::PipelineLayout;
|
||||
use descriptor::descriptor_set::collection::TrackedDescriptorSetsCollection;
|
||||
use framebuffer::Framebuffer;
|
||||
use framebuffer::RenderPass;
|
||||
use framebuffer::RenderPassClearValues;
|
||||
use image::traits::TrackedImage;
|
||||
use instance::QueueFamily;
|
||||
use pipeline::ComputePipeline;
|
||||
|
||||
pub use self::dispatch::DispatchCommand;
|
||||
pub use self::empty::PrimaryCb;
|
||||
pub use self::empty::PrimaryCbBuilder;
|
||||
pub use self::update_buffer::UpdateCommand;
|
||||
|
||||
mod dispatch;
|
||||
mod empty;
|
||||
mod update_buffer;
|
||||
pub mod dispatch;
|
||||
pub mod empty;
|
||||
pub mod render_pass;
|
||||
pub mod update_buffer;
|
||||
|
||||
/// A list of commands that can be turned into a command buffer.
|
||||
pub unsafe trait StdCommandsList {
|
||||
@ -43,10 +44,10 @@ pub unsafe trait StdCommandsList {
|
||||
/// After this command is executed, the content of `buffer` will become `data`.
|
||||
#[inline]
|
||||
fn update_buffer<'a, B, D: ?Sized>(self, buffer: B, data: &'a D)
|
||||
-> UpdateCommand<'a, Self, B, D>
|
||||
-> update_buffer::UpdateCommand<'a, Self, B, D>
|
||||
where Self: Sized + OutsideRenderPass, B: TrackedBuffer, D: Copy + 'static
|
||||
{
|
||||
UpdateCommand::new(self, buffer, data)
|
||||
update_buffer::UpdateCommand::new(self, buffer, data)
|
||||
}
|
||||
|
||||
/// Adds a command that executes a compute shader.
|
||||
@ -59,15 +60,56 @@ pub unsafe trait StdCommandsList {
|
||||
#[inline]
|
||||
fn dispatch<'a, Pl, S, Pc>(self, pipeline: Arc<ComputePipeline<Pl>>, sets: S,
|
||||
dimensions: [u32; 3], push_constants: &'a Pc)
|
||||
-> DispatchCommand<'a, Self, Pl, S, Pc>
|
||||
-> dispatch::DispatchCommand<'a, Self, Pl, S, Pc>
|
||||
where Self: Sized + StdCommandsList + OutsideRenderPass, Pl: PipelineLayout,
|
||||
S: TrackedDescriptorSetsCollection, Pc: 'a
|
||||
{
|
||||
DispatchCommand::new(self, pipeline, sets, dimensions, push_constants)
|
||||
dispatch::DispatchCommand::new(self, pipeline, sets, dimensions, push_constants)
|
||||
}
|
||||
|
||||
/// Adds a command that starts a render pass.
|
||||
///
|
||||
/// If `secondary` is true, then you will only be able to add secondary command buffers while
|
||||
/// you're inside the first subpass on the render pass. If `secondary` is false, you will only
|
||||
/// be able to add inline draw commands and not secondary command buffers.
|
||||
///
|
||||
/// You must call this before you can add draw commands.
|
||||
#[inline]
|
||||
fn begin_render_pass<Rp, C>(self, framebuffer: Arc<Framebuffer<Rp>>, secondary: bool,
|
||||
clear_values: C)
|
||||
-> render_pass::BeginRenderPassCommand<Self, Rp, Rp>
|
||||
where Self: Sized + OutsideRenderPass,
|
||||
Rp: RenderPass + RenderPassClearValues<C>
|
||||
{
|
||||
render_pass::BeginRenderPassCommand::new(self, framebuffer, secondary, clear_values)
|
||||
}
|
||||
|
||||
/// Adds a command that jumps to the next subpass of the current render pass.
|
||||
fn next_subpass(self, secondary: bool) -> render_pass::NextSubpassCommand<Self>
|
||||
where Self: Sized + InsideRenderPass
|
||||
{
|
||||
render_pass::NextSubpassCommand::new(self, secondary)
|
||||
}
|
||||
|
||||
/// Adds a command that ends the current render pass.
|
||||
///
|
||||
/// This must be called after you went through all the subpasses and before you can build
|
||||
/// the command buffer or add further commands.
|
||||
fn end_render_pass(self) -> render_pass::EndRenderPassCommand<Self>
|
||||
where Self: Sized + InsideRenderPass
|
||||
{
|
||||
render_pass::EndRenderPassCommand::new(self)
|
||||
}
|
||||
|
||||
/// Returns true if the command buffer can be built. This function should always return true,
|
||||
/// except when we're building a primary command buffer that is inside a render pass.
|
||||
fn buildable_state(&self) -> bool;
|
||||
|
||||
/// Turns the commands list into a command buffer that can be submitted.
|
||||
fn build(self) -> Self::Output where Self: Sized {
|
||||
assert!(self.buildable_state(), "Tried to build a command buffer still inside a \
|
||||
render pass");
|
||||
|
||||
unsafe {
|
||||
self.raw_build(|_| {}, iter::empty(), PipelineBarrierBuilder::new())
|
||||
}
|
||||
@ -122,6 +164,8 @@ pub unsafe trait StdCommandsList {
|
||||
/// the command numbers to be inferior to `num_commands`.
|
||||
/// - `final_barrier` is a pipeline barrier that must be added at the end of the
|
||||
/// command buffer builder.
|
||||
///
|
||||
/// This function doesn't check that `buildable_state` returns true.
|
||||
unsafe fn raw_build<I, F>(self, additional_elements: F, barriers: I,
|
||||
final_barrier: PipelineBarrierBuilder) -> Self::Output
|
||||
where F: FnOnce(&mut UnsafeCommandBufferBuilder<Self::Pool>),
|
||||
@ -136,7 +180,18 @@ pub unsafe trait InsideRenderPass: StdCommandsList {
|
||||
type RenderPass: RenderPass;
|
||||
type Framebuffer;
|
||||
|
||||
fn render_pass(&self) -> &Self::RenderPass;
|
||||
/// Returns the number of the subpass we're in. The value is 0-indexed, so immediately after
|
||||
/// calling `begin_render_pass` the value will be `0`.
|
||||
///
|
||||
/// The value should always be strictly inferior to the number of subpasses in the render pass.
|
||||
fn current_subpass(&self) -> u32;
|
||||
|
||||
/// If true, only secondary command buffers can be added inside the subpass. If false, only
|
||||
/// inline draw commands can be added.
|
||||
fn secondary_subpass(&self) -> bool;
|
||||
|
||||
// TODO: don't use Arc
|
||||
fn render_pass(&self) -> &Arc<Self::RenderPass>;
|
||||
|
||||
fn framebuffer(&self) -> &Self::Framebuffer;
|
||||
}
|
||||
|
442
vulkano/src/command_buffer/std/render_pass.rs
Normal file
442
vulkano/src/command_buffer/std/render_pass.rs
Normal file
@ -0,0 +1,442 @@
|
||||
// Copyright (c) 2016 The vulkano developers
|
||||
// Licensed under the Apache License, Version 2.0
|
||||
// <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
|
||||
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
||||
// at your option. All files in the project carrying such
|
||||
// notice may not be copied, modified, or distributed except
|
||||
// according to those terms.
|
||||
|
||||
use std::iter;
|
||||
use std::sync::Arc;
|
||||
use std::ops::Range;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use buffer::traits::TrackedBuffer;
|
||||
use command_buffer::std::InsideRenderPass;
|
||||
use command_buffer::std::OutsideRenderPass;
|
||||
use command_buffer::std::StdCommandsList;
|
||||
use command_buffer::submit::CommandBuffer;
|
||||
use command_buffer::submit::SubmitInfo;
|
||||
use command_buffer::sys::PipelineBarrierBuilder;
|
||||
use command_buffer::sys::UnsafeCommandBuffer;
|
||||
use command_buffer::sys::UnsafeCommandBufferBuilder;
|
||||
use device::Queue;
|
||||
use format::ClearValue;
|
||||
use framebuffer::Framebuffer;
|
||||
use framebuffer::RenderPass;
|
||||
use framebuffer::RenderPassClearValues;
|
||||
use image::traits::TrackedImage;
|
||||
use instance::QueueFamily;
|
||||
use sync::Fence;
|
||||
|
||||
/// Wraps around a commands list and adds an update buffer command at the end of it.
|
||||
pub struct BeginRenderPassCommand<L, Rp, Rpf>
|
||||
where L: StdCommandsList, Rp: RenderPass, Rpf: RenderPass
|
||||
{
|
||||
// Parent commands list.
|
||||
previous: L,
|
||||
// True if only secondary command buffers can be added.
|
||||
secondary: bool,
|
||||
rect: [Range<u32>; 2],
|
||||
clear_values: SmallVec<[ClearValue; 6]>,
|
||||
render_pass: Arc<Rp>,
|
||||
framebuffer: Arc<Framebuffer<Rpf>>,
|
||||
}
|
||||
|
||||
impl<L, Rp> BeginRenderPassCommand<L, Rp, Rp>
|
||||
where L: StdCommandsList + OutsideRenderPass, Rp: RenderPass
|
||||
{
|
||||
/// See the documentation of the `begin_render_pass` method.
|
||||
// TODO: allow setting more parameters
|
||||
pub fn new<C>(previous: L, framebuffer: Arc<Framebuffer<Rp>>, secondary: bool, clear_values: C)
|
||||
-> BeginRenderPassCommand<L, Rp, Rp>
|
||||
where Rp: RenderPassClearValues<C>
|
||||
{
|
||||
// FIXME: transition states of the images in the framebuffer
|
||||
|
||||
let clear_values = framebuffer.render_pass().convert_clear_values(clear_values)
|
||||
.collect();
|
||||
|
||||
BeginRenderPassCommand {
|
||||
previous: previous,
|
||||
secondary: secondary,
|
||||
rect: [0 .. framebuffer.width(), 0 .. framebuffer.height()],
|
||||
clear_values: clear_values,
|
||||
render_pass: framebuffer.render_pass().clone(),
|
||||
framebuffer: framebuffer.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<L, Rp, Rpf> StdCommandsList for BeginRenderPassCommand<L, Rp, Rpf>
|
||||
where L: StdCommandsList, Rp: RenderPass, Rpf: RenderPass
|
||||
{
|
||||
type Pool = L::Pool;
|
||||
type Output = BeginRenderPassCommandCb<L, Rp, Rpf>;
|
||||
|
||||
#[inline]
|
||||
fn num_commands(&self) -> usize {
|
||||
self.previous.num_commands() + 1
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn check_queue_validity(&self, queue: QueueFamily) -> Result<(), ()> {
|
||||
if !queue.supports_graphics() {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
self.previous.check_queue_validity(queue)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn buildable_state(&self) -> bool {
|
||||
// We are no longer in a buildable state after entering a render pass.
|
||||
false
|
||||
}
|
||||
|
||||
unsafe fn extract_current_buffer_state<Ob>(&mut self, buffer: &Ob)
|
||||
-> Option<Ob::CommandListState>
|
||||
where Ob: TrackedBuffer
|
||||
{
|
||||
// FIXME: state of images in the framebuffer
|
||||
self.previous.extract_current_buffer_state(buffer)
|
||||
}
|
||||
|
||||
unsafe fn extract_current_image_state<I>(&mut self, image: &I) -> Option<I::CommandListState>
|
||||
where I: TrackedImage
|
||||
{
|
||||
// FIXME: state of images in the framebuffer
|
||||
self.previous.extract_current_image_state(image)
|
||||
}
|
||||
|
||||
unsafe fn raw_build<I, F>(self, additional_elements: F, barriers: I,
|
||||
final_barrier: PipelineBarrierBuilder) -> Self::Output
|
||||
where F: FnOnce(&mut UnsafeCommandBufferBuilder<L::Pool>),
|
||||
I: Iterator<Item = (usize, PipelineBarrierBuilder)>
|
||||
{
|
||||
let my_command_num = self.num_commands();
|
||||
let barriers = barriers.map(move |(n, b)| { assert!(n < my_command_num); (n, b) });
|
||||
|
||||
let my_render_pass = self.render_pass;
|
||||
let my_framebuffer = self.framebuffer;
|
||||
let mut my_clear_values = self.clear_values;
|
||||
let my_rect = self.rect;
|
||||
let my_secondary = self.secondary;
|
||||
|
||||
let parent = self.previous.raw_build(|cb| {
|
||||
cb.begin_render_pass(my_render_pass.inner(), &my_framebuffer,
|
||||
my_clear_values.into_iter(), my_rect, my_secondary);
|
||||
additional_elements(cb);
|
||||
}, barriers, final_barrier);
|
||||
|
||||
BeginRenderPassCommandCb {
|
||||
previous: parent,
|
||||
render_pass: my_render_pass,
|
||||
framebuffer: my_framebuffer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<L, Rp, Rpf> InsideRenderPass for BeginRenderPassCommand<L, Rp, Rpf>
|
||||
where L: StdCommandsList, Rp: RenderPass, Rpf: RenderPass
|
||||
{
|
||||
type RenderPass = Rp;
|
||||
type Framebuffer = Arc<Framebuffer<Rpf>>;
|
||||
|
||||
#[inline]
|
||||
fn current_subpass(&self) -> u32 {
|
||||
0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn secondary_subpass(&self) -> bool {
|
||||
self.secondary
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn render_pass(&self) -> &Arc<Self::RenderPass> {
|
||||
&self.render_pass
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn framebuffer(&self) -> &Self::Framebuffer {
|
||||
&self.framebuffer
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps around a command buffer and adds an update buffer command at the end of it.
|
||||
pub struct BeginRenderPassCommandCb<L, Rp, Rpf>
|
||||
where L: StdCommandsList, Rp: RenderPass, Rpf: RenderPass
|
||||
{
|
||||
// The previous commands.
|
||||
previous: L::Output,
|
||||
render_pass: Arc<Rp>,
|
||||
framebuffer: Arc<Framebuffer<Rpf>>,
|
||||
}
|
||||
|
||||
unsafe impl<L, Rp, Rpf> CommandBuffer for BeginRenderPassCommandCb<L, Rp, Rpf>
|
||||
where L: StdCommandsList, Rp: RenderPass, Rpf: RenderPass
|
||||
{
|
||||
type Pool = L::Pool;
|
||||
type SemaphoresWaitIterator = <L::Output as CommandBuffer>::SemaphoresWaitIterator;
|
||||
type SemaphoresSignalIterator = <L::Output as CommandBuffer>::SemaphoresSignalIterator;
|
||||
|
||||
#[inline]
|
||||
fn inner(&self) -> &UnsafeCommandBuffer<Self::Pool> {
|
||||
self.previous.inner()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn on_submit<F>(&self, queue: &Arc<Queue>, mut fence: F)
|
||||
-> SubmitInfo<Self::SemaphoresWaitIterator,
|
||||
Self::SemaphoresSignalIterator>
|
||||
where F: FnMut() -> Arc<Fence>
|
||||
{
|
||||
self.previous.on_submit(queue, &mut fence)
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps around a commands list and adds a command at the end of it that jumps to the next subpass.
|
||||
pub struct NextSubpassCommand<L> where L: StdCommandsList {
|
||||
// Parent commands list.
|
||||
previous: L,
|
||||
// True if only secondary command buffers can be added.
|
||||
secondary: bool,
|
||||
}
|
||||
|
||||
impl<L> NextSubpassCommand<L> where L: StdCommandsList + InsideRenderPass {
|
||||
/// See the documentation of the `next_subpass` method.
|
||||
#[inline]
|
||||
pub fn new(previous: L, secondary: bool) -> NextSubpassCommand<L> {
|
||||
// FIXME: put this check
|
||||
//assert!(previous.current_subpass() + 1 < previous.render_pass().num_subpasses()); // TODO: error instead
|
||||
|
||||
NextSubpassCommand {
|
||||
previous: previous,
|
||||
secondary: secondary,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<L> StdCommandsList for NextSubpassCommand<L>
|
||||
where L: StdCommandsList + InsideRenderPass
|
||||
{
|
||||
type Pool = L::Pool;
|
||||
type Output = NextSubpassCommandCb<L>;
|
||||
|
||||
#[inline]
|
||||
fn num_commands(&self) -> usize {
|
||||
self.previous.num_commands() + 1
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn check_queue_validity(&self, queue: QueueFamily) -> Result<(), ()> {
|
||||
if !queue.supports_graphics() {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
self.previous.check_queue_validity(queue)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn buildable_state(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn extract_current_buffer_state<Ob>(&mut self, buffer: &Ob)
|
||||
-> Option<Ob::CommandListState>
|
||||
where Ob: TrackedBuffer
|
||||
{
|
||||
self.previous.extract_current_buffer_state(buffer)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn extract_current_image_state<I>(&mut self, image: &I) -> Option<I::CommandListState>
|
||||
where I: TrackedImage
|
||||
{
|
||||
self.previous.extract_current_image_state(image)
|
||||
}
|
||||
|
||||
unsafe fn raw_build<I, F>(self, additional_elements: F, barriers: I,
|
||||
final_barrier: PipelineBarrierBuilder) -> Self::Output
|
||||
where F: FnOnce(&mut UnsafeCommandBufferBuilder<L::Pool>),
|
||||
I: Iterator<Item = (usize, PipelineBarrierBuilder)>
|
||||
{
|
||||
let secondary = self.secondary;
|
||||
|
||||
let parent = self.previous.raw_build(|cb| {
|
||||
cb.next_subpass(secondary);
|
||||
additional_elements(cb);
|
||||
}, barriers, final_barrier);
|
||||
|
||||
NextSubpassCommandCb {
|
||||
previous: parent,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<L> InsideRenderPass for NextSubpassCommand<L>
|
||||
where L: StdCommandsList + InsideRenderPass
|
||||
{
|
||||
type RenderPass = L::RenderPass;
|
||||
type Framebuffer = L::Framebuffer;
|
||||
|
||||
#[inline]
|
||||
fn current_subpass(&self) -> u32 {
|
||||
self.previous.current_subpass() + 1
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn secondary_subpass(&self) -> bool {
|
||||
self.secondary
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn render_pass(&self) -> &Arc<Self::RenderPass> {
|
||||
self.previous.render_pass()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn framebuffer(&self) -> &Self::Framebuffer {
|
||||
self.previous.framebuffer()
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps around a command buffer and adds an end render pass command at the end of it.
|
||||
pub struct NextSubpassCommandCb<L> where L: StdCommandsList {
|
||||
// The previous commands.
|
||||
previous: L::Output,
|
||||
}
|
||||
|
||||
unsafe impl<L> CommandBuffer for NextSubpassCommandCb<L> where L: StdCommandsList {
|
||||
type Pool = L::Pool;
|
||||
type SemaphoresWaitIterator = <L::Output as CommandBuffer>::SemaphoresWaitIterator;
|
||||
type SemaphoresSignalIterator = <L::Output as CommandBuffer>::SemaphoresSignalIterator;
|
||||
|
||||
#[inline]
|
||||
fn inner(&self) -> &UnsafeCommandBuffer<Self::Pool> {
|
||||
self.previous.inner()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn on_submit<F>(&self, queue: &Arc<Queue>, mut fence: F)
|
||||
-> SubmitInfo<Self::SemaphoresWaitIterator,
|
||||
Self::SemaphoresSignalIterator>
|
||||
where F: FnMut() -> Arc<Fence>
|
||||
{
|
||||
self.previous.on_submit(queue, &mut fence)
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps around a commands list and adds an end render pass command at the end of it.
|
||||
pub struct EndRenderPassCommand<L> where L: StdCommandsList {
|
||||
// Parent commands list.
|
||||
previous: L,
|
||||
}
|
||||
|
||||
impl<L> EndRenderPassCommand<L> where L: StdCommandsList + InsideRenderPass {
|
||||
/// See the documentation of the `end_render_pass` method.
|
||||
#[inline]
|
||||
pub fn new(previous: L) -> EndRenderPassCommand<L> {
|
||||
// FIXME: check that the number of subpasses is correct
|
||||
|
||||
EndRenderPassCommand {
|
||||
previous: previous,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<L> StdCommandsList for EndRenderPassCommand<L> where L: StdCommandsList {
|
||||
type Pool = L::Pool;
|
||||
type Output = EndRenderPassCommandCb<L>;
|
||||
|
||||
#[inline]
|
||||
fn num_commands(&self) -> usize {
|
||||
self.previous.num_commands() + 1
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn check_queue_validity(&self, queue: QueueFamily) -> Result<(), ()> {
|
||||
if !queue.supports_graphics() {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
self.previous.check_queue_validity(queue)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn buildable_state(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn extract_current_buffer_state<Ob>(&mut self, buffer: &Ob)
|
||||
-> Option<Ob::CommandListState>
|
||||
where Ob: TrackedBuffer
|
||||
{
|
||||
self.previous.extract_current_buffer_state(buffer)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn extract_current_image_state<I>(&mut self, image: &I) -> Option<I::CommandListState>
|
||||
where I: TrackedImage
|
||||
{
|
||||
self.previous.extract_current_image_state(image)
|
||||
}
|
||||
|
||||
unsafe fn raw_build<I, F>(self, additional_elements: F, barriers: I,
|
||||
final_barrier: PipelineBarrierBuilder) -> Self::Output
|
||||
where F: FnOnce(&mut UnsafeCommandBufferBuilder<L::Pool>),
|
||||
I: Iterator<Item = (usize, PipelineBarrierBuilder)>
|
||||
{
|
||||
// We need to flush all the barriers because regular (ie. non-self-referencing) barriers
|
||||
// aren't allowed inside render passes.
|
||||
|
||||
let mut pipeline_barrier = PipelineBarrierBuilder::new();
|
||||
for (num, barrier) in barriers {
|
||||
debug_assert!(num <= self.num_commands());
|
||||
pipeline_barrier.merge(barrier);
|
||||
}
|
||||
|
||||
let parent = self.previous.raw_build(|cb| {
|
||||
cb.end_render_pass();
|
||||
cb.pipeline_barrier(pipeline_barrier);
|
||||
additional_elements(cb);
|
||||
}, iter::empty(), final_barrier);
|
||||
|
||||
EndRenderPassCommandCb {
|
||||
previous: parent,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<L> OutsideRenderPass for EndRenderPassCommand<L> where L: StdCommandsList {
|
||||
}
|
||||
|
||||
/// Wraps around a command buffer and adds an end render pass command at the end of it.
|
||||
pub struct EndRenderPassCommandCb<L> where L: StdCommandsList {
|
||||
// The previous commands.
|
||||
previous: L::Output,
|
||||
}
|
||||
|
||||
unsafe impl<L> CommandBuffer for EndRenderPassCommandCb<L> where L: StdCommandsList {
|
||||
type Pool = L::Pool;
|
||||
type SemaphoresWaitIterator = <L::Output as CommandBuffer>::SemaphoresWaitIterator;
|
||||
type SemaphoresSignalIterator = <L::Output as CommandBuffer>::SemaphoresSignalIterator;
|
||||
|
||||
#[inline]
|
||||
fn inner(&self) -> &UnsafeCommandBuffer<Self::Pool> {
|
||||
self.previous.inner()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn on_submit<F>(&self, queue: &Arc<Queue>, mut fence: F)
|
||||
-> SubmitInfo<Self::SemaphoresWaitIterator,
|
||||
Self::SemaphoresSignalIterator>
|
||||
where F: FnMut() -> Arc<Fence>
|
||||
{
|
||||
self.previous.on_submit(queue, &mut fence)
|
||||
}
|
||||
}
|
@ -101,6 +101,11 @@ unsafe impl<'a, L, B, D: ?Sized> StdCommandsList for UpdateCommand<'a, L, B, D>
|
||||
self.previous.check_queue_validity(queue)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn buildable_state(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
unsafe fn extract_current_buffer_state<Ob>(&mut self, buffer: &Ob)
|
||||
-> Option<Ob::CommandListState>
|
||||
where Ob: TrackedBuffer
|
||||
|
Loading…
Reference in New Issue
Block a user