mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
Merge #13
13: Basic command buffer creation and submission r=grovesNL a=kvark Co-authored-by: Dzmitry Malyshau <kvark@mozilla.com>
This commit is contained in:
commit
ebe0af0a7f
@ -11,3 +11,9 @@ before_install:
|
|||||||
# Do not run bors builds against the nightly compiler.
|
# Do not run bors builds against the nightly compiler.
|
||||||
# We want to find out about nightly bugs, so they're done in master, but we don't block on them.
|
# We want to find out about nightly bugs, so they're done in master, but we don't block on them.
|
||||||
- if [[ $TRAVIS_RUST_VERSION == "nightly" && $TRAVIS_BRANCH == "staging" ]]; then exit; fi
|
- if [[ $TRAVIS_RUST_VERSION == "nightly" && $TRAVIS_BRANCH == "staging" ]]; then exit; fi
|
||||||
|
|
||||||
|
script:
|
||||||
|
- cargo test
|
||||||
|
- cargo build --manifest-path wgpu-native/Cargo.toml --features remote
|
||||||
|
- cargo build
|
||||||
|
#- (cd examples && make) #TODO
|
||||||
|
|||||||
@ -38,5 +38,11 @@ int main()
|
|||||||
.code = read_file("./../data/hello_triangle.frag.spv"),
|
.code = read_file("./../data/hello_triangle.frag.spv"),
|
||||||
};
|
};
|
||||||
WGPUShaderModuleId _fs = wgpu_device_create_shader_module(device, fs_desc);
|
WGPUShaderModuleId _fs = wgpu_device_create_shader_module(device, fs_desc);
|
||||||
|
|
||||||
|
WGPUCommandBufferDescriptor cmd_buf_desc = {
|
||||||
|
};
|
||||||
|
WGPUCommandBufferId cmd_buf = wgpu_device_create_command_buffer(device, cmd_buf_desc);
|
||||||
|
WGPUQueueId queue = wgpu_device_get_queue(device);
|
||||||
|
wgpu_queue_submit(queue, &cmd_buf, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,4 +17,9 @@ fn main() {
|
|||||||
let _vs = device.create_shader_module(vs_bytes);
|
let _vs = 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");
|
||||||
let _fs = device.create_shader_module(fs_bytes);
|
let _fs = device.create_shader_module(fs_bytes);
|
||||||
|
|
||||||
|
let cmd_buf = device.create_command_buffer(wgpu::CommandBufferDescriptor {
|
||||||
|
});
|
||||||
|
let queue = device.get_queue();
|
||||||
|
queue.submit(&[cmd_buf]);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,6 +34,10 @@ typedef WGPUId WGPUCommandBufferId;
|
|||||||
|
|
||||||
typedef WGPUId WGPUInstanceId;
|
typedef WGPUId WGPUInstanceId;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
|
||||||
|
} WGPUCommandBufferDescriptor;
|
||||||
|
|
||||||
typedef WGPUId WGPUShaderModuleId;
|
typedef WGPUId WGPUShaderModuleId;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -45,19 +49,30 @@ typedef struct {
|
|||||||
WGPUByteArray code;
|
WGPUByteArray code;
|
||||||
} WGPUShaderModuleDescriptor;
|
} WGPUShaderModuleDescriptor;
|
||||||
|
|
||||||
|
typedef WGPUId WGPUQueueId;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
WGPUPowerPreference power_preference;
|
WGPUPowerPreference power_preference;
|
||||||
} WGPUAdapterDescriptor;
|
} WGPUAdapterDescriptor;
|
||||||
|
|
||||||
WGPUDeviceId wgpu_adapter_create_device(WGPUAdapterId adapter_id, WGPUDeviceDescriptor desc);
|
WGPUDeviceId wgpu_adapter_create_device(WGPUAdapterId adapter_id, WGPUDeviceDescriptor _desc);
|
||||||
|
|
||||||
WGPUComputePassId wgpu_command_buffer_begin_compute_pass(void);
|
WGPUComputePassId wgpu_command_buffer_begin_compute_pass(void);
|
||||||
|
|
||||||
WGPURenderPassId wgpu_command_buffer_begin_render_pass(WGPUCommandBufferId command_buffer);
|
WGPURenderPassId wgpu_command_buffer_begin_render_pass(WGPUCommandBufferId _command_buffer);
|
||||||
|
|
||||||
WGPUInstanceId wgpu_create_instance(void);
|
WGPUInstanceId wgpu_create_instance(void);
|
||||||
|
|
||||||
|
WGPUCommandBufferId wgpu_device_create_command_buffer(WGPUDeviceId device_id,
|
||||||
|
WGPUCommandBufferDescriptor desc);
|
||||||
|
|
||||||
WGPUShaderModuleId wgpu_device_create_shader_module(WGPUDeviceId device_id,
|
WGPUShaderModuleId wgpu_device_create_shader_module(WGPUDeviceId device_id,
|
||||||
WGPUShaderModuleDescriptor desc);
|
WGPUShaderModuleDescriptor desc);
|
||||||
|
|
||||||
|
WGPUQueueId wgpu_device_get_queue(WGPUDeviceId device_id);
|
||||||
|
|
||||||
WGPUAdapterId wgpu_instance_get_adapter(WGPUInstanceId instance_id, WGPUAdapterDescriptor desc);
|
WGPUAdapterId wgpu_instance_get_adapter(WGPUInstanceId instance_id, WGPUAdapterDescriptor desc);
|
||||||
|
|
||||||
|
void wgpu_queue_submit(WGPUQueueId queue_id,
|
||||||
|
const WGPUCommandBufferId *command_buffer_ptr,
|
||||||
|
uintptr_t command_buffer_count);
|
||||||
|
|||||||
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 hal;
|
||||||
|
|
||||||
use {CommandBuffer, CommandBufferId, ComputePassId};
|
//use {CommandBuffer, CommandBufferId, ComputePassId};
|
||||||
|
|
||||||
pub struct ComputePass<B: hal::Backend> {
|
pub struct ComputePass<B: hal::Backend> {
|
||||||
raw: B::CommandBuffer,
|
raw: B::CommandBuffer,
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
|
mod allocator;
|
||||||
mod compute;
|
mod compute;
|
||||||
mod render;
|
mod render;
|
||||||
|
|
||||||
|
pub use self::allocator::*;
|
||||||
pub use self::compute::*;
|
pub use self::compute::*;
|
||||||
pub use self::render::*;
|
pub use self::render::*;
|
||||||
|
|
||||||
@ -11,6 +13,9 @@ use {
|
|||||||
TextureViewId,
|
TextureViewId,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use std::thread::ThreadId;
|
||||||
|
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub enum LoadOp {
|
pub enum LoadOp {
|
||||||
Clear = 0,
|
Clear = 0,
|
||||||
@ -65,15 +70,17 @@ pub struct TextureCopyView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct CommandBuffer<B: hal::Backend> {
|
pub struct CommandBuffer<B: hal::Backend> {
|
||||||
raw: B::CommandBuffer,
|
pub(crate) raw: B::CommandBuffer,
|
||||||
|
fence: B::Fence,
|
||||||
|
recorded_thread_id: ThreadId,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct CommandBufferDescriptor;
|
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: CommandBufferId,
|
||||||
) -> RenderPassId {
|
) -> RenderPassId {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use hal;
|
use hal;
|
||||||
|
|
||||||
use {CommandBuffer, CommandBufferId, RenderPassId};
|
//use {CommandBuffer, CommandBufferId, RenderPassId};
|
||||||
|
|
||||||
pub struct RenderPass<B: hal::Backend> {
|
pub struct RenderPass<B: hal::Backend> {
|
||||||
raw: B::CommandBuffer,
|
raw: B::CommandBuffer,
|
||||||
|
|||||||
@ -1,28 +1,31 @@
|
|||||||
use hal::{self, Device as _Device, QueueGroup};
|
use hal::{self, Device as _Device};
|
||||||
use {conv, memory, pipeline, resource};
|
use hal::queue::RawCommandQueue;
|
||||||
|
use {command, conv, memory, pipeline, resource};
|
||||||
|
|
||||||
use registry::{self, Registry};
|
use registry::{self, Registry};
|
||||||
use {BufferId, CommandBufferId, DeviceId, ShaderModuleId};
|
use {BufferId, CommandBufferId, DeviceId, QueueId, ShaderModuleId};
|
||||||
|
|
||||||
|
use std::{iter, slice};
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct CommandBufferDescriptor {}
|
|
||||||
|
|
||||||
pub struct Device<B: hal::Backend> {
|
pub struct Device<B: hal::Backend> {
|
||||||
device: B::Device,
|
device: B::Device,
|
||||||
queue_group: QueueGroup<B, hal::General>,
|
queue_group: hal::QueueGroup<B, hal::General>,
|
||||||
allocator: memory::SmartAllocator<B>,
|
mem_allocator: memory::SmartAllocator<B>,
|
||||||
|
com_allocator: command::CommandAllocator<B>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: hal::Backend> Device<B> {
|
impl<B: hal::Backend> Device<B> {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
device: B::Device,
|
device: B::Device,
|
||||||
queue_group: QueueGroup<B, hal::General>,
|
queue_group: hal::QueueGroup<B, hal::General>,
|
||||||
mem_props: hal::MemoryProperties,
|
mem_props: hal::MemoryProperties,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Device {
|
Device {
|
||||||
device,
|
device,
|
||||||
|
mem_allocator: memory::SmartAllocator::new(mem_props, 1, 1, 1, 1),
|
||||||
|
com_allocator: command::CommandAllocator::new(queue_group.family()),
|
||||||
queue_group,
|
queue_group,
|
||||||
allocator: memory::SmartAllocator::new(mem_props, 1, 1, 1, 1),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -40,7 +43,53 @@ pub extern "C" fn wgpu_device_create_shader_module(
|
|||||||
let shader = device
|
let shader = device
|
||||||
.device
|
.device
|
||||||
.create_shader_module(unsafe {
|
.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();
|
}).unwrap();
|
||||||
registry::SHADER_MODULE_REGISTRY.register(ShaderModule { raw: shader })
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn wgpu_device_get_queue(
|
||||||
|
device_id: DeviceId,
|
||||||
|
) -> QueueId {
|
||||||
|
device_id
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn wgpu_queue_submit(
|
||||||
|
queue_id: QueueId,
|
||||||
|
command_buffer_ptr: *const CommandBufferId,
|
||||||
|
command_buffer_count: usize,
|
||||||
|
) {
|
||||||
|
let mut device = registry::DEVICE_REGISTRY.get_mut(queue_id);
|
||||||
|
let command_buffer_ids = unsafe {
|
||||||
|
slice::from_raw_parts(command_buffer_ptr, command_buffer_count)
|
||||||
|
};
|
||||||
|
//TODO: submit at once, requires `get_all()`
|
||||||
|
for &cmb_id in command_buffer_ids {
|
||||||
|
let cmd_buf = registry::COMMAND_BUFFER_REGISTRY.take(cmb_id);
|
||||||
|
{
|
||||||
|
let submission = hal::queue::RawSubmission {
|
||||||
|
cmd_buffers: iter::once(&cmd_buf.raw),
|
||||||
|
wait_semaphores: &[],
|
||||||
|
signal_semaphores: &[],
|
||||||
|
};
|
||||||
|
unsafe {
|
||||||
|
device.queue_group.queues[0]
|
||||||
|
.as_raw_mut()
|
||||||
|
.submit_raw(submission, None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
device.com_allocator.submit(cmd_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -71,7 +71,7 @@ pub extern "C" fn wgpu_instance_get_adapter(
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wgpu_adapter_create_device(
|
pub extern "C" fn wgpu_adapter_create_device(
|
||||||
adapter_id: AdapterId,
|
adapter_id: AdapterId,
|
||||||
desc: DeviceDescriptor,
|
_desc: DeviceDescriptor,
|
||||||
) -> DeviceId {
|
) -> DeviceId {
|
||||||
let mut adapter = registry::ADAPTER_REGISTRY.get_mut(adapter_id);
|
let mut adapter = registry::ADAPTER_REGISTRY.get_mut(adapter_id);
|
||||||
let (device, queue_group) = adapter.open_with::<_, hal::General>(1, |_qf| true).unwrap();
|
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 back::Backend as B;
|
||||||
use registry::Id;
|
use registry::Id;
|
||||||
|
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Color {
|
pub struct Color {
|
||||||
pub r: f32,
|
pub r: f32,
|
||||||
@ -69,11 +70,12 @@ pub struct ByteArray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub type InstanceId = Id;
|
pub type InstanceId = Id;
|
||||||
pub(crate) type InstanceHandle = back::Instance;
|
type InstanceHandle = back::Instance;
|
||||||
pub type AdapterId = Id;
|
pub type AdapterId = Id;
|
||||||
pub(crate) type AdapterHandle = hal::Adapter<B>;
|
type AdapterHandle = hal::Adapter<B>;
|
||||||
pub type DeviceId = Id;
|
pub type DeviceId = Id;
|
||||||
pub(crate) type DeviceHandle = Device<B>;
|
type DeviceHandle = Device<B>;
|
||||||
|
pub type QueueId = Id;
|
||||||
pub type BufferId = Id;
|
pub type BufferId = Id;
|
||||||
|
|
||||||
// Resource
|
// Resource
|
||||||
@ -90,11 +92,12 @@ pub type BlendStateId = Id;
|
|||||||
pub type DepthStencilStateId = Id;
|
pub type DepthStencilStateId = Id;
|
||||||
pub type InputStateId = Id;
|
pub type InputStateId = Id;
|
||||||
pub type ShaderModuleId = Id;
|
pub type ShaderModuleId = Id;
|
||||||
pub(crate) type ShaderModuleHandle = ShaderModule<B>;
|
type ShaderModuleHandle = ShaderModule<B>;
|
||||||
pub type AttachmentStateId = Id;
|
pub type AttachmentStateId = Id;
|
||||||
pub type ComputePipelineId = Id;
|
pub type ComputePipelineId = Id;
|
||||||
pub type RenderPipelineId = Id;
|
pub type RenderPipelineId = Id;
|
||||||
|
|
||||||
pub type CommandBufferId = Id;
|
pub type CommandBufferId = Id;
|
||||||
|
type CommandBufferHandle = CommandBuffer<B>;
|
||||||
pub type RenderPassId = Id;
|
pub type RenderPassId = Id;
|
||||||
pub type ComputePassId = Id;
|
pub type ComputePassId = Id;
|
||||||
|
|||||||
@ -1,13 +1,18 @@
|
|||||||
|
#[cfg(not(feature = "remote"))]
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
#[cfg(not(feature = "remote"))]
|
||||||
use std::os::raw::c_void;
|
use std::os::raw::c_void;
|
||||||
|
|
||||||
#[cfg(feature = "remote")]
|
#[cfg(feature = "remote")]
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
#[cfg(feature = "remote")]
|
#[cfg(feature = "remote")]
|
||||||
use parking_lot::{Mutex, MutexGuard, MappedMutexGuard};
|
use parking_lot::{Mutex, MutexGuard, MappedMutexGuard};
|
||||||
use std::{borrow, cmp, fmt, ops, ptr};
|
|
||||||
|
|
||||||
|
#[cfg(feature = "remote")]
|
||||||
use hal::backend::FastHashMap;
|
use hal::backend::FastHashMap;
|
||||||
use {AdapterHandle, DeviceHandle, InstanceHandle, ShaderModuleHandle};
|
|
||||||
|
use {AdapterHandle, CommandBufferHandle, DeviceHandle, InstanceHandle, ShaderModuleHandle};
|
||||||
|
|
||||||
|
|
||||||
#[cfg(not(feature = "remote"))]
|
#[cfg(not(feature = "remote"))]
|
||||||
pub(crate) type Id = *mut c_void;
|
pub(crate) type Id = *mut c_void;
|
||||||
@ -23,6 +28,7 @@ pub(crate) trait Registry<T> {
|
|||||||
fn new() -> Self;
|
fn new() -> Self;
|
||||||
fn register(&self, handle: T) -> Id;
|
fn register(&self, handle: T) -> Id;
|
||||||
fn get_mut(&self, id: Id) -> RegistryItem<T>;
|
fn get_mut(&self, id: Id) -> RegistryItem<T>;
|
||||||
|
fn take(&self, id: Id) -> T;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "remote"))]
|
#[cfg(not(feature = "remote"))]
|
||||||
@ -39,18 +45,25 @@ impl<T> Registry<T> for LocalRegistry<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn register(&self, handle: T) -> Id {
|
fn register(&self, handle: T) -> Id {
|
||||||
::std::boxed::Box::into_raw(Box::new(handle)) as *mut _ as *mut c_void
|
Box::into_raw(Box::new(handle)) as *mut _ as *mut c_void
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_mut(&self, id: Id) -> RegistryItem<T> {
|
fn get_mut(&self, id: Id) -> RegistryItem<T> {
|
||||||
unsafe { (id as *mut T).as_mut() }.unwrap()
|
unsafe { (id as *mut T).as_mut() }.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn take(&self, id: Id) -> T {
|
||||||
|
unsafe {
|
||||||
|
*Box::from_raw(id as *mut T)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "remote")]
|
#[cfg(feature = "remote")]
|
||||||
struct Registrations<T> {
|
struct Registrations<T> {
|
||||||
next_id: Id,
|
next_id: Id,
|
||||||
tracked: FastHashMap<Id, T>,
|
tracked: FastHashMap<Id, T>,
|
||||||
|
free: Vec<Id>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "remote")]
|
#[cfg(feature = "remote")]
|
||||||
@ -59,6 +72,7 @@ impl<T> Registrations<T> {
|
|||||||
Registrations {
|
Registrations {
|
||||||
next_id: 0,
|
next_id: 0,
|
||||||
tracked: FastHashMap::default(),
|
tracked: FastHashMap::default(),
|
||||||
|
free: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,15 +92,26 @@ impl<T> Registry<T> for RemoteRegistry<T> {
|
|||||||
|
|
||||||
fn register(&self, handle: T) -> Id {
|
fn register(&self, handle: T) -> Id {
|
||||||
let mut registrations = self.registrations.lock();
|
let mut registrations = self.registrations.lock();
|
||||||
let id = registrations.next_id;
|
let id = match registrations.free.pop() {
|
||||||
registrations.tracked.insert(id, handle);
|
Some(id) => id,
|
||||||
|
None => {
|
||||||
registrations.next_id += 1;
|
registrations.next_id += 1;
|
||||||
|
registrations.next_id - 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
registrations.tracked.insert(id, handle);
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_mut(&self, id: Id) -> RegistryItem<T> {
|
fn get_mut(&self, id: Id) -> RegistryItem<T> {
|
||||||
MutexGuard::map(self.registrations.lock(), |r| r.tracked.get_mut(&id).unwrap())
|
MutexGuard::map(self.registrations.lock(), |r| r.tracked.get_mut(&id).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn take(&self, id: Id) -> T {
|
||||||
|
let mut registrations = self.registrations.lock();
|
||||||
|
registrations.free.push(id);
|
||||||
|
registrations.tracked.remove(&id).unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "remote"))]
|
#[cfg(not(feature = "remote"))]
|
||||||
@ -99,4 +124,5 @@ lazy_static! {
|
|||||||
pub(crate) static ref DEVICE_REGISTRY: ConcreteRegistry<DeviceHandle> = ConcreteRegistry::new();
|
pub(crate) static ref DEVICE_REGISTRY: ConcreteRegistry<DeviceHandle> = ConcreteRegistry::new();
|
||||||
pub(crate) static ref INSTANCE_REGISTRY: ConcreteRegistry<InstanceHandle> = 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 SHADER_MODULE_REGISTRY: ConcreteRegistry<ShaderModuleHandle> = ConcreteRegistry::new();
|
||||||
|
pub(crate) static ref COMMAND_BUFFER_REGISTRY: ConcreteRegistry<CommandBufferHandle> = ConcreteRegistry::new();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ extern crate wgpu_native as wgn;
|
|||||||
pub use wgn::{
|
pub use wgn::{
|
||||||
Color, Origin3d, Extent3d,
|
Color, Origin3d, Extent3d,
|
||||||
AdapterDescriptor, Extensions, DeviceDescriptor, PowerPreference,
|
AdapterDescriptor, Extensions, DeviceDescriptor, PowerPreference,
|
||||||
ShaderModuleDescriptor,
|
ShaderModuleDescriptor, CommandBufferDescriptor,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -23,6 +23,14 @@ pub struct ShaderModule {
|
|||||||
id: wgn::ShaderModuleId,
|
id: wgn::ShaderModuleId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct CommandBuffer {
|
||||||
|
id: wgn::CommandBufferId,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Queue {
|
||||||
|
id: wgn::QueueId,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Instance {
|
impl Instance {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
@ -58,4 +66,26 @@ impl Device {
|
|||||||
id: wgn::wgpu_device_create_shader_module(self.id, desc),
|
id: wgn::wgpu_device_create_shader_module(self.id, desc),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_queue(&self) -> Queue {
|
||||||
|
Queue {
|
||||||
|
id: wgn::wgpu_device_get_queue(self.id),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_command_buffer(&self, desc: CommandBufferDescriptor) -> CommandBuffer {
|
||||||
|
CommandBuffer {
|
||||||
|
id: wgn::wgpu_device_create_command_buffer(self.id, desc),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Queue {
|
||||||
|
pub fn submit(&self, command_buffers: &[CommandBuffer]) {
|
||||||
|
wgn::wgpu_queue_submit(
|
||||||
|
self.id,
|
||||||
|
command_buffers.as_ptr() as *const _,
|
||||||
|
command_buffers.len(),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user