mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 00:03:29 +00:00
wgn: command pools and buffer creation
This commit is contained in:
parent
3c583160d4
commit
212cc386f3
101
wgpu-native/src/command/allocator.rs
Normal file
101
wgpu-native/src/command/allocator.rs
Normal file
@ -0,0 +1,101 @@
|
||||
use super::CommandBuffer;
|
||||
|
||||
use hal::{self, Device};
|
||||
use hal::command::RawCommandBuffer;
|
||||
use hal::pool::RawCommandPool;
|
||||
|
||||
use std::collections::HashMap;
|
||||
//TODO: use `parking_lot::Mutex`?
|
||||
use std::sync::Mutex;
|
||||
use std::thread;
|
||||
|
||||
|
||||
struct CommandPool<B: hal::Backend> {
|
||||
raw: B::CommandPool,
|
||||
available: Vec<CommandBuffer<B>>,
|
||||
}
|
||||
|
||||
pub struct Inner<B: hal::Backend> {
|
||||
pools: HashMap<thread::ThreadId, CommandPool<B>>,
|
||||
pending: Vec<CommandBuffer<B>>,
|
||||
}
|
||||
|
||||
pub struct CommandAllocator<B: hal::Backend> {
|
||||
queue_family: hal::queue::QueueFamilyId,
|
||||
inner: Mutex<Inner<B>>,
|
||||
}
|
||||
|
||||
impl<B: hal::Backend> CommandAllocator<B> {
|
||||
pub fn new(queue_family: hal::queue::QueueFamilyId) -> Self {
|
||||
CommandAllocator {
|
||||
queue_family,
|
||||
inner: Mutex::new(Inner {
|
||||
pools: HashMap::new(),
|
||||
pending: Vec::new(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn allocate(&self, device: &B::Device) -> CommandBuffer<B> {
|
||||
let thread_id = thread::current().id();
|
||||
let mut inner = self.inner.lock().unwrap();
|
||||
let pool = inner.pools
|
||||
.entry(thread_id)
|
||||
.or_insert_with(|| CommandPool {
|
||||
raw: device.create_command_pool(
|
||||
self.queue_family,
|
||||
hal::pool::CommandPoolCreateFlags::RESET_INDIVIDUAL,
|
||||
),
|
||||
available: Vec::new(),
|
||||
});
|
||||
|
||||
if let Some(cmd_buf) = pool.available.pop() {
|
||||
device.reset_fence(&cmd_buf.fence);
|
||||
return cmd_buf;
|
||||
}
|
||||
|
||||
for raw in pool.raw.allocate(20, hal::command::RawLevel::Primary) {
|
||||
pool.available.push(CommandBuffer {
|
||||
raw,
|
||||
fence: device.create_fence(false),
|
||||
recorded_thread_id: thread_id,
|
||||
});
|
||||
}
|
||||
pool.available.pop().unwrap()
|
||||
}
|
||||
|
||||
pub fn submit(&self, cmd_buf: CommandBuffer<B>) {
|
||||
self.inner
|
||||
.lock()
|
||||
.unwrap()
|
||||
.pending
|
||||
.push(cmd_buf);
|
||||
}
|
||||
|
||||
pub fn recycle(&self, mut cmd_buf: CommandBuffer<B>) {
|
||||
cmd_buf.raw.reset(false);
|
||||
self.inner
|
||||
.lock()
|
||||
.unwrap()
|
||||
.pools
|
||||
.get_mut(&cmd_buf.recorded_thread_id)
|
||||
.unwrap()
|
||||
.available
|
||||
.push(cmd_buf);
|
||||
}
|
||||
|
||||
pub fn maintain(&self, device: &B::Device) {
|
||||
let mut inner = self.inner.lock().unwrap();
|
||||
for i in (0 .. inner.pending.len()).rev() {
|
||||
if device.get_fence_status(&inner.pending[i].fence) {
|
||||
let cmd_buf = inner.pending.swap_remove(i);
|
||||
inner
|
||||
.pools
|
||||
.get_mut(&cmd_buf.recorded_thread_id)
|
||||
.unwrap()
|
||||
.available
|
||||
.push(cmd_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
use hal;
|
||||
|
||||
use {CommandBuffer, CommandBufferId, ComputePassId};
|
||||
//use {CommandBuffer, CommandBufferId, ComputePassId};
|
||||
|
||||
pub struct ComputePass<B: hal::Backend> {
|
||||
raw: B::CommandBuffer,
|
||||
|
@ -1,6 +1,8 @@
|
||||
mod allocator;
|
||||
mod compute;
|
||||
mod render;
|
||||
|
||||
pub use self::allocator::*;
|
||||
pub use self::compute::*;
|
||||
pub use self::render::*;
|
||||
|
||||
@ -11,6 +13,9 @@ use {
|
||||
TextureViewId,
|
||||
};
|
||||
|
||||
use std::thread::ThreadId;
|
||||
|
||||
|
||||
#[repr(C)]
|
||||
pub enum LoadOp {
|
||||
Clear = 0,
|
||||
@ -66,14 +71,16 @@ pub struct TextureCopyView {
|
||||
|
||||
pub struct CommandBuffer<B: hal::Backend> {
|
||||
raw: B::CommandBuffer,
|
||||
fence: B::Fence,
|
||||
recorded_thread_id: ThreadId,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CommandBufferDescriptor;
|
||||
pub struct CommandBufferDescriptor {}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wgpu_command_buffer_begin_render_pass(
|
||||
command_buffer: CommandBufferId,
|
||||
_command_buffer: CommandBufferId,
|
||||
) -> RenderPassId {
|
||||
unimplemented!()
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use hal;
|
||||
|
||||
use {CommandBuffer, CommandBufferId, RenderPassId};
|
||||
//use {CommandBuffer, CommandBufferId, RenderPassId};
|
||||
|
||||
pub struct RenderPass<B: hal::Backend> {
|
||||
raw: B::CommandBuffer,
|
||||
|
@ -1,16 +1,17 @@
|
||||
use hal::{self, Device as _Device, QueueGroup};
|
||||
use {conv, memory, pipeline, resource};
|
||||
use {command, conv, memory, pipeline, resource};
|
||||
|
||||
use registry::{self, Registry};
|
||||
use {BufferId, CommandBufferId, DeviceId, ShaderModuleId};
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CommandBufferDescriptor {}
|
||||
use std::slice;
|
||||
|
||||
|
||||
pub struct Device<B: hal::Backend> {
|
||||
device: B::Device,
|
||||
queue_group: QueueGroup<B, hal::General>,
|
||||
allocator: memory::SmartAllocator<B>,
|
||||
mem_allocator: memory::SmartAllocator<B>,
|
||||
com_allocator: command::CommandAllocator<B>,
|
||||
}
|
||||
|
||||
impl<B: hal::Backend> Device<B> {
|
||||
@ -21,8 +22,9 @@ impl<B: hal::Backend> Device<B> {
|
||||
) -> Self {
|
||||
Device {
|
||||
device,
|
||||
mem_allocator: memory::SmartAllocator::new(mem_props, 1, 1, 1, 1),
|
||||
com_allocator: command::CommandAllocator::new(queue_group.family()),
|
||||
queue_group,
|
||||
allocator: memory::SmartAllocator::new(mem_props, 1, 1, 1, 1),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -40,7 +42,17 @@ pub extern "C" fn wgpu_device_create_shader_module(
|
||||
let shader = device
|
||||
.device
|
||||
.create_shader_module(unsafe {
|
||||
::std::slice::from_raw_parts(desc.code.bytes, desc.code.length)
|
||||
slice::from_raw_parts(desc.code.bytes, desc.code.length)
|
||||
}).unwrap();
|
||||
registry::SHADER_MODULE_REGISTRY.register(ShaderModule { raw: shader })
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wgpu_device_create_command_buffer(
|
||||
device_id: DeviceId,
|
||||
desc: command::CommandBufferDescriptor,
|
||||
) -> CommandBufferId {
|
||||
let device = registry::DEVICE_REGISTRY.get_mut(device_id);
|
||||
let cmd_buf = device.com_allocator.allocate(&device.device);
|
||||
registry::COMMAND_BUFFER_REGISTRY.register(cmd_buf)
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ pub extern "C" fn wgpu_instance_get_adapter(
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wgpu_adapter_create_device(
|
||||
adapter_id: AdapterId,
|
||||
desc: DeviceDescriptor,
|
||||
_desc: DeviceDescriptor,
|
||||
) -> DeviceId {
|
||||
let mut adapter = registry::ADAPTER_REGISTRY.get_mut(adapter_id);
|
||||
let (device, queue_group) = adapter.open_with::<_, hal::General>(1, |_qf| true).unwrap();
|
||||
|
@ -40,6 +40,7 @@ pub use self::resource::*;
|
||||
use back::Backend as B;
|
||||
use registry::Id;
|
||||
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Color {
|
||||
pub r: f32,
|
||||
@ -69,11 +70,11 @@ pub struct ByteArray {
|
||||
}
|
||||
|
||||
pub type InstanceId = Id;
|
||||
pub(crate) type InstanceHandle = back::Instance;
|
||||
type InstanceHandle = back::Instance;
|
||||
pub type AdapterId = Id;
|
||||
pub(crate) type AdapterHandle = hal::Adapter<B>;
|
||||
type AdapterHandle = hal::Adapter<B>;
|
||||
pub type DeviceId = Id;
|
||||
pub(crate) type DeviceHandle = Device<B>;
|
||||
type DeviceHandle = Device<B>;
|
||||
pub type BufferId = Id;
|
||||
|
||||
// Resource
|
||||
@ -90,11 +91,12 @@ pub type BlendStateId = Id;
|
||||
pub type DepthStencilStateId = Id;
|
||||
pub type InputStateId = Id;
|
||||
pub type ShaderModuleId = Id;
|
||||
pub(crate) type ShaderModuleHandle = ShaderModule<B>;
|
||||
type ShaderModuleHandle = ShaderModule<B>;
|
||||
pub type AttachmentStateId = Id;
|
||||
pub type ComputePipelineId = Id;
|
||||
pub type RenderPipelineId = Id;
|
||||
|
||||
pub type CommandBufferId = Id;
|
||||
type CommandBufferHandle = CommandBuffer<B>;
|
||||
pub type RenderPassId = Id;
|
||||
pub type ComputePassId = Id;
|
||||
|
@ -4,10 +4,14 @@ use std::os::raw::c_void;
|
||||
use std::sync::Arc;
|
||||
#[cfg(feature = "remote")]
|
||||
use parking_lot::{Mutex, MutexGuard, MappedMutexGuard};
|
||||
#[cfg(feature = "remote")]
|
||||
use std::{borrow, cmp, fmt, ops, ptr};
|
||||
|
||||
#[cfg(feature = "remote")]
|
||||
use hal::backend::FastHashMap;
|
||||
use {AdapterHandle, DeviceHandle, InstanceHandle, ShaderModuleHandle};
|
||||
|
||||
use {AdapterHandle, CommandBufferHandle, DeviceHandle, InstanceHandle, ShaderModuleHandle};
|
||||
|
||||
|
||||
#[cfg(not(feature = "remote"))]
|
||||
pub(crate) type Id = *mut c_void;
|
||||
@ -99,4 +103,5 @@ lazy_static! {
|
||||
pub(crate) static ref DEVICE_REGISTRY: ConcreteRegistry<DeviceHandle> = ConcreteRegistry::new();
|
||||
pub(crate) static ref INSTANCE_REGISTRY: ConcreteRegistry<InstanceHandle> = ConcreteRegistry::new();
|
||||
pub(crate) static ref SHADER_MODULE_REGISTRY: ConcreteRegistry<ShaderModuleHandle> = ConcreteRegistry::new();
|
||||
pub(crate) static ref COMMAND_BUFFER_REGISTRY: ConcreteRegistry<CommandBufferHandle> = ConcreteRegistry::new();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user