62: Separate object identity from storage r=grovesNL a=kvark

This turned out to be a giant change touching multiple parts... with main goal to prepare for wgpu-remote. The basic incompatibility I found is that the client side needs to know the IDs and manage them, while the server side needs to access the actual objects by those IDs. This change moves the `IdentityManager` out, while still making it convenient for the local bindings to use it the old way.

The actions for creating a buffer remotely would be:
  1. client allocates a new ID
  2. client sends the descriptor and ID to the server
  3. server creates an actual backend object from the descriptor
  4. server associates it with the given ID

While doing that, I also decided to bring the local/remote registries closer together. There isn't much benefit from representing an ID with a pointer in local mode. Locking is still the same (at least, it's hugely problematic to make it different and maintain both paths sanely), and the cache utilization is better when they are stored sequentially. This simplification leaded to the renaming and refactoring of "registry/mod.rs" to just "hub.rs".

Total list of changes:
  - separate object identity from storage, this affects all the entry points creating items. They are now split into a public-visible "_impl()" method that just creates something, and the old creation is only visible under "local" feature now, using that helper. The sequence of actions on remote is different, as described above.
  - unified local/remote registries
  - "local" feature instead of "remote"
  - removed blend and depth/stencil interfaces in favor of structs inside the pipeline descriptors
  - pipeline descriptors are update to reflect the IDL (shader stages, rasterization state, color states, etc)

Co-authored-by: Dzmitry Malyshau <dmalyshau@mozilla.com>
This commit is contained in:
bors[bot] 2019-02-15 15:14:47 +00:00
commit a60f3f13fa
31 changed files with 1081 additions and 969 deletions

View File

@ -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

View File

@ -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)

View File

@ -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"

View File

@ -81,7 +81,6 @@ fn main() {
layout: &pipeline_layout,
compute_stage: wgpu::PipelineStageDescriptor {
module: &cs_module,
stage: wgpu::ShaderStage::Compute,
entry_point: "main",
},
});

View File

@ -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};

View File

@ -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"

View File

@ -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

View File

@ -10,15 +10,22 @@ pub fn cast_slice<T>(data: &[T]) -> &[u8] {
}
}
pub fn load_glsl(name: &str, stage: wgpu::ShaderStage) -> Vec<u8> {
#[allow(dead_code)]
pub enum ShaderStage {
Vertex,
Fragment,
Compute,
}
pub fn load_glsl(name: &str, stage: ShaderStage) -> Vec<u8> {
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();

View File

@ -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"));

View File

@ -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);

View File

@ -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 }

View File

@ -38,8 +38,8 @@ pub struct BindGroupLayoutDescriptor {
pub bindings_length: usize,
}
pub(crate) struct BindGroupLayout<B: hal::Backend> {
pub raw: B::DescriptorSetLayout,
pub struct BindGroupLayout<B: hal::Backend> {
pub(crate) raw: B::DescriptorSetLayout,
}
#[repr(C)]
@ -48,9 +48,9 @@ pub struct PipelineLayoutDescriptor {
pub bind_group_layouts_length: usize,
}
pub(crate) struct PipelineLayout<B: hal::Backend> {
pub raw: B::PipelineLayout,
pub bind_group_layout_ids: Vec<WeaklyStored<BindGroupLayoutId>>,
pub struct PipelineLayout<B: hal::Backend> {
pub(crate) raw: B::PipelineLayout,
pub(crate) bind_group_layout_ids: Vec<WeaklyStored<BindGroupLayoutId>>,
}
#[repr(C)]
@ -80,10 +80,10 @@ pub struct BindGroupDescriptor {
pub bindings_length: usize,
}
pub(crate) struct BindGroup<B: hal::Backend> {
pub raw: B::DescriptorSet,
pub layout_id: WeaklyStored<BindGroupLayoutId>,
pub life_guard: LifeGuard,
pub used_buffers: BufferTracker,
pub used_textures: TextureTracker,
pub struct BindGroup<B: hal::Backend> {
pub(crate) raw: B::DescriptorSet,
pub(crate) layout_id: WeaklyStored<BindGroupLayoutId>,
pub(crate) life_guard: LifeGuard,
pub(crate) used_buffers: BufferTracker,
pub(crate) used_textures: TextureTracker,
}

View File

@ -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<B>) -> 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<B>
&mut self, index: usize, bind_group_id: BindGroupId, bind_group: &BindGroupHandle
) -> Option<PipelineLayoutId> {
self.ensure_length(index + 1);
if self.entries[index].provide(bind_group_id, bind_group) {

View File

@ -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<B: hal::Backend> ComputePass<B> {
#[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

View File

@ -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<B: hal::Backend> {
pub(crate) swap_chain_links: Vec<SwapChainLink<SwapImageEpoch>>,
}
impl CommandBuffer<B> {
pub(crate) fn insert_barriers<I, J, Gb, Gt>(
raw: &mut <B as hal::Backend>::CommandBuffer,
impl CommandBufferHandle {
pub(crate) fn insert_barriers<I, J>(
raw: &mut <Backend as hal::Backend>::CommandBuffer,
buffer_iter: I,
texture_iter: J,
buffer_guard: &Gb,
texture_guard: &Gt,
buffer_guard: &Storage<BufferHandle>,
texture_guard: &Storage<TextureHandle>,
) where
I: Iterator<Item = (BufferId, Range<BufferUsageFlags>)>,
J: Iterator<Item = (TextureId, Range<TextureUsageFlags>)>,
Gb: Items<resource::Buffer<B>>,
Gt: Items<resource::Texture<B>>,
{
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<Backend> {
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<Backend> {
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)
}

View File

@ -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<B: hal::Backend> RenderPass<B> {
#[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();

View File

@ -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::{

View File

@ -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,
}
}

File diff suppressed because it is too large Load Diff

134
wgpu-native/src/hub.rs Normal file
View File

@ -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<Id>,
}
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<T> {
//TODO: consider concurrent hashmap?
map: FastHashMap<Id, T>,
}
impl<T> Storage<T> {
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<T> {
#[cfg(feature = "local")]
identity: Mutex<IdentityManager>,
data: RwLock<Storage<T>>,
}
impl<T> Default for Registry<T> {
fn default() -> Self {
Registry {
#[cfg(feature = "local")]
identity: Mutex::new(IdentityManager::default()),
data: RwLock::new(Storage {
map: FastHashMap::default(),
}),
}
}
}
impl<T> ops::Deref for Registry<T> {
type Target = RwLock<Storage<T>>;
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl<T> ops::DerefMut for Registry<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.data
}
}
#[cfg(feature = "local")]
impl<T> Registry<T> {
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<Registry<InstanceHandle>>,
pub(crate) adapters: Arc<Registry<AdapterHandle>>,
pub(crate) devices: Arc<Registry<DeviceHandle>>,
pub(crate) pipeline_layouts: Arc<Registry<PipelineLayoutHandle>>,
pub(crate) bind_group_layouts: Arc<Registry<BindGroupLayoutHandle>>,
pub(crate) bind_groups: Arc<Registry<BindGroupHandle>>,
pub(crate) shader_modules: Arc<Registry<ShaderModuleHandle>>,
pub(crate) command_buffers: Arc<Registry<CommandBufferHandle>>,
pub(crate) render_pipelines: Arc<Registry<RenderPipelineHandle>>,
pub(crate) compute_pipelines: Arc<Registry<ComputePipelineHandle>>,
pub(crate) render_passes: Arc<Registry<RenderPassHandle>>,
pub(crate) compute_passes: Arc<Registry<ComputePassHandle>>,
pub(crate) buffers: Arc<Registry<BufferHandle>>,
pub(crate) textures: Arc<Registry<TextureHandle>>,
pub(crate) texture_views: Arc<Registry<TextureViewHandle>>,
pub(crate) samplers: Arc<Registry<SamplerHandle>>,
pub(crate) surfaces: Arc<Registry<SurfaceHandle>>,
pub(crate) swap_chains: Arc<Registry<SwapChainHandle>>,
}
lazy_static! {
pub static ref HUB: Hub = Hub::default();
}

View File

@ -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)
}

View File

@ -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<AtomicUsize>);
pub struct RefCount(ptr::NonNull<AtomicUsize>);
impl RefCount {
const MAX: usize = 1 << 24;
@ -105,8 +106,6 @@ unsafe impl<T> Sync for Stored<T> {}
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
struct WeaklyStored<T>(T);
unsafe impl<T> Send for WeaklyStored<T> {}
unsafe impl<T> Sync for WeaklyStored<T> {}
#[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<B>;
pub type DeviceId = Id;
type DeviceHandle = Device<B>;
pub type AdapterId = hub::Id;
type AdapterHandle = hal::Adapter<back::Backend>;
pub type DeviceId = hub::Id;
type DeviceHandle = Device<back::Backend>;
pub type QueueId = DeviceId;
pub type BufferId = Id;
type BufferHandle = Buffer<B>;
pub type BufferId = hub::Id;
type BufferHandle = Buffer<back::Backend>;
// Resource
pub type TextureViewId = Id;
type TextureViewHandle = TextureView<B>;
pub type TextureId = Id;
type TextureHandle = Texture<B>;
pub type SamplerId = Id;
type SamplerHandle = Sampler<B>;
pub type TextureViewId = hub::Id;
type TextureViewHandle = TextureView<back::Backend>;
pub type TextureId = hub::Id;
type TextureHandle = Texture<back::Backend>;
pub type SamplerId = hub::Id;
type SamplerHandle = Sampler<back::Backend>;
// Binding model
pub type BindGroupLayoutId = Id;
type BindGroupLayoutHandle = BindGroupLayout<B>;
pub type PipelineLayoutId = Id;
type PipelineLayoutHandle = PipelineLayout<B>;
pub type BindGroupId = Id;
type BindGroupHandle = BindGroup<B>;
pub type BindGroupLayoutId = hub::Id;
type BindGroupLayoutHandle = BindGroupLayout<back::Backend>;
pub type PipelineLayoutId = hub::Id;
type PipelineLayoutHandle = PipelineLayout<back::Backend>;
pub type BindGroupId = hub::Id;
type BindGroupHandle = BindGroup<back::Backend>;
// 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<B>;
pub type RenderPipelineId = Id;
type RenderPipelineHandle = RenderPipeline<B>;
pub type ComputePipelineId = Id;
type ComputePipelineHandle = ComputePipeline<B>;
pub type CommandBufferId = Id;
type CommandBufferHandle = CommandBuffer<B>;
pub type InputStateId = hub::Id;
pub type ShaderModuleId = hub::Id;
type ShaderModuleHandle = ShaderModule<back::Backend>;
pub type RenderPipelineId = hub::Id;
type RenderPipelineHandle = RenderPipeline<back::Backend>;
pub type ComputePipelineId = hub::Id;
type ComputePipelineHandle = ComputePipeline<back::Backend>;
// Command
pub type CommandBufferId = hub::Id;
type CommandBufferHandle = CommandBuffer<back::Backend>;
pub type CommandEncoderId = CommandBufferId;
pub type RenderPassId = Id;
type RenderPassHandle = RenderPass<B>;
pub type ComputePassId = Id;
type ComputePassHandle = ComputePass<B>;
pub type SurfaceId = Id;
type SurfaceHandle = Surface<B>;
pub type SwapChainId = Id;
type SwapChainHandle = SwapChain<B>;
pub type RenderPassId = hub::Id;
type RenderPassHandle = RenderPass<back::Backend>;
pub type ComputePassId = hub::Id;
type ComputePassHandle = ComputePass<back::Backend>;
// Swap chain
pub type SurfaceId = hub::Id;
type SurfaceHandle = Surface<back::Backend>;
pub type SwapChainId = hub::Id;
type SwapChainHandle = SwapChain<back::Backend>;

View File

@ -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<B: hal::Backend> {
pub raw: B::ComputePipeline,
pub layout_id: WeaklyStored<PipelineLayoutId>,
pub struct ComputePipeline<B: hal::Backend> {
pub(crate) raw: B::ComputePipeline,
pub(crate) layout_id: WeaklyStored<PipelineLayoutId>,
}
#[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<B: hal::Backend> {
pub raw: B::GraphicsPipeline,
pub layout_id: WeaklyStored<PipelineLayoutId>,
pub struct RenderPipeline<B: hal::Backend> {
pub(crate) raw: B::GraphicsPipeline,
pub(crate) layout_id: WeaklyStored<PipelineLayoutId>,
}

View File

@ -1,34 +0,0 @@
use std::marker::PhantomData;
use std::os::raw::c_void;
pub type Id = *mut c_void;
pub struct Items<T> {
marker: PhantomData<T>,
}
impl<T> Default for Items<T> {
fn default() -> Self {
Items {
marker: PhantomData,
}
}
}
impl<T> super::Items<T> for Items<T> {
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) }
}
}

View File

@ -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<T>: 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<T> = Arc<RwLock<ConcreteItems<T>>>;
#[derive(Default)]
pub struct Hub {
pub(crate) instances: ConcreteRegistry<InstanceHandle>,
pub(crate) adapters: ConcreteRegistry<AdapterHandle>,
pub(crate) devices: ConcreteRegistry<DeviceHandle>,
pub(crate) pipeline_layouts: ConcreteRegistry<PipelineLayoutHandle>,
pub(crate) bind_group_layouts: ConcreteRegistry<BindGroupLayoutHandle>,
pub(crate) bind_groups: ConcreteRegistry<BindGroupHandle>,
pub(crate) blend_states: ConcreteRegistry<BlendStateHandle>,
pub(crate) depth_stencil_states: ConcreteRegistry<DepthStencilStateHandle>,
pub(crate) shader_modules: ConcreteRegistry<ShaderModuleHandle>,
pub(crate) command_buffers: ConcreteRegistry<CommandBufferHandle>,
pub(crate) render_pipelines: ConcreteRegistry<RenderPipelineHandle>,
pub(crate) compute_pipelines: ConcreteRegistry<ComputePipelineHandle>,
pub(crate) render_passes: ConcreteRegistry<RenderPassHandle>,
pub(crate) compute_passes: ConcreteRegistry<ComputePassHandle>,
pub(crate) buffers: ConcreteRegistry<BufferHandle>,
pub(crate) textures: ConcreteRegistry<TextureHandle>,
pub(crate) texture_views: ConcreteRegistry<TextureViewHandle>,
pub(crate) samplers: ConcreteRegistry<SamplerHandle>,
pub(crate) surfaces: ConcreteRegistry<SurfaceHandle>,
pub(crate) swap_chains: ConcreteRegistry<SwapChainHandle>,
}
lazy_static! {
pub static ref HUB: Hub = Hub::default();
}

View File

@ -1,46 +0,0 @@
use hal::backend::FastHashMap;
pub type Id = u32;
pub struct Items<T> {
next_id: Id,
tracked: FastHashMap<Id, T>,
free: Vec<Id>,
}
impl<T> Default for Items<T> {
fn default() -> Self {
Items {
next_id: 0,
tracked: FastHashMap::default(),
free: Vec::new(),
}
}
}
impl<T> super::Items<T> for Items<T> {
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()
}
}

View File

@ -33,11 +33,11 @@ pub struct BufferDescriptor {
pub usage: BufferUsageFlags,
}
pub(crate) struct Buffer<B: hal::Backend> {
pub raw: B::Buffer,
pub device_id: Stored<DeviceId>,
pub struct Buffer<B: hal::Backend> {
pub(crate) raw: B::Buffer,
pub(crate) device_id: Stored<DeviceId>,
//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<B: hal::Backend> {
pub raw: B::Image,
pub device_id: Stored<DeviceId>,
pub kind: hal::image::Kind,
pub format: TextureFormat,
pub full_range: hal::image::SubresourceRange,
pub swap_chain_link: Option<SwapChainLink<Mutex<SwapImageEpoch>>>,
pub life_guard: LifeGuard,
pub struct Texture<B: hal::Backend> {
pub(crate) raw: B::Image,
pub(crate) device_id: Stored<DeviceId>,
pub(crate) kind: hal::image::Kind,
pub(crate) format: TextureFormat,
pub(crate) full_range: hal::image::SubresourceRange,
pub(crate) swap_chain_link: Option<SwapChainLink<Mutex<SwapImageEpoch>>>,
pub(crate) life_guard: LifeGuard,
}
impl<B: hal::Backend> Borrow<RefCount> for Texture<B> {
@ -134,14 +134,15 @@ pub struct TextureViewDescriptor {
pub array_count: u32,
}
pub(crate) struct TextureView<B: hal::Backend> {
pub raw: B::ImageView,
pub texture_id: Stored<TextureId>,
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<B: hal::Backend> {
pub(crate) raw: B::ImageView,
pub(crate) texture_id: Stored<TextureId>,
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<B: hal::Backend> {
pub raw: B::Sampler,
pub struct Sampler<B: hal::Backend> {
pub(crate) raw: B::Sampler,
}

View File

@ -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<E> {
pub image_index: hal::SwapImageIndex,
}
pub(crate) struct Surface<B: hal::Backend> {
pub raw: B::Surface,
pub struct Surface<B: hal::Backend> {
pub(crate) raw: B::Surface,
}
pub(crate) struct Frame<B: hal::Backend> {
@ -36,13 +36,14 @@ pub(crate) struct Frame<B: hal::Backend> {
//TODO: does it need a ref-counted lifetime?
pub(crate) struct SwapChain<B: hal::Backend> {
pub raw: B::Swapchain,
pub device_id: Stored<DeviceId>,
pub frames: Vec<Frame<B>>,
pub acquired: Vec<hal::SwapImageIndex>,
pub sem_available: B::Semaphore,
pub command_pool: hal::CommandPool<B, hal::General>,
pub struct SwapChain<B: hal::Backend> {
pub(crate) raw: B::Swapchain,
pub(crate) device_id: Stored<DeviceId>,
pub(crate) frames: Vec<Frame<B>>,
pub(crate) acquired: Vec<hal::SwapImageIndex>,
pub(crate) sem_available: B::Semaphore,
#[cfg_attr(not(feature = "local"), allow(dead_code))] //TODO: remove
pub(crate) command_pool: hal::CommandPool<B, hal::General>,
}
#[repr(C)]

View File

@ -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<I: Clone + Hash + Eq, U: Copy + GenericUsage + BitOr<Output = U> + PartialE
}
impl<U: Copy + GenericUsage + BitOr<Output = U> + PartialEq> Tracker<Id, U> {
fn _get_with_usage<'a, T: 'a + Borrow<RefCount>, V: Items<T>>(
fn _get_with_usage<'a, T: 'a + Borrow<RefCount>>(
&mut self,
items: &'a V,
storage: &'a Storage<T>,
id: Id,
usage: U,
permit: TrackPermit,
) -> Result<(&'a T, Tracktion<U>), 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<RefCount>, V: Items<T>>(
pub(crate) fn get_with_extended_usage<'a, T: 'a + Borrow<RefCount>>(
&mut self,
items: &'a V,
storage: &'a Storage<T>,
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<RefCount>, V: Items<T>>(
pub(crate) fn get_with_replaced_usage<'a, T: 'a + Borrow<RefCount>>(
&mut self,
items: &'a V,
storage: &'a Storage<T>,
id: Id,
usage: U,
) -> Result<(&'a T, Option<U>), 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 |

View File

@ -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"

View File

@ -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<Attachment>,
}
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<DepthStencilStateDescriptor>,
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::<ArrayVec<[_; 2]>>();
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::<ArrayVec<[_; 2]>>();
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::<Vec<_>>();
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),
}
}
}