mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-22 14:56:42 +00:00
Merge pull request #593 from tomaka/clear-color-image
Add AutoCommandBufferBuilder::clear_color_image
This commit is contained in:
commit
84caa04414
@ -33,6 +33,7 @@ use command_buffer::sys::Flags;
|
|||||||
use command_buffer::sys::Kind;
|
use command_buffer::sys::Kind;
|
||||||
use command_buffer::sys::UnsafeCommandBuffer;
|
use command_buffer::sys::UnsafeCommandBuffer;
|
||||||
use command_buffer::sys::UnsafeCommandBufferBuilderBufferImageCopy;
|
use command_buffer::sys::UnsafeCommandBufferBuilderBufferImageCopy;
|
||||||
|
use command_buffer::sys::UnsafeCommandBufferBuilderColorImageClear;
|
||||||
use command_buffer::sys::UnsafeCommandBufferBuilderImageAspect;
|
use command_buffer::sys::UnsafeCommandBufferBuilderImageAspect;
|
||||||
use command_buffer::validity::*;
|
use command_buffer::validity::*;
|
||||||
use descriptor::descriptor_set::DescriptorSetsCollection;
|
use descriptor::descriptor_set::DescriptorSetsCollection;
|
||||||
@ -40,6 +41,7 @@ use descriptor::pipeline_layout::PipelineLayoutAbstract;
|
|||||||
use device::Device;
|
use device::Device;
|
||||||
use device::DeviceOwned;
|
use device::DeviceOwned;
|
||||||
use device::Queue;
|
use device::Queue;
|
||||||
|
use format::ClearValue;
|
||||||
use framebuffer::FramebufferAbstract;
|
use framebuffer::FramebufferAbstract;
|
||||||
use framebuffer::RenderPassDescClearValues;
|
use framebuffer::RenderPassDescClearValues;
|
||||||
use framebuffer::SubpassContents;
|
use framebuffer::SubpassContents;
|
||||||
@ -169,6 +171,58 @@ impl<P> AutoCommandBufferBuilder<P> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds a command that clears all the layers and mipmap levels of a color image with a
|
||||||
|
/// specific value.
|
||||||
|
///
|
||||||
|
/// # Panic
|
||||||
|
///
|
||||||
|
/// Panics if `color` is not a color value.
|
||||||
|
///
|
||||||
|
pub fn clear_color_image<I>(self, image: I, color: ClearValue)
|
||||||
|
-> Result<Self, ClearColorImageError>
|
||||||
|
where I: ImageAccess + Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
let layers = image.dimensions().array_layers();
|
||||||
|
let levels = image.mipmap_levels();
|
||||||
|
|
||||||
|
self.clear_color_image_dimensions(image, 0, layers, 0, levels, color)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds a command that clears a color image with a specific value.
|
||||||
|
///
|
||||||
|
/// # Panic
|
||||||
|
///
|
||||||
|
/// - Panics if `color` is not a color value.
|
||||||
|
///
|
||||||
|
pub fn clear_color_image_dimensions<I>(mut self, image: I, first_layer: u32, num_layers: u32,
|
||||||
|
first_mipmap: u32, num_mipmaps: u32, color: ClearValue)
|
||||||
|
-> Result<Self, ClearColorImageError>
|
||||||
|
where I: ImageAccess + Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
unsafe {
|
||||||
|
self.ensure_outside_render_pass()?;
|
||||||
|
check_clear_color_image(self.device(), &image, first_layer, num_layers,
|
||||||
|
first_mipmap, num_mipmaps)?;
|
||||||
|
|
||||||
|
match color {
|
||||||
|
ClearValue::Float(_) | ClearValue::Int(_) | ClearValue::Uint(_) => {},
|
||||||
|
_ => panic!("The clear color is not a color value"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let region = UnsafeCommandBufferBuilderColorImageClear {
|
||||||
|
base_mip_level: first_mipmap,
|
||||||
|
level_count: num_mipmaps,
|
||||||
|
base_array_layer: first_layer,
|
||||||
|
layer_count: num_layers,
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: let choose layout
|
||||||
|
self.inner.clear_color_image(image, ImageLayout::TransferDstOptimal, color,
|
||||||
|
iter::once(region))?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Adds a command that copies from a buffer to another.
|
/// Adds a command that copies from a buffer to another.
|
||||||
///
|
///
|
||||||
/// This command will copy from the source to the destination. If their size is not equal, then
|
/// This command will copy from the source to the destination. If their size is not equal, then
|
||||||
@ -664,6 +718,12 @@ err_gen!(BeginRenderPassError {
|
|||||||
SyncCommandBufferBuilderError
|
SyncCommandBufferBuilderError
|
||||||
});
|
});
|
||||||
|
|
||||||
|
err_gen!(ClearColorImageError {
|
||||||
|
AutoCommandBufferBuilderContextError,
|
||||||
|
CheckClearColorImageError,
|
||||||
|
SyncCommandBufferBuilderError
|
||||||
|
});
|
||||||
|
|
||||||
err_gen!(CopyBufferError {
|
err_gen!(CopyBufferError {
|
||||||
AutoCommandBufferBuilderContextError,
|
AutoCommandBufferBuilderContextError,
|
||||||
CheckCopyBufferError,
|
CheckCopyBufferError,
|
||||||
|
@ -31,6 +31,7 @@ use command_buffer::sys::UnsafeCommandBuffer;
|
|||||||
use command_buffer::sys::UnsafeCommandBufferBuilder;
|
use command_buffer::sys::UnsafeCommandBufferBuilder;
|
||||||
use command_buffer::sys::UnsafeCommandBufferBuilderBindVertexBuffer;
|
use command_buffer::sys::UnsafeCommandBufferBuilderBindVertexBuffer;
|
||||||
use command_buffer::sys::UnsafeCommandBufferBuilderBufferImageCopy;
|
use command_buffer::sys::UnsafeCommandBufferBuilderBufferImageCopy;
|
||||||
|
use command_buffer::sys::UnsafeCommandBufferBuilderColorImageClear;
|
||||||
use command_buffer::sys::UnsafeCommandBufferBuilderPipelineBarrier;
|
use command_buffer::sys::UnsafeCommandBufferBuilderPipelineBarrier;
|
||||||
use descriptor::descriptor::ShaderStages;
|
use descriptor::descriptor::ShaderStages;
|
||||||
use descriptor::descriptor_set::DescriptorSet;
|
use descriptor::descriptor_set::DescriptorSet;
|
||||||
@ -801,6 +802,75 @@ impl<P> SyncCommandBufferBuilder<P> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calls `vkCmdClearColorImage` on the builder.
|
||||||
|
///
|
||||||
|
/// Does nothing if the list of regions is empty, as it would be a no-op and isn't a valid
|
||||||
|
/// usage of the command anyway.
|
||||||
|
pub unsafe fn clear_color_image<I, R>(&mut self, image: I, layout: ImageLayout,
|
||||||
|
color: ClearValue, regions: R)
|
||||||
|
-> Result<(), SyncCommandBufferBuilderError>
|
||||||
|
where I: ImageAccess + Send + Sync + 'static,
|
||||||
|
R: Iterator<Item = UnsafeCommandBufferBuilderColorImageClear> + Send + Sync + 'static
|
||||||
|
{
|
||||||
|
struct Cmd<I, R> {
|
||||||
|
image: Option<I>,
|
||||||
|
layout: ImageLayout,
|
||||||
|
color: ClearValue,
|
||||||
|
regions: Option<R>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P, I, R> Command<P> for Cmd<I, R>
|
||||||
|
where I: ImageAccess + Send + Sync + 'static,
|
||||||
|
R: Iterator<Item = UnsafeCommandBufferBuilderColorImageClear> + Send + Sync + 'static
|
||||||
|
{
|
||||||
|
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder<P>) {
|
||||||
|
out.clear_color_image(self.image.as_ref().unwrap(), self.layout, self.color,
|
||||||
|
self.regions.take().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_final_command(mut self: Box<Self>) -> Box<FinalCommand + Send + Sync> {
|
||||||
|
struct Fin<I>(I);
|
||||||
|
impl<I> FinalCommand for Fin<I>
|
||||||
|
where I: ImageAccess + Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
fn image(&self, num: usize) -> &ImageAccess {
|
||||||
|
assert_eq!(num, 0);
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: borrow checker somehow doesn't accept `self.image` without using an Option.
|
||||||
|
Box::new(Fin(self.image.take().unwrap()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn image(&self, num: usize) -> &ImageAccess {
|
||||||
|
assert_eq!(num, 0);
|
||||||
|
self.image.as_ref().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.commands.lock().unwrap().commands.push(Box::new(Cmd {
|
||||||
|
image: Some(image),
|
||||||
|
layout,
|
||||||
|
color,
|
||||||
|
regions: Some(regions),
|
||||||
|
}));
|
||||||
|
self.prev_cmd_resource(KeyTy::Image,
|
||||||
|
0,
|
||||||
|
true,
|
||||||
|
PipelineStages {
|
||||||
|
transfer: true,
|
||||||
|
..PipelineStages::none()
|
||||||
|
},
|
||||||
|
AccessFlagBits {
|
||||||
|
transfer_write: true,
|
||||||
|
..AccessFlagBits::none()
|
||||||
|
},
|
||||||
|
layout,
|
||||||
|
layout)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Calls `vkCmdCopyBuffer` on the builder.
|
/// Calls `vkCmdCopyBuffer` on the builder.
|
||||||
///
|
///
|
||||||
/// Does nothing if the list of regions is empty, as it would be a no-op and isn't a valid
|
/// Does nothing if the list of regions is empty, as it would be a no-op and isn't a valid
|
||||||
|
@ -30,6 +30,7 @@ use descriptor::pipeline_layout::PipelineLayoutAbstract;
|
|||||||
use device::Device;
|
use device::Device;
|
||||||
use device::DeviceOwned;
|
use device::DeviceOwned;
|
||||||
use format::ClearValue;
|
use format::ClearValue;
|
||||||
|
use format::FormatTy;
|
||||||
use framebuffer::EmptySinglePassRenderPassDesc;
|
use framebuffer::EmptySinglePassRenderPassDesc;
|
||||||
use framebuffer::Framebuffer;
|
use framebuffer::Framebuffer;
|
||||||
use framebuffer::FramebufferAbstract;
|
use framebuffer::FramebufferAbstract;
|
||||||
@ -507,6 +508,73 @@ impl<P> UnsafeCommandBufferBuilder<P> {
|
|||||||
rects.len() as u32, rects.as_ptr());
|
rects.len() as u32, rects.as_ptr());
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
/// Calls `vkCmdClearColorImage` on the builder.
|
||||||
|
///
|
||||||
|
/// Does nothing if the list of regions is empty, as it would be a no-op and isn't a valid
|
||||||
|
/// usage of the command anyway.
|
||||||
|
// TODO: ClearValue could be more precise
|
||||||
|
pub unsafe fn clear_color_image<I, R>(&mut self, image: &I, layout: ImageLayout,
|
||||||
|
color: ClearValue, regions: R)
|
||||||
|
where I: ?Sized + ImageAccess,
|
||||||
|
R: Iterator<Item = UnsafeCommandBufferBuilderColorImageClear>
|
||||||
|
{
|
||||||
|
debug_assert!(image.format().ty() == FormatTy::Float ||
|
||||||
|
image.format().ty() == FormatTy::Uint ||
|
||||||
|
image.format().ty() == FormatTy::Sint);
|
||||||
|
|
||||||
|
let image = image.inner();
|
||||||
|
debug_assert!(image.image.usage_transfer_destination());
|
||||||
|
debug_assert!(layout == ImageLayout::General ||
|
||||||
|
layout == ImageLayout::TransferDstOptimal);
|
||||||
|
|
||||||
|
let color = match color {
|
||||||
|
ClearValue::Float(val) => {
|
||||||
|
vk::ClearColorValue::float32(val)
|
||||||
|
},
|
||||||
|
ClearValue::Int(val) => {
|
||||||
|
vk::ClearColorValue::int32(val)
|
||||||
|
},
|
||||||
|
ClearValue::Uint(val) => {
|
||||||
|
vk::ClearColorValue::uint32(val)
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
vk::ClearColorValue::float32([0.0; 4])
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let regions: SmallVec<[_; 8]> = regions
|
||||||
|
.filter_map(|region| {
|
||||||
|
debug_assert!(region.layer_count + region.base_array_layer <= image.num_layers as u32);
|
||||||
|
debug_assert!(region.level_count + region.base_mip_level <= image.num_mipmap_levels as u32);
|
||||||
|
|
||||||
|
if region.layer_count == 0 || region.level_count == 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(vk::ImageSubresourceRange {
|
||||||
|
aspectMask: vk::IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
baseMipLevel: region.base_mip_level + image.first_mipmap_level as u32,
|
||||||
|
levelCount: region.level_count,
|
||||||
|
baseArrayLayer: region.base_array_layer + image.first_layer as u32,
|
||||||
|
layerCount: region.layer_count,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if regions.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let vk = self.device().pointers();
|
||||||
|
let cmd = self.internal_object();
|
||||||
|
vk.CmdClearColorImage(cmd,
|
||||||
|
image.image.internal_object(),
|
||||||
|
layout as u32,
|
||||||
|
&color,
|
||||||
|
regions.len() as u32,
|
||||||
|
regions.as_ptr());
|
||||||
|
}
|
||||||
|
|
||||||
/// Calls `vkCmdCopyBuffer` on the builder.
|
/// Calls `vkCmdCopyBuffer` on the builder.
|
||||||
///
|
///
|
||||||
/// Does nothing if the list of regions is empty, as it would be a no-op and isn't a valid
|
/// Does nothing if the list of regions is empty, as it would be a no-op and isn't a valid
|
||||||
@ -1098,6 +1166,15 @@ impl UnsafeCommandBufferBuilderImageAspect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: move somewhere else?
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
|
pub struct UnsafeCommandBufferBuilderColorImageClear {
|
||||||
|
pub base_mip_level: u32,
|
||||||
|
pub level_count: u32,
|
||||||
|
pub base_array_layer: u32,
|
||||||
|
pub layer_count: u32,
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: move somewhere else?
|
// TODO: move somewhere else?
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub struct UnsafeCommandBufferBuilderBufferImageCopy {
|
pub struct UnsafeCommandBufferBuilderBufferImageCopy {
|
||||||
|
74
vulkano/src/command_buffer/validity/clear_color_image.rs
Normal file
74
vulkano/src/command_buffer/validity/clear_color_image.rs
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// 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::error;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
use VulkanObject;
|
||||||
|
use device::Device;
|
||||||
|
use image::ImageAccess;
|
||||||
|
|
||||||
|
/// Checks whether a clear color image command is valid.
|
||||||
|
///
|
||||||
|
/// # Panic
|
||||||
|
///
|
||||||
|
/// - Panics if the destination was not created with `device`.
|
||||||
|
///
|
||||||
|
pub fn check_clear_color_image<I>(device: &Device, image: &I, first_layer: u32, num_layers: u32,
|
||||||
|
first_mipmap: u32, num_mipmaps: u32)
|
||||||
|
-> Result<(), CheckClearColorImageError>
|
||||||
|
where I: ?Sized + ImageAccess,
|
||||||
|
{
|
||||||
|
assert_eq!(image.inner().image.device().internal_object(),
|
||||||
|
device.internal_object());
|
||||||
|
|
||||||
|
if !image.inner().image.usage_transfer_destination() {
|
||||||
|
return Err(CheckClearColorImageError::MissingTransferUsage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if first_layer + num_layers > image.dimensions().array_layers() {
|
||||||
|
return Err(CheckClearColorImageError::OutOfRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
if first_mipmap + num_mipmaps > image.mipmap_levels() {
|
||||||
|
return Err(CheckClearColorImageError::OutOfRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Error that can happen from `check_clear_color_image`.
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub enum CheckClearColorImageError {
|
||||||
|
/// The image is missing the transfer destination usage.
|
||||||
|
MissingTransferUsage,
|
||||||
|
/// The array layers and mipmap levels are out of range.
|
||||||
|
OutOfRange,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl error::Error for CheckClearColorImageError {
|
||||||
|
#[inline]
|
||||||
|
fn description(&self) -> &str {
|
||||||
|
match *self {
|
||||||
|
CheckClearColorImageError::MissingTransferUsage => {
|
||||||
|
"the image is missing the transfer destination usage"
|
||||||
|
},
|
||||||
|
CheckClearColorImageError::OutOfRange => {
|
||||||
|
"the array layers and mipmap levels are out of range"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for CheckClearColorImageError {
|
||||||
|
#[inline]
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
|
write!(fmt, "{}", error::Error::description(self))
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
//! Functions that check the validity of commands.
|
//! Functions that check the validity of commands.
|
||||||
|
|
||||||
|
pub use self::clear_color_image::{check_clear_color_image, CheckClearColorImageError};
|
||||||
pub use self::copy_buffer::{CheckCopyBufferError, check_copy_buffer, CheckCopyBuffer};
|
pub use self::copy_buffer::{CheckCopyBufferError, check_copy_buffer, CheckCopyBuffer};
|
||||||
pub use self::descriptor_sets::{check_descriptor_sets_validity, CheckDescriptorSetsValidityError};
|
pub use self::descriptor_sets::{check_descriptor_sets_validity, CheckDescriptorSetsValidityError};
|
||||||
pub use self::dispatch::{check_dispatch, CheckDispatchError};
|
pub use self::dispatch::{check_dispatch, CheckDispatchError};
|
||||||
@ -19,6 +20,7 @@ pub use self::push_constants::{check_push_constants_validity, CheckPushConstants
|
|||||||
pub use self::update_buffer::{CheckUpdateBufferError, check_update_buffer};
|
pub use self::update_buffer::{CheckUpdateBufferError, check_update_buffer};
|
||||||
pub use self::vertex_buffers::{check_vertex_buffers, CheckVertexBuffer, CheckVertexBufferError};
|
pub use self::vertex_buffers::{check_vertex_buffers, CheckVertexBuffer, CheckVertexBufferError};
|
||||||
|
|
||||||
|
mod clear_color_image;
|
||||||
mod copy_buffer;
|
mod copy_buffer;
|
||||||
mod descriptor_sets;
|
mod descriptor_sets;
|
||||||
mod dispatch;
|
mod dispatch;
|
||||||
|
Loading…
Reference in New Issue
Block a user