Render pass creation

This commit is contained in:
Dzmitry Malyshau 2018-10-25 17:32:57 -04:00
parent 32b92afa5c
commit 08a1bd4bc7
7 changed files with 123 additions and 16 deletions

View File

@ -6,15 +6,17 @@ pub use self::allocator::CommandAllocator;
pub use self::compute::*;
pub use self::render::*;
use hal;
use hal::{self, Device};
use {
Color, Origin3d, Stored,
BufferId, CommandBufferId, ComputePassId, DeviceId, RenderPassId, TextureId, TextureViewId,
};
use conv;
use registry::{HUB, Items, Registry};
use track::{BufferTracker, TextureTracker};
use std::iter;
use std::thread::ThreadId;
@ -88,17 +90,72 @@ pub struct CommandBufferDescriptor {}
#[no_mangle]
pub extern "C" fn wgpu_command_buffer_begin_render_pass(
command_buffer_id: CommandBufferId,
_descriptor: RenderPassDescriptor<TextureViewId>,
desc: RenderPassDescriptor<TextureViewId>,
) -> RenderPassId {
let mut cmb_guard = HUB.command_buffers.lock();
let cmb = cmb_guard.get_mut(command_buffer_id);
let device_guard = HUB.devices.lock();
let device = device_guard.get(cmb.device_id.0);
let current_comb = device.com_allocator.extend(cmb);
//let render_pass = device.create_render_pass();
let render_pass = {
let tracker = &mut cmb.texture_tracker;
let view_guard = HUB.texture_views.lock();
let depth_stencil_attachment = match desc.depth_stencil_attachment {
Some(ref at) => {
let view = view_guard.get(at.attachment);
let query = tracker.query(view.source_id.0);
let (_, layout) = conv::map_texture_state(
query.usage,
hal::format::Aspects::DEPTH | hal::format::Aspects::STENCIL,
);
Some(hal::pass::Attachment {
format: Some(conv::map_texture_format(view.format)),
samples: view.samples,
ops: conv::map_load_store_ops(at.depth_load_op, at.depth_store_op),
stencil_ops: conv::map_load_store_ops(at.stencil_load_op, at.stencil_store_op),
layouts: layout .. layout,
})
}
None => None,
};
let color_attachments = desc.color_attachments
.iter()
.map(|at| {
let view = view_guard.get(at.attachment);
let query = tracker.query(view.source_id.0);
let (_, layout) = conv::map_texture_state(query.usage, hal::format::Aspects::COLOR);
hal::pass::Attachment {
format: Some(conv::map_texture_format(view.format)),
samples: view.samples,
ops: conv::map_load_store_ops(at.load_op, at.store_op),
stencil_ops: hal::pass::AttachmentOps::DONT_CARE,
layouts: layout .. layout,
}
});
let attachments = color_attachments.chain(depth_stencil_attachment);
//TODO: retain the storage
let color_refs = (0 .. desc.color_attachments.len())
.map(|i| {
(i, hal::image::Layout::ColorAttachmentOptimal)
})
.collect::<Vec<_>>();
let ds_ref = desc.depth_stencil_attachment.as_ref().map(|_| {
(desc.color_attachments.len(), hal::image::Layout::DepthStencilAttachmentOptimal)
});
let subpass = hal::pass::SubpassDesc {
colors: &color_refs,
depth_stencil: ds_ref.as_ref(),
inputs: &[],
resolves: &[],
preserves: &[],
};
device.raw.create_render_pass(attachments, iter::once(subpass), &[])
};
//let framebuffer = device.create_framebuffer();
/*TODO:

View File

@ -1,6 +1,6 @@
use hal;
use {Extent3d, binding_model, pipeline, resource};
use {Extent3d, binding_model, command, pipeline, resource};
pub fn map_buffer_usage(
@ -358,3 +358,15 @@ pub fn map_texture_state(
(access, layout)
}
pub fn map_load_store_ops(load: command::LoadOp, store: command::StoreOp) -> hal::pass::AttachmentOps {
hal::pass::AttachmentOps {
load: match load {
command::LoadOp::Clear => hal::pass::AttachmentLoadOp::Clear,
command::LoadOp::Load => hal::pass::AttachmentLoadOp::Load,
},
store: match store {
command::StoreOp::Store => hal::pass::AttachmentStoreOp::Store,
},
}
}

View File

@ -1,6 +1,6 @@
use {back, binding_model, command, conv, pipeline, resource};
use registry::{HUB, Items, Registry};
use track::{BufferTracker, TextureTracker, TrackPermit};
use track::{BufferTracker, TextureTracker};
use {
AttachmentStateId, BindGroupLayoutId, BlendStateId, CommandBufferId, DepthStencilStateId,
DeviceId, PipelineLayoutId, QueueId, RenderPipelineId, ShaderModuleId, TextureId,
@ -115,11 +115,11 @@ pub extern "C" fn wgpu_device_create_texture(
raw: bound_image,
aspects,
});
device.texture_tracker
let query = device.texture_tracker
.lock()
.unwrap()
.track(id, resource::TextureUsageFlags::empty(), TrackPermit::empty())
.expect("Resource somehow is already registered");
.query(id);
assert!(query.initialized);
id
}

View File

@ -100,6 +100,7 @@ type BufferHandle = Buffer<B>;
// Resource
pub type TextureViewId = Id;
type TextureViewHandle = TextureView<B>;
pub type TextureId = Id;
type TextureHandle = Texture<B>;
pub type SamplerId = Id;

View File

@ -13,7 +13,7 @@ use {
BlendStateHandle, CommandBufferHandle, DepthStencilStateHandle, DeviceHandle, InstanceHandle,
RenderPassHandle, ComputePassHandle,
PipelineLayoutHandle, RenderPipelineHandle, ComputePipelineHandle, ShaderModuleHandle,
BufferHandle, TextureHandle,
BufferHandle, TextureHandle, TextureViewHandle,
};
@ -50,6 +50,7 @@ pub struct Hub {
pub(crate) compute_passes: ConcreteRegistry<ComputePassHandle>,
pub(crate) buffers: ConcreteRegistry<BufferHandle>,
pub(crate) textures: ConcreteRegistry<TextureHandle>,
pub(crate) texture_views: ConcreteRegistry<TextureViewHandle>,
}
lazy_static! {

View File

@ -1,4 +1,4 @@
use {Extent3d};
use {Extent3d, Stored, TextureId};
use hal;
@ -32,9 +32,6 @@ pub(crate) struct Buffer<B: hal::Backend> {
// TODO: mapping, unmap()
}
pub struct TextureView {
// TODO
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
@ -81,6 +78,13 @@ pub(crate) struct Texture<B: hal::Backend> {
pub aspects: hal::format::Aspects,
}
pub(crate) struct TextureView<B: hal::Backend> {
pub raw: B::ImageView,
pub source_id: Stored<TextureId>,
pub format: TextureFormat,
pub samples: hal::image::NumSamples,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub enum AddressMode {

View File

@ -14,6 +14,12 @@ pub enum Tracktion<T> {
Replace { old: T },
}
#[derive(Clone, Debug, PartialEq)]
pub struct Query<T> {
pub usage: T,
pub initialized: bool,
}
bitflags! {
pub struct TrackPermit: u32 {
const EXTEND = 1;
@ -23,14 +29,21 @@ bitflags! {
pub trait GenericUsage {
fn default() -> Self;
fn is_exclusive(&self) -> bool;
}
impl GenericUsage for BufferUsageFlags {
fn default() -> Self {
BufferUsageFlags::empty()
}
fn is_exclusive(&self) -> bool {
BufferUsageFlags::WRITE_ALL.intersects(*self)
}
}
impl GenericUsage for TextureUsageFlags {
fn default() -> Self {
TextureUsageFlags::empty()
}
fn is_exclusive(&self) -> bool {
TextureUsageFlags::WRITE_ALL.intersects(*self)
}
@ -53,7 +66,26 @@ impl<
}
}
pub fn track(&mut self, id: I, usage: U, permit: TrackPermit) -> Result<Tracktion<U>, U> {
pub fn query(&mut self, id: I) -> Query<U> {
match self.map.entry(Stored(id)) {
Entry::Vacant(e) => {
let usage = U::default();
e.insert(usage);
Query {
usage,
initialized: true,
}
}
Entry::Occupied(e) => {
Query {
usage: *e.get(),
initialized: false,
}
}
}
}
pub fn transit(&mut self, id: I, usage: U, permit: TrackPermit) -> Result<Tracktion<U>, U> {
match self.map.entry(Stored(id)) {
Entry::Vacant(e) => {
e.insert(usage);
@ -77,7 +109,7 @@ impl<
pub(crate) fn consume<'a>(&'a mut self, other: Self) -> impl 'a + Iterator<Item = (I, Range<U>)> {
other.map
.into_iter()
.flat_map(move |(id, new)| match self.track(id.0.clone(), new, TrackPermit::REPLACE) {
.flat_map(move |(id, new)| match self.transit(id.0.clone(), new, TrackPermit::REPLACE) {
Ok(Tracktion::Init) |
Ok(Tracktion::Keep) => None,
Ok(Tracktion::Replace { old }) => Some((id.0, old .. new)),