mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
Merge #16
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:
commit
69df9c4eae
@ -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]);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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]
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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),
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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)]
|
||||||
|
|||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user