Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What if Ash #12

Closed
wants to merge 21 commits into from
13 changes: 7 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
[workspace]

members = [
"chain",
"command",
"factory",
"frame",
"memory",
"mesh",
"renderer",
"rendy",
"resource",
"command",
"layout",
"layout-derive",
"graph",
"rendy"
"wsi",
]
4 changes: 1 addition & 3 deletions chain/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,5 @@ version = "0.1.0"
authors = ["omni-viral <scareaangel@gmail.com>"]

[dependencies]
bitflags = "1.0"
ash = { path = "../../ash/ash" }
fnv = "1.0"
failure = "0.1"
rendy-resource = { path = "../resource" }
153 changes: 73 additions & 80 deletions chain/src/access.rs
Original file line number Diff line number Diff line change
@@ -1,89 +1,82 @@
bitflags! {
/// Bitmask specifying memory access types that will participate in a memory dependency.
/// See Vulkan docs for detailed info:
/// <https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkAccessFlagBits.html>
#[repr(transparent)]
pub struct AccessFlags: u32 {
/// Access type performed by the device to read commands from indirect command buffer.
const INDIRECT_COMMAND_READ = 0x00000001;

/// Access type performed by the device to read from index buffer.
const INDEX_READ = 0x00000002;
use ash::vk::AccessFlags;

/// Access type performed by the device to read from vertex attributes.
const VERTEX_ATTRIBUTE_READ = 0x00000004;

/// Access type performed by the device to read from uniform buffers.
const UNIFORM_READ = 0x00000008;

/// Access type performed by the device to read from input attachment.
const INPUT_ATTACHMENT_READ = 0x00000010;

/// Access type performed by the device to read from storage/uniform-texel/storage-texel buffers or sampled/storage images.
const SHADER_READ = 0x00000020;

/// Access type performed by the device to write to storage/storage-texel buffers or storage images.
const SHADER_WRITE = 0x00000040;

/// Access type performed by the device to read from color attachment.
const COLOR_ATTACHMENT_READ = 0x00000080;

/// Access type performed by the device to write to color attachment.
const COLOR_ATTACHMENT_WRITE = 0x00000100;

/// Access type performed by the device to read from depth-stencil attachment.
const DEPTH_STENCIL_ATTACHMENT_READ = 0x00000200;

/// Access type performed by the device to write to depth-stencil attachment.
const DEPTH_STENCIL_ATTACHMENT_WRITE = 0x00000400;

/// Access type performed by the device to read content from source of transfer operations.
const TRANSFER_READ = 0x00000800;

/// Access type performed by the device to write content to destination of transfer operations.
const TRANSFER_WRITE = 0x00001000;

/// Access type performed by host reading.
const HOST_READ = 0x00002000;

/// Access type performed by host writing.
const HOST_WRITE = 0x00004000;
/// Add methods to fetch higher-level info from access flags.
pub trait AccessFlagsExt {
/// Check if this access must be exclusive.
///
/// Basically this checks if all flags are known read flags.
fn exclusive(&self) -> bool;
}

/// Access type performed to read data via non-specific entities.
const MEMORY_READ = 0x00008000;
#[inline]
#[allow(unused)]
fn known_flags() -> AccessFlags { AccessFlags::INDIRECT_COMMAND_READ
| AccessFlags::INDEX_READ
| AccessFlags::VERTEX_ATTRIBUTE_READ
| AccessFlags::UNIFORM_READ
| AccessFlags::INPUT_ATTACHMENT_READ
| AccessFlags::SHADER_READ
| AccessFlags::SHADER_WRITE
| AccessFlags::COLOR_ATTACHMENT_READ
| AccessFlags::COLOR_ATTACHMENT_WRITE
| AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ
| AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE
| AccessFlags::TRANSFER_READ
| AccessFlags::TRANSFER_WRITE
| AccessFlags::HOST_READ
| AccessFlags::HOST_WRITE
| AccessFlags::MEMORY_READ
| AccessFlags::MEMORY_WRITE
// | AccessFlags::TRANSFORM_FEEDBACK_WRITE_EXT
// | AccessFlags::TRANSFORM_FEEDBACK_COUNTER_READ_EXT
// | AccessFlags::TRANSFORM_FEEDBACK_COUNTER_WRITE_EXT
// | AccessFlags::CONDITIONAL_RENDERING_READ_EXT
| AccessFlags::COMMAND_PROCESS_READ_NVX
| AccessFlags::COMMAND_PROCESS_WRITE_NVX
| AccessFlags::COLOR_ATTACHMENT_READ_NONCOHERENT_EXT
// | AccessFlags::SHADING_RATE_IMAGE_READ_NV
// | AccessFlags::ACCELERATION_STRUCTURE_READ_NVX
// | AccessFlags::ACCELERATION_STRUCTURE_WRITE_NVX
}

/// Access type performed to write data via non-specific entities.
const MEMORY_WRITE = 0x00010000;
}
#[inline]
#[allow(unused)]
fn write_flags() -> AccessFlags { AccessFlags::SHADER_WRITE
| AccessFlags::COLOR_ATTACHMENT_WRITE
| AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE
| AccessFlags::TRANSFER_WRITE
| AccessFlags::HOST_WRITE
| AccessFlags::MEMORY_WRITE
// | AccessFlags::TRANSFORM_FEEDBACK_WRITE_EXT
// | AccessFlags::TRANSFORM_FEEDBACK_COUNTER_WRITE_EXT
| AccessFlags::COMMAND_PROCESS_WRITE_NVX
// | AccessFlags::ACCELERATION_STRUCTURE_WRITE_NVX
}

impl AccessFlags {
/// Check if flags contains at least on write flag.
pub fn is_write(&self) -> bool {
self.intersects(
AccessFlags::SHADER_WRITE
| AccessFlags::COLOR_ATTACHMENT_WRITE
| AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE
| AccessFlags::TRANSFER_WRITE
| AccessFlags::HOST_WRITE
| AccessFlags::MEMORY_WRITE,
)
}
#[inline]
fn read_flags() -> AccessFlags { AccessFlags::INDIRECT_COMMAND_READ
| AccessFlags::INDEX_READ
| AccessFlags::VERTEX_ATTRIBUTE_READ
| AccessFlags::UNIFORM_READ
| AccessFlags::INPUT_ATTACHMENT_READ
| AccessFlags::SHADER_READ
| AccessFlags::COLOR_ATTACHMENT_READ
| AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ
| AccessFlags::TRANSFER_READ
| AccessFlags::HOST_READ
| AccessFlags::MEMORY_READ
// | AccessFlags::TRANSFORM_FEEDBACK_COUNTER_READ_EXT
// | AccessFlags::CONDITIONAL_RENDERING_READ_EXT
| AccessFlags::COMMAND_PROCESS_READ_NVX
| AccessFlags::COLOR_ATTACHMENT_READ_NONCOHERENT_EXT
// | AccessFlags::SHADING_RATE_IMAGE_READ_NV
// | AccessFlags::ACCELERATION_STRUCTURE_READ_NVX
}

/// Check if flags contains at least on read flag.
pub fn is_read(&self) -> bool {
self.intersects(
AccessFlags::INDIRECT_COMMAND_READ
| AccessFlags::INDEX_READ
| AccessFlags::VERTEX_ATTRIBUTE_READ
| AccessFlags::UNIFORM_READ
| AccessFlags::INPUT_ATTACHMENT_READ
| AccessFlags::SHADER_READ
| AccessFlags::COLOR_ATTACHMENT_READ
| AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ
| AccessFlags::TRANSFER_READ
| AccessFlags::HOST_READ
| AccessFlags::MEMORY_READ,
)
impl AccessFlagsExt for AccessFlags {
#[inline]
fn exclusive(&self) -> bool {
read_flags().subset(*self)
}
}
14 changes: 8 additions & 6 deletions chain/src/chain/link.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use access::AccessFlags;

use ash::vk::{AccessFlags, PipelineStageFlags};

use access::AccessFlagsExt;
use node::State;
use resource::Resource;
use schedule::{FamilyId, QueueId, SubmissionId};
use stage::PipelineStageFlags;
use schedule::{FamilyIndex, QueueId, SubmissionId};

/// State of the link associated with queue.
/// Contains submissions range, combined access and stages bits by submissions from the range.
Expand Down Expand Up @@ -57,7 +59,7 @@ pub(crate) struct Link<R: Resource> {
queues: Vec<Option<LinkQueueState>>,

/// Family of queues.
family: FamilyId,
family: FamilyIndex,
}

/// Node for the link.
Expand Down Expand Up @@ -107,7 +109,7 @@ where

/// Get queue family that owns the resource at the link.
/// All associated submissions must be from the same queue family.
pub(crate) fn family(&self) -> FamilyId {
pub(crate) fn family(&self) -> FamilyIndex {
self.family
}

Expand Down Expand Up @@ -150,7 +152,7 @@ where
/// If compatible then the submission can be associated with the link.
pub(crate) fn compatible(&self, node: &LinkNode<R>) -> bool {
// If queue the same and states are compatible.
self.family == node.sid.family() && !(self.access | node.state.access).is_write()
self.family == node.sid.family() && !(self.access | node.state.access).exclusive()
}

/// Insert submission with specified state to the link.
Expand Down
18 changes: 9 additions & 9 deletions chain/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use chain::{BufferChains, Chain, ImageChains, Link, LinkNode};
use node::{Node, State};
use resource::{Buffer, Image, Resource};

use schedule::{FamilyId, Queue, QueueId, Schedule, Submission, SubmissionId};
use schedule::{FamilyIndex, Queue, QueueId, Schedule, Submission, SubmissionId};

use Id;

Expand All @@ -18,9 +18,9 @@ pub struct Unsynchronized;

/// Result of node scheduler.
#[derive(Debug)]
pub struct Chains<S = Unsynchronized> {
pub struct Chains {
/// Contains submissions for nodes spread among queue schedule.
pub schedule: Schedule<S>,
pub schedule: Schedule<Unsynchronized>,

/// Contains all buffer chains.
pub buffers: BufferChains,
Expand All @@ -37,7 +37,7 @@ struct Fitness {

struct ResolvedNode {
id: usize,
family: FamilyId,
family: FamilyIndex,
queues: Range<usize>,
rev_deps: Vec<usize>,
buffers: Vec<(usize, State<Buffer>)>,
Expand All @@ -48,7 +48,7 @@ impl Default for ResolvedNode {
fn default() -> Self {
ResolvedNode {
id: 0,
family: FamilyId(0),
family: FamilyIndex(0),
queues: 0..0,
rev_deps: Vec::new(),
buffers: Vec::new(),
Expand All @@ -68,7 +68,7 @@ struct ChainData<R: Resource> {
chain: Chain<R>,
last_link_wait_factor: usize,
current_link_wait_factor: usize,
current_family: Option<FamilyId>,
current_family: Option<FamilyIndex>,
}
impl<R: Resource> Default for ChainData<R> {
fn default() -> Self {
Expand All @@ -90,7 +90,7 @@ struct QueueData {
/// This function tries to find most appropriate schedule for nodes execution.
pub fn collect<Q>(nodes: Vec<Node>, max_queues: Q) -> Chains
where
Q: Fn(FamilyId) -> usize,
Q: Fn(FamilyIndex) -> usize,
{
// Resolve nodes into a form faster to work with.
let (nodes, mut unscheduled_nodes) = resolve_nodes(nodes, max_queues);
Expand Down Expand Up @@ -205,7 +205,7 @@ impl<I: Hash + Eq + Copy> LookupBuilder<I> {

fn resolve_nodes<Q>(nodes: Vec<Node>, max_queues: Q) -> (ResolvedNodeSet, Vec<usize>)
where
Q: Fn(FamilyId) -> usize,
Q: Fn(FamilyIndex) -> usize,
{
let node_count = nodes.len();

Expand Down Expand Up @@ -382,7 +382,7 @@ fn schedule_node<'a>(

fn add_to_chain<R, S>(
id: Id,
family: FamilyId,
family: FamilyIndex,
chain_data: &mut ChainData<R>,
sid: SubmissionId,
submission: &mut Submission<S>,
Expand Down
59 changes: 24 additions & 35 deletions chain/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,55 +1,44 @@
//! This crate can derive synchronization required
//! for the dependency chain of the whole execution graph.

// #![forbid(overflowing_literals)]
// #![deny(missing_copy_implementations)]
// #![deny(missing_debug_implementations)]
// #![deny(missing_docs)]
// #![deny(intra_doc_link_resolution_failure)]
// #![deny(path_statements)]
// #![deny(trivial_bounds)]
// #![deny(type_alias_bounds)]
// #![deny(unconditional_recursion)]
// #![deny(unions_with_drop_fields)]
// #![deny(while_true)]
// #![deny(unused)]
// #![deny(bad_style)]
// #![deny(future_incompatible)]
// #![warn(rust_2018_compatibility)]
// #![warn(rust_2018_idioms)]

#[macro_use]
extern crate bitflags;

#![forbid(overflowing_literals)]
#![deny(missing_copy_implementations)]
#![deny(missing_debug_implementations)]
#![deny(missing_docs)]
#![deny(intra_doc_link_resolution_failure)]
#![deny(path_statements)]
#![deny(trivial_bounds)]
#![deny(type_alias_bounds)]
#![deny(unconditional_recursion)]
#![deny(unions_with_drop_fields)]
#![deny(while_true)]
#![deny(unused)]
#![deny(bad_style)]
#![deny(future_incompatible)]
#![deny(rust_2018_compatibility)]
#![deny(rust_2018_idioms)]

extern crate ash;
extern crate fnv;

extern crate rendy_resource;

/// Unique resource id.
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Id(pub u64);

/// ???
mod access;
/// ???
mod chain;
/// ???
mod collect;
/// ???
mod node;
/// ???
mod resource;
/// ???
mod schedule;
/// ???
mod stage;
/// ???
mod sync;

pub use access::AccessFlagsExt;
pub use chain::Chain;
pub use node::{Node, State};
pub use collect::{collect, Chains, Unsynchronized};
pub use node::{Node, State, BufferState, ImageState};
pub use resource::{Buffer, Image, Resource};
pub use stage::{PipelineStageFlags, GraphicsPipelineStage, ComputePipelineStage};
pub use sync::SyncData;
pub use schedule::Schedule;

pub use schedule::{Family, FamilyIndex, Queue, QueueId, Schedule, Submission, SubmissionId};
pub use stage::{ComputePipelineStage, GraphicsPipelineStage};
pub use sync::{sync, SyncData, Barriers, BufferBarriers, ImageBarriers, Guard, Wait, Signal};
Loading