From a735eddf812a33f1aad1e7e44bf941b403f81a73 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Sat, 2 Feb 2019 22:37:51 -0500 Subject: [PATCH] Sampler creation support --- wgpu-bindings/wgpu.h | 36 +++++++++++++++++++++++++++++ wgpu-native/src/conv.rs | 24 +++++++++++++++++++- wgpu-native/src/device.rs | 45 ++++++++++++++++++++++++++++++++++++- wgpu-native/src/resource.rs | 2 +- wgpu-rs/src/lib.rs | 10 ++++++++- 5 files changed, 113 insertions(+), 4 deletions(-) diff --git a/wgpu-bindings/wgpu.h b/wgpu-bindings/wgpu.h index 8435b4c84..12cc9eec4 100644 --- a/wgpu-bindings/wgpu.h +++ b/wgpu-bindings/wgpu.h @@ -9,6 +9,13 @@ #include #include +typedef enum { + WGPUAddressMode_ClampToEdge = 0, + WGPUAddressMode_Repeat = 1, + WGPUAddressMode_MirrorRepeat = 2, + WGPUAddressMode_ClampToBorderColor = 3, +} WGPUAddressMode; + typedef enum { WGPUBindingType_UniformBuffer = 0, WGPUBindingType_Sampler = 1, @@ -40,6 +47,12 @@ typedef enum { WGPUBlendOperation_Max = 4, } WGPUBlendOperation; +typedef enum { + WGPUBorderColor_TransparentBlack = 0, + WGPUBorderColor_OpaqueBlack = 1, + WGPUBorderColor_OpaqueWhite = 2, +} WGPUBorderColor; + typedef enum { WGPUCompareFunction_Never = 0, WGPUCompareFunction_Less = 1, @@ -51,6 +64,11 @@ typedef enum { WGPUCompareFunction_Always = 7, } WGPUCompareFunction; +typedef enum { + WGPUFilterMode_Nearest = 0, + WGPUFilterMode_Linear = 1, +} WGPUFilterMode; + typedef enum { WGPULoadOp_Clear = 0, WGPULoadOp_Load = 1, @@ -317,6 +335,20 @@ typedef struct { WGPUDepthStencilStateId depth_stencil_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; @@ -444,6 +476,8 @@ typedef struct { #define WGPUTextureUsageFlags_TRANSFER_SRC 1 +#define WGPUTextureUsageFlags_UNINITIALIZED 65535 + #define WGPUTrackPermit_EXTEND (WGPUTrackPermit){ .bits = 1 } #define WGPUTrackPermit_REPLACE (WGPUTrackPermit){ .bits = 2 } @@ -498,6 +532,8 @@ WGPUPipelineLayoutId wgpu_device_create_pipeline_layout(WGPUDeviceId device_id, 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); diff --git a/wgpu-native/src/conv.rs b/wgpu-native/src/conv.rs index 4e9c02e87..be48535d7 100644 --- a/wgpu-native/src/conv.rs +++ b/wgpu-native/src/conv.rs @@ -1,4 +1,5 @@ use crate::{binding_model, command, pipeline, resource, Color, Extent3d}; +use log::warn; pub fn map_buffer_usage( usage: resource::BufferUsageFlags, @@ -222,7 +223,7 @@ fn map_stencil_face( } } -fn map_compare_function(compare_function: resource::CompareFunction) -> hal::pso::Comparison { +pub fn map_compare_function(compare_function: resource::CompareFunction) -> hal::pso::Comparison { use hal::pso::Comparison as H; use crate::resource::CompareFunction::*; match compare_function { @@ -408,3 +409,24 @@ pub fn map_load_store_ops( pub fn map_color(color: Color) -> hal::pso::ColorValue { [color.r, color.g, color.b, color.a] } + +pub fn map_filter(filter: resource::FilterMode) -> hal::image::Filter { + match filter { + resource::FilterMode::Nearest => hal::image::Filter::Nearest, + resource::FilterMode::Linear => hal::image::Filter::Linear, + } +} + +pub fn map_wrap(address: resource::AddressMode) -> hal::image::WrapMode { + use hal::image::WrapMode as W; + use crate::resource::AddressMode as Am; + match address { + Am::ClampToEdge => W::Clamp, + Am::Repeat => W::Tile, + Am::MirrorRepeat => { + warn!("MirrorRepeat isn't supported yet"); + W::Tile + } + Am::ClampToBorderColor => W::Border, + } +} \ No newline at end of file diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index e187c3356..b327daae7 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -6,7 +6,7 @@ use crate::{ BindGroupLayoutId, BindGroupId, BlendStateId, BufferId, CommandBufferId, DepthStencilStateId, AdapterId, DeviceId, PipelineLayoutId, QueueId, RenderPipelineId, ShaderModuleId, - TextureId, TextureViewId, + SamplerId, TextureId, TextureViewId, SurfaceId, SwapChainId, }; @@ -525,6 +525,49 @@ pub extern "C" fn wgpu_texture_view_destroy(_texture_view_id: TextureViewId) { unimplemented!() } +#[no_mangle] +pub extern "C" fn wgpu_device_create_sampler( + device_id: DeviceId, desc: &resource::SamplerDescriptor +) -> SamplerId { + let device_guard = HUB.devices.read(); + let device = &device_guard.get(device_id); + + let info = hal::image::SamplerInfo { + min_filter: conv::map_filter(desc.min_filter), + mag_filter: conv::map_filter(desc.mag_filter), + mip_filter: conv::map_filter(desc.mipmap_filter), + wrap_mode: ( + conv::map_wrap(desc.r_address_mode), + conv::map_wrap(desc.s_address_mode), + conv::map_wrap(desc.t_address_mode), + ), + lod_bias: 0.0.into(), + lod_range: desc.lod_min_clamp.into() .. desc.lod_max_clamp.into(), + comparison: if desc.compare_function == resource::CompareFunction::Always { + None + } else { + Some(conv::map_compare_function(desc.compare_function)) + }, + border: hal::image::PackedColor(match desc.border_color { + resource::BorderColor::TransparentBlack => 0x00000000, + resource::BorderColor::OpaqueBlack => 0x000000FF, + resource::BorderColor::OpaqueWhite => 0xFFFFFFFF, + }), + anisotropic: hal::image::Anisotropic::Off, //TODO + }; + let raw = unsafe { + device.raw + .create_sampler(info) + .unwrap() + }; + + HUB.samplers + .write() + .register(resource::Sampler { + raw + }) +} + #[no_mangle] pub extern "C" fn wgpu_device_create_bind_group_layout( device_id: DeviceId, diff --git a/wgpu-native/src/resource.rs b/wgpu-native/src/resource.rs index aa5e30254..729aee860 100644 --- a/wgpu-native/src/resource.rs +++ b/wgpu-native/src/resource.rs @@ -188,7 +188,7 @@ pub struct SamplerDescriptor { pub t_address_mode: AddressMode, pub mag_filter: FilterMode, pub min_filter: FilterMode, - pub mipmap_filer: FilterMode, + pub mipmap_filter: FilterMode, pub lod_min_clamp: f32, pub lod_max_clamp: f32, pub max_anisotropy: u32, diff --git a/wgpu-rs/src/lib.rs b/wgpu-rs/src/lib.rs index b2dc5b4e4..2733996bd 100644 --- a/wgpu-rs/src/lib.rs +++ b/wgpu-rs/src/lib.rs @@ -10,11 +10,13 @@ use std::ptr; pub use wgn::{ AdapterDescriptor, Attachment, BindGroupLayoutBinding, BindingType, BlendStateDescriptor, - BufferDescriptor, Color, ColorWriteFlags, CommandBufferDescriptor, DepthStencilStateDescriptor, + BufferDescriptor, BufferUsageFlags, + Color, ColorWriteFlags, CommandBufferDescriptor, DepthStencilStateDescriptor, DeviceDescriptor, Extensions, Extent3d, LoadOp, Origin3d, PowerPreference, PrimitiveTopology, RenderPassColorAttachmentDescriptor, RenderPassDepthStencilAttachmentDescriptor, ShaderModuleDescriptor, ShaderStage, ShaderStageFlags, StoreOp, SwapChainDescriptor, TextureDescriptor, TextureDimension, TextureFormat, TextureUsageFlags, TextureViewDescriptor, + SamplerDescriptor, AddressMode, FilterMode, CompareFunction, BorderColor, }; pub struct Instance { @@ -353,6 +355,12 @@ impl Device { } } + pub fn create_sampler(&self, desc: &SamplerDescriptor) -> Sampler { + Sampler { + id: wgn::wgpu_device_create_sampler(self.id, desc), + } + } + pub fn create_swap_chain(&self, surface: &Surface, desc: &SwapChainDescriptor) -> SwapChain { SwapChain { id: wgn::wgpu_device_create_swap_chain(self.id, surface.id, desc),