diff --git a/.travis.yml b/.travis.yml index 2f2fa19f0..97b2c3532 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,4 +14,4 @@ before_install: script: - cargo test - - cargo check --manifest-path wgpu-native/Cargo.toml --features remote + - cargo check --manifest-path wgpu-native/Cargo.toml diff --git a/Makefile b/Makefile index 9470668fc..a9542b10b 100644 --- a/Makefile +++ b/Makefile @@ -60,7 +60,7 @@ examples-native: lib-native wgpu-bindings/wgpu.h $(wildcard wgpu-native/**/*.c) #$(MAKE) -C examples examples-rust: lib-rust examples/Cargo.toml $(wildcard wgpu-native/**/*.rs) - cargo build --manifest-path examples/Cargo.toml --features winit,$(FEATURE_RUST) + cargo build --manifest-path examples/Cargo.toml --features $(FEATURE_RUST) examples-gfx: lib-rust gfx-examples/Cargo.toml $(wildcard gfx-examples/*.rs) cargo build --manifest-path gfx-examples/Cargo.toml --features $(FEATURE_RUST) diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 6d33a9087..705ec1bb1 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -17,7 +17,7 @@ path = "hello_compute_rust/main.rs" [features] default = [] -remote = ["wgpu-native/remote"] +local = ["wgpu-native/local"] metal = ["wgpu/metal"] dx11 = ["wgpu/dx11"] dx12 = ["wgpu/dx12"] @@ -25,5 +25,5 @@ vulkan = ["wgpu/vulkan"] [dependencies] wgpu-native = { path = "../wgpu-native" } -wgpu = { path = "../wgpu-rs", features=["winit"] } +wgpu = { path = "../wgpu-rs" } env_logger = "0.5" diff --git a/examples/hello_compute_rust/main.rs b/examples/hello_compute_rust/main.rs index ef5d02b99..5c646a986 100644 --- a/examples/hello_compute_rust/main.rs +++ b/examples/hello_compute_rust/main.rs @@ -81,7 +81,6 @@ fn main() { layout: &pipeline_layout, compute_stage: wgpu::PipelineStageDescriptor { module: &cs_module, - stage: wgpu::ShaderStage::Compute, entry_point: "main", }, }); diff --git a/examples/hello_triangle_rust/main.rs b/examples/hello_triangle_rust/main.rs index 80e698eb8..c5954e2d5 100644 --- a/examples/hello_triangle_rust/main.rs +++ b/examples/hello_triangle_rust/main.rs @@ -25,36 +25,36 @@ fn main() { bind_group_layouts: &[&bind_group_layout], }); - let blend_state0 = device.create_blend_state(&wgpu::BlendStateDescriptor::REPLACE); - let depth_stencil_state = - device.create_depth_stencil_state(&wgpu::DepthStencilStateDescriptor::IGNORE); - let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { layout: &pipeline_layout, - stages: &[ - wgpu::PipelineStageDescriptor { - module: &vs_module, - stage: wgpu::ShaderStage::Vertex, - entry_point: "main", - }, - wgpu::PipelineStageDescriptor { - module: &fs_module, - stage: wgpu::ShaderStage::Fragment, - entry_point: "main", + vertex_stage: wgpu::PipelineStageDescriptor { + module: &vs_module, + entry_point: "main", + }, + fragment_stage: wgpu::PipelineStageDescriptor { + module: &fs_module, + entry_point: "main", + }, + rasterization_state: wgpu::RasterizationStateDescriptor { + front_face: wgpu::FrontFace::Ccw, + cull_mode: wgpu::CullMode::None, + depth_bias: 0, + depth_bias_slope_scale: 0.0, + depth_bias_clamp: wgpu::MAX_DEPTH_BIAS_CLAMP, + }, + primitive_topology: wgpu::PrimitiveTopology::TriangleList, + color_states: &[ + wgpu::ColorStateDescriptor { + format: wgpu::TextureFormat::B8g8r8a8Unorm, + color: wgpu::BlendDescriptor::REPLACE, + alpha: wgpu::BlendDescriptor::REPLACE, + write_mask: wgpu::ColorWriteFlags::ALL, }, ], - primitive_topology: wgpu::PrimitiveTopology::TriangleList, - attachments_state: wgpu::AttachmentsState { - color_attachments: &[wgpu::Attachment { - format: wgpu::TextureFormat::B8g8r8a8Unorm, - samples: 1, - }], - depth_stencil_attachment: None, - }, - blend_states: &[&blend_state0], - depth_stencil_state: &depth_stencil_state, + depth_stencil_state: None, index_format: wgpu::IndexFormat::Uint16, vertex_buffers: &[], + sample_count: 1, }); use wgpu::winit::{ControlFlow, Event, ElementState, EventsLoop, KeyboardInput, Window, WindowEvent, VirtualKeyCode}; diff --git a/gfx-examples/Cargo.toml b/gfx-examples/Cargo.toml index 619ddc463..ce4959801 100644 --- a/gfx-examples/Cargo.toml +++ b/gfx-examples/Cargo.toml @@ -20,7 +20,7 @@ dx12 = ["wgpu/dx12"] vulkan = ["wgpu/vulkan"] [dependencies] -wgpu = { path = "../wgpu-rs", features = ["winit"] } +wgpu = { path = "../wgpu-rs" } cgmath = "0.17" env_logger = "0.5" glsl-to-spirv = "0.1" diff --git a/gfx-examples/src/cube.rs b/gfx-examples/src/cube.rs index e62554584..5f078bda4 100644 --- a/gfx-examples/src/cube.rs +++ b/gfx-examples/src/cube.rs @@ -152,7 +152,7 @@ impl framework::Example for Cube { format: wgpu::TextureFormat::R8g8b8a8Unorm, usage: wgpu::TextureUsageFlags::SAMPLED | wgpu::TextureUsageFlags::TRANSFER_DST }); - let texture_view = texture.create_default_texture_view(); + let texture_view = texture.create_default_view(); let temp_buf = device.create_buffer(&wgpu::BufferDescriptor { size: texels.len() as u32, usage: wgpu::BufferUsageFlags::TRANSFER_SRC | wgpu::BufferUsageFlags::TRANSFER_DST @@ -232,39 +232,38 @@ impl framework::Example for Cube { }); // Create the render pipeline - let vs_bytes = framework::load_glsl("cube.vert", wgpu::ShaderStage::Vertex); - let fs_bytes = framework::load_glsl("cube.frag", wgpu::ShaderStage::Fragment); + let vs_bytes = framework::load_glsl("cube.vert", framework::ShaderStage::Vertex); + let fs_bytes = framework::load_glsl("cube.frag", framework::ShaderStage::Fragment); let vs_module = device.create_shader_module(&vs_bytes); let fs_module = device.create_shader_module(&fs_bytes); - let blend_state0 = device.create_blend_state(&wgpu::BlendStateDescriptor::REPLACE); - let depth_stencil_state = - device.create_depth_stencil_state(&wgpu::DepthStencilStateDescriptor::IGNORE); - let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { layout: &pipeline_layout, - stages: &[ - wgpu::PipelineStageDescriptor { - module: &vs_module, - stage: wgpu::ShaderStage::Vertex, - entry_point: "main", - }, - wgpu::PipelineStageDescriptor { - module: &fs_module, - stage: wgpu::ShaderStage::Fragment, - entry_point: "main", + vertex_stage: wgpu::PipelineStageDescriptor { + module: &vs_module, + entry_point: "main", + }, + fragment_stage: wgpu::PipelineStageDescriptor { + module: &fs_module, + entry_point: "main", + }, + rasterization_state: wgpu::RasterizationStateDescriptor { + front_face: wgpu::FrontFace::Cw, + cull_mode: wgpu::CullMode::Back, + depth_bias: 0, + depth_bias_slope_scale: 0.0, + depth_bias_clamp: wgpu::MAX_DEPTH_BIAS_CLAMP, + }, + primitive_topology: wgpu::PrimitiveTopology::TriangleList, + color_states: &[ + wgpu::ColorStateDescriptor { + format: sc_desc.format, + color: wgpu::BlendDescriptor::REPLACE, + alpha: wgpu::BlendDescriptor::REPLACE, + write_mask: wgpu::ColorWriteFlags::ALL, }, ], - primitive_topology: wgpu::PrimitiveTopology::TriangleList, - attachments_state: wgpu::AttachmentsState { - color_attachments: &[wgpu::Attachment { - format: sc_desc.format, - samples: 1, - }], - depth_stencil_attachment: None, - }, - blend_states: &[&blend_state0], - depth_stencil_state: &depth_stencil_state, + depth_stencil_state: None, index_format: wgpu::IndexFormat::Uint16, vertex_buffers: &[ wgpu::VertexBufferDescriptor { @@ -284,6 +283,7 @@ impl framework::Example for Cube { ], }, ], + sample_count: 1, }); // Done diff --git a/gfx-examples/src/framework.rs b/gfx-examples/src/framework.rs index 609e07870..805c776b2 100644 --- a/gfx-examples/src/framework.rs +++ b/gfx-examples/src/framework.rs @@ -10,15 +10,22 @@ pub fn cast_slice(data: &[T]) -> &[u8] { } } -pub fn load_glsl(name: &str, stage: wgpu::ShaderStage) -> Vec { +#[allow(dead_code)] +pub enum ShaderStage { + Vertex, + Fragment, + Compute, +} + +pub fn load_glsl(name: &str, stage: ShaderStage) -> Vec { use std::fs::read_to_string; use std::io::Read; use std::path::PathBuf; let ty = match stage { - wgpu::ShaderStage::Vertex => glsl_to_spirv::ShaderType::Vertex, - wgpu::ShaderStage::Fragment => glsl_to_spirv::ShaderType::Fragment, - wgpu::ShaderStage::Compute => glsl_to_spirv::ShaderType::Compute, + ShaderStage::Vertex => glsl_to_spirv::ShaderType::Vertex, + ShaderStage::Fragment => glsl_to_spirv::ShaderType::Fragment, + ShaderStage::Compute => glsl_to_spirv::ShaderType::Compute, }; let path = PathBuf::from("data").join(name); let code = read_to_string(path).unwrap(); diff --git a/wgpu-bindings/src/main.rs b/wgpu-bindings/src/main.rs index 02f719a07..c0ae3386c 100644 --- a/wgpu-bindings/src/main.rs +++ b/wgpu-bindings/src/main.rs @@ -36,6 +36,7 @@ fn main() { .with_crate(source_dir) .with_config(config) .with_parse_expand(&["wgpu-native"]) + .with_parse_expand_features(&["local"]) .generate() .unwrap() .write_to_file(crate_dir.join("wgpu.h")); diff --git a/wgpu-bindings/wgpu.h b/wgpu-bindings/wgpu.h index 08962f848..518b97577 100644 --- a/wgpu-bindings/wgpu.h +++ b/wgpu-bindings/wgpu.h @@ -11,6 +11,8 @@ #define WGPUBITS_PER_BYTE 8 +#define WGPUMAX_DEPTH_BIAS_CLAMP 16 + typedef enum { WGPUAddressMode_ClampToEdge = 0, WGPUAddressMode_Repeat = 1, @@ -66,11 +68,22 @@ typedef enum { WGPUCompareFunction_Always = 7, } WGPUCompareFunction; +typedef enum { + WGPUCullMode_None = 0, + WGPUCullMode_Front = 1, + WGPUCullMode_Back = 2, +} WGPUCullMode; + typedef enum { WGPUFilterMode_Nearest = 0, WGPUFilterMode_Linear = 1, } WGPUFilterMode; +typedef enum { + WGPUFrontFace_Ccw = 0, + WGPUFrontFace_Cw = 1, +} WGPUFrontFace; + typedef enum { WGPUIndexFormat_Uint16 = 0, WGPUIndexFormat_Uint32 = 1, @@ -100,12 +113,6 @@ typedef enum { WGPUPrimitiveTopology_TriangleStrip = 4, } WGPUPrimitiveTopology; -typedef enum { - WGPUShaderStage_Vertex = 0, - WGPUShaderStage_Fragment = 1, - WGPUShaderStage_Compute = 2, -} WGPUShaderStage; - typedef enum { WGPUStencilOperation_Keep = 0, WGPUStencilOperation_Zero = 1, @@ -299,23 +306,6 @@ typedef struct { uintptr_t bindings_length; } WGPUBindGroupLayoutDescriptor; -typedef WGPUId WGPUBlendStateId; - -typedef struct { - WGPUBlendFactor src_factor; - WGPUBlendFactor dst_factor; - WGPUBlendOperation operation; -} WGPUBlendDescriptor; - -typedef uint32_t WGPUColorWriteFlags; - -typedef struct { - bool blend_enabled; - WGPUBlendDescriptor alpha; - WGPUBlendDescriptor color; - WGPUColorWriteFlags write_mask; -} WGPUBlendStateDescriptor; - typedef uint32_t WGPUBufferUsageFlags; typedef struct { @@ -333,7 +323,6 @@ typedef WGPUId WGPUShaderModuleId; typedef struct { WGPUShaderModuleId module; - WGPUShaderStage stage; const char *entry_point; } WGPUPipelineStageDescriptor; @@ -342,24 +331,6 @@ typedef struct { WGPUPipelineStageDescriptor compute_stage; } WGPUComputePipelineDescriptor; -typedef WGPUId WGPUDepthStencilStateId; - -typedef struct { - WGPUCompareFunction compare; - WGPUStencilOperation stencil_fail_op; - WGPUStencilOperation depth_fail_op; - WGPUStencilOperation pass_op; -} WGPUStencilStateFaceDescriptor; - -typedef struct { - bool depth_write_enabled; - WGPUCompareFunction depth_compare; - WGPUStencilStateFaceDescriptor front; - WGPUStencilStateFaceDescriptor back; - uint32_t stencil_read_mask; - uint32_t stencil_write_mask; -} WGPUDepthStencilStateDescriptor; - typedef struct { const WGPUBindGroupLayoutId *bind_group_layouts; uintptr_t bind_group_layouts_length; @@ -368,15 +339,44 @@ typedef struct { typedef WGPUId WGPURenderPipelineId; typedef struct { - WGPUTextureFormat format; - uint32_t samples; -} WGPUAttachment; + WGPUFrontFace front_face; + WGPUCullMode cull_mode; + int32_t depth_bias; + float depth_bias_slope_scale; + float depth_bias_clamp; +} WGPURasterizationStateDescriptor; typedef struct { - const WGPUAttachment *color_attachments; - uintptr_t color_attachments_length; - const WGPUAttachment *depth_stencil_attachment; -} WGPUAttachmentsState; + WGPUBlendFactor src_factor; + WGPUBlendFactor dst_factor; + WGPUBlendOperation operation; +} WGPUBlendDescriptor; + +typedef uint32_t WGPUColorWriteFlags; + +typedef struct { + WGPUTextureFormat format; + WGPUBlendDescriptor alpha; + WGPUBlendDescriptor color; + WGPUColorWriteFlags write_mask; +} WGPUColorStateDescriptor; + +typedef struct { + WGPUCompareFunction compare; + WGPUStencilOperation fail_op; + WGPUStencilOperation depth_fail_op; + WGPUStencilOperation pass_op; +} WGPUStencilStateFaceDescriptor; + +typedef struct { + WGPUTextureFormat format; + bool depth_write_enabled; + WGPUCompareFunction depth_compare; + WGPUStencilStateFaceDescriptor stencil_front; + WGPUStencilStateFaceDescriptor stencil_back; + uint32_t stencil_read_mask; + uint32_t stencil_write_mask; +} WGPUDepthStencilStateDescriptor; typedef uint32_t WGPUShaderAttributeIndex; @@ -401,14 +401,15 @@ typedef struct { typedef struct { WGPUPipelineLayoutId layout; - const WGPUPipelineStageDescriptor *stages; - uintptr_t stages_length; + WGPUPipelineStageDescriptor vertex_stage; + WGPUPipelineStageDescriptor fragment_stage; WGPUPrimitiveTopology primitive_topology; - WGPUAttachmentsState attachments_state; - const WGPUBlendStateId *blend_states; - uintptr_t blend_states_length; - WGPUDepthStencilStateId depth_stencil_state; + WGPURasterizationStateDescriptor rasterization_state; + const WGPUColorStateDescriptor *color_states; + uintptr_t color_states_length; + const WGPUDepthStencilStateDescriptor *depth_stencil_state; WGPUVertexBufferStateDescriptor vertex_buffer_state; + uint32_t sample_count; } WGPURenderPipelineDescriptor; typedef struct { @@ -550,8 +551,7 @@ typedef struct { #define WGPUTrackPermit_REPLACE (WGPUTrackPermit){ .bits = 2 } -WGPUDeviceId wgpu_adapter_create_device(WGPUAdapterId adapter_id, - const WGPUDeviceDescriptor *_desc); +WGPUDeviceId wgpu_adapter_create_device(WGPUAdapterId adapter_id, const WGPUDeviceDescriptor *desc); void wgpu_buffer_destroy(WGPUBufferId buffer_id); @@ -607,20 +607,14 @@ WGPUBindGroupId wgpu_device_create_bind_group(WGPUDeviceId device_id, WGPUBindGroupLayoutId wgpu_device_create_bind_group_layout(WGPUDeviceId device_id, const WGPUBindGroupLayoutDescriptor *desc); -WGPUBlendStateId wgpu_device_create_blend_state(WGPUDeviceId _device_id, - const WGPUBlendStateDescriptor *desc); - WGPUBufferId wgpu_device_create_buffer(WGPUDeviceId device_id, const WGPUBufferDescriptor *desc); WGPUCommandEncoderId wgpu_device_create_command_encoder(WGPUDeviceId device_id, - const WGPUCommandEncoderDescriptor *_desc); + const WGPUCommandEncoderDescriptor *desc); WGPUComputePipelineId wgpu_device_create_compute_pipeline(WGPUDeviceId device_id, const WGPUComputePipelineDescriptor *desc); -WGPUDepthStencilStateId wgpu_device_create_depth_stencil_state(WGPUDeviceId _device_id, - const WGPUDepthStencilStateDescriptor *desc); - WGPUPipelineLayoutId wgpu_device_create_pipeline_layout(WGPUDeviceId device_id, const WGPUPipelineLayoutDescriptor *desc); @@ -647,6 +641,9 @@ WGPUSurfaceId wgpu_instance_create_surface_from_windows_hwnd(WGPUInstanceId inst void *hinstance, void *hwnd); +WGPUSurfaceId wgpu_instance_create_surface_from_winit(WGPUInstanceId instance_id, + const WGPUWindow *window); + WGPUSurfaceId wgpu_instance_create_surface_from_xlib(WGPUInstanceId instance_id, const void **display, uint64_t window); @@ -692,10 +689,10 @@ WGPUSwapChainOutput wgpu_swap_chain_get_next_texture(WGPUSwapChainId swap_chain_ void wgpu_swap_chain_present(WGPUSwapChainId swap_chain_id); -WGPUTextureViewId wgpu_texture_create_default_texture_view(WGPUTextureId texture_id); +WGPUTextureViewId wgpu_texture_create_default_view(WGPUTextureId texture_id); -WGPUTextureViewId wgpu_texture_create_texture_view(WGPUTextureId texture_id, - const WGPUTextureViewDescriptor *desc); +WGPUTextureViewId wgpu_texture_create_view(WGPUTextureId texture_id, + const WGPUTextureViewDescriptor *desc); void wgpu_texture_destroy(WGPUTextureId texture_id); diff --git a/wgpu-native/Cargo.toml b/wgpu-native/Cargo.toml index 7ea7c546d..7a5c2fb5e 100644 --- a/wgpu-native/Cargo.toml +++ b/wgpu-native/Cargo.toml @@ -17,7 +17,7 @@ crate-type = ["lib", "cdylib", "staticlib"] [features] default = [] -remote = [] +local = ["winit", "gfx-backend-empty/winit"] [dependencies] bitflags = "1.0" @@ -25,7 +25,7 @@ lazy_static = "1.1.0" log = "0.4" parking_lot = { version = "0.7" } gfx-hal = "0.1.0" -gfx-backend-empty = { version = "0.1.1", features = ["winit"] } +gfx-backend-empty = { version = "0.1.1" } gfx-backend-vulkan = { version = "0.1.0", optional = true } gfx-backend-dx11 = { version = "0.1.0", optional = true } gfx-backend-dx12 = { version = "0.1.0", optional = true } diff --git a/wgpu-native/src/binding_model.rs b/wgpu-native/src/binding_model.rs index 29975d5b5..79b841097 100644 --- a/wgpu-native/src/binding_model.rs +++ b/wgpu-native/src/binding_model.rs @@ -38,8 +38,8 @@ pub struct BindGroupLayoutDescriptor { pub bindings_length: usize, } -pub(crate) struct BindGroupLayout { - pub raw: B::DescriptorSetLayout, +pub struct BindGroupLayout { + pub(crate) raw: B::DescriptorSetLayout, } #[repr(C)] @@ -48,9 +48,9 @@ pub struct PipelineLayoutDescriptor { pub bind_group_layouts_length: usize, } -pub(crate) struct PipelineLayout { - pub raw: B::PipelineLayout, - pub bind_group_layout_ids: Vec>, +pub struct PipelineLayout { + pub(crate) raw: B::PipelineLayout, + pub(crate) bind_group_layout_ids: Vec>, } #[repr(C)] @@ -80,10 +80,10 @@ pub struct BindGroupDescriptor { pub bindings_length: usize, } -pub(crate) struct BindGroup { - pub raw: B::DescriptorSet, - pub layout_id: WeaklyStored, - pub life_guard: LifeGuard, - pub used_buffers: BufferTracker, - pub used_textures: TextureTracker, +pub struct BindGroup { + pub(crate) raw: B::DescriptorSet, + pub(crate) layout_id: WeaklyStored, + pub(crate) life_guard: LifeGuard, + pub(crate) used_buffers: BufferTracker, + pub(crate) used_textures: TextureTracker, } diff --git a/wgpu-native/src/command/bind.rs b/wgpu-native/src/command/bind.rs index 249395d34..a9579e9f6 100644 --- a/wgpu-native/src/command/bind.rs +++ b/wgpu-native/src/command/bind.rs @@ -1,5 +1,5 @@ use crate::{ - B, BindGroup, Stored, WeaklyStored, + BindGroupHandle, Stored, WeaklyStored, BindGroupId, BindGroupLayoutId, PipelineLayoutId, }; @@ -16,7 +16,7 @@ pub struct BindGroupEntry { } impl BindGroupEntry { - fn provide(&mut self, bind_group_id: BindGroupId, bind_group: &BindGroup) -> bool { + fn provide(&mut self, bind_group_id: BindGroupId, bind_group: &BindGroupHandle) -> bool { if let Some(BindGroupPair { ref layout_id, ref group_id }) = self.provided { if group_id.value == bind_group_id { assert_eq!(*layout_id, bind_group.layout_id); @@ -66,7 +66,7 @@ impl Binder { } pub(crate) fn provide_entry( - &mut self, index: usize, bind_group_id: BindGroupId, bind_group: &BindGroup + &mut self, index: usize, bind_group_id: BindGroupId, bind_group: &BindGroupHandle ) -> Option { self.ensure_length(index + 1); if self.entries[index].provide(bind_group_id, bind_group) { diff --git a/wgpu-native/src/command/compute.rs b/wgpu-native/src/command/compute.rs index e9a739d86..ab017d70c 100644 --- a/wgpu-native/src/command/compute.rs +++ b/wgpu-native/src/command/compute.rs @@ -1,5 +1,5 @@ use crate::command::bind::{Binder}; -use crate::registry::{Items, HUB}; +use crate::hub::HUB; use crate::track::{BufferTracker, TextureTracker}; use crate::{ Stored, CommandBuffer, @@ -34,6 +34,8 @@ impl ComputePass { #[no_mangle] pub extern "C" fn wgpu_compute_pass_end_pass(pass_id: ComputePassId) -> CommandBufferId { + #[cfg(feature = "local")] + HUB.compute_passes.unregister(pass_id); let pass = HUB.compute_passes.write().take(pass_id); HUB.command_buffers diff --git a/wgpu-native/src/command/mod.rs b/wgpu-native/src/command/mod.rs index d694cdcd9..975f9f1f3 100644 --- a/wgpu-native/src/command/mod.rs +++ b/wgpu-native/src/command/mod.rs @@ -13,18 +13,22 @@ use crate::device::{ FramebufferKey, RenderPassKey, all_buffer_stages, all_image_stages, }; -use crate::registry::{Items, HUB}; +use crate::hub::{HUB, Storage}; use crate::swap_chain::{SwapChainLink, SwapImageEpoch}; use crate::track::{BufferTracker, TextureTracker}; -use crate::{conv, resource}; +use crate::conv; use crate::{ + BufferHandle, TextureHandle, BufferId, CommandBufferId, CommandEncoderId, DeviceId, - ComputePassId, RenderPassId, TextureId, TextureViewId, + TextureId, TextureViewId, BufferUsageFlags, TextureUsageFlags, Color, LifeGuard, Stored, WeaklyStored, - B, + CommandBufferHandle, }; +#[cfg(feature = "local")] +use crate::{RenderPassId, ComputePassId}; +use back::Backend; use hal::command::RawCommandBuffer; use hal::{Device as _Device}; use log::trace; @@ -86,30 +90,25 @@ pub struct CommandBuffer { pub(crate) swap_chain_links: Vec>, } -impl CommandBuffer { - pub(crate) fn insert_barriers( - raw: &mut ::CommandBuffer, +impl CommandBufferHandle { + pub(crate) fn insert_barriers( + raw: &mut ::CommandBuffer, buffer_iter: I, texture_iter: J, - buffer_guard: &Gb, - texture_guard: &Gt, + buffer_guard: &Storage, + texture_guard: &Storage, ) where I: Iterator)>, J: Iterator)>, - Gb: Items>, - Gt: Items>, { let buffer_barriers = buffer_iter.map(|(id, transit)| { let b = buffer_guard.get(id); trace!("transit {:?} {:?}", id, transit); hal::memory::Barrier::Buffer { - states: conv::map_buffer_state(transit.start)..conv::map_buffer_state(transit.end), + states: conv::map_buffer_state(transit.start) .. conv::map_buffer_state(transit.end), target: &b.raw, - range: Range { - start: None, - end: None, - }, + range: None .. None, families: None, } }); @@ -155,11 +154,10 @@ pub extern "C" fn wgpu_command_encoder_finish( command_encoder_id } -#[no_mangle] -pub extern "C" fn wgpu_command_encoder_begin_render_pass( +pub fn command_encoder_begin_render_pass( command_encoder_id: CommandEncoderId, desc: RenderPassDescriptor, -) -> RenderPassId { +) -> RenderPass { let mut cmb_guard = HUB.command_buffers.write(); let cmb = cmb_guard.get_mut(command_encoder_id); let device_guard = HUB.devices.read(); @@ -351,19 +349,28 @@ pub extern "C" fn wgpu_command_encoder_begin_render_pass( })); } - HUB.render_passes.write().register(RenderPass::new( + RenderPass::new( current_comb, Stored { value: command_encoder_id, ref_count: cmb.life_guard.ref_count.clone(), }, - )) + ) } +#[cfg(feature = "local")] #[no_mangle] -pub extern "C" fn wgpu_command_encoder_begin_compute_pass( +pub extern "C" fn wgpu_command_encoder_begin_render_pass( command_encoder_id: CommandEncoderId, -) -> ComputePassId { + desc: RenderPassDescriptor, +) -> RenderPassId { + let pass = command_encoder_begin_render_pass(command_encoder_id, desc); + HUB.render_passes.register(pass) +} + +pub fn command_encoder_begin_compute_pass( + command_encoder_id: CommandEncoderId, +) -> ComputePass { let mut cmb_guard = HUB.command_buffers.write(); let cmb = cmb_guard.get_mut(command_encoder_id); @@ -373,7 +380,14 @@ pub extern "C" fn wgpu_command_encoder_begin_compute_pass( ref_count: cmb.life_guard.ref_count.clone(), }; - HUB.compute_passes - .write() - .register(ComputePass::new(raw, stored)) + ComputePass::new(raw, stored) +} + +#[cfg(feature = "local")] +#[no_mangle] +pub extern "C" fn wgpu_command_encoder_begin_compute_pass( + command_encoder_id: CommandEncoderId, +) -> ComputePassId { + let pass = command_encoder_begin_compute_pass(command_encoder_id); + HUB.compute_passes.register(pass) } diff --git a/wgpu-native/src/command/render.rs b/wgpu-native/src/command/render.rs index 8b3b772d3..1b9a2c1ee 100644 --- a/wgpu-native/src/command/render.rs +++ b/wgpu-native/src/command/render.rs @@ -1,6 +1,6 @@ use crate::command::bind::Binder; +use crate::hub::HUB; use crate::resource::BufferUsageFlags; -use crate::registry::{Items, HUB}; use crate::track::{BufferTracker, TextureTracker}; use crate::{ CommandBuffer, Stored, @@ -34,6 +34,8 @@ impl RenderPass { #[no_mangle] pub extern "C" fn wgpu_render_pass_end_pass(pass_id: RenderPassId) -> CommandBufferId { + #[cfg(feature = "local")] + HUB.render_passes.unregister(pass_id); let mut pass = HUB.render_passes.write().take(pass_id); unsafe { pass.raw.end_render_pass(); diff --git a/wgpu-native/src/command/transfer.rs b/wgpu-native/src/command/transfer.rs index a9e96e384..e8b14216c 100644 --- a/wgpu-native/src/command/transfer.rs +++ b/wgpu-native/src/command/transfer.rs @@ -1,5 +1,5 @@ use crate::device::{all_buffer_stages, all_image_stages}; -use crate::registry::{Items, HUB}; +use crate::hub::HUB; use crate::swap_chain::SwapChainLink; use crate::conv; use crate::{ diff --git a/wgpu-native/src/conv.rs b/wgpu-native/src/conv.rs index 41fff1e5a..a584b4290 100644 --- a/wgpu-native/src/conv.rs +++ b/wgpu-native/src/conv.rs @@ -1,6 +1,7 @@ use crate::{ binding_model, command, pipeline, resource, Color, Extent3d, Origin3d, + MAX_DEPTH_BIAS_CLAMP, }; @@ -132,11 +133,13 @@ pub fn map_primitive_topology(primitive_topology: pipeline::PrimitiveTopology) - } } -pub fn map_blend_state_descriptor( - desc: &pipeline::BlendStateDescriptor, +pub fn map_color_state_descriptor( + desc: &pipeline::ColorStateDescriptor, ) -> hal::pso::ColorBlendDesc { let color_mask = desc.write_mask; - let blend_state = if desc.blend_enabled { + let blend_state = if desc.color != pipeline::BlendDescriptor::REPLACE || + desc.alpha != pipeline::BlendDescriptor::REPLACE + { hal::pso::BlendState::On { color: map_blend_descriptor(&desc.color), alpha: map_blend_descriptor(&desc.alpha), @@ -208,20 +211,29 @@ fn map_blend_factor(blend_factor: pipeline::BlendFactor) -> hal::pso::Factor { } } -pub fn map_depth_stencil_state( +pub fn map_depth_stencil_state_descriptor( desc: &pipeline::DepthStencilStateDescriptor, ) -> hal::pso::DepthStencilDesc { hal::pso::DepthStencilDesc { - // TODO DepthTest::Off? - depth: hal::pso::DepthTest::On { - fun: map_compare_function(desc.depth_compare), - write: desc.depth_write_enabled, + depth: if desc.depth_write_enabled || desc.depth_compare != resource::CompareFunction::Always { + hal::pso::DepthTest::On { + fun: map_compare_function(desc.depth_compare), + write: desc.depth_write_enabled, + } + } else { + hal::pso::DepthTest::Off }, depth_bounds: false, // TODO - // TODO StencilTest::Off? - stencil: hal::pso::StencilTest::On { - front: map_stencil_face(&desc.front, desc.stencil_read_mask, desc.stencil_write_mask), - back: map_stencil_face(&desc.back, desc.stencil_read_mask, desc.stencil_write_mask), + stencil: if desc.stencil_read_mask != !0 || desc.stencil_write_mask != !0 || + desc.stencil_front != pipeline::StencilStateFaceDescriptor::IGNORE || + desc.stencil_back != pipeline::StencilStateFaceDescriptor::IGNORE + { + hal::pso::StencilTest::On { + front: map_stencil_face(&desc.stencil_front, desc.stencil_read_mask, desc.stencil_write_mask), + back: map_stencil_face(&desc.stencil_back, desc.stencil_read_mask, desc.stencil_write_mask), + } + } else { + hal::pso::StencilTest::Off }, } } @@ -235,7 +247,7 @@ fn map_stencil_face( fun: map_compare_function(stencil_state_face_desc.compare), mask_read: 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.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), reference: hal::pso::State::Static(0), // TODO can this be set? @@ -457,3 +469,31 @@ pub fn map_wrap(address: resource::AddressMode) -> hal::image::WrapMode { Am::ClampToBorderColor => W::Border, } } + +pub fn map_rasterization_state_descriptor( + desc: &pipeline::RasterizationStateDescriptor +) -> hal::pso::Rasterizer { + hal::pso::Rasterizer { + depth_clamping: false, + polygon_mode: hal::pso::PolygonMode::Fill, + cull_face: match desc.cull_mode { + pipeline::CullMode::None => hal::pso::Face::empty(), + pipeline::CullMode::Front => hal::pso::Face::FRONT, + pipeline::CullMode::Back => hal::pso::Face::BACK, + }, + front_face: match desc.front_face { + pipeline::FrontFace::Ccw => hal::pso::FrontFace::CounterClockwise, + pipeline::FrontFace::Cw => hal::pso::FrontFace::Clockwise, + }, + depth_bias: if desc.depth_bias != 0 || desc.depth_bias_slope_scale != 0.0 || desc.depth_bias_clamp < MAX_DEPTH_BIAS_CLAMP { + Some(hal::pso::State::Static(hal::pso::DepthBias { + const_factor: desc.depth_bias as f32, + slope_factor: desc.depth_bias_slope_scale, + clamp: desc.depth_bias_clamp, + })) + } else { + None + }, + conservative: false, + } +} diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index 456cd0445..0be36ae73 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -1,16 +1,20 @@ -use crate::{back, binding_model, command, conv, pipeline, resource, swap_chain}; -use crate::registry::{HUB, Items}; +use crate::{binding_model, command, conv, pipeline, resource, swap_chain}; +use crate::hub::{HUB, Storage}; use crate::track::{BufferTracker, TextureTracker, TrackPermit}; use crate::{ LifeGuard, RefCount, Stored, SubmissionIndex, WeaklyStored, - BindGroupLayoutId, BindGroupId, - BlendStateId, BufferId, CommandBufferId, CommandEncoderId, DepthStencilStateId, - ComputePipelineId, RenderPipelineId, - AdapterId, DeviceId, PipelineLayoutId, QueueId, ShaderModuleId, - SamplerId, TextureId, TextureViewId, - SurfaceId, SwapChainId, +}; +use crate::{ + BufferId, CommandBufferId, AdapterId, DeviceId, QueueId, + TextureId, TextureViewId, SurfaceId, +}; +#[cfg(feature = "local")] +use crate::{ + BindGroupId, BindGroupLayoutId, PipelineLayoutId, SamplerId, SwapChainId, + ShaderModuleId, CommandEncoderId, RenderPipelineId, ComputePipelineId, }; +use back; use hal::command::RawCommandBuffer; use hal::queue::RawCommandQueue; use hal::{self, @@ -97,11 +101,11 @@ impl DestroyedResources { .push((resource_id, life_guard.ref_count.clone())); } - fn triage_referenced(&mut self, buffer_guard: &mut Gb, texture_guard: &mut Gt) - where - Gb: Items>, - Gt: Items>, - { + fn triage_referenced( + &mut self, + buffer_guard: &mut Storage>, + texture_guard: &mut Storage>, + ) { for i in (0..self.referenced.len()).rev() { // one in resource itself, and one here in this list let num_refs = self.referenced[i].1.load(); @@ -110,11 +114,15 @@ impl DestroyedResources { let resource_id = self.referenced.swap_remove(i).0; let (submit_index, resource) = match resource_id { ResourceId::Buffer(id) => { + #[cfg(feature = "local")] + HUB.buffers.unregister(id); let buf = buffer_guard.take(id); let si = buf.life_guard.submission_index.load(Ordering::Acquire); (si, Resource::Buffer(buf)) } ResourceId::Texture(id) => { + #[cfg(feature = "local")] + HUB.textures.unregister(id); let tex = texture_guard.take(id); let si = tex.life_guard.submission_index.load(Ordering::Acquire); (si, Resource::Texture(tex)) @@ -263,15 +271,15 @@ impl Device { } -pub(crate) struct ShaderModule { - pub raw: B::ShaderModule, +pub struct ShaderModule { + pub(crate) raw: B::ShaderModule, } -#[no_mangle] -pub extern "C" fn wgpu_device_create_buffer( + +pub fn device_create_buffer( device_id: DeviceId, desc: &resource::BufferDescriptor, -) -> BufferId { +) -> resource::Buffer { let device_guard = HUB.devices.read(); let device = &device_guard.get(device_id); let (usage, _) = conv::map_buffer_usage(desc.usage); @@ -308,26 +316,43 @@ pub extern "C" fn wgpu_device_create_buffer( .unwrap() }; - let life_guard = LifeGuard::new(); - let ref_count = life_guard.ref_count.clone(); - let id = HUB.buffers - .write() - .register(resource::Buffer { - raw: buffer, - device_id: Stored { - value: device_id, - ref_count: device.life_guard.ref_count.clone(), - }, - life_guard, - }); - let query = device.buffer_tracker + resource::Buffer { + raw: buffer, + device_id: Stored { + value: device_id, + ref_count: device.life_guard.ref_count.clone(), + }, + life_guard: LifeGuard::new(), + } +} + +pub fn device_track_buffer( + device_id: DeviceId, + buffer_id: BufferId, + ref_count: RefCount, +) { + let query = HUB.devices + .read() + .get(device_id) + .buffer_tracker .lock() .query( - &Stored { value: id, ref_count }, + &Stored { value: buffer_id, ref_count }, resource::BufferUsageFlags::empty(), ); assert!(query.initialized); +} +#[cfg(feature = "local")] +#[no_mangle] +pub extern "C" fn wgpu_device_create_buffer( + device_id: DeviceId, + desc: &resource::BufferDescriptor, +) -> BufferId { + let buffer = device_create_buffer(device_id, desc); + let ref_count = buffer.life_guard.ref_count.clone(); + let id = HUB.buffers.register(buffer); + device_track_buffer(device_id, id, ref_count); id } @@ -343,11 +368,11 @@ pub extern "C" fn wgpu_buffer_destroy(buffer_id: BufferId) { .add(ResourceId::Buffer(buffer_id), &buffer.life_guard); } -#[no_mangle] -pub extern "C" fn wgpu_device_create_texture( + +pub fn device_create_texture( device_id: DeviceId, desc: &resource::TextureDescriptor, -) -> TextureId { +) -> resource::Texture { let kind = conv::map_texture_dimension_size(desc.dimension, desc.size); let format = conv::map_texture_format(desc.format); let aspects = format.surface_desc().aspects; @@ -395,44 +420,58 @@ pub extern "C" fn wgpu_device_create_texture( .unwrap() }; - let full_range = hal::image::SubresourceRange { - aspects, - levels: 0..1, //TODO: mips - layers: 0..1, //TODO - }; + resource::Texture { + raw: image, + device_id: Stored { + value: device_id, + ref_count: device.life_guard.ref_count.clone(), + }, + kind, + format: desc.format, + full_range: hal::image::SubresourceRange { + aspects, + levels: 0..1, //TODO: mips + layers: 0..1, //TODO + }, + swap_chain_link: None, + life_guard: LifeGuard::new(), + } +} - let life_guard = LifeGuard::new(); - let ref_count = life_guard.ref_count.clone(); - let id = HUB.textures - .write() - .register(resource::Texture { - raw: image, - device_id: Stored { - value: device_id, - ref_count: device.life_guard.ref_count.clone(), - }, - kind, - format: desc.format, - full_range, - swap_chain_link: None, - life_guard, - }); - let query = device.texture_tracker +pub fn device_track_texture( + device_id: DeviceId, + texture_id: TextureId, + ref_count: RefCount, +) { + let query = HUB.devices + .read() + .get(device_id) + .texture_tracker .lock() .query( - &Stored { value: id, ref_count }, + &Stored { value: texture_id, ref_count }, resource::TextureUsageFlags::UNINITIALIZED, ); assert!(query.initialized); +} +#[cfg(feature = "local")] +#[no_mangle] +pub extern "C" fn wgpu_device_create_texture( + device_id: DeviceId, + desc: &resource::TextureDescriptor, +) -> TextureId { + let texture = device_create_texture(device_id, desc); + let ref_count = texture.life_guard.ref_count.clone(); + let id = HUB.textures.register(texture); + device_track_texture(device_id, id, ref_count); id } -#[no_mangle] -pub extern "C" fn wgpu_texture_create_texture_view( +pub fn texture_create_view( texture_id: TextureId, desc: &resource::TextureViewDescriptor, -) -> TextureViewId { +) -> resource::TextureView { let texture_guard = HUB.textures.read(); let texture = texture_guard.get(texture_id); @@ -455,24 +494,33 @@ pub extern "C" fn wgpu_texture_create_texture_view( .unwrap() }; - HUB.texture_views - .write() - .register(resource::TextureView { - raw, - texture_id: Stored { - value: texture_id, - ref_count: texture.life_guard.ref_count.clone(), - }, - format: texture.format, - extent: texture.kind.extent(), - samples: texture.kind.num_samples(), - is_owned_by_swap_chain: false, - life_guard: LifeGuard::new(), - }) + resource::TextureView { + raw, + texture_id: Stored { + value: texture_id, + ref_count: texture.life_guard.ref_count.clone(), + }, + format: texture.format, + extent: texture.kind.extent(), + samples: texture.kind.num_samples(), + is_owned_by_swap_chain: false, + life_guard: LifeGuard::new(), + } } +#[cfg(feature = "local")] #[no_mangle] -pub extern "C" fn wgpu_texture_create_default_texture_view(texture_id: TextureId) -> TextureViewId { +pub extern "C" fn wgpu_texture_create_view( + texture_id: TextureId, + desc: &resource::TextureViewDescriptor, +) -> TextureViewId { + let view = texture_create_view(texture_id, desc); + HUB.texture_views.register(view) +} + +pub fn texture_create_default_view( + texture_id: TextureId +) -> resource::TextureView { let texture_guard = HUB.textures.read(); let texture = texture_guard.get(texture_id); @@ -497,20 +545,25 @@ pub extern "C" fn wgpu_texture_create_default_texture_view(texture_id: TextureId .unwrap() }; - HUB.texture_views - .write() - .register(resource::TextureView { - raw, - texture_id: Stored { - value: texture_id, - ref_count: texture.life_guard.ref_count.clone(), - }, - format: texture.format, - extent: texture.kind.extent(), - samples: texture.kind.num_samples(), - is_owned_by_swap_chain: false, - life_guard: LifeGuard::new(), - }) + resource::TextureView { + raw, + texture_id: Stored { + value: texture_id, + ref_count: texture.life_guard.ref_count.clone(), + }, + format: texture.format, + extent: texture.kind.extent(), + samples: texture.kind.num_samples(), + is_owned_by_swap_chain: false, + life_guard: LifeGuard::new(), + } +} + +#[cfg(feature = "local")] +#[no_mangle] +pub extern "C" fn wgpu_texture_create_default_view(texture_id: TextureId) -> TextureViewId { + let view = texture_create_default_view(texture_id); + HUB.texture_views.register(view) } #[no_mangle] @@ -530,10 +583,10 @@ pub extern "C" fn wgpu_texture_view_destroy(_texture_view_id: TextureViewId) { unimplemented!() } -#[no_mangle] -pub extern "C" fn wgpu_device_create_sampler( + +pub fn device_create_sampler( device_id: DeviceId, desc: &resource::SamplerDescriptor -) -> SamplerId { +) -> resource::Sampler { let device_guard = HUB.devices.read(); let device = &device_guard.get(device_id); @@ -566,21 +619,28 @@ pub extern "C" fn wgpu_device_create_sampler( .unwrap() }; - HUB.samplers - .write() - .register(resource::Sampler { - raw - }) + resource::Sampler { + raw, + } } +#[cfg(feature = "local")] #[no_mangle] -pub extern "C" fn wgpu_device_create_bind_group_layout( +pub extern "C" fn wgpu_device_create_sampler( + device_id: DeviceId, desc: &resource::SamplerDescriptor +) -> SamplerId { + let sampler = device_create_sampler(device_id, desc); + HUB.samplers.register(sampler) +} + + +pub fn device_create_bind_group_layout( device_id: DeviceId, desc: &binding_model::BindGroupLayoutDescriptor, -) -> BindGroupLayoutId { +) -> binding_model::BindGroupLayout { let bindings = unsafe { slice::from_raw_parts(desc.bindings, desc.bindings_length) }; - let descriptor_set_layout = unsafe { + let raw = unsafe { HUB.devices .read() .get(device_id) @@ -597,21 +657,28 @@ pub extern "C" fn wgpu_device_create_bind_group_layout( }), &[], ) - } - .unwrap(); + .unwrap() + }; - HUB.bind_group_layouts - .write() - .register(binding_model::BindGroupLayout { - raw: descriptor_set_layout, - }) + binding_model::BindGroupLayout { + raw, + } } +#[cfg(feature = "local")] #[no_mangle] -pub extern "C" fn wgpu_device_create_pipeline_layout( +pub extern "C" fn wgpu_device_create_bind_group_layout( + device_id: DeviceId, + desc: &binding_model::BindGroupLayoutDescriptor, +) -> BindGroupLayoutId { + let layout = device_create_bind_group_layout(device_id, desc); + HUB.bind_group_layouts.register(layout) +} + +pub fn device_create_pipeline_layout( device_id: DeviceId, desc: &binding_model::PipelineLayoutDescriptor, -) -> PipelineLayoutId { +) -> binding_model::PipelineLayout { let bind_group_layout_ids = unsafe { slice::from_raw_parts(desc.bind_group_layouts, desc.bind_group_layouts_length) }; @@ -630,23 +697,30 @@ pub extern "C" fn wgpu_device_create_pipeline_layout( } .unwrap(); - HUB.pipeline_layouts - .write() - .register(binding_model::PipelineLayout { - raw: pipeline_layout, - bind_group_layout_ids: bind_group_layout_ids - .iter() - .cloned() - .map(WeaklyStored) - .collect(), - }) + binding_model::PipelineLayout { + raw: pipeline_layout, + bind_group_layout_ids: bind_group_layout_ids + .iter() + .cloned() + .map(WeaklyStored) + .collect(), + } } +#[cfg(feature = "local")] #[no_mangle] -pub extern "C" fn wgpu_device_create_bind_group( +pub extern "C" fn wgpu_device_create_pipeline_layout( + device_id: DeviceId, + desc: &binding_model::PipelineLayoutDescriptor, +) -> PipelineLayoutId { + let layout = device_create_pipeline_layout(device_id, desc); + HUB.pipeline_layouts.register(layout) +} + +pub fn device_create_bind_group( device_id: DeviceId, desc: &binding_model::BindGroupDescriptor, -) -> BindGroupId { +) -> binding_model::BindGroup { let device_guard = HUB.devices.read(); let device = device_guard.get(device_id); let bind_group_layout_guard = HUB.bind_group_layouts.read(); @@ -713,44 +787,30 @@ pub extern "C" fn wgpu_device_create_bind_group( device.raw.write_descriptor_sets(writes); } - HUB.bind_groups - .write() - .register(binding_model::BindGroup { - raw: desc_set, - layout_id: WeaklyStored(desc.layout), - life_guard: LifeGuard::new(), - used_buffers, - used_textures, - }) + binding_model::BindGroup { + raw: desc_set, + layout_id: WeaklyStored(desc.layout), + life_guard: LifeGuard::new(), + used_buffers, + used_textures, + } } +#[cfg(feature = "local")] #[no_mangle] -pub extern "C" fn wgpu_device_create_blend_state( - _device_id: DeviceId, - desc: &pipeline::BlendStateDescriptor, -) -> BlendStateId { - HUB.blend_states.write().register(pipeline::BlendState { - raw: conv::map_blend_state_descriptor(desc), - }) +pub extern "C" fn wgpu_device_create_bind_group( + device_id: DeviceId, + desc: &binding_model::BindGroupDescriptor, +) -> BindGroupId { + let bind_group = device_create_bind_group(device_id, desc); + HUB.bind_groups.register(bind_group) } -#[no_mangle] -pub extern "C" fn wgpu_device_create_depth_stencil_state( - _device_id: DeviceId, - desc: &pipeline::DepthStencilStateDescriptor, -) -> DepthStencilStateId { - HUB.depth_stencil_states - .write() - .register(pipeline::DepthStencilState { - raw: conv::map_depth_stencil_state(desc), - }) -} -#[no_mangle] -pub extern "C" fn wgpu_device_create_shader_module( +pub fn device_create_shader_module( device_id: DeviceId, desc: &pipeline::ShaderModuleDescriptor, -) -> ShaderModuleId { +) -> ShaderModule { let spv = unsafe { slice::from_raw_parts(desc.code.bytes, desc.code.length) }; let shader = unsafe { HUB.devices @@ -758,19 +818,26 @@ pub extern "C" fn wgpu_device_create_shader_module( .get(device_id) .raw .create_shader_module(spv) - } - .unwrap(); + .unwrap() + }; - HUB.shader_modules - .write() - .register(ShaderModule { raw: shader }) + ShaderModule { raw: shader } } +#[cfg(feature = "local")] #[no_mangle] -pub extern "C" fn wgpu_device_create_command_encoder( +pub extern "C" fn wgpu_device_create_shader_module( + device_id: DeviceId, + desc: &pipeline::ShaderModuleDescriptor, +) -> ShaderModuleId { + let module = device_create_shader_module(device_id, desc); + HUB.shader_modules.register(module) +} + +pub fn device_create_command_encoder( device_id: DeviceId, _desc: &command::CommandEncoderDescriptor, -) -> CommandEncoderId { +) -> command::CommandBuffer { let device_guard = HUB.devices.read(); let device = device_guard.get(device_id); @@ -785,7 +852,17 @@ pub extern "C" fn wgpu_device_create_command_encoder( hal::command::CommandBufferInheritanceInfo::default(), ); } - HUB.command_buffers.write().register(cmb) + cmb +} + +#[cfg(feature = "local")] +#[no_mangle] +pub extern "C" fn wgpu_device_create_command_encoder( + device_id: DeviceId, + desc: &command::CommandEncoderDescriptor, +) -> CommandEncoderId { + let cmb = device_create_command_encoder(device_id, desc); + HUB.command_buffers.register(cmb) } #[no_mangle] @@ -918,48 +995,47 @@ pub extern "C" fn wgpu_queue_submit( // finally, return the command buffers to the allocator for &cmb_id in command_buffer_ids { + #[cfg(feature = "local")] + HUB.command_buffers.unregister(cmb_id); let cmd_buf = command_buffer_guard.take(cmb_id); device.com_allocator.after_submit(cmd_buf); } } -#[no_mangle] -pub extern "C" fn wgpu_device_create_render_pipeline( + +pub fn device_create_render_pipeline( device_id: DeviceId, desc: &pipeline::RenderPipelineDescriptor, -) -> RenderPipelineId { +) -> pipeline::RenderPipeline { let device_guard = HUB.devices.read(); let device = device_guard.get(device_id); let pipeline_layout_guard = HUB.pipeline_layouts.read(); let layout = &pipeline_layout_guard.get(desc.layout).raw; - let pipeline_stages = unsafe { slice::from_raw_parts(desc.stages, desc.stages_length) }; let shader_module_guard = HUB.shader_modules.read(); + let color_states = unsafe { + slice::from_raw_parts( + desc.color_states, + desc.color_states_length, + ) + }; + let depth_stencil_state = unsafe { + desc.depth_stencil_state.as_ref() + }; + let rp_key = { - let op_keep = hal::pass::AttachmentOps { - load: hal::pass::AttachmentLoadOp::Load, - store: hal::pass::AttachmentStoreOp::Store, - }; - let color_attachments = unsafe { - slice::from_raw_parts( - desc.attachments_state.color_attachments, - desc.attachments_state.color_attachments_length, - ) - }; - let depth_stencil_attachment = - unsafe { desc.attachments_state.depth_stencil_attachment.as_ref() }; - let color_keys = color_attachments.iter().map(|at| hal::pass::Attachment { + let color_keys = color_states.iter().map(|at| hal::pass::Attachment { format: Some(conv::map_texture_format(at.format)), - samples: at.samples as u8, - ops: op_keep, + samples: desc.sample_count as u8, + ops: hal::pass::AttachmentOps::PRESERVE, stencil_ops: hal::pass::AttachmentOps::DONT_CARE, layouts: hal::image::Layout::General..hal::image::Layout::General, }); - let depth_stencil_key = depth_stencil_attachment.map(|at| hal::pass::Attachment { + let depth_stencil_key = depth_stencil_state.map(|at| hal::pass::Attachment { format: Some(conv::map_texture_format(at.format)), - samples: at.samples as u8, - ops: op_keep, - stencil_ops: op_keep, + samples: desc.sample_count as u8, + ops: hal::pass::AttachmentOps::PRESERVE, + stencil_ops: hal::pass::AttachmentOps::PRESERVE, layouts: hal::image::Layout::General..hal::image::Layout::General, }); RenderPassKey { @@ -978,17 +1054,13 @@ pub extern "C" fn wgpu_device_create_render_pipeline( (3, hal::image::Layout::ColorAttachmentOptimal), ]; let depth_id = ( - desc.attachments_state.color_attachments_length, + desc.color_states_length, hal::image::Layout::DepthStencilAttachmentOptimal, ); let subpass = hal::pass::SubpassDesc { - colors: &color_ids[..desc.attachments_state.color_attachments_length], - depth_stencil: if desc.attachments_state.depth_stencil_attachment.is_null() { - None - } else { - Some(&depth_id) - }, + colors: &color_ids[..desc.color_states_length], + depth_stencil: depth_stencil_state.map(|_| &depth_id), inputs: &[], resolves: &[], preserves: &[], @@ -1004,51 +1076,39 @@ pub extern "C" fn wgpu_device_create_render_pipeline( } }; - let shaders = { - let mut vertex = None; - let mut fragment = None; - for pipeline_stage in pipeline_stages.iter() { - let entry = hal::pso::EntryPoint:: { - entry: unsafe { ffi::CStr::from_ptr(pipeline_stage.entry_point) } - .to_str() - .to_owned() - .unwrap(), // TODO - module: &shader_module_guard.get(pipeline_stage.module).raw, - specialization: hal::pso::Specialization { - // TODO - constants: &[], - data: &[], - }, - }; - match pipeline_stage.stage { - pipeline::ShaderStage::Vertex => { - vertex = Some(entry); - } - pipeline::ShaderStage::Fragment => { - fragment = Some(entry); - } - pipeline::ShaderStage::Compute => unimplemented!(), // TODO - } - } - - hal::pso::GraphicsShaderSet { - vertex: vertex.unwrap(), // TODO - hull: None, - domain: None, - geometry: None, - fragment, - } + let vertex = hal::pso::EntryPoint:: { + entry: unsafe { ffi::CStr::from_ptr(desc.vertex_stage.entry_point) } + .to_str() + .to_owned() + .unwrap(), // TODO + module: &shader_module_guard.get(desc.vertex_stage.module).raw, + specialization: hal::pso::Specialization { + // TODO + constants: &[], + data: &[], + }, + }; + let fragment = hal::pso::EntryPoint:: { + entry: unsafe { ffi::CStr::from_ptr(desc.fragment_stage.entry_point) } + .to_str() + .to_owned() + .unwrap(), // TODO + module: &shader_module_guard.get(desc.fragment_stage.module).raw, + specialization: hal::pso::Specialization { + // TODO + constants: &[], + data: &[], + }, }; - // TODO - let rasterizer = hal::pso::Rasterizer { - depth_clamping: false, - polygon_mode: hal::pso::PolygonMode::Fill, - cull_face: hal::pso::Face::BACK, - front_face: hal::pso::FrontFace::Clockwise, - depth_bias: None, - conservative: false, + let shaders = hal::pso::GraphicsShaderSet { + vertex, + hull: None, + domain: None, + geometry: None, + fragment: Some(fragment), }; + let rasterizer = conv::map_rasterization_state_descriptor(&desc.rasterization_state); let desc_vbs = unsafe { slice::from_raw_parts(desc.vertex_buffer_state.vertex_buffers, desc.vertex_buffer_state.vertex_buffers_count) @@ -1087,20 +1147,16 @@ pub extern "C" fn wgpu_device_create_render_pipeline( primitive_restart: hal::pso::PrimitiveRestart::Disabled, // TODO }; - let blend_state_guard = HUB.blend_states.read(); - let blend_states = - unsafe { slice::from_raw_parts(desc.blend_states, desc.blend_states_length) } - .iter() - .map(|id| blend_state_guard.get(id.clone()).raw) - .collect(); - let blender = hal::pso::BlendDesc { logic_op: None, // TODO - targets: blend_states, + targets: color_states + .iter() + .map(conv::map_color_state_descriptor) + .collect(), }; - - let depth_stencil_state_guard = HUB.depth_stencil_states.read(); - let depth_stencil = depth_stencil_state_guard.get(desc.depth_stencil_state).raw; + let depth_stencil = depth_stencil_state + .map(conv::map_depth_stencil_state_descriptor) + .unwrap_or_default(); // TODO let multisampling: Option = None; @@ -1140,21 +1196,32 @@ pub extern "C" fn wgpu_device_create_render_pipeline( }; // TODO: cache - let pipeline = unsafe { device.raw.create_graphics_pipeline(&pipeline_desc, None) }.unwrap(); + let pipeline = unsafe { + device.raw + .create_graphics_pipeline(&pipeline_desc, None) + .unwrap() + }; - HUB.render_pipelines - .write() - .register(pipeline::RenderPipeline { - raw: pipeline, - layout_id: WeaklyStored(desc.layout), - }) + pipeline::RenderPipeline { + raw: pipeline, + layout_id: WeaklyStored(desc.layout), + } } +#[cfg(feature = "local")] #[no_mangle] -pub extern "C" fn wgpu_device_create_compute_pipeline( +pub extern "C" fn wgpu_device_create_render_pipeline( + device_id: DeviceId, + desc: &pipeline::RenderPipelineDescriptor, +) -> RenderPipelineId { + let pipeline = device_create_render_pipeline(device_id, desc); + HUB.render_pipelines.register(pipeline) +} + +pub fn device_create_compute_pipeline( device_id: DeviceId, desc: &pipeline::ComputePipelineDescriptor, -) -> ComputePipelineId { +) -> pipeline::ComputePipeline { let device_guard = HUB.devices.read(); let device = device_guard.get(device_id); let pipeline_layout_guard = HUB.pipeline_layouts.read(); @@ -1162,8 +1229,6 @@ pub extern "C" fn wgpu_device_create_compute_pipeline( let pipeline_stage = &desc.compute_stage; let shader_module_guard = HUB.shader_modules.read(); - assert!(pipeline_stage.stage == pipeline::ShaderStage::Compute); // TODO - let shader = hal::pso::EntryPoint:: { entry: unsafe { ffi::CStr::from_ptr(pipeline_stage.entry_point) } .to_str() @@ -1189,22 +1254,34 @@ pub extern "C" fn wgpu_device_create_compute_pipeline( parent, }; - let pipeline = unsafe { device.raw.create_compute_pipeline(&pipeline_desc, None) }.unwrap(); + let pipeline = unsafe { + device.raw + .create_compute_pipeline(&pipeline_desc, None) + .unwrap() + }; - HUB.compute_pipelines - .write() - .register(pipeline::ComputePipeline { - raw: pipeline, - layout_id: WeaklyStored(desc.layout), - }) + pipeline::ComputePipeline { + raw: pipeline, + layout_id: WeaklyStored(desc.layout), + } } +#[cfg(feature = "local")] #[no_mangle] -pub extern "C" fn wgpu_device_create_swap_chain( +pub extern "C" fn wgpu_device_create_compute_pipeline( + device_id: DeviceId, + desc: &pipeline::ComputePipelineDescriptor, +) -> ComputePipelineId { + let pipeline = device_create_compute_pipeline(device_id, desc); + HUB.compute_pipelines.register(pipeline) +} + + +pub fn device_create_swap_chain( device_id: DeviceId, surface_id: SurfaceId, desc: &swap_chain::SwapChainDescriptor, -) -> SwapChainId { +) -> (swap_chain::SwapChain, Vec>) { let device_guard = HUB.devices.read(); let device = device_guard.get(device_id); let mut surface_guard = HUB.surfaces.write(); @@ -1217,11 +1294,10 @@ pub extern "C" fn wgpu_device_create_swap_chain( surface.raw.compatibility(&adapter.physical_device) }; let num_frames = caps.image_count.start; //TODO: configure? - let frame_format = conv::map_texture_format(desc.format); let config = hal::SwapchainConfig::new( desc.width, desc.height, - frame_format, + conv::map_texture_format(desc.format), num_frames, //TODO: configure? ); @@ -1255,67 +1331,79 @@ pub extern "C" fn wgpu_device_create_swap_chain( .unwrap() }; - let mut swap_chain_guard = HUB.swap_chains.write(); - - let swap_chain_id = swap_chain_guard - .register(swap_chain::SwapChain { - raw, - device_id: Stored { - value: device_id, - ref_count: device.life_guard.ref_count.clone(), - }, - frames: Vec::with_capacity(num_frames as usize), - acquired: Vec::with_capacity(1), //TODO: get it from gfx-hal? - sem_available: device.raw.create_semaphore().unwrap(), - command_pool, - }); - let swap_chain = swap_chain_guard.get_mut(swap_chain_id); + let swap_chain = swap_chain::SwapChain { + raw, + device_id: Stored { + value: device_id, + ref_count: device.life_guard.ref_count.clone(), + }, + frames: Vec::with_capacity(num_frames as usize), + acquired: Vec::with_capacity(1), //TODO: get it from gfx-hal? + sem_available: device.raw.create_semaphore().unwrap(), + command_pool, + }; let images = match backbuffer { hal::Backbuffer::Images(images) => images, hal::Backbuffer::Framebuffer(_) => panic!("Deprecated API detected!"), }; - let mut texture_guard = HUB.textures.write(); - let mut texture_view_guard = HUB.texture_views.write(); - - for (i, image) in images.into_iter().enumerate() { - let kind = hal::image::Kind::D2(desc.width, desc.height, 1, 1); - let full_range = hal::image::SubresourceRange { - aspects: hal::format::Aspects::COLOR, - levels: 0 .. 1, - layers: 0 .. 1, - }; - let view_raw = unsafe { - device.raw - .create_image_view( - &image, - hal::image::ViewKind::D2, - frame_format, - hal::format::Swizzle::NO, - full_range.clone(), - ) - .unwrap() - }; - let texture = resource::Texture { - raw: image, + let textures = images + .into_iter() + .map(|raw| resource::Texture { + raw, device_id: Stored { value: device_id, ref_count: device.life_guard.ref_count.clone(), }, - kind, + kind: hal::image::Kind::D2(desc.width, desc.height, 1, 1), format: desc.format, - full_range, - swap_chain_link: Some(swap_chain::SwapChainLink { - swap_chain_id: WeaklyStored(swap_chain_id), //TODO: strongly - epoch: Mutex::new(0), - image_index: i as hal::SwapImageIndex, - }), + full_range: hal::image::SubresourceRange { + aspects: hal::format::Aspects::COLOR, + levels: 0 .. 1, + layers: 0 .. 1, + }, + swap_chain_link: None, life_guard: LifeGuard::new(), - }; + }) + .collect(); + + (swap_chain, textures) +} + +#[cfg(feature = "local")] +fn swap_chain_populate_textures( + swap_chain_id: SwapChainId, + textures: Vec>, +) { + let mut swap_chain_guard = HUB.swap_chains.write(); + let swap_chain = swap_chain_guard.get_mut(swap_chain_id); + let device_guard = HUB.devices.read(); + let device = device_guard.get(swap_chain.device_id.value); + + for (i, mut texture) in textures.into_iter().enumerate() { + let format = texture.format; + let kind = texture.kind; + + let view_raw = unsafe { + device.raw + .create_image_view( + &texture.raw, + hal::image::ViewKind::D2, + conv::map_texture_format(format), + hal::format::Swizzle::NO, + texture.full_range.clone(), + ) + .unwrap() + }; + texture.swap_chain_link = Some(swap_chain::SwapChainLink { + swap_chain_id: WeaklyStored(swap_chain_id), //TODO: strongly + epoch: Mutex::new(0), + image_index: i as hal::SwapImageIndex, + }); let texture_id = Stored { ref_count: texture.life_guard.ref_count.clone(), - value: texture_guard.register(texture), + value: HUB.textures.register(texture), }; device.texture_tracker .lock() @@ -1324,7 +1412,7 @@ pub extern "C" fn wgpu_device_create_swap_chain( let view = resource::TextureView { raw: view_raw, texture_id: texture_id.clone(), - format: desc.format, + format, extent: kind.extent(), samples: kind.num_samples(), is_owned_by_swap_chain: true, @@ -1334,7 +1422,7 @@ pub extern "C" fn wgpu_device_create_swap_chain( texture_id, view_id: Stored { ref_count: view.life_guard.ref_count.clone(), - value: texture_view_guard.register(view), + value: HUB.texture_views.register(view), }, fence: device.raw.create_fence(true).unwrap(), sem_available: device.raw.create_semaphore().unwrap(), @@ -1342,10 +1430,20 @@ pub extern "C" fn wgpu_device_create_swap_chain( comb: swap_chain.command_pool.acquire_command_buffer(), }); } - - swap_chain_id } +#[cfg(feature = "local")] +#[no_mangle] +pub extern "C" fn wgpu_device_create_swap_chain( + device_id: DeviceId, + surface_id: SurfaceId, + desc: &swap_chain::SwapChainDescriptor, +) -> SwapChainId { + let (swap_chain, textures) = device_create_swap_chain(device_id, surface_id, desc); + let id = HUB.swap_chains.register(swap_chain); + swap_chain_populate_textures(id, textures); + id +} #[no_mangle] diff --git a/wgpu-native/src/hub.rs b/wgpu-native/src/hub.rs new file mode 100644 index 000000000..74d036c97 --- /dev/null +++ b/wgpu-native/src/hub.rs @@ -0,0 +1,134 @@ +use crate::{ + AdapterHandle, BindGroupLayoutHandle, BindGroupHandle, + CommandBufferHandle, DeviceHandle, InstanceHandle, + RenderPassHandle, ComputePassHandle, + PipelineLayoutHandle, RenderPipelineHandle, ComputePipelineHandle, ShaderModuleHandle, + BufferHandle, SamplerHandle, TextureHandle, TextureViewHandle, + SurfaceHandle, SwapChainHandle, +}; + +use hal::backend::FastHashMap; +use lazy_static::lazy_static; +use parking_lot::RwLock; +#[cfg(feature = "local")] +use parking_lot::Mutex; + +use std::ops; +use std::sync::Arc; + +//TODO: use Vec instead of HashMap +//TODO: track epochs of indices + +pub type Id = u32; + +/// A simple structure to manage identities of objects. +#[derive(Default)] +pub struct IdentityManager { + last_id: Id, + free: Vec, +} + +impl IdentityManager { + pub fn alloc(&mut self) -> Id { + match self.free.pop() { + Some(id) => id, + None => { + self.last_id += 1; + assert_ne!(self.last_id, 0); + self.last_id + } + } + } + + pub fn free(&mut self, id: Id) { + debug_assert!(id <= self.last_id && !self.free.contains(&id)); + self.free.push(id); + } +} + +pub struct Storage { + //TODO: consider concurrent hashmap? + map: FastHashMap, +} + +impl Storage { + pub fn get(&self, id: Id) -> &T { + self.map.get(&id).unwrap() + } + pub fn get_mut(&mut self, id: Id) -> &mut T { + self.map.get_mut(&id).unwrap() + } + pub fn take(&mut self, id: Id) -> T { + self.map.remove(&id).unwrap() + } +} + +pub struct Registry { + #[cfg(feature = "local")] + identity: Mutex, + data: RwLock>, +} + +impl Default for Registry { + fn default() -> Self { + Registry { + #[cfg(feature = "local")] + identity: Mutex::new(IdentityManager::default()), + data: RwLock::new(Storage { + map: FastHashMap::default(), + }), + } + } +} + +impl ops::Deref for Registry { + type Target = RwLock>; + fn deref(&self) -> &Self::Target { + &self.data + } +} + +impl ops::DerefMut for Registry { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.data + } +} + +#[cfg(feature = "local")] +impl Registry { + pub fn register(&self, value: T) -> Id { + let id = self.identity.lock().alloc(); + let old = self.data.write().map.insert(id, value); + assert!(old.is_none()); + id + } + pub fn unregister(&self, id: Id) { + self.identity.lock().free(id); + } +} + +#[derive(Default)] +pub struct Hub { + pub(crate) instances: Arc>, + pub(crate) adapters: Arc>, + pub(crate) devices: Arc>, + pub(crate) pipeline_layouts: Arc>, + pub(crate) bind_group_layouts: Arc>, + pub(crate) bind_groups: Arc>, + pub(crate) shader_modules: Arc>, + pub(crate) command_buffers: Arc>, + pub(crate) render_pipelines: Arc>, + pub(crate) compute_pipelines: Arc>, + pub(crate) render_passes: Arc>, + pub(crate) compute_passes: Arc>, + pub(crate) buffers: Arc>, + pub(crate) textures: Arc>, + pub(crate) texture_views: Arc>, + pub(crate) samplers: Arc>, + pub(crate) surfaces: Arc>, + pub(crate) swap_chains: Arc>, +} + +lazy_static! { + pub static ref HUB: Hub = Hub::default(); +} diff --git a/wgpu-native/src/instance.rs b/wgpu-native/src/instance.rs index 4eb2f4720..6654fecc6 100644 --- a/wgpu-native/src/instance.rs +++ b/wgpu-native/src/instance.rs @@ -1,5 +1,11 @@ -use crate::registry::{HUB, Items}; -use crate::{AdapterId, Device, DeviceId, InstanceId, Surface, SurfaceId, WeaklyStored}; +use crate::hub::HUB; +use crate::{ + WeaklyStored, + AdapterHandle, DeviceHandle, SurfaceHandle, + AdapterId, InstanceId, +}; +#[cfg(feature = "local")] +use crate::{DeviceId, SurfaceId}; use hal::{self, Instance as _Instance, PhysicalDevice as _PhysicalDevice}; @@ -27,13 +33,18 @@ pub struct DeviceDescriptor { pub extensions: Extensions, } -#[no_mangle] -pub extern "C" fn wgpu_create_instance() -> InstanceId { - let inst = ::back::Instance::create("wgpu", 1); - HUB.instances.write().register(inst) +pub fn create_instance() -> ::back::Instance { + ::back::Instance::create("wgpu", 1) } -#[cfg(feature = "winit")] +#[no_mangle] +#[cfg(feature = "local")] +pub extern "C" fn wgpu_create_instance() -> InstanceId { + let inst = create_instance(); + HUB.instances.register(inst) +} + +#[cfg(feature = "local")] #[no_mangle] pub extern "C" fn wgpu_instance_create_surface_from_winit( instance_id: InstanceId, @@ -43,114 +54,111 @@ pub extern "C" fn wgpu_instance_create_surface_from_winit( .read() .get(instance_id) .create_surface(window); - let surface = Surface { + let surface = SurfaceHandle { raw, }; - HUB.surfaces - .write() - .register(surface) + HUB.surfaces.register(surface) } -#[allow(unused)] +#[allow(unused_variables)] +pub fn instance_create_surface_from_xlib( + instance_id: InstanceId, + display: *mut *const std::ffi::c_void, + window: u64, +) -> SurfaceHandle { + #[cfg(not(all(unix, feature = "gfx-backend-vulkan")))] + unimplemented!(); + + #[cfg(all(unix, feature = "gfx-backend-vulkan"))] + SurfaceHandle { + raw: HUB.instances + .read() + .get(instance_id) + .create_surface_from_xlib(display, window), + } +} + +#[cfg(feature = "local")] #[no_mangle] pub extern "C" fn wgpu_instance_create_surface_from_xlib( instance_id: InstanceId, display: *mut *const std::ffi::c_void, window: u64, ) -> SurfaceId { - #[cfg(not(all(unix, feature = "gfx-backend-vulkan")))] + let surface = instance_create_surface_from_xlib(instance_id, display, window); + HUB.surfaces.register(surface) +} + +#[allow(unused_variables)] +pub fn instance_create_surface_from_macos_layer( + instance_id: InstanceId, + layer: *mut std::ffi::c_void, +) -> SurfaceHandle { + #[cfg(not(feature = "gfx-backend-metal"))] unimplemented!(); - #[cfg(all(unix, feature = "gfx-backend-vulkan"))] - { - let raw = HUB.instances + #[cfg(feature = "gfx-backend-metal")] + SurfaceHandle { + raw: HUB.instances .read() .get(instance_id) - .create_surface_from_xlib(display, window); - let surface = Surface { - raw, - }; - - HUB.surfaces - .write() - .register(surface) + .create_surface_from_layer(layer as *mut _), } } -#[allow(unused)] +#[cfg(feature = "local")] #[no_mangle] pub extern "C" fn wgpu_instance_create_surface_from_macos_layer( instance_id: InstanceId, layer: *mut std::ffi::c_void, ) -> SurfaceId { - #[cfg(not(feature = "gfx-backend-metal"))] - unimplemented!(); + let surface = instance_create_surface_from_macos_layer(instance_id, layer); + HUB.surfaces.register(surface) +} - #[cfg(feature = "gfx-backend-metal")] - { - let raw = HUB.instances - .read() - .get(instance_id) - .create_surface_from_layer(layer as *mut _); - let surface = Surface { - raw, - }; +#[allow(unused_variables)] +pub fn instance_create_surface_from_windows_hwnd( + instance_id: InstanceId, + hinstance: *mut std::ffi::c_void, + hwnd: *mut std::ffi::c_void, +) -> SurfaceHandle { + #[cfg(not(target_os = "windows"))] + let raw = unimplemented!(); - HUB.surfaces - .write() - .register(surface) + #[cfg(any(feature = "gfx-backend-dx11", feature = "gfx-backend-dx12"))] + let raw = HUB.instances + .read() + .get(instance_id) + .create_surface_from_hwnd(hwnd); + + #[cfg(all(target_os = "windows", feature = "gfx-backend-vulkan"))] + let raw = HUB.instances + .read() + .get(instance_id) + .create_surface_from_hwnd(hinstance, hwnd); + + #[cfg_attr(not(target_os = "windows"), allow(unreachable_code))] + SurfaceHandle { + raw, } } -#[allow(unused)] +#[cfg(feature = "local")] #[no_mangle] pub extern "C" fn wgpu_instance_create_surface_from_windows_hwnd( instance_id: InstanceId, hinstance: *mut std::ffi::c_void, hwnd: *mut std::ffi::c_void, ) -> SurfaceId { - #[cfg(not(target_os = "windows"))] - unimplemented!(); - - #[cfg(any(feature = "gfx-backend-dx11", feature = "gfx-backend-dx12"))] - { - let raw = HUB.instances - .read() - .get(instance_id) - .create_surface_from_hwnd(hwnd); - - let surface = Surface { - raw, - }; - - HUB.surfaces - .write() - .register(surface) - } - - #[cfg(all(target_os = "windows", feature = "gfx-backend-vulkan"))] - { - let raw = HUB.instances - .read() - .get(instance_id) - .create_surface_from_hwnd(hinstance, hwnd); - - let surface = Surface { - raw, - }; - - HUB.surfaces - .write() - .register(surface) - } + let surface = instance_create_surface_from_windows_hwnd(instance_id, hinstance, hwnd); + HUB.surfaces.register(surface) } -#[no_mangle] -pub extern "C" fn wgpu_instance_get_adapter( +pub fn instance_get_adapter( instance_id: InstanceId, desc: &AdapterDescriptor, -) -> AdapterId { +) -> AdapterHandle { let instance_guard = HUB.instances.read(); let instance = instance_guard.get(instance_id); let (mut low, mut high, mut other) = (None, None, None); @@ -166,21 +174,36 @@ pub extern "C" fn wgpu_instance_get_adapter( PowerPreference::LowPower => low.or(high), PowerPreference::HighPerformance | PowerPreference::Default => high.or(low), }; - HUB.adapters.write().register(some.or(other).unwrap()) + some.or(other).unwrap() } +#[cfg(feature = "local")] #[no_mangle] -pub extern "C" fn wgpu_adapter_create_device( +pub extern "C" fn wgpu_instance_get_adapter( + instance_id: InstanceId, + desc: &AdapterDescriptor, +) -> AdapterId { + let adapter = instance_get_adapter(instance_id, desc); + HUB.adapters.register(adapter) +} + +pub fn adapter_create_device( adapter_id: AdapterId, _desc: &DeviceDescriptor, -) -> DeviceId { +) -> DeviceHandle { let mut adapter_guard = HUB.adapters.write(); let adapter = adapter_guard.get_mut(adapter_id); let (raw, queue_group) = adapter.open_with::<_, hal::General>(1, |_qf| true).unwrap(); let mem_props = adapter.physical_device.memory_properties(); - let device = Device::new(raw, WeaklyStored(adapter_id), queue_group, mem_props); - - HUB.devices - .write() - .register(device) + DeviceHandle::new(raw, WeaklyStored(adapter_id), queue_group, mem_props) +} + +#[cfg(feature = "local")] +#[no_mangle] +pub extern "C" fn wgpu_adapter_create_device( + adapter_id: AdapterId, + desc: &DeviceDescriptor, +) -> DeviceId { + let device = adapter_create_device(adapter_id, desc); + HUB.devices.register(device) } diff --git a/wgpu-native/src/lib.rs b/wgpu-native/src/lib.rs index bc4fc200d..c4255ad68 100644 --- a/wgpu-native/src/lib.rs +++ b/wgpu-native/src/lib.rs @@ -1,4 +1,4 @@ -#[cfg(feature = "winit")] +#[cfg(feature = "local")] pub extern crate winit; #[cfg(feature = "gfx-backend-dx11")] @@ -24,9 +24,9 @@ mod binding_model; mod command; mod conv; mod device; +mod hub; mod instance; mod pipeline; -mod registry; mod resource; mod swap_chain; mod track; @@ -38,17 +38,18 @@ pub use self::instance::*; pub use self::pipeline::*; pub use self::resource::*; pub use self::swap_chain::*; - -use back::Backend as B; -pub use crate::registry::Id; +#[cfg(not(feature = "local"))] +pub use self::hub::{Id, IdentityManager}; use std::ptr; use std::sync::atomic::{AtomicUsize, Ordering}; +pub const MAX_DEPTH_BIAS_CLAMP: f32 = 16.0; type SubmissionIndex = usize; +//TODO: make it private. Currently used for swapchain creation impl. #[derive(Debug)] -struct RefCount(ptr::NonNull); +pub struct RefCount(ptr::NonNull); impl RefCount { const MAX: usize = 1 << 24; @@ -105,8 +106,6 @@ unsafe impl Sync for Stored {} #[derive(Clone, Debug, Hash, PartialEq, Eq)] struct WeaklyStored(T); -unsafe impl Send for WeaklyStored {} -unsafe impl Sync for WeaklyStored {} #[repr(C)] #[derive(Clone, Copy, Debug)] @@ -178,55 +177,47 @@ pub struct ByteArray { pub length: usize, } -pub type InstanceId = Id; +pub type InstanceId = hub::Id; type InstanceHandle = back::Instance; -pub type AdapterId = Id; -type AdapterHandle = hal::Adapter; -pub type DeviceId = Id; -type DeviceHandle = Device; +pub type AdapterId = hub::Id; +type AdapterHandle = hal::Adapter; +pub type DeviceId = hub::Id; +type DeviceHandle = Device; pub type QueueId = DeviceId; -pub type BufferId = Id; -type BufferHandle = Buffer; - +pub type BufferId = hub::Id; +type BufferHandle = Buffer; // Resource -pub type TextureViewId = Id; -type TextureViewHandle = TextureView; -pub type TextureId = Id; -type TextureHandle = Texture; -pub type SamplerId = Id; -type SamplerHandle = Sampler; - +pub type TextureViewId = hub::Id; +type TextureViewHandle = TextureView; +pub type TextureId = hub::Id; +type TextureHandle = Texture; +pub type SamplerId = hub::Id; +type SamplerHandle = Sampler; // Binding model -pub type BindGroupLayoutId = Id; -type BindGroupLayoutHandle = BindGroupLayout; -pub type PipelineLayoutId = Id; -type PipelineLayoutHandle = PipelineLayout; -pub type BindGroupId = Id; -type BindGroupHandle = BindGroup; - +pub type BindGroupLayoutId = hub::Id; +type BindGroupLayoutHandle = BindGroupLayout; +pub type PipelineLayoutId = hub::Id; +type PipelineLayoutHandle = PipelineLayout; +pub type BindGroupId = hub::Id; +type BindGroupHandle = BindGroup; // Pipeline -pub type BlendStateId = Id; -type BlendStateHandle = BlendState; -pub type DepthStencilStateId = Id; -type DepthStencilStateHandle = DepthStencilState; -pub type InputStateId = Id; -pub type ShaderModuleId = Id; -type ShaderModuleHandle = ShaderModule; -pub type RenderPipelineId = Id; -type RenderPipelineHandle = RenderPipeline; -pub type ComputePipelineId = Id; -type ComputePipelineHandle = ComputePipeline; - -pub type CommandBufferId = Id; -type CommandBufferHandle = CommandBuffer; +pub type InputStateId = hub::Id; +pub type ShaderModuleId = hub::Id; +type ShaderModuleHandle = ShaderModule; +pub type RenderPipelineId = hub::Id; +type RenderPipelineHandle = RenderPipeline; +pub type ComputePipelineId = hub::Id; +type ComputePipelineHandle = ComputePipeline; +// Command +pub type CommandBufferId = hub::Id; +type CommandBufferHandle = CommandBuffer; pub type CommandEncoderId = CommandBufferId; -pub type RenderPassId = Id; -type RenderPassHandle = RenderPass; -pub type ComputePassId = Id; -type ComputePassHandle = ComputePass; - - -pub type SurfaceId = Id; -type SurfaceHandle = Surface; -pub type SwapChainId = Id; -type SwapChainHandle = SwapChain; +pub type RenderPassId = hub::Id; +type RenderPassHandle = RenderPass; +pub type ComputePassId = hub::Id; +type ComputePassHandle = ComputePass; +// Swap chain +pub type SurfaceId = hub::Id; +type SurfaceHandle = Surface; +pub type SwapChainId = hub::Id; +type SwapChainHandle = SwapChain; diff --git a/wgpu-native/src/pipeline.rs b/wgpu-native/src/pipeline.rs index da6e6e55e..cfe2f2f33 100644 --- a/wgpu-native/src/pipeline.rs +++ b/wgpu-native/src/pipeline.rs @@ -1,6 +1,6 @@ use crate::resource; use crate::{ - BlendStateId, ByteArray, DepthStencilStateId, PipelineLayoutId, ShaderModuleId, WeaklyStored, + ByteArray, PipelineLayoutId, ShaderModuleId, WeaklyStored, }; use bitflags::bitflags; @@ -48,6 +48,7 @@ bitflags! { } #[repr(C)] +#[derive(Clone, Debug, PartialEq)] pub struct BlendDescriptor { pub src_factor: BlendFactor, pub dst_factor: BlendFactor, @@ -63,26 +64,14 @@ impl BlendDescriptor { } #[repr(C)] -pub struct BlendStateDescriptor { - pub blend_enabled: bool, +#[derive(Clone, Debug)] +pub struct ColorStateDescriptor { + pub format: resource::TextureFormat, pub alpha: BlendDescriptor, pub color: BlendDescriptor, pub write_mask: ColorWriteFlags, } -impl BlendStateDescriptor { - pub const REPLACE: Self = BlendStateDescriptor { - blend_enabled: false, - alpha: BlendDescriptor::REPLACE, - color: BlendDescriptor::REPLACE, - write_mask: ColorWriteFlags::ALL, - }; -} - -pub(crate) struct BlendState { - pub raw: hal::pso::ColorBlendDesc, -} - #[repr(C)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] pub enum StencilOperation { @@ -97,9 +86,10 @@ pub enum StencilOperation { } #[repr(C)] +#[derive(Clone, Debug, PartialEq)] pub struct StencilStateFaceDescriptor { pub compare: resource::CompareFunction, - pub stencil_fail_op: StencilOperation, + pub fail_op: StencilOperation, pub depth_fail_op: StencilOperation, pub pass_op: StencilOperation, } @@ -107,37 +97,24 @@ pub struct StencilStateFaceDescriptor { impl StencilStateFaceDescriptor { pub const IGNORE: Self = StencilStateFaceDescriptor { compare: resource::CompareFunction::Always, - stencil_fail_op: StencilOperation::Keep, + fail_op: StencilOperation::Keep, depth_fail_op: StencilOperation::Keep, pass_op: StencilOperation::Keep, }; } #[repr(C)] +#[derive(Clone, Debug)] pub struct DepthStencilStateDescriptor { + pub format: resource::TextureFormat, pub depth_write_enabled: bool, pub depth_compare: resource::CompareFunction, - pub front: StencilStateFaceDescriptor, - pub back: StencilStateFaceDescriptor, + pub stencil_front: StencilStateFaceDescriptor, + pub stencil_back: StencilStateFaceDescriptor, pub stencil_read_mask: u32, pub stencil_write_mask: u32, } -impl DepthStencilStateDescriptor { - pub const IGNORE: Self = DepthStencilStateDescriptor { - depth_write_enabled: false, - depth_compare: resource::CompareFunction::Always, - front: StencilStateFaceDescriptor::IGNORE, - back: StencilStateFaceDescriptor::IGNORE, - stencil_read_mask: 0xFF, - stencil_write_mask: 0xFF, - }; -} - -pub(crate) struct DepthStencilState { - pub raw: hal::pso::DepthStencilDesc, -} - #[repr(C)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] pub enum IndexFormat { @@ -162,6 +139,7 @@ pub enum InputStepMode { } #[repr(C)] +#[derive(Clone, Debug)] pub struct VertexAttributeDescriptor { pub offset: u32, pub format: VertexFormat, @@ -188,18 +166,9 @@ pub struct ShaderModuleDescriptor { pub code: ByteArray, } -#[repr(C)] -#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] -pub enum ShaderStage { - Vertex = 0, - Fragment = 1, - Compute = 2, -} - #[repr(C)] pub struct PipelineStageDescriptor { pub module: ShaderModuleId, - pub stage: ShaderStage, pub entry_point: *const ::std::os::raw::c_char, } @@ -209,9 +178,9 @@ pub struct ComputePipelineDescriptor { pub compute_stage: PipelineStageDescriptor, } -pub(crate) struct ComputePipeline { - pub raw: B::ComputePipeline, - pub layout_id: WeaklyStored, +pub struct ComputePipeline { + pub(crate) raw: B::ComputePipeline, + pub(crate) layout_id: WeaklyStored, } #[repr(C)] @@ -225,32 +194,45 @@ pub enum PrimitiveTopology { } #[repr(C)] -pub struct Attachment { - pub format: resource::TextureFormat, - pub samples: u32, +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] +pub enum FrontFace { + Ccw = 0, + Cw = 1, } #[repr(C)] -pub struct AttachmentsState { - pub color_attachments: *const Attachment, - pub color_attachments_length: usize, - pub depth_stencil_attachment: *const Attachment, +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] +pub enum CullMode { + None = 0, + Front = 1, + Back = 2, +} + +#[repr(C)] +#[derive(Clone, Debug)] +pub struct RasterizationStateDescriptor { + pub front_face: FrontFace, + pub cull_mode: CullMode, + pub depth_bias: i32, + pub depth_bias_slope_scale: f32, + pub depth_bias_clamp: f32, } #[repr(C)] pub struct RenderPipelineDescriptor { pub layout: PipelineLayoutId, - pub stages: *const PipelineStageDescriptor, - pub stages_length: usize, + pub vertex_stage: PipelineStageDescriptor, + pub fragment_stage: PipelineStageDescriptor, pub primitive_topology: PrimitiveTopology, - pub attachments_state: AttachmentsState, - pub blend_states: *const BlendStateId, - pub blend_states_length: usize, - pub depth_stencil_state: DepthStencilStateId, + pub rasterization_state: RasterizationStateDescriptor, + pub color_states: *const ColorStateDescriptor, + pub color_states_length: usize, + pub depth_stencil_state: *const DepthStencilStateDescriptor, pub vertex_buffer_state: VertexBufferStateDescriptor, + pub sample_count: u32, } -pub(crate) struct RenderPipeline { - pub raw: B::GraphicsPipeline, - pub layout_id: WeaklyStored, +pub struct RenderPipeline { + pub(crate) raw: B::GraphicsPipeline, + pub(crate) layout_id: WeaklyStored, } diff --git a/wgpu-native/src/registry/local.rs b/wgpu-native/src/registry/local.rs deleted file mode 100644 index 7c14aeb75..000000000 --- a/wgpu-native/src/registry/local.rs +++ /dev/null @@ -1,34 +0,0 @@ -use std::marker::PhantomData; -use std::os::raw::c_void; - -pub type Id = *mut c_void; - -pub struct Items { - marker: PhantomData, -} - -impl Default for Items { - fn default() -> Self { - Items { - marker: PhantomData, - } - } -} - -impl super::Items for Items { - fn register(&mut self, handle: T) -> Id { - Box::into_raw(Box::new(handle)) as *mut _ as *mut c_void - } - - fn get(&self, id: Id) -> &T { - unsafe { (id as *mut T).as_ref() }.unwrap() - } - - fn get_mut(&mut self, id: Id) -> &mut T { - unsafe { (id as *mut T).as_mut() }.unwrap() - } - - fn take(&mut self, id: Id) -> T { - unsafe { *Box::from_raw(id as *mut T) } - } -} diff --git a/wgpu-native/src/registry/mod.rs b/wgpu-native/src/registry/mod.rs deleted file mode 100644 index c73880d87..000000000 --- a/wgpu-native/src/registry/mod.rs +++ /dev/null @@ -1,61 +0,0 @@ -use crate::{ - AdapterHandle, BindGroupLayoutHandle, BindGroupHandle, - BlendStateHandle, CommandBufferHandle, DepthStencilStateHandle, DeviceHandle, InstanceHandle, - RenderPassHandle, ComputePassHandle, - PipelineLayoutHandle, RenderPipelineHandle, ComputePipelineHandle, ShaderModuleHandle, - BufferHandle, SamplerHandle, TextureHandle, TextureViewHandle, - SurfaceHandle, SwapChainHandle, -}; - -use lazy_static::lazy_static; -use parking_lot::RwLock; - -use std::sync::Arc; - - -#[cfg(not(feature = "remote"))] -mod local; -#[cfg(feature = "remote")] -mod remote; - -#[cfg(not(feature = "remote"))] -pub use self::local::{Id, Items as ConcreteItems}; -#[cfg(feature = "remote")] -pub use self::remote::{Id, Items as ConcreteItems}; - -pub trait Items: Default { - fn register(&mut self, handle: T) -> Id; - fn get(&self, id: Id) -> &T; - fn get_mut(&mut self, id: Id) -> &mut T; - fn take(&mut self, id: Id) -> T; -} - -pub type ConcreteRegistry = Arc>>; - -#[derive(Default)] -pub struct Hub { - pub(crate) instances: ConcreteRegistry, - pub(crate) adapters: ConcreteRegistry, - pub(crate) devices: ConcreteRegistry, - pub(crate) pipeline_layouts: ConcreteRegistry, - pub(crate) bind_group_layouts: ConcreteRegistry, - pub(crate) bind_groups: ConcreteRegistry, - pub(crate) blend_states: ConcreteRegistry, - pub(crate) depth_stencil_states: ConcreteRegistry, - pub(crate) shader_modules: ConcreteRegistry, - pub(crate) command_buffers: ConcreteRegistry, - pub(crate) render_pipelines: ConcreteRegistry, - pub(crate) compute_pipelines: ConcreteRegistry, - pub(crate) render_passes: ConcreteRegistry, - pub(crate) compute_passes: ConcreteRegistry, - pub(crate) buffers: ConcreteRegistry, - pub(crate) textures: ConcreteRegistry, - pub(crate) texture_views: ConcreteRegistry, - pub(crate) samplers: ConcreteRegistry, - pub(crate) surfaces: ConcreteRegistry, - pub(crate) swap_chains: ConcreteRegistry, -} - -lazy_static! { - pub static ref HUB: Hub = Hub::default(); -} diff --git a/wgpu-native/src/registry/remote.rs b/wgpu-native/src/registry/remote.rs deleted file mode 100644 index b1c2222b9..000000000 --- a/wgpu-native/src/registry/remote.rs +++ /dev/null @@ -1,46 +0,0 @@ -use hal::backend::FastHashMap; - -pub type Id = u32; - -pub struct Items { - next_id: Id, - tracked: FastHashMap, - free: Vec, -} - -impl Default for Items { - fn default() -> Self { - Items { - next_id: 0, - tracked: FastHashMap::default(), - free: Vec::new(), - } - } -} - -impl super::Items for Items { - fn register(&mut self, handle: T) -> Id { - let id = match self.free.pop() { - Some(id) => id, - None => { - self.next_id += 1; - self.next_id - 1 - } - }; - self.tracked.insert(id, handle); - id - } - - fn get(&self, id: Id) -> &T { - self.tracked.get(&id).unwrap() - } - - fn get_mut(&mut self, id: Id) -> &mut T { - self.tracked.get_mut(&id).unwrap() - } - - fn take(&mut self, id: Id) -> T { - self.free.push(id); - self.tracked.remove(&id).unwrap() - } -} diff --git a/wgpu-native/src/resource.rs b/wgpu-native/src/resource.rs index 729aee860..5e6745ee9 100644 --- a/wgpu-native/src/resource.rs +++ b/wgpu-native/src/resource.rs @@ -33,11 +33,11 @@ pub struct BufferDescriptor { pub usage: BufferUsageFlags, } -pub(crate) struct Buffer { - pub raw: B::Buffer, - pub device_id: Stored, +pub struct Buffer { + pub(crate) raw: B::Buffer, + pub(crate) device_id: Stored, //pub memory_properties: hal::memory::Properties, - pub life_guard: LifeGuard, + pub(crate) life_guard: LifeGuard, // TODO: mapping, unmap() } @@ -87,14 +87,14 @@ pub struct TextureDescriptor { pub usage: TextureUsageFlags, } -pub(crate) struct Texture { - pub raw: B::Image, - pub device_id: Stored, - pub kind: hal::image::Kind, - pub format: TextureFormat, - pub full_range: hal::image::SubresourceRange, - pub swap_chain_link: Option>>, - pub life_guard: LifeGuard, +pub struct Texture { + pub(crate) raw: B::Image, + pub(crate) device_id: Stored, + pub(crate) kind: hal::image::Kind, + pub(crate) format: TextureFormat, + pub(crate) full_range: hal::image::SubresourceRange, + pub(crate) swap_chain_link: Option>>, + pub(crate) life_guard: LifeGuard, } impl Borrow for Texture { @@ -134,14 +134,15 @@ pub struct TextureViewDescriptor { pub array_count: u32, } -pub(crate) struct TextureView { - pub raw: B::ImageView, - pub texture_id: Stored, - pub format: TextureFormat, - pub extent: hal::image::Extent, - pub samples: hal::image::NumSamples, - pub is_owned_by_swap_chain: bool, - pub life_guard: LifeGuard, +pub struct TextureView { + pub(crate) raw: B::ImageView, + pub(crate) texture_id: Stored, + pub(crate) format: TextureFormat, + pub(crate) extent: hal::image::Extent, + pub(crate) samples: hal::image::NumSamples, + pub(crate) is_owned_by_swap_chain: bool, + #[cfg_attr(not(feature = "local"), allow(dead_code))] + pub(crate) life_guard: LifeGuard, //TODO: use } #[repr(C)] @@ -196,6 +197,6 @@ pub struct SamplerDescriptor { pub border_color: BorderColor, } -pub(crate) struct Sampler { - pub raw: B::Sampler, +pub struct Sampler { + pub(crate) raw: B::Sampler, } diff --git a/wgpu-native/src/swap_chain.rs b/wgpu-native/src/swap_chain.rs index 1ad3e3c7a..53552fee7 100644 --- a/wgpu-native/src/swap_chain.rs +++ b/wgpu-native/src/swap_chain.rs @@ -3,7 +3,7 @@ use crate::{Stored, WeaklyStored, }; use crate::{conv, resource}; use crate::device::all_image_stages; -use crate::registry::{HUB, Items}; +use crate::hub::HUB; use crate::track::{TrackPermit}; use hal; @@ -21,8 +21,8 @@ pub(crate) struct SwapChainLink { pub image_index: hal::SwapImageIndex, } -pub(crate) struct Surface { - pub raw: B::Surface, +pub struct Surface { + pub(crate) raw: B::Surface, } pub(crate) struct Frame { @@ -36,13 +36,14 @@ pub(crate) struct Frame { //TODO: does it need a ref-counted lifetime? -pub(crate) struct SwapChain { - pub raw: B::Swapchain, - pub device_id: Stored, - pub frames: Vec>, - pub acquired: Vec, - pub sem_available: B::Semaphore, - pub command_pool: hal::CommandPool, +pub struct SwapChain { + pub(crate) raw: B::Swapchain, + pub(crate) device_id: Stored, + pub(crate) frames: Vec>, + pub(crate) acquired: Vec, + pub(crate) sem_available: B::Semaphore, + #[cfg_attr(not(feature = "local"), allow(dead_code))] //TODO: remove + pub(crate) command_pool: hal::CommandPool, } #[repr(C)] diff --git a/wgpu-native/src/track.rs b/wgpu-native/src/track.rs index 721764d35..808f8b785 100644 --- a/wgpu-native/src/track.rs +++ b/wgpu-native/src/track.rs @@ -1,4 +1,4 @@ -use crate::registry::{Id, Items}; +use crate::hub::{Id, Storage}; use crate::resource::{BufferUsageFlags, TextureUsageFlags}; use crate::{BufferId, RefCount, Stored, TextureId, WeaklyStored}; @@ -190,36 +190,36 @@ impl + PartialE } impl + PartialEq> Tracker { - fn _get_with_usage<'a, T: 'a + Borrow, V: Items>( + fn _get_with_usage<'a, T: 'a + Borrow>( &mut self, - items: &'a V, + storage: &'a Storage, id: Id, usage: U, permit: TrackPermit, ) -> Result<(&'a T, Tracktion), U> { - let item = items.get(id); + let item = storage.get(id); self.transit(id, item.borrow(), usage, permit) .map(|tracktion| (item, tracktion)) } - pub(crate) fn get_with_extended_usage<'a, T: 'a + Borrow, V: Items>( + pub(crate) fn get_with_extended_usage<'a, T: 'a + Borrow>( &mut self, - items: &'a V, + storage: &'a Storage, id: Id, usage: U, ) -> Result<&'a T, U> { - let item = items.get(id); + let item = storage.get(id); self.transit(id, item.borrow(), usage, TrackPermit::EXTEND) .map(|_tracktion| item) } - pub(crate) fn get_with_replaced_usage<'a, T: 'a + Borrow, V: Items>( + pub(crate) fn get_with_replaced_usage<'a, T: 'a + Borrow>( &mut self, - items: &'a V, + storage: &'a Storage, id: Id, usage: U, ) -> Result<(&'a T, Option), U> { - let item = items.get(id); + let item = storage.get(id); self.transit(id, item.borrow(), usage, TrackPermit::REPLACE) .map(|tracktion| (item, match tracktion { Tracktion::Init | diff --git a/wgpu-rs/Cargo.toml b/wgpu-rs/Cargo.toml index d1f0ec72e..27a3bbf61 100644 --- a/wgpu-rs/Cargo.toml +++ b/wgpu-rs/Cargo.toml @@ -16,12 +16,11 @@ license = "MPL-2.0" [features] default = [] -winit = ["wgpu-native/winit"] metal = ["wgpu-native/gfx-backend-metal"] dx11 = ["wgpu-native/gfx-backend-dx11"] dx12 = ["wgpu-native/gfx-backend-dx12"] vulkan = ["wgpu-native/gfx-backend-vulkan"] [dependencies] -wgpu-native = { version = "0.1", path = "../wgpu-native" } +wgpu-native = { version = "0.1", path = "../wgpu-native", features = ["local"] } arrayvec = "0.4" diff --git a/wgpu-rs/src/lib.rs b/wgpu-rs/src/lib.rs index 1d750be0c..6d4a1ea50 100644 --- a/wgpu-rs/src/lib.rs +++ b/wgpu-rs/src/lib.rs @@ -8,21 +8,26 @@ use std::marker::PhantomData; use std::ops::Range; use std::ptr; -#[cfg(feature = "winit")] pub use wgn::winit; - pub use wgn::{ - AdapterDescriptor, Attachment, BindGroupLayoutBinding, BindingType, BlendStateDescriptor, + MAX_DEPTH_BIAS_CLAMP, + AdapterDescriptor, BindGroupLayoutBinding, BindingType, + BlendDescriptor, BlendOperation, BlendFactor, ColorWriteFlags, + RasterizationStateDescriptor, CullMode, FrontFace, BufferDescriptor, BufferUsageFlags, IndexFormat, InputStepMode, ShaderAttributeIndex, VertexAttributeDescriptor, VertexFormat, - Color, ColorWriteFlags, CommandEncoderDescriptor, DepthStencilStateDescriptor, + Color, CommandEncoderDescriptor, + ColorStateDescriptor, DepthStencilStateDescriptor, DeviceDescriptor, Extensions, Extent3d, LoadOp, Origin3d, PowerPreference, PrimitiveTopology, RenderPassColorAttachmentDescriptor, RenderPassDepthStencilAttachmentDescriptor, - ShaderModuleDescriptor, ShaderStage, ShaderStageFlags, StoreOp, SwapChainDescriptor, + ShaderModuleDescriptor, ShaderStageFlags, StoreOp, SwapChainDescriptor, SamplerDescriptor, AddressMode, FilterMode, BorderColor, CompareFunction, TextureDescriptor, TextureDimension, TextureFormat, TextureUsageFlags, TextureViewDescriptor, }; + +//Note: we need some better guidelines on which structures receive by value, and which by pointer. + pub struct Instance { id: wgn::InstanceId, } @@ -89,14 +94,6 @@ pub struct PipelineLayout { id: wgn::PipelineLayoutId, } -pub struct BlendState { - id: wgn::BlendStateId, -} - -pub struct DepthStencilState { - id: wgn::DepthStencilStateId, -} - pub struct RenderPipeline { id: wgn::RenderPipelineId, } @@ -143,15 +140,9 @@ pub struct PipelineLayoutDescriptor<'a> { pub struct PipelineStageDescriptor<'a> { pub module: &'a ShaderModule, - pub stage: ShaderStage, pub entry_point: &'a str, } -pub struct AttachmentsState<'a> { - pub color_attachments: &'a [Attachment], - pub depth_stencil_attachment: Option, -} - pub struct VertexBufferDescriptor<'a> { pub stride: u32, pub step_mode: InputStepMode, @@ -160,13 +151,15 @@ pub struct VertexBufferDescriptor<'a> { pub struct RenderPipelineDescriptor<'a> { pub layout: &'a PipelineLayout, - pub stages: &'a [PipelineStageDescriptor<'a>], + pub vertex_stage: PipelineStageDescriptor<'a>, + pub fragment_stage: PipelineStageDescriptor<'a>, + pub rasterization_state: RasterizationStateDescriptor, pub primitive_topology: PrimitiveTopology, - pub attachments_state: AttachmentsState<'a>, - pub blend_states: &'a [&'a BlendState], - pub depth_stencil_state: &'a DepthStencilState, + pub color_states: &'a [ColorStateDescriptor], + pub depth_stencil_state: Option, pub index_format: IndexFormat, pub vertex_buffers: &'a [VertexBufferDescriptor<'a>], + pub sample_count: u32, } pub struct ComputePipelineDescriptor<'a> { @@ -235,7 +228,6 @@ impl Instance { } } - #[cfg(feature = "winit")] pub fn create_surface(&self, window: &winit::Window) -> Surface { Surface { id: wgn::wgpu_instance_create_surface_from_winit(self.id, window), @@ -343,39 +335,11 @@ impl Device { } } - pub fn create_blend_state(&self, desc: &BlendStateDescriptor) -> BlendState { - BlendState { - id: wgn::wgpu_device_create_blend_state(self.id, desc), - } - } - - pub fn create_depth_stencil_state( - &self, - desc: &DepthStencilStateDescriptor, - ) -> DepthStencilState { - DepthStencilState { - id: wgn::wgpu_device_create_depth_stencil_state(self.id, desc), - } - } - pub fn create_render_pipeline(&self, desc: &RenderPipelineDescriptor) -> RenderPipeline { - let entry_points = desc - .stages - .iter() - .map(|ps| CString::new(ps.entry_point).unwrap()) - .collect::>(); - let stages = desc - .stages - .iter() - .zip(&entry_points) - .map(|(ps, ep_name)| wgn::PipelineStageDescriptor { - module: ps.module.id, - stage: ps.stage, - entry_point: ep_name.as_ptr(), - }) - .collect::>(); + let vertex_entry_point = CString::new(desc.vertex_stage.entry_point).unwrap(); + let fragment_entry_point = CString::new(desc.fragment_stage.entry_point).unwrap(); - let temp_blend_states = desc.blend_states.iter().map(|bs| bs.id).collect::>(); + let temp_color_states = desc.color_states.to_vec(); let temp_vertex_buffers = desc .vertex_buffers .iter() @@ -392,27 +356,27 @@ impl Device { self.id, &wgn::RenderPipelineDescriptor { layout: desc.layout.id, - stages: stages.as_ptr(), - stages_length: stages.len(), - primitive_topology: desc.primitive_topology, - attachments_state: wgn::AttachmentsState { - color_attachments: desc.attachments_state.color_attachments.as_ptr(), - color_attachments_length: desc.attachments_state.color_attachments.len(), - depth_stencil_attachment: desc - .attachments_state - .depth_stencil_attachment - .as_ref() - .map(|at| at as *const _) - .unwrap_or(ptr::null()), + vertex_stage: wgn::PipelineStageDescriptor { + module: desc.vertex_stage.module.id, + entry_point: vertex_entry_point.as_ptr(), }, - blend_states: temp_blend_states.as_ptr(), - blend_states_length: temp_blend_states.len(), - depth_stencil_state: desc.depth_stencil_state.id, + fragment_stage: wgn::PipelineStageDescriptor { + module: desc.fragment_stage.module.id, + entry_point: fragment_entry_point.as_ptr(), + }, + rasterization_state: desc.rasterization_state.clone(), + primitive_topology: desc.primitive_topology, + color_states: temp_color_states.as_ptr(), + color_states_length: temp_color_states.len(), + depth_stencil_state: desc.depth_stencil_state + .as_ref() + .map_or(ptr::null(), |p| p as *const _), vertex_buffer_state: wgn::VertexBufferStateDescriptor { index_format: desc.index_format, vertex_buffers: temp_vertex_buffers.as_ptr(), vertex_buffers_count: temp_vertex_buffers.len(), }, + sample_count: desc.sample_count, }, ), } @@ -420,18 +384,16 @@ impl Device { pub fn create_compute_pipeline(&self, desc: &ComputePipelineDescriptor) -> ComputePipeline { let entry_point = CString::new(desc.compute_stage.entry_point).unwrap(); - let compute_stage = wgn::PipelineStageDescriptor { - module: desc.compute_stage.module.id, - stage: desc.compute_stage.stage, - entry_point: entry_point.as_ptr(), - }; ComputePipeline { id: wgn::wgpu_device_create_compute_pipeline( self.id, &wgn::ComputePipelineDescriptor { layout: desc.layout.id, - compute_stage, + compute_stage: wgn::PipelineStageDescriptor { + module: desc.compute_stage.module.id, + entry_point: entry_point.as_ptr(), + }, }, ), } @@ -469,15 +431,15 @@ impl Buffer { } impl Texture { - pub fn create_texture_view(&self, desc: &TextureViewDescriptor) -> TextureView { + pub fn create_view(&self, desc: &TextureViewDescriptor) -> TextureView { TextureView { - id: wgn::wgpu_texture_create_texture_view(self.id, desc), + id: wgn::wgpu_texture_create_view(self.id, desc), } } - pub fn create_default_texture_view(&self) -> TextureView { + pub fn create_default_view(&self) -> TextureView { TextureView { - id: wgn::wgpu_texture_create_default_texture_view(self.id), + id: wgn::wgpu_texture_create_default_view(self.id), } } }