16: [WIP] render pass begin/end r=grovesNL a=kvark

Depends on https://github.com/gpuweb/gpuweb/pull/91 and https://github.com/gpuweb/gpuweb/pull/92

Co-authored-by: Dzmitry Malyshau <kvark@mozilla.com>
This commit is contained in:
bors[bot] 2018-10-01 18:14:00 +00:00
commit 69df9c4eae
10 changed files with 242 additions and 79 deletions

View File

@ -9,6 +9,7 @@ fn main() {
anisotropic_filtering: false, anisotropic_filtering: false,
}, },
}); });
let vs_bytes = include_bytes!("./../data/hello_triangle.vert.spv"); let vs_bytes = include_bytes!("./../data/hello_triangle.vert.spv");
let vs_module = device.create_shader_module(vs_bytes); let vs_module = device.create_shader_module(vs_bytes);
let fs_bytes = include_bytes!("./../data/hello_triangle.frag.spv"); let fs_bytes = include_bytes!("./../data/hello_triangle.frag.spv");
@ -49,7 +50,25 @@ fn main() {
attachment_state: &attachment_state, attachment_state: &attachment_state,
}); });
let cmd_buf = device.create_command_buffer(wgpu::CommandBufferDescriptor {}); let mut cmd_buf = device.create_command_buffer(wgpu::CommandBufferDescriptor {});
{
let color_view = unimplemented!(); //TODO!
let rpass = cmd_buf.begin_render_pass(wgpu::RenderPassDescriptor {
color_attachments: &[
wgpu::RenderPassColorAttachmentDescriptor {
attachment: &color_view,
load_op: wgpu::LoadOp::Clear,
store_op: wgpu::StoreOp::Store,
clear_color: wgpu::Color::GREEN,
},
],
depth_stencil_attachment: None,
});
rpass.end_pass();
}
let queue = device.get_queue(); let queue = device.get_queue();
queue.submit(&[cmd_buf]); queue.submit(&[cmd_buf]);
} }

View File

@ -1,4 +1,5 @@
use super::CommandBuffer; use super::CommandBuffer;
use {DeviceId, Stored};
use hal::command::RawCommandBuffer; use hal::command::RawCommandBuffer;
use hal::pool::RawCommandPool; use hal::pool::RawCommandPool;
@ -14,7 +15,7 @@ struct CommandPool<B: hal::Backend> {
available: Vec<CommandBuffer<B>>, available: Vec<CommandBuffer<B>>,
} }
pub struct Inner<B: hal::Backend> { struct Inner<B: hal::Backend> {
pools: HashMap<thread::ThreadId, CommandPool<B>>, pools: HashMap<thread::ThreadId, CommandPool<B>>,
pending: Vec<CommandBuffer<B>>, pending: Vec<CommandBuffer<B>>,
} }
@ -35,7 +36,9 @@ impl<B: hal::Backend> CommandAllocator<B> {
} }
} }
pub fn allocate(&self, device: &B::Device) -> CommandBuffer<B> { pub fn allocate(
&self, device_id: DeviceId, device: &B::Device
) -> CommandBuffer<B> {
let thread_id = thread::current().id(); let thread_id = thread::current().id();
let mut inner = self.inner.lock().unwrap(); let mut inner = self.inner.lock().unwrap();
let pool = inner.pools.entry(thread_id).or_insert_with(|| CommandPool { let pool = inner.pools.entry(thread_id).or_insert_with(|| CommandPool {
@ -47,15 +50,17 @@ impl<B: hal::Backend> CommandAllocator<B> {
}); });
if let Some(cmd_buf) = pool.available.pop() { if let Some(cmd_buf) = pool.available.pop() {
assert_eq!(device_id, cmd_buf.device_id.0);
device.reset_fence(&cmd_buf.fence); device.reset_fence(&cmd_buf.fence);
return cmd_buf; return cmd_buf;
} }
for raw in pool.raw.allocate(20, hal::command::RawLevel::Primary) { for cmbuf in pool.raw.allocate(20, hal::command::RawLevel::Primary) {
pool.available.push(CommandBuffer { pool.available.push(CommandBuffer {
raw, raw: Some(cmbuf),
fence: device.create_fence(false), fence: device.create_fence(false),
recorded_thread_id: thread_id, recorded_thread_id: thread_id,
device_id: Stored(device_id),
}); });
} }
pool.available.pop().unwrap() pool.available.pop().unwrap()
@ -66,7 +71,7 @@ impl<B: hal::Backend> CommandAllocator<B> {
} }
pub fn recycle(&self, mut cmd_buf: CommandBuffer<B>) { pub fn recycle(&self, mut cmd_buf: CommandBuffer<B>) {
cmd_buf.raw.reset(false); cmd_buf.raw.as_mut().unwrap().reset(false);
self.inner self.inner
.lock() .lock()
.unwrap() .unwrap()

View File

@ -2,16 +2,17 @@ mod allocator;
mod compute; mod compute;
mod render; mod render;
pub use self::allocator::*; pub use self::allocator::CommandAllocator;
pub use self::compute::*; pub use self::compute::*;
pub use self::render::*; pub use self::render::*;
use hal; use hal;
use { use {
BufferId, Color, CommandBufferId, ComputePassId, Origin3d, RenderPassId, TextureId, Color, Origin3d, Stored,
TextureViewId, BufferId, CommandBufferId, ComputePassId, DeviceId, RenderPassId, TextureId, TextureViewId,
}; };
use registry::{self, Items, Registry};
use std::thread::ThreadId; use std::thread::ThreadId;
@ -29,16 +30,16 @@ pub enum StoreOp {
} }
#[repr(C)] #[repr(C)]
pub struct RenderPassColorAttachmentDescriptor { pub struct RenderPassColorAttachmentDescriptor<T> {
pub attachment: TextureViewId, pub attachment: T,
pub load_op: LoadOp, pub load_op: LoadOp,
pub store_op: StoreOp, pub store_op: StoreOp,
pub clear_color: Color, pub clear_color: Color,
} }
#[repr(C)] #[repr(C)]
pub struct RenderPassDepthStencilAttachmentDescriptor { pub struct RenderPassDepthStencilAttachmentDescriptor<T> {
pub attachment: TextureViewId, pub attachment: T,
pub depth_load_op: LoadOp, pub depth_load_op: LoadOp,
pub depth_store_op: StoreOp, pub depth_store_op: StoreOp,
pub clear_depth: f32, pub clear_depth: f32,
@ -48,9 +49,9 @@ pub struct RenderPassDepthStencilAttachmentDescriptor {
} }
#[repr(C)] #[repr(C)]
pub struct RenderPassDescriptor<'a> { pub struct RenderPassDescriptor<'a, T: 'a> {
pub color_attachments: &'a [RenderPassColorAttachmentDescriptor], pub color_attachments: &'a [RenderPassColorAttachmentDescriptor<T>],
pub depth_stencil_attachment: RenderPassDepthStencilAttachmentDescriptor, pub depth_stencil_attachment: Option<RenderPassDepthStencilAttachmentDescriptor<T>>,
} }
#[repr(C)] #[repr(C)]
@ -71,9 +72,10 @@ pub struct TextureCopyView {
} }
pub struct CommandBuffer<B: hal::Backend> { pub struct CommandBuffer<B: hal::Backend> {
pub(crate) raw: B::CommandBuffer, pub(crate) raw: Option<B::CommandBuffer>,
fence: B::Fence, fence: B::Fence,
recorded_thread_id: ThreadId, recorded_thread_id: ThreadId,
device_id: Stored<DeviceId>,
} }
#[repr(C)] #[repr(C)]
@ -81,9 +83,32 @@ pub struct CommandBufferDescriptor {}
#[no_mangle] #[no_mangle]
pub extern "C" fn wgpu_command_buffer_begin_render_pass( pub extern "C" fn wgpu_command_buffer_begin_render_pass(
_command_buffer: CommandBufferId, command_buffer_id: CommandBufferId,
_descriptor: RenderPassDescriptor<TextureViewId>,
) -> RenderPassId { ) -> RenderPassId {
unimplemented!() let mut cmb_guard = registry::COMMAND_BUFFER_REGISTRY.lock();
let mut cmb = cmb_guard.get_mut(command_buffer_id);
let raw = cmb.raw.take().unwrap();
let mut device_guard = registry::DEVICE_REGISTRY.lock();
let device = &device_guard.get(cmb.device_id.0).raw;
//let render_pass = device.create_render_pass();
//let framebuffer = device.create_framebuffer();
/*TODO:
raw.begin_render_pass(
render_pass: &B::RenderPass,
framebuffer: &B::Framebuffer,
render_area: pso::Rect,
clear_values: T,
hal::SubpassContents::Inline,
);*/
registry::RENDER_PASS_REGISTRY
.lock()
.register(RenderPass::new(raw, command_buffer_id))
} }
#[no_mangle] #[no_mangle]

View File

@ -1,7 +1,42 @@
use hal; use hal;
use hal::command::RawCommandBuffer;
//use {CommandBuffer, CommandBufferId, RenderPassId}; use registry::{self, Items, Registry};
use {
Stored,
CommandBufferId, RenderPassId,
};
pub struct RenderPass<B: hal::Backend> { pub struct RenderPass<B: hal::Backend> {
raw: B::CommandBuffer, raw: B::CommandBuffer,
cmb_id: Stored<CommandBufferId>,
}
// This is needed for `cmb_id` - would be great to remove.
#[cfg(not(feature = "remote"))]
unsafe impl<B: hal::Backend> Sync for RenderPass<B> {}
impl<B: hal::Backend> RenderPass<B> {
pub fn new(raw: B::CommandBuffer, cmb_id: CommandBufferId) -> Self {
RenderPass {
raw,
cmb_id: Stored(cmb_id),
}
}
}
#[no_mangle]
pub extern "C" fn wgpu_render_pass_end_pass(
render_pass_id: RenderPassId,
) -> CommandBufferId {
let mut rp = registry::RENDER_PASS_REGISTRY
.lock()
.take(render_pass_id);
rp.raw.end_render_pass();
registry::COMMAND_BUFFER_REGISTRY
.lock()
.get_mut(rp.cmb_id.0)
.raw = Some(rp.raw);
rp.cmb_id.0
} }

View File

@ -189,7 +189,7 @@ fn map_stencil_face(
hal::pso::StencilFace { hal::pso::StencilFace {
fun: map_compare_function(stencil_state_face_desc.compare), fun: map_compare_function(stencil_state_face_desc.compare),
mask_read: hal::pso::State::Static(stencil_read_mask), // TODO dynamic? mask_read: hal::pso::State::Static(stencil_read_mask), // TODO dynamic?
mask_write: hal::pso::State::Static(stencil_read_mask), // TODO dynamic? mask_write: hal::pso::State::Static(stencil_write_mask), // TODO dynamic?
op_fail: map_stencil_operation(stencil_state_face_desc.stencil_fail_op), op_fail: map_stencil_operation(stencil_state_face_desc.stencil_fail_op),
op_depth_fail: map_stencil_operation(stencil_state_face_desc.depth_fail_op), op_depth_fail: map_stencil_operation(stencil_state_face_desc.depth_fail_op),
op_pass: map_stencil_operation(stencil_state_face_desc.pass_op), op_pass: map_stencil_operation(stencil_state_face_desc.pass_op),

View File

@ -11,7 +11,7 @@ use {
}; };
pub struct Device<B: hal::Backend> { pub struct Device<B: hal::Backend> {
device: B::Device, pub(crate) raw: B::Device,
queue_group: hal::QueueGroup<B, hal::General>, queue_group: hal::QueueGroup<B, hal::General>,
mem_allocator: memory::SmartAllocator<B>, mem_allocator: memory::SmartAllocator<B>,
com_allocator: command::CommandAllocator<B>, com_allocator: command::CommandAllocator<B>,
@ -19,12 +19,12 @@ pub struct Device<B: hal::Backend> {
impl<B: hal::Backend> Device<B> { impl<B: hal::Backend> Device<B> {
pub(crate) fn new( pub(crate) fn new(
device: B::Device, raw: B::Device,
queue_group: hal::QueueGroup<B, hal::General>, queue_group: hal::QueueGroup<B, hal::General>,
mem_props: hal::MemoryProperties, mem_props: hal::MemoryProperties,
) -> Self { ) -> Self {
Device { Device {
device, raw,
mem_allocator: memory::SmartAllocator::new(mem_props, 1, 1, 1, 1), mem_allocator: memory::SmartAllocator::new(mem_props, 1, 1, 1, 1),
com_allocator: command::CommandAllocator::new(queue_group.family()), com_allocator: command::CommandAllocator::new(queue_group.family()),
queue_group, queue_group,
@ -44,7 +44,7 @@ pub extern "C" fn wgpu_device_create_bind_group_layout(
let bindings = unsafe { slice::from_raw_parts(desc.bindings, desc.bindings_length) }; let bindings = unsafe { slice::from_raw_parts(desc.bindings, desc.bindings_length) };
let device_guard = registry::DEVICE_REGISTRY.lock(); let device_guard = registry::DEVICE_REGISTRY.lock();
let device = device_guard.get(device_id); let device = device_guard.get(device_id);
let descriptor_set_layout = device.device.create_descriptor_set_layout( let descriptor_set_layout = device.raw.create_descriptor_set_layout(
bindings.iter().map(|binding| { bindings.iter().map(|binding| {
hal::pso::DescriptorSetLayoutBinding { hal::pso::DescriptorSetLayoutBinding {
binding: binding.binding, binding: binding.binding,
@ -75,7 +75,7 @@ pub extern "C" fn wgpu_device_create_pipeline_layout(
.map(|id| bind_group_layout_guard.get(id.clone())) .map(|id| bind_group_layout_guard.get(id.clone()))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let device_guard = registry::DEVICE_REGISTRY.lock(); let device_guard = registry::DEVICE_REGISTRY.lock();
let device = &device_guard.get(device_id).device; let device = &device_guard.get(device_id).raw;
let pipeline_layout = let pipeline_layout =
device.create_pipeline_layout(descriptor_set_layouts.iter().map(|d| &d.raw), &[]); // TODO: push constants device.create_pipeline_layout(descriptor_set_layouts.iter().map(|d| &d.raw), &[]); // TODO: push constants
registry::PIPELINE_LAYOUT_REGISTRY registry::PIPELINE_LAYOUT_REGISTRY
@ -99,7 +99,7 @@ pub extern "C" fn wgpu_device_create_blend_state(
#[no_mangle] #[no_mangle]
pub extern "C" fn wgpu_device_create_depth_stencil_state( pub extern "C" fn wgpu_device_create_depth_stencil_state(
device_id: DeviceId, _device_id: DeviceId,
desc: pipeline::DepthStencilStateDescriptor, desc: pipeline::DepthStencilStateDescriptor,
) -> DepthStencilStateId { ) -> DepthStencilStateId {
registry::DEPTH_STENCIL_STATE_REGISTRY registry::DEPTH_STENCIL_STATE_REGISTRY
@ -115,7 +115,7 @@ pub extern "C" fn wgpu_device_create_shader_module(
desc: pipeline::ShaderModuleDescriptor, desc: pipeline::ShaderModuleDescriptor,
) -> ShaderModuleId { ) -> ShaderModuleId {
let device_guard = registry::DEVICE_REGISTRY.lock(); let device_guard = registry::DEVICE_REGISTRY.lock();
let device = &device_guard.get(device_id).device; let device = &device_guard.get(device_id).raw;
let shader = device let shader = device
.create_shader_module(unsafe { slice::from_raw_parts(desc.code.bytes, desc.code.length) }) .create_shader_module(unsafe { slice::from_raw_parts(desc.code.bytes, desc.code.length) })
.unwrap(); .unwrap();
@ -131,8 +131,8 @@ pub extern "C" fn wgpu_device_create_command_buffer(
) -> CommandBufferId { ) -> CommandBufferId {
let mut device_guard = registry::DEVICE_REGISTRY.lock(); let mut device_guard = registry::DEVICE_REGISTRY.lock();
let device = device_guard.get_mut(device_id); let device = device_guard.get_mut(device_id);
let mut cmd_buf = device.com_allocator.allocate(&device.device); let mut cmd_buf = device.com_allocator.allocate(device_id, &device.raw);
cmd_buf.raw.begin( cmd_buf.raw.as_mut().unwrap().begin(
hal::command::CommandBufferFlags::ONE_TIME_SUBMIT, hal::command::CommandBufferFlags::ONE_TIME_SUBMIT,
hal::command::CommandBufferInheritanceInfo::default(), hal::command::CommandBufferInheritanceInfo::default(),
); );
@ -158,10 +158,11 @@ pub extern "C" fn wgpu_queue_submit(
let mut command_buffer_guard = registry::COMMAND_BUFFER_REGISTRY.lock(); let mut command_buffer_guard = registry::COMMAND_BUFFER_REGISTRY.lock();
for &cmb_id in command_buffer_ids { for &cmb_id in command_buffer_ids {
let mut cmd_buf = command_buffer_guard.take(cmb_id); let mut cmd_buf = command_buffer_guard.take(cmb_id);
cmd_buf.raw.finish();
{ {
let mut raw = cmd_buf.raw.as_mut().unwrap();
raw.finish();
let submission = hal::queue::RawSubmission { let submission = hal::queue::RawSubmission {
cmd_buffers: iter::once(&cmd_buf.raw), cmd_buffers: iter::once(raw),
wait_semaphores: &[], wait_semaphores: &[],
signal_semaphores: &[], signal_semaphores: &[],
}; };
@ -180,29 +181,52 @@ pub extern "C" fn wgpu_device_create_attachment_state(
device_id: DeviceId, device_id: DeviceId,
desc: pipeline::AttachmentStateDescriptor, desc: pipeline::AttachmentStateDescriptor,
) -> AttachmentStateId { ) -> AttachmentStateId {
// TODO: Assume that `AttachmentStateDescriptor` contains multiple attachments. let device_guard = registry::DEVICE_REGISTRY.lock();
let attachments = unsafe { slice::from_raw_parts(desc.formats, desc.formats_length) } let device = &device_guard.get(device_id).raw;
let color_formats = unsafe {
slice::from_raw_parts(desc.formats, desc.formats_length)
};
let color_formats: Vec<_> = color_formats
.iter() .iter()
.map(|format| { .cloned()
hal::pass::Attachment { .map(conv::map_texture_format)
format: Some(conv::map_texture_format(*format)), .collect();
samples: 1, // TODO map let depth_stencil_format = None;
ops: hal::pass::AttachmentOps {
// TODO map let base_pass = {
load: hal::pass::AttachmentLoadOp::Clear, let attachments = color_formats.iter().map(|cf| hal::pass::Attachment {
store: hal::pass::AttachmentStoreOp::Store, format: Some(*cf),
}, samples: 1,
stencil_ops: hal::pass::AttachmentOps { ops: hal::pass::AttachmentOps::DONT_CARE,
// TODO map stencil_ops: hal::pass::AttachmentOps::DONT_CARE,
load: hal::pass::AttachmentLoadOp::DontCare, layouts: hal::image::Layout::General .. hal::image::Layout::General,
store: hal::pass::AttachmentStoreOp::DontCare, });
},
layouts: hal::image::Layout::Undefined..hal::image::Layout::Present, // TODO map let subpass = hal::pass::SubpassDesc {
} colors: &[(0, hal::image::Layout::ColorAttachmentOptimal)],
}).collect(); depth_stencil: None,
inputs: &[],
resolves: &[],
preserves: &[],
};
device.create_render_pass(
attachments,
&[subpass],
&[],
)
};
let at_state = pipeline::AttachmentState {
base_pass,
color_formats,
depth_stencil_format,
};
registry::ATTACHMENT_STATE_REGISTRY registry::ATTACHMENT_STATE_REGISTRY
.lock() .lock()
.register(pipeline::AttachmentState { raw: attachments }) .register(at_state)
} }
#[no_mangle] #[no_mangle]
@ -217,7 +241,7 @@ pub extern "C" fn wgpu_device_create_render_pipeline(
}; };
let device_guard = registry::DEVICE_REGISTRY.lock(); let device_guard = registry::DEVICE_REGISTRY.lock();
let device = &device_guard.get(device_id).device; let device = &device_guard.get(device_id).raw;
let pipeline_layout_guard = registry::PIPELINE_LAYOUT_REGISTRY.lock(); let pipeline_layout_guard = registry::PIPELINE_LAYOUT_REGISTRY.lock();
let layout = &pipeline_layout_guard.get(desc.layout).raw; let layout = &pipeline_layout_guard.get(desc.layout).raw;
let pipeline_stages = unsafe { slice::from_raw_parts(desc.stages, desc.stages_length) }; let pipeline_stages = unsafe { slice::from_raw_parts(desc.stages, desc.stages_length) };
@ -318,33 +342,12 @@ pub extern "C" fn wgpu_device_create_render_pipeline(
}; };
let attachment_state_guard = registry::ATTACHMENT_STATE_REGISTRY.lock(); let attachment_state_guard = registry::ATTACHMENT_STATE_REGISTRY.lock();
let attachments = &attachment_state_guard.get(desc.attachment_state).raw; let attachment_state = attachment_state_guard.get(desc.attachment_state);
// TODO
let subpass = hal::pass::SubpassDesc {
colors: &[(0, hal::image::Layout::ColorAttachmentOptimal)],
depth_stencil: None,
inputs: &[],
resolves: &[],
preserves: &[],
};
// TODO
let subpass_dependency = hal::pass::SubpassDependency {
passes: hal::pass::SubpassRef::External..hal::pass::SubpassRef::Pass(0),
stages: hal::pso::PipelineStage::COLOR_ATTACHMENT_OUTPUT
..hal::pso::PipelineStage::COLOR_ATTACHMENT_OUTPUT,
accesses: hal::image::Access::empty()
..(hal::image::Access::COLOR_ATTACHMENT_READ
| hal::image::Access::COLOR_ATTACHMENT_WRITE),
};
let main_pass = &device.create_render_pass(&attachments[..], &[subpass], &[subpass_dependency]);
// TODO // TODO
let subpass = hal::pass::Subpass { let subpass = hal::pass::Subpass {
index: 0, index: 0,
main_pass, main_pass: &attachment_state.base_pass,
}; };
// TODO // TODO

View File

@ -40,7 +40,15 @@ pub use self::resource::*;
use back::Backend as B; use back::Backend as B;
use registry::Id; use registry::Id;
#[derive(Debug, PartialEq)]
struct Stored<T>(T);
#[cfg(not(feature = "remote"))]
unsafe impl<T> Sync for Stored<T> {}
#[cfg(not(feature = "remote"))]
unsafe impl<T> Send for Stored<T> {}
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct Color { pub struct Color {
pub r: f32, pub r: f32,
pub g: f32, pub g: f32,
@ -48,7 +56,17 @@ pub struct Color {
pub a: f32, pub a: f32,
} }
impl Color {
pub const TRANSPARENT : Self = Color { r: 0.0, g: 0.0, b: 0.0, a: 0.0 };
pub const BLACK : Self = Color { r: 0.0, g: 0.0, b: 0.0, a: 1.0 };
pub const WHITE : Self = Color { r: 1.0, g: 1.0, b: 1.0, a: 1.0 };
pub const RED : Self = Color { r: 1.0, g: 0.0, b: 0.0, a: 1.0 };
pub const GREEN : Self = Color { r: 0.0, g: 1.0, b: 0.0, a: 1.0 };
pub const BLUE : Self = Color { r: 0.0, g: 0.0, b: 1.0, a: 1.0 };
}
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct Origin3d { pub struct Origin3d {
pub x: f32, pub x: f32,
pub y: f32, pub y: f32,
@ -56,6 +74,7 @@ pub struct Origin3d {
} }
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct Extent3d { pub struct Extent3d {
pub width: f32, pub width: f32,
pub height: f32, pub height: f32,
@ -97,7 +116,7 @@ pub type InputStateId = Id;
pub type ShaderModuleId = Id; pub type ShaderModuleId = Id;
type ShaderModuleHandle = ShaderModule<B>; type ShaderModuleHandle = ShaderModule<B>;
pub type AttachmentStateId = Id; pub type AttachmentStateId = Id;
type AttachmentStateHandle = AttachmentState; type AttachmentStateHandle = AttachmentState<B>;
pub type ComputePipelineId = Id; pub type ComputePipelineId = Id;
pub type RenderPipelineId = Id; pub type RenderPipelineId = Id;
type RenderPipelineHandle = RenderPipeline<B>; type RenderPipelineHandle = RenderPipeline<B>;
@ -105,4 +124,5 @@ type RenderPipelineHandle = RenderPipeline<B>;
pub type CommandBufferId = Id; pub type CommandBufferId = Id;
type CommandBufferHandle = CommandBuffer<B>; type CommandBufferHandle = CommandBuffer<B>;
pub type RenderPassId = Id; pub type RenderPassId = Id;
type RenderPassHandle = RenderPass<B>;
pub type ComputePassId = Id; pub type ComputePassId = Id;

View File

@ -200,8 +200,10 @@ pub struct AttachmentStateDescriptor {
pub formats_length: usize, pub formats_length: usize,
} }
pub(crate) struct AttachmentState { pub(crate) struct AttachmentState<B: hal::Backend> {
pub raw: Vec<hal::pass::Attachment>, pub base_pass: B::RenderPass,
pub color_formats: Vec<hal::format::Format>,
pub depth_stencil_format: Option<hal::format::Format>,
} }
#[repr(C)] #[repr(C)]

View File

@ -12,6 +12,7 @@ use std::sync::Arc;
use { use {
AdapterHandle, AttachmentStateHandle, BindGroupLayoutHandle, BlendStateHandle, AdapterHandle, AttachmentStateHandle, BindGroupLayoutHandle, BlendStateHandle,
CommandBufferHandle, DepthStencilStateHandle, DeviceHandle, InstanceHandle, CommandBufferHandle, DepthStencilStateHandle, DeviceHandle, InstanceHandle,
RenderPassHandle,
PipelineLayoutHandle, RenderPipelineHandle, ShaderModuleHandle, PipelineLayoutHandle, RenderPipelineHandle, ShaderModuleHandle,
}; };
@ -175,4 +176,6 @@ lazy_static! {
ConcreteRegistry::new(); ConcreteRegistry::new();
pub(crate) static ref SHADER_MODULE_REGISTRY: ConcreteRegistry<ShaderModuleHandle> = pub(crate) static ref SHADER_MODULE_REGISTRY: ConcreteRegistry<ShaderModuleHandle> =
ConcreteRegistry::new(); ConcreteRegistry::new();
pub(crate) static ref RENDER_PASS_REGISTRY: ConcreteRegistry<RenderPassHandle> =
ConcreteRegistry::new();
} }

View File

@ -10,6 +10,8 @@ pub use wgn::{
Origin3d, PowerPreference, ShaderModuleDescriptor, ShaderStage, Origin3d, PowerPreference, ShaderModuleDescriptor, ShaderStage,
BindGroupLayoutBinding, TextureFormat, BindGroupLayoutBinding, TextureFormat,
PrimitiveTopology, BlendStateDescriptor, ColorWriteFlags, DepthStencilStateDescriptor, PrimitiveTopology, BlendStateDescriptor, ColorWriteFlags, DepthStencilStateDescriptor,
RenderPassDescriptor, RenderPassColorAttachmentDescriptor, RenderPassDepthStencilAttachmentDescriptor,
LoadOp, StoreOp,
}; };
@ -25,6 +27,10 @@ pub struct Device {
id: wgn::DeviceId, id: wgn::DeviceId,
} }
pub struct TextureView {
id: wgn::TextureViewId,
}
pub struct BindGroupLayout { pub struct BindGroupLayout {
id: wgn::BindGroupLayoutId, id: wgn::BindGroupLayoutId,
} }
@ -57,6 +63,11 @@ pub struct CommandBuffer {
id: wgn::CommandBufferId, id: wgn::CommandBufferId,
} }
pub struct RenderPass<'a> {
id: wgn::RenderPassId,
parent: &'a mut CommandBuffer,
}
pub struct Queue { pub struct Queue {
id: wgn::QueueId, id: wgn::QueueId,
} }
@ -205,6 +216,46 @@ impl Device {
} }
} }
impl CommandBuffer {
pub fn begin_render_pass(&mut self, desc: RenderPassDescriptor<&TextureView>) -> RenderPass {
let colors = desc.color_attachments
.iter()
.map(|ca| RenderPassColorAttachmentDescriptor {
attachment: ca.attachment.id,
load_op: ca.load_op,
store_op: ca.store_op,
clear_color: ca.clear_color,
})
.collect::<ArrayVec<[_; 4]>>();
let depth_stencil = desc.depth_stencil_attachment
.map(|dsa| RenderPassDepthStencilAttachmentDescriptor {
attachment: dsa.attachment.id,
depth_load_op: dsa.depth_load_op,
depth_store_op: dsa.depth_store_op,
clear_depth: dsa.clear_depth,
stencil_load_op: dsa.stencil_load_op,
stencil_store_op: dsa.stencil_store_op,
clear_stencil: dsa.clear_stencil,
});
RenderPass {
id: wgn::wgpu_command_buffer_begin_render_pass(self.id, RenderPassDescriptor {
color_attachments: &colors,
depth_stencil_attachment: depth_stencil,
}),
parent: self,
}
}
}
impl<'a> RenderPass<'a> {
pub fn end_pass(self) -> &'a mut CommandBuffer {
wgn::wgpu_render_pass_end_pass(self.id);
self.parent
}
}
impl Queue { impl Queue {
pub fn submit(&self, command_buffers: &[CommandBuffer]) { pub fn submit(&self, command_buffers: &[CommandBuffer]) {
wgn::wgpu_queue_submit( wgn::wgpu_queue_submit(