Separate object identity from storage

This commit is contained in:
Dzmitry Malyshau 2019-02-14 14:08:19 -05:00
parent 844d371989
commit 2e21285434
30 changed files with 1021 additions and 1389 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 {
vertex_stage: wgpu::PipelineStageDescriptor {
module: &vs_module,
stage: wgpu::ShaderStage::Vertex,
entry_point: "main",
},
wgpu::PipelineStageDescriptor {
fragment_stage: wgpu::PipelineStageDescriptor {
module: &fs_module,
stage: wgpu::ShaderStage::Fragment,
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: 16.0,
},
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 {
vertex_stage: wgpu::PipelineStageDescriptor {
module: &vs_module,
stage: wgpu::ShaderStage::Vertex,
entry_point: "main",
},
wgpu::PipelineStageDescriptor {
fragment_stage: wgpu::PipelineStageDescriptor {
module: &fs_module,
stage: wgpu::ShaderStage::Fragment,
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: 16.0,
},
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

@ -11,157 +11,6 @@
#define WGPUBITS_PER_BYTE 8
typedef enum {
WGPUAddressMode_ClampToEdge = 0,
WGPUAddressMode_Repeat = 1,
WGPUAddressMode_MirrorRepeat = 2,
WGPUAddressMode_ClampToBorderColor = 3,
} WGPUAddressMode;
typedef enum {
WGPUBindingType_UniformBuffer = 0,
WGPUBindingType_Sampler = 1,
WGPUBindingType_SampledTexture = 2,
WGPUBindingType_StorageBuffer = 3,
} WGPUBindingType;
typedef enum {
WGPUBlendFactor_Zero = 0,
WGPUBlendFactor_One = 1,
WGPUBlendFactor_SrcColor = 2,
WGPUBlendFactor_OneMinusSrcColor = 3,
WGPUBlendFactor_SrcAlpha = 4,
WGPUBlendFactor_OneMinusSrcAlpha = 5,
WGPUBlendFactor_DstColor = 6,
WGPUBlendFactor_OneMinusDstColor = 7,
WGPUBlendFactor_DstAlpha = 8,
WGPUBlendFactor_OneMinusDstAlpha = 9,
WGPUBlendFactor_SrcAlphaSaturated = 10,
WGPUBlendFactor_BlendColor = 11,
WGPUBlendFactor_OneMinusBlendColor = 12,
} WGPUBlendFactor;
typedef enum {
WGPUBlendOperation_Add = 0,
WGPUBlendOperation_Subtract = 1,
WGPUBlendOperation_ReverseSubtract = 2,
WGPUBlendOperation_Min = 3,
WGPUBlendOperation_Max = 4,
} WGPUBlendOperation;
typedef enum {
WGPUBorderColor_TransparentBlack = 0,
WGPUBorderColor_OpaqueBlack = 1,
WGPUBorderColor_OpaqueWhite = 2,
} WGPUBorderColor;
typedef enum {
WGPUCompareFunction_Never = 0,
WGPUCompareFunction_Less = 1,
WGPUCompareFunction_Equal = 2,
WGPUCompareFunction_LessEqual = 3,
WGPUCompareFunction_Greater = 4,
WGPUCompareFunction_NotEqual = 5,
WGPUCompareFunction_GreaterEqual = 6,
WGPUCompareFunction_Always = 7,
} WGPUCompareFunction;
typedef enum {
WGPUFilterMode_Nearest = 0,
WGPUFilterMode_Linear = 1,
} WGPUFilterMode;
typedef enum {
WGPUIndexFormat_Uint16 = 0,
WGPUIndexFormat_Uint32 = 1,
} WGPUIndexFormat;
typedef enum {
WGPUInputStepMode_Vertex = 0,
WGPUInputStepMode_Instance = 1,
} WGPUInputStepMode;
typedef enum {
WGPULoadOp_Clear = 0,
WGPULoadOp_Load = 1,
} WGPULoadOp;
typedef enum {
WGPUPowerPreference_Default = 0,
WGPUPowerPreference_LowPower = 1,
WGPUPowerPreference_HighPerformance = 2,
} WGPUPowerPreference;
typedef enum {
WGPUPrimitiveTopology_PointList = 0,
WGPUPrimitiveTopology_LineList = 1,
WGPUPrimitiveTopology_LineStrip = 2,
WGPUPrimitiveTopology_TriangleList = 3,
WGPUPrimitiveTopology_TriangleStrip = 4,
} WGPUPrimitiveTopology;
typedef enum {
WGPUShaderStage_Vertex = 0,
WGPUShaderStage_Fragment = 1,
WGPUShaderStage_Compute = 2,
} WGPUShaderStage;
typedef enum {
WGPUStencilOperation_Keep = 0,
WGPUStencilOperation_Zero = 1,
WGPUStencilOperation_Replace = 2,
WGPUStencilOperation_Invert = 3,
WGPUStencilOperation_IncrementClamp = 4,
WGPUStencilOperation_DecrementClamp = 5,
WGPUStencilOperation_IncrementWrap = 6,
WGPUStencilOperation_DecrementWrap = 7,
} WGPUStencilOperation;
typedef enum {
WGPUStoreOp_Store = 0,
} WGPUStoreOp;
typedef enum {
WGPUTextureDimension_D1,
WGPUTextureDimension_D2,
WGPUTextureDimension_D3,
} WGPUTextureDimension;
typedef enum {
WGPUTextureFormat_R8g8b8a8Unorm = 0,
WGPUTextureFormat_R8g8b8a8Uint = 1,
WGPUTextureFormat_B8g8r8a8Unorm = 2,
WGPUTextureFormat_D32FloatS8Uint = 3,
} WGPUTextureFormat;
typedef enum {
WGPUTextureViewDimension_D1,
WGPUTextureViewDimension_D2,
WGPUTextureViewDimension_D2Array,
WGPUTextureViewDimension_Cube,
WGPUTextureViewDimension_CubeArray,
WGPUTextureViewDimension_D3,
} WGPUTextureViewDimension;
typedef enum {
WGPUVertexFormat_FloatR32G32B32A32 = 0,
WGPUVertexFormat_FloatR32G32B32 = 1,
WGPUVertexFormat_FloatR32G32 = 2,
WGPUVertexFormat_FloatR32 = 3,
} WGPUVertexFormat;
typedef WGPUId WGPUDeviceId;
typedef WGPUId WGPUAdapterId;
typedef struct {
bool anisotropic_filtering;
} WGPUExtensions;
typedef struct {
WGPUExtensions extensions;
} WGPUDeviceDescriptor;
typedef WGPUId WGPUBufferId;
typedef WGPUId WGPUCommandBufferId;
@ -194,289 +43,30 @@ typedef struct {
uint32_t depth;
} WGPUExtent3d;
typedef WGPUId WGPUComputePassId;
typedef WGPUCommandBufferId WGPUCommandEncoderId;
typedef WGPUId WGPURenderPassId;
typedef WGPUId WGPUTextureViewId;
typedef struct {
float r;
float g;
float b;
float a;
} WGPUColor;
typedef struct {
WGPUTextureViewId attachment;
WGPULoadOp load_op;
WGPUStoreOp store_op;
WGPUColor clear_color;
} WGPURenderPassColorAttachmentDescriptor_TextureViewId;
typedef struct {
WGPUTextureViewId attachment;
WGPULoadOp depth_load_op;
WGPUStoreOp depth_store_op;
float clear_depth;
WGPULoadOp stencil_load_op;
WGPUStoreOp stencil_store_op;
uint32_t clear_stencil;
} WGPURenderPassDepthStencilAttachmentDescriptor_TextureViewId;
typedef struct {
const WGPURenderPassColorAttachmentDescriptor_TextureViewId *color_attachments;
uintptr_t color_attachments_length;
const WGPURenderPassDepthStencilAttachmentDescriptor_TextureViewId *depth_stencil_attachment;
} WGPURenderPassDescriptor;
typedef WGPUId WGPUComputePassId;
typedef WGPUId WGPUBindGroupId;
typedef WGPUId WGPUComputePipelineId;
typedef WGPUId WGPUInstanceId;
typedef WGPUId WGPUBindGroupLayoutId;
typedef struct {
WGPUBufferId buffer;
uint32_t offset;
uint32_t size;
} WGPUBufferBinding;
typedef WGPUId WGPUSamplerId;
typedef enum {
WGPUBindingResource_Buffer,
WGPUBindingResource_Sampler,
WGPUBindingResource_TextureView,
} WGPUBindingResource_Tag;
typedef struct {
WGPUBufferBinding _0;
} WGPUBindingResource_WGPUBuffer_Body;
typedef struct {
WGPUSamplerId _0;
} WGPUBindingResource_WGPUSampler_Body;
typedef struct {
WGPUTextureViewId _0;
} WGPUBindingResource_WGPUTextureView_Body;
typedef struct {
WGPUBindingResource_Tag tag;
union {
WGPUBindingResource_WGPUBuffer_Body buffer;
WGPUBindingResource_WGPUSampler_Body sampler;
WGPUBindingResource_WGPUTextureView_Body texture_view;
};
} WGPUBindingResource;
typedef struct {
uint32_t binding;
WGPUBindingResource resource;
} WGPUBinding;
typedef struct {
WGPUBindGroupLayoutId layout;
const WGPUBinding *bindings;
uintptr_t bindings_length;
} WGPUBindGroupDescriptor;
typedef uint32_t WGPUShaderStageFlags;
typedef struct {
uint32_t binding;
WGPUShaderStageFlags visibility;
WGPUBindingType ty;
} WGPUBindGroupLayoutBinding;
typedef struct {
const WGPUBindGroupLayoutBinding *bindings;
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 {
uint32_t size;
WGPUBufferUsageFlags usage;
} WGPUBufferDescriptor;
typedef struct {
uint32_t todo;
} WGPUCommandEncoderDescriptor;
typedef WGPUId WGPUPipelineLayoutId;
typedef WGPUId WGPUShaderModuleId;
typedef struct {
WGPUShaderModuleId module;
WGPUShaderStage stage;
const char *entry_point;
} WGPUPipelineStageDescriptor;
typedef struct {
WGPUPipelineLayoutId layout;
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;
} WGPUPipelineLayoutDescriptor;
typedef WGPUId WGPURenderPipelineId;
typedef struct {
WGPUTextureFormat format;
uint32_t samples;
} WGPUAttachment;
typedef struct {
const WGPUAttachment *color_attachments;
uintptr_t color_attachments_length;
const WGPUAttachment *depth_stencil_attachment;
} WGPUAttachmentsState;
typedef uint32_t WGPUShaderAttributeIndex;
typedef struct {
uint32_t offset;
WGPUVertexFormat format;
WGPUShaderAttributeIndex attribute_index;
} WGPUVertexAttributeDescriptor;
typedef struct {
uint32_t stride;
WGPUInputStepMode step_mode;
const WGPUVertexAttributeDescriptor *attributes;
uintptr_t attributes_count;
} WGPUVertexBufferDescriptor;
typedef struct {
WGPUIndexFormat index_format;
const WGPUVertexBufferDescriptor *vertex_buffers;
uintptr_t vertex_buffers_count;
} WGPUVertexBufferStateDescriptor;
typedef struct {
WGPUPipelineLayoutId layout;
const WGPUPipelineStageDescriptor *stages;
uintptr_t stages_length;
WGPUPrimitiveTopology primitive_topology;
WGPUAttachmentsState attachments_state;
const WGPUBlendStateId *blend_states;
uintptr_t blend_states_length;
WGPUDepthStencilStateId depth_stencil_state;
WGPUVertexBufferStateDescriptor vertex_buffer_state;
} WGPURenderPipelineDescriptor;
typedef struct {
WGPUAddressMode r_address_mode;
WGPUAddressMode s_address_mode;
WGPUAddressMode t_address_mode;
WGPUFilterMode mag_filter;
WGPUFilterMode min_filter;
WGPUFilterMode mipmap_filter;
float lod_min_clamp;
float lod_max_clamp;
uint32_t max_anisotropy;
WGPUCompareFunction compare_function;
WGPUBorderColor border_color;
} WGPUSamplerDescriptor;
typedef struct {
const uint8_t *bytes;
uintptr_t length;
} WGPUByteArray;
typedef struct {
WGPUByteArray code;
} WGPUShaderModuleDescriptor;
typedef WGPUId WGPUSwapChainId;
typedef WGPUId WGPUSurfaceId;
typedef uint32_t WGPUTextureUsageFlags;
typedef struct {
WGPUTextureUsageFlags usage;
WGPUTextureFormat format;
uint32_t width;
uint32_t height;
} WGPUSwapChainDescriptor;
typedef struct {
WGPUExtent3d size;
uint32_t array_size;
WGPUTextureDimension dimension;
WGPUTextureFormat format;
WGPUTextureUsageFlags usage;
} WGPUTextureDescriptor;
typedef WGPUId WGPUDeviceId;
typedef WGPUDeviceId WGPUQueueId;
typedef struct {
WGPUPowerPreference power_preference;
} WGPUAdapterDescriptor;
typedef WGPUId WGPURenderPassId;
typedef WGPUId WGPURenderPipelineId;
typedef WGPUId WGPUTextureViewId;
typedef struct {
WGPUTextureId texture_id;
WGPUTextureViewId view_id;
} WGPUSwapChainOutput;
typedef uint32_t WGPUTextureAspectFlags;
typedef struct {
WGPUTextureFormat format;
WGPUTextureViewDimension dimension;
WGPUTextureAspectFlags aspect;
uint32_t base_mip_level;
uint32_t level_count;
uint32_t base_array_layer;
uint32_t array_count;
} WGPUTextureViewDescriptor;
typedef WGPUId WGPUSwapChainId;
#define WGPUBufferUsageFlags_INDEX 16
@ -550,9 +140,6 @@ typedef struct {
#define WGPUTrackPermit_REPLACE (WGPUTrackPermit){ .bits = 2 }
WGPUDeviceId wgpu_adapter_create_device(WGPUAdapterId adapter_id,
const WGPUDeviceDescriptor *_desc);
void wgpu_buffer_destroy(WGPUBufferId buffer_id);
void wgpu_buffer_set_sub_data(WGPUBufferId buffer_id,
@ -582,11 +169,6 @@ void wgpu_command_buffer_copy_texture_to_texture(WGPUCommandBufferId command_buf
const WGPUTextureCopyView *destination,
WGPUExtent3d copy_size);
WGPUComputePassId wgpu_command_encoder_begin_compute_pass(WGPUCommandEncoderId command_encoder_id);
WGPURenderPassId wgpu_command_encoder_begin_render_pass(WGPUCommandEncoderId command_encoder_id,
WGPURenderPassDescriptor desc);
WGPUCommandBufferId wgpu_command_encoder_finish(WGPUCommandEncoderId command_encoder_id);
void wgpu_compute_pass_dispatch(WGPUComputePassId pass_id, uint32_t x, uint32_t y, uint32_t z);
@ -599,61 +181,8 @@ void wgpu_compute_pass_set_bind_group(WGPUComputePassId pass_id,
void wgpu_compute_pass_set_pipeline(WGPUComputePassId pass_id, WGPUComputePipelineId pipeline_id);
WGPUInstanceId wgpu_create_instance(void);
WGPUBindGroupId wgpu_device_create_bind_group(WGPUDeviceId device_id,
const WGPUBindGroupDescriptor *desc);
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);
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);
WGPURenderPipelineId wgpu_device_create_render_pipeline(WGPUDeviceId device_id,
const WGPURenderPipelineDescriptor *desc);
WGPUSamplerId wgpu_device_create_sampler(WGPUDeviceId device_id, const WGPUSamplerDescriptor *desc);
WGPUShaderModuleId wgpu_device_create_shader_module(WGPUDeviceId device_id,
const WGPUShaderModuleDescriptor *desc);
WGPUSwapChainId wgpu_device_create_swap_chain(WGPUDeviceId device_id,
WGPUSurfaceId surface_id,
const WGPUSwapChainDescriptor *desc);
WGPUTextureId wgpu_device_create_texture(WGPUDeviceId device_id, const WGPUTextureDescriptor *desc);
WGPUQueueId wgpu_device_get_queue(WGPUDeviceId device_id);
WGPUSurfaceId wgpu_instance_create_surface_from_macos_layer(WGPUInstanceId instance_id,
void *layer);
WGPUSurfaceId wgpu_instance_create_surface_from_windows_hwnd(WGPUInstanceId instance_id,
void *hinstance,
void *hwnd);
WGPUSurfaceId wgpu_instance_create_surface_from_xlib(WGPUInstanceId instance_id,
const void **display,
uint64_t window);
WGPUAdapterId wgpu_instance_get_adapter(WGPUInstanceId instance_id,
const WGPUAdapterDescriptor *desc);
void wgpu_queue_submit(WGPUQueueId queue_id,
const WGPUCommandBufferId *command_buffer_ptr,
uintptr_t command_buffer_count);
@ -692,11 +221,6 @@ 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_texture_view(WGPUTextureId texture_id,
const WGPUTextureViewDescriptor *desc);
void wgpu_texture_destroy(WGPUTextureId texture_id);
void wgpu_texture_view_destroy(WGPUTextureViewId _texture_view_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,18 +90,16 @@ 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)| {
@ -155,11 +157,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 wgpu_command_encoder_begin_render_pass_impl(
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 +352,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 = wgpu_command_encoder_begin_render_pass_impl(command_encoder_id, desc);
HUB.render_passes.register(pass)
}
pub fn wgpu_command_encoder_begin_compute_pass_impl(
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 +383,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 = wgpu_command_encoder_begin_compute_pass_impl(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

@ -132,14 +132,16 @@ 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),
color: map_blend_descriptor(desc.color),
alpha: map_blend_descriptor(desc.alpha),
}
} else {
hal::pso::BlendState::Off
@ -208,20 +210,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 {
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 +246,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 +468,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 < 16.0 {
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,
}
}

View File

@ -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<B: hal::Backend> DestroyedResources<B> {
.push((resource_id, life_guard.ref_count.clone()));
}
fn triage_referenced<Gb, Gt>(&mut self, buffer_guard: &mut Gb, texture_guard: &mut Gt)
where
Gb: Items<resource::Buffer<B>>,
Gt: Items<resource::Texture<B>>,
{
fn triage_referenced(
&mut self,
buffer_guard: &mut Storage<resource::Buffer<B>>,
texture_guard: &mut Storage<resource::Texture<B>>,
) {
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<B: hal::Backend> DestroyedResources<B> {
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<B: hal::Backend> Device<B> {
}
pub(crate) struct ShaderModule<B: hal::Backend> {
pub raw: B::ShaderModule,
pub struct ShaderModule<B: hal::Backend> {
pub(crate) raw: B::ShaderModule,
}
#[no_mangle]
pub extern "C" fn wgpu_device_create_buffer(
pub fn wgpu_device_create_buffer_impl(
device_id: DeviceId,
desc: &resource::BufferDescriptor,
) -> BufferId {
) -> resource::Buffer<back::Backend> {
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 {
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
life_guard: LifeGuard::new(),
}
}
pub fn wgpu_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 = wgpu_device_create_buffer_impl(device_id, desc);
let ref_count = buffer.life_guard.ref_count.clone();
let id = HUB.buffers.register(buffer);
wgpu_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 wgpu_device_create_texture_impl(
device_id: DeviceId,
desc: &resource::TextureDescriptor,
) -> TextureId {
) -> resource::Texture<back::Backend> {
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,17 +420,7 @@ 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
};
let life_guard = LifeGuard::new();
let ref_count = life_guard.ref_count.clone();
let id = HUB.textures
.write()
.register(resource::Texture {
resource::Texture {
raw: image,
device_id: Stored {
value: device_id,
@ -413,26 +428,50 @@ pub extern "C" fn wgpu_device_create_texture(
},
kind,
format: desc.format,
full_range,
full_range: hal::image::SubresourceRange {
aspects,
levels: 0..1, //TODO: mips
layers: 0..1, //TODO
},
swap_chain_link: None,
life_guard,
});
let query = device.texture_tracker
life_guard: LifeGuard::new(),
}
}
pub fn wgpu_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 = wgpu_device_create_texture_impl(device_id, desc);
let ref_count = texture.life_guard.ref_count.clone();
let id = HUB.textures.register(texture);
wgpu_device_track_texture(device_id, id, ref_count);
id
}
#[no_mangle]
pub extern "C" fn wgpu_texture_create_texture_view(
pub fn wgpu_texture_create_view_impl(
texture_id: TextureId,
desc: &resource::TextureViewDescriptor,
) -> TextureViewId {
) -> resource::TextureView<back::Backend> {
let texture_guard = HUB.textures.read();
let texture = texture_guard.get(texture_id);
@ -455,9 +494,7 @@ pub extern "C" fn wgpu_texture_create_texture_view(
.unwrap()
};
HUB.texture_views
.write()
.register(resource::TextureView {
resource::TextureView {
raw,
texture_id: Stored {
value: texture_id,
@ -468,11 +505,22 @@ pub extern "C" fn wgpu_texture_create_texture_view(
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 = wgpu_texture_create_view_impl(texture_id, desc);
HUB.texture_views.register(view)
}
pub fn wgpu_texture_create_default_view_impl(
texture_id: TextureId
) -> resource::TextureView<back::Backend> {
let texture_guard = HUB.textures.read();
let texture = texture_guard.get(texture_id);
@ -497,9 +545,7 @@ pub extern "C" fn wgpu_texture_create_default_texture_view(texture_id: TextureId
.unwrap()
};
HUB.texture_views
.write()
.register(resource::TextureView {
resource::TextureView {
raw,
texture_id: Stored {
value: texture_id,
@ -510,7 +556,14 @@ pub extern "C" fn wgpu_texture_create_default_texture_view(texture_id: TextureId
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 = wgpu_texture_create_default_view_impl(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 wgpu_device_create_sampler_impl(
device_id: DeviceId, desc: &resource::SamplerDescriptor
) -> SamplerId {
) -> resource::Sampler<back::Backend> {
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 = wgpu_device_create_sampler_impl(device_id, desc);
HUB.samplers.register(sampler)
}
pub fn wgpu_device_create_bind_group_layout_impl(
device_id: DeviceId,
desc: &binding_model::BindGroupLayoutDescriptor,
) -> BindGroupLayoutId {
) -> binding_model::BindGroupLayout<back::Backend> {
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 = wgpu_device_create_bind_group_layout_impl(device_id, desc);
HUB.bind_group_layouts.register(layout)
}
pub fn wgpu_device_create_pipeline_layout_impl(
device_id: DeviceId,
desc: &binding_model::PipelineLayoutDescriptor,
) -> PipelineLayoutId {
) -> binding_model::PipelineLayout<back::Backend> {
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 {
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 = wgpu_device_create_pipeline_layout_impl(device_id, desc);
HUB.pipeline_layouts.register(layout)
}
pub fn wgpu_device_create_bind_group_impl(
device_id: DeviceId,
desc: &binding_model::BindGroupDescriptor,
) -> BindGroupId {
) -> binding_model::BindGroup<back::Backend> {
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 {
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 = wgpu_device_create_bind_group_impl(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 wgpu_device_create_shader_module_impl(
device_id: DeviceId,
desc: &pipeline::ShaderModuleDescriptor,
) -> ShaderModuleId {
) -> ShaderModule<back::Backend> {
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 = wgpu_device_create_shader_module_impl(device_id, desc);
HUB.shader_modules.register(module)
}
pub fn wgpu_device_create_command_encoder_impl(
device_id: DeviceId,
_desc: &command::CommandEncoderDescriptor,
) -> CommandEncoderId {
) -> command::CommandBuffer<back::Backend> {
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 = wgpu_device_create_command_encoder_impl(device_id, desc);
HUB.command_buffers.register(cmb)
}
#[no_mangle]
@ -918,48 +995,44 @@ 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 wgpu_device_create_render_pipeline_impl(
device_id: DeviceId,
desc: &pipeline::RenderPipelineDescriptor,
) -> RenderPipelineId {
) -> pipeline::RenderPipeline<back::Backend> {
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 rp_key = {
let op_keep = hal::pass::AttachmentOps {
load: hal::pass::AttachmentLoadOp::Load,
store: hal::pass::AttachmentStoreOp::Store,
};
let color_attachments = unsafe {
let color_states = unsafe {
slice::from_raw_parts(
desc.attachments_state.color_attachments,
desc.attachments_state.color_attachments_length,
desc.color_states,
desc.color_states_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 rp_key = {
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 = desc.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 +1051,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: desc.depth_stencil_state.map(|_| &depth_id),
inputs: &[],
resolves: &[],
preserves: &[],
@ -1004,51 +1073,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::<back::Backend> {
entry: unsafe { ffi::CStr::from_ptr(pipeline_stage.entry_point) }
let vertex = hal::pso::EntryPoint::<back::Backend> {
entry: unsafe { ffi::CStr::from_ptr(desc.vertex_stage.entry_point) }
.to_str()
.to_owned()
.unwrap(), // TODO
module: &shader_module_guard.get(pipeline_stage.module).raw,
module: &shader_module_guard.get(desc.vertex_stage.module).raw,
specialization: hal::pso::Specialization {
// TODO
constants: &[],
data: &[],
},
};
let fragment = hal::pso::EntryPoint::<back::Backend> {
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: &[],
},
};
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
let shaders = hal::pso::GraphicsShaderSet {
vertex,
hull: None,
domain: None,
geometry: None,
fragment,
}
};
// 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,
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 +1144,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 = desc.depth_stencil_state
.map(conv::map_depth_stencil_state_descriptor)
.unwrap_or_default();
// TODO
let multisampling: Option<hal::pso::Multisampling> = None;
@ -1140,21 +1193,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 {
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 = wgpu_device_create_render_pipeline_impl(device_id, desc);
HUB.render_pipelines.register(pipeline)
}
pub fn wgpu_device_create_compute_pipeline_impl(
device_id: DeviceId,
desc: &pipeline::ComputePipelineDescriptor,
) -> ComputePipelineId {
) -> pipeline::ComputePipeline<back::Backend> {
let device_guard = HUB.devices.read();
let device = device_guard.get(device_id);
let pipeline_layout_guard = HUB.pipeline_layouts.read();
@ -1162,8 +1226,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::<back::Backend> {
entry: unsafe { ffi::CStr::from_ptr(pipeline_stage.entry_point) }
.to_str()
@ -1189,22 +1251,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 {
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 = wgpu_device_create_compute_pipeline_impl(device_id, desc);
HUB.compute_pipelines.register(pipeline)
}
pub fn wgpu_device_create_swap_chain_impl(
device_id: DeviceId,
surface_id: SurfaceId,
desc: &swap_chain::SwapChainDescriptor,
) -> SwapChainId {
) -> (swap_chain::SwapChain<back::Backend>, Vec<resource::Texture<back::Backend>>) {
let device_guard = HUB.devices.read();
let device = device_guard.get(device_id);
let mut surface_guard = HUB.surfaces.write();
@ -1217,11 +1291,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,10 +1328,7 @@ 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 {
let swap_chain = swap_chain::SwapChain {
raw,
device_id: Stored {
value: device_id,
@ -1268,54 +1338,69 @@ pub extern "C" fn wgpu_device_create_swap_chain(
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 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 {
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")]
pub fn wgpu_swap_chain_populate_textures(
swap_chain_id: SwapChainId,
textures: Vec<resource::Texture<back::Backend>>,
) {
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,
}),
life_guard: LifeGuard::new(),
};
});
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 +1409,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 +1419,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 +1427,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) = wgpu_device_create_swap_chain_impl(device_id, surface_id, desc);
let id = HUB.swap_chains.register(swap_chain);
wgpu_swap_chain_populate_textures(id, textures);
id
}
#[no_mangle]

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 wgpu_create_instance_impl() -> ::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 = wgpu_create_instance_impl();
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 wgpu_instance_create_surface_from_xlib_impl(
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 = wgpu_instance_create_surface_from_xlib_impl(instance_id, display, window);
HUB.surfaces.register(surface)
}
#[allow(unused_variables)]
pub fn wgpu_instance_create_surface_from_macos_layer_impl(
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 = wgpu_instance_create_surface_from_macos_layer_impl(instance_id, layer);
HUB.surfaces.register(surface)
}
#[cfg(feature = "gfx-backend-metal")]
{
#[allow(unused_variables)]
pub fn wgpu_instance_create_surface_from_windows_hwnd_impl(
instance_id: InstanceId,
hinstance: *mut std::ffi::c_void,
hwnd: *mut std::ffi::c_void,
) -> SurfaceHandle {
#[cfg(not(target_os = "windows"))]
let raw = unimplemented!();
#[cfg(any(feature = "gfx-backend-dx11", feature = "gfx-backend-dx12"))]
let raw = HUB.instances
.read()
.get(instance_id)
.create_surface_from_layer(layer as *mut _);
let surface = Surface {
raw,
};
.create_surface_from_hwnd(hwnd);
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);
#[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 = wgpu_instance_create_surface_from_windows_hwnd_impl(instance_id, hinstance, hwnd);
HUB.surfaces.register(surface)
}
#[no_mangle]
pub extern "C" fn wgpu_instance_get_adapter(
pub fn wgpu_instance_get_adapter_impl(
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 = wgpu_instance_get_adapter_impl(instance_id, desc);
HUB.adapters.register(adapter)
}
pub fn wgpu_adapter_create_device_impl(
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 = wgpu_adapter_create_device_impl(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,17 @@ 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};
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 +105,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 +176,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,
pub alpha: BlendDescriptor,
pub color: BlendDescriptor,
#[derive(Clone, Debug)]
pub struct ColorStateDescriptor<'a> {
pub format: resource::TextureFormat,
pub alpha: &'a BlendDescriptor,
pub color: &'a 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)]
pub struct DepthStencilStateDescriptor {
#[derive(Clone, Debug)]
pub struct DepthStencilStateDescriptor<'a> {
pub format: resource::TextureFormat,
pub depth_write_enabled: bool,
pub depth_compare: resource::CompareFunction,
pub front: StencilStateFaceDescriptor,
pub back: StencilStateFaceDescriptor,
pub stencil_front: &'a StencilStateFaceDescriptor,
pub stencil_back: &'a 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,30 +166,21 @@ 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,
}
#[repr(C)]
pub struct ComputePipelineDescriptor {
pub struct ComputePipelineDescriptor<'a> {
pub layout: PipelineLayoutId,
pub compute_stage: PipelineStageDescriptor,
pub compute_stage: &'a 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,44 @@ 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)]
pub struct RenderPipelineDescriptor {
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<'a> {
pub layout: PipelineLayoutId,
pub stages: *const PipelineStageDescriptor,
pub stages_length: usize,
pub vertex_stage: &'a PipelineStageDescriptor,
pub fragment_stage: &'a 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: &'a RasterizationStateDescriptor,
pub color_states: *const ColorStateDescriptor<'a>,
pub color_states_length: usize,
pub depth_stencil_state: Option<&'a DepthStencilStateDescriptor<'a>>,
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,25 @@ 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,
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 +93,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 +139,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 +150,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<'a>],
pub depth_stencil_state: Option<DepthStencilStateDescriptor<'a>>,
pub index_format: IndexFormat,
pub vertex_buffers: &'a [VertexBufferDescriptor<'a>],
pub sample_count: u32,
}
pub struct ComputePipelineDescriptor<'a> {
@ -235,7 +227,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 +334,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 +355,25 @@ 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,
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(),
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 +381,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 +428,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),
}
}
}