use crate::{
command::{LoadOp, PassChannel, StoreOp},
resource, PrivateFeatures,
};
use std::convert::TryInto;
pub fn map_buffer_usage(usage: wgt::BufferUsage) -> (hal::buffer::Usage, hal::memory::Properties) {
use hal::buffer::Usage as U;
use hal::memory::Properties as P;
use wgt::BufferUsage as W;
let mut hal_memory = P::empty();
if usage.contains(W::MAP_READ) {
hal_memory |= P::CPU_VISIBLE | P::CPU_CACHED;
}
if usage.contains(W::MAP_WRITE) {
hal_memory |= P::CPU_VISIBLE;
}
let mut hal_usage = U::empty();
if usage.contains(W::COPY_SRC) {
hal_usage |= U::TRANSFER_SRC;
}
if usage.contains(W::COPY_DST) {
hal_usage |= U::TRANSFER_DST;
}
if usage.contains(W::INDEX) {
hal_usage |= U::INDEX;
}
if usage.contains(W::VERTEX) {
hal_usage |= U::VERTEX;
}
if usage.contains(W::UNIFORM) {
hal_usage |= U::UNIFORM;
}
if usage.contains(W::STORAGE) {
hal_usage |= U::STORAGE;
}
if usage.contains(W::INDIRECT) {
hal_usage |= U::INDIRECT;
}
(hal_usage, hal_memory)
}
pub fn map_texture_usage(
usage: wgt::TextureUsage,
aspects: hal::format::Aspects,
) -> hal::image::Usage {
use hal::image::Usage as U;
use wgt::TextureUsage as W;
let mut value = U::empty();
if usage.contains(W::COPY_SRC) {
value |= U::TRANSFER_SRC;
}
if usage.contains(W::COPY_DST) {
value |= U::TRANSFER_DST;
}
if usage.contains(W::SAMPLED) {
value |= U::SAMPLED;
}
if usage.contains(W::STORAGE) {
value |= U::STORAGE;
}
if usage.contains(W::OUTPUT_ATTACHMENT) {
if aspects.intersects(hal::format::Aspects::DEPTH | hal::format::Aspects::STENCIL) {
value |= U::DEPTH_STENCIL_ATTACHMENT;
} else {
value |= U::COLOR_ATTACHMENT;
}
}
value
}
pub fn map_binding_type(binding: &wgt::BindGroupLayoutEntry) -> hal::pso::DescriptorType {
use hal::pso;
use wgt::BindingType as Bt;
match binding.ty {
Bt::UniformBuffer {
dynamic,
min_binding_size: _,
} => pso::DescriptorType::Buffer {
ty: pso::BufferDescriptorType::Uniform,
format: pso::BufferDescriptorFormat::Structured {
dynamic_offset: dynamic,
},
},
Bt::StorageBuffer {
readonly,
dynamic,
min_binding_size: _,
} => pso::DescriptorType::Buffer {
ty: pso::BufferDescriptorType::Storage {
read_only: readonly,
},
format: pso::BufferDescriptorFormat::Structured {
dynamic_offset: dynamic,
},
},
Bt::Sampler { comparison: _ } => pso::DescriptorType::Sampler,
Bt::SampledTexture { .. } => pso::DescriptorType::Image {
ty: pso::ImageDescriptorType::Sampled {
with_sampler: false,
},
},
Bt::StorageTexture { readonly, .. } => pso::DescriptorType::Image {
ty: pso::ImageDescriptorType::Storage {
read_only: readonly,
},
},
}
}
pub fn map_shader_stage_flags(shader_stage_flags: wgt::ShaderStage) -> hal::pso::ShaderStageFlags {
use hal::pso::ShaderStageFlags as H;
use wgt::ShaderStage as Ss;
let mut value = H::empty();
if shader_stage_flags.contains(Ss::VERTEX) {
value |= H::VERTEX;
}
if shader_stage_flags.contains(Ss::FRAGMENT) {
value |= H::FRAGMENT;
}
if shader_stage_flags.contains(Ss::COMPUTE) {
value |= H::COMPUTE;
}
value
}
pub fn map_extent(extent: &wgt::Extent3d, dim: wgt::TextureDimension) -> hal::image::Extent {
hal::image::Extent {
width: extent.width,
height: extent.height,
depth: match dim {
wgt::TextureDimension::D1 | wgt::TextureDimension::D2 => 1,
wgt::TextureDimension::D3 => extent.depth,
},
}
}
pub fn map_primitive_topology(primitive_topology: wgt::PrimitiveTopology) -> hal::pso::Primitive {
use hal::pso::Primitive as H;
use wgt::PrimitiveTopology as Pt;
match primitive_topology {
Pt::PointList => H::PointList,
Pt::LineList => H::LineList,
Pt::LineStrip => H::LineStrip,
Pt::TriangleList => H::TriangleList,
Pt::TriangleStrip => H::TriangleStrip,
}
}
pub fn map_color_state_descriptor(desc: &wgt::ColorStateDescriptor) -> hal::pso::ColorBlendDesc {
let color_mask = desc.write_mask;
let blend_state = if desc.color_blend != wgt::BlendDescriptor::REPLACE
|| desc.alpha_blend != wgt::BlendDescriptor::REPLACE
{
Some(hal::pso::BlendState {
color: map_blend_descriptor(&desc.color_blend),
alpha: map_blend_descriptor(&desc.alpha_blend),
})
} else {
None
};
hal::pso::ColorBlendDesc {
mask: map_color_write_flags(color_mask),
blend: blend_state,
}
}
fn map_color_write_flags(flags: wgt::ColorWrite) -> hal::pso::ColorMask {
use hal::pso::ColorMask as H;
use wgt::ColorWrite as Cw;
let mut value = H::empty();
if flags.contains(Cw::RED) {
value |= H::RED;
}
if flags.contains(Cw::GREEN) {
value |= H::GREEN;
}
if flags.contains(Cw::BLUE) {
value |= H::BLUE;
}
if flags.contains(Cw::ALPHA) {
value |= H::ALPHA;
}
value
}
fn map_blend_descriptor(blend_desc: &wgt::BlendDescriptor) -> hal::pso::BlendOp {
use hal::pso::BlendOp as H;
use wgt::BlendOperation as Bo;
match blend_desc.operation {
Bo::Add => H::Add {
src: map_blend_factor(blend_desc.src_factor),
dst: map_blend_factor(blend_desc.dst_factor),
},
Bo::Subtract => H::Sub {
src: map_blend_factor(blend_desc.src_factor),
dst: map_blend_factor(blend_desc.dst_factor),
},
Bo::ReverseSubtract => H::RevSub {
src: map_blend_factor(blend_desc.src_factor),
dst: map_blend_factor(blend_desc.dst_factor),
},
Bo::Min => H::Min,
Bo::Max => H::Max,
}
}
fn map_blend_factor(blend_factor: wgt::BlendFactor) -> hal::pso::Factor {
use hal::pso::Factor as H;
use wgt::BlendFactor as Bf;
match blend_factor {
Bf::Zero => H::Zero,
Bf::One => H::One,
Bf::SrcColor => H::SrcColor,
Bf::OneMinusSrcColor => H::OneMinusSrcColor,
Bf::SrcAlpha => H::SrcAlpha,
Bf::OneMinusSrcAlpha => H::OneMinusSrcAlpha,
Bf::DstColor => H::DstColor,
Bf::OneMinusDstColor => H::OneMinusDstColor,
Bf::DstAlpha => H::DstAlpha,
Bf::OneMinusDstAlpha => H::OneMinusDstAlpha,
Bf::SrcAlphaSaturated => H::SrcAlphaSaturate,
Bf::BlendColor => H::ConstColor,
Bf::OneMinusBlendColor => H::OneMinusConstColor,
}
}
pub fn map_depth_stencil_state_descriptor(
desc: &wgt::DepthStencilStateDescriptor,
) -> hal::pso::DepthStencilDesc {
hal::pso::DepthStencilDesc {
depth: if desc.is_depth_enabled() {
Some(hal::pso::DepthTest {
fun: map_compare_function(desc.depth_compare),
write: desc.depth_write_enabled,
})
} else {
None
},
depth_bounds: false,
stencil: if desc.stencil.is_enabled() {
let s = &desc.stencil;
Some(hal::pso::StencilTest {
faces: hal::pso::Sided {
front: map_stencil_face(&s.front),
back: map_stencil_face(&s.back),
},
read_masks: hal::pso::State::Static(hal::pso::Sided::new(s.read_mask)),
write_masks: hal::pso::State::Static(hal::pso::Sided::new(s.write_mask)),
reference_values: if s.needs_ref_value() {
hal::pso::State::Dynamic
} else {
hal::pso::State::Static(hal::pso::Sided::new(0))
},
})
} else {
None
},
}
}
fn map_stencil_face(
stencil_state_face_desc: &wgt::StencilStateFaceDescriptor,
) -> hal::pso::StencilFace {
hal::pso::StencilFace {
fun: map_compare_function(stencil_state_face_desc.compare),
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),
}
}
pub fn map_compare_function(compare_function: wgt::CompareFunction) -> hal::pso::Comparison {
use hal::pso::Comparison as H;
use wgt::CompareFunction as Cf;
match compare_function {
Cf::Never => H::Never,
Cf::Less => H::Less,
Cf::Equal => H::Equal,
Cf::LessEqual => H::LessEqual,
Cf::Greater => H::Greater,
Cf::NotEqual => H::NotEqual,
Cf::GreaterEqual => H::GreaterEqual,
Cf::Always => H::Always,
}
}
fn map_stencil_operation(stencil_operation: wgt::StencilOperation) -> hal::pso::StencilOp {
use hal::pso::StencilOp as H;
use wgt::StencilOperation as So;
match stencil_operation {
So::Keep => H::Keep,
So::Zero => H::Zero,
So::Replace => H::Replace,
So::Invert => H::Invert,
So::IncrementClamp => H::IncrementClamp,
So::DecrementClamp => H::DecrementClamp,
So::IncrementWrap => H::IncrementWrap,
So::DecrementWrap => H::DecrementWrap,
}
}
pub(crate) fn map_texture_format(
texture_format: wgt::TextureFormat,
private_features: PrivateFeatures,
) -> hal::format::Format {
use hal::format::Format as H;
use wgt::TextureFormat as Tf;
match texture_format {
Tf::R8Unorm => H::R8Unorm,
Tf::R8Snorm => H::R8Snorm,
Tf::R8Uint => H::R8Uint,
Tf::R8Sint => H::R8Sint,
Tf::R16Uint => H::R16Uint,
Tf::R16Sint => H::R16Sint,
Tf::R16Float => H::R16Sfloat,
Tf::Rg8Unorm => H::Rg8Unorm,
Tf::Rg8Snorm => H::Rg8Snorm,
Tf::Rg8Uint => H::Rg8Uint,
Tf::Rg8Sint => H::Rg8Sint,
Tf::R32Uint => H::R32Uint,
Tf::R32Sint => H::R32Sint,
Tf::R32Float => H::R32Sfloat,
Tf::Rg16Uint => H::Rg16Uint,
Tf::Rg16Sint => H::Rg16Sint,
Tf::Rg16Float => H::Rg16Sfloat,
Tf::Rgba8Unorm => H::Rgba8Unorm,
Tf::Rgba8UnormSrgb => H::Rgba8Srgb,
Tf::Rgba8Snorm => H::Rgba8Snorm,
Tf::Rgba8Uint => H::Rgba8Uint,
Tf::Rgba8Sint => H::Rgba8Sint,
Tf::Bgra8Unorm => H::Bgra8Unorm,
Tf::Bgra8UnormSrgb => H::Bgra8Srgb,
Tf::Rgb10a2Unorm => H::A2r10g10b10Unorm,
Tf::Rg11b10Float => H::B10g11r11Ufloat,
Tf::Rg32Uint => H::Rg32Uint,
Tf::Rg32Sint => H::Rg32Sint,
Tf::Rg32Float => H::Rg32Sfloat,
Tf::Rgba16Uint => H::Rgba16Uint,
Tf::Rgba16Sint => H::Rgba16Sint,
Tf::Rgba16Float => H::Rgba16Sfloat,
Tf::Rgba32Uint => H::Rgba32Uint,
Tf::Rgba32Sint => H::Rgba32Sint,
Tf::Rgba32Float => H::Rgba32Sfloat,
Tf::Depth32Float => H::D32Sfloat,
Tf::Depth24Plus => {
if private_features.texture_d24 {
H::X8D24Unorm
} else {
H::D32Sfloat
}
}
Tf::Depth24PlusStencil8 => {
if private_features.texture_d24_s8 {
H::D24UnormS8Uint
} else {
H::D32SfloatS8Uint
}
}
Tf::Bc1RgbaUnorm => H::Bc1RgbaUnorm,
Tf::Bc1RgbaUnormSrgb => H::Bc1RgbaSrgb,
Tf::Bc2RgbaUnorm => H::Bc2Unorm,
Tf::Bc2RgbaUnormSrgb => H::Bc2Srgb,
Tf::Bc3RgbaUnorm => H::Bc3Unorm,
Tf::Bc3RgbaUnormSrgb => H::Bc3Srgb,
Tf::Bc4RUnorm => H::Bc4Unorm,
Tf::Bc4RSnorm => H::Bc4Snorm,
Tf::Bc5RgUnorm => H::Bc5Unorm,
Tf::Bc5RgSnorm => H::Bc5Snorm,
Tf::Bc6hRgbSfloat => H::Bc6hSfloat,
Tf::Bc6hRgbUfloat => H::Bc6hUfloat,
Tf::Bc7RgbaUnorm => H::Bc7Unorm,
Tf::Bc7RgbaUnormSrgb => H::Bc7Srgb,
}
}
pub fn texture_block_size(format: wgt::TextureFormat) -> (u32, u32) {
use wgt::TextureFormat as Tf;
match format {
Tf::R8Unorm
| Tf::R8Snorm
| Tf::R8Uint
| Tf::R8Sint
| Tf::R16Uint
| Tf::R16Sint
| Tf::R16Float
| Tf::Rg8Unorm
| Tf::Rg8Snorm
| Tf::Rg8Uint
| Tf::Rg8Sint
| Tf::R32Uint
| Tf::R32Sint
| Tf::R32Float
| Tf::Rg16Uint
| Tf::Rg16Sint
| Tf::Rg16Float
| Tf::Rgba8Unorm
| Tf::Rgba8UnormSrgb
| Tf::Rgba8Snorm
| Tf::Rgba8Uint
| Tf::Rgba8Sint
| Tf::Bgra8Unorm
| Tf::Bgra8UnormSrgb
| Tf::Rgb10a2Unorm
| Tf::Rg11b10Float
| Tf::Rg32Uint
| Tf::Rg32Sint
| Tf::Rg32Float
| Tf::Rgba16Uint
| Tf::Rgba16Sint
| Tf::Rgba16Float
| Tf::Rgba32Uint
| Tf::Rgba32Sint
| Tf::Rgba32Float
| Tf::Depth32Float
| Tf::Depth24Plus
| Tf::Depth24PlusStencil8 => (1, 1),
Tf::Bc1RgbaUnorm
| Tf::Bc1RgbaUnormSrgb
| Tf::Bc2RgbaUnorm
| Tf::Bc2RgbaUnormSrgb
| Tf::Bc3RgbaUnorm
| Tf::Bc3RgbaUnormSrgb
| Tf::Bc4RUnorm
| Tf::Bc4RSnorm
| Tf::Bc5RgUnorm
| Tf::Bc5RgSnorm
| Tf::Bc6hRgbUfloat
| Tf::Bc6hRgbSfloat
| Tf::Bc7RgbaUnorm
| Tf::Bc7RgbaUnormSrgb => (4, 4),
}
}
pub fn texture_features(format: wgt::TextureFormat) -> wgt::Features {
use wgt::TextureFormat as Tf;
match format {
Tf::R8Unorm
| Tf::R8Snorm
| Tf::R8Uint
| Tf::R8Sint
| Tf::R16Uint
| Tf::R16Sint
| Tf::R16Float
| Tf::Rg8Unorm
| Tf::Rg8Snorm
| Tf::Rg8Uint
| Tf::Rg8Sint
| Tf::R32Uint
| Tf::R32Sint
| Tf::R32Float
| Tf::Rg16Uint
| Tf::Rg16Sint
| Tf::Rg16Float
| Tf::Rgba8Unorm
| Tf::Rgba8UnormSrgb
| Tf::Rgba8Snorm
| Tf::Rgba8Uint
| Tf::Rgba8Sint
| Tf::Bgra8Unorm
| Tf::Bgra8UnormSrgb
| Tf::Rgb10a2Unorm
| Tf::Rg11b10Float
| Tf::Rg32Uint
| Tf::Rg32Sint
| Tf::Rg32Float
| Tf::Rgba16Uint
| Tf::Rgba16Sint
| Tf::Rgba16Float
| Tf::Rgba32Uint
| Tf::Rgba32Sint
| Tf::Rgba32Float
| Tf::Depth32Float
| Tf::Depth24Plus
| Tf::Depth24PlusStencil8 => wgt::Features::empty(),
Tf::Bc1RgbaUnorm
| Tf::Bc1RgbaUnormSrgb
| Tf::Bc2RgbaUnorm
| Tf::Bc2RgbaUnormSrgb
| Tf::Bc3RgbaUnorm
| Tf::Bc3RgbaUnormSrgb
| Tf::Bc4RUnorm
| Tf::Bc4RSnorm
| Tf::Bc5RgUnorm
| Tf::Bc5RgSnorm
| Tf::Bc6hRgbUfloat
| Tf::Bc6hRgbSfloat
| Tf::Bc7RgbaUnorm
| Tf::Bc7RgbaUnormSrgb => wgt::Features::TEXTURE_COMPRESSION_BC,
}
}
pub fn map_vertex_format(vertex_format: wgt::VertexFormat) -> hal::format::Format {
use hal::format::Format as H;
use wgt::VertexFormat as Vf;
match vertex_format {
Vf::Uchar2 => H::Rg8Uint,
Vf::Uchar4 => H::Rgba8Uint,
Vf::Char2 => H::Rg8Sint,
Vf::Char4 => H::Rgba8Sint,
Vf::Uchar2Norm => H::Rg8Unorm,
Vf::Uchar4Norm => H::Rgba8Unorm,
Vf::Char2Norm => H::Rg8Snorm,
Vf::Char4Norm => H::Rgba8Snorm,
Vf::Ushort2 => H::Rg16Uint,
Vf::Ushort4 => H::Rgba16Uint,
Vf::Short2 => H::Rg16Sint,
Vf::Short4 => H::Rgba16Sint,
Vf::Ushort2Norm => H::Rg16Unorm,
Vf::Ushort4Norm => H::Rgba16Unorm,
Vf::Short2Norm => H::Rg16Snorm,
Vf::Short4Norm => H::Rgba16Snorm,
Vf::Half2 => H::Rg16Sfloat,
Vf::Half4 => H::Rgba16Sfloat,
Vf::Float => H::R32Sfloat,
Vf::Float2 => H::Rg32Sfloat,
Vf::Float3 => H::Rgb32Sfloat,
Vf::Float4 => H::Rgba32Sfloat,
Vf::Uint => H::R32Uint,
Vf::Uint2 => H::Rg32Uint,
Vf::Uint3 => H::Rgb32Uint,
Vf::Uint4 => H::Rgba32Uint,
Vf::Int => H::R32Sint,
Vf::Int2 => H::Rg32Sint,
Vf::Int3 => H::Rgb32Sint,
Vf::Int4 => H::Rgba32Sint,
}
}
pub fn is_power_of_two(val: u32) -> bool {
val != 0 && (val & (val - 1)) == 0
}
pub fn is_valid_copy_src_texture_format(format: wgt::TextureFormat) -> bool {
use wgt::TextureFormat as Tf;
match format {
Tf::Depth24Plus | Tf::Depth24PlusStencil8 => false,
_ => true,
}
}
pub fn is_valid_copy_dst_texture_format(format: wgt::TextureFormat) -> bool {
use wgt::TextureFormat as Tf;
match format {
Tf::Depth32Float | Tf::Depth24Plus | Tf::Depth24PlusStencil8 => false,
_ => true,
}
}
pub fn map_texture_dimension_size(
dimension: wgt::TextureDimension,
wgt::Extent3d {
width,
height,
depth,
}: wgt::Extent3d,
sample_size: u32,
) -> Result<hal::image::Kind, resource::TextureDimensionError> {
use hal::image::Kind as H;
use resource::TextureDimensionError as Tde;
use wgt::TextureDimension::*;
Ok(match dimension {
D1 => {
if height != 1 {
return Err(Tde::InvalidHeight);
}
if sample_size != 1 {
return Err(Tde::InvalidSampleCount(sample_size));
}
let layers = depth.try_into().or(Err(Tde::TooManyLayers(depth)))?;
H::D1(width, layers)
}
D2 => {
if sample_size > 32 || !is_power_of_two(sample_size) {
return Err(Tde::InvalidSampleCount(sample_size));
}
let layers = depth.try_into().or(Err(Tde::TooManyLayers(depth)))?;
H::D2(width, height, layers, sample_size as u8)
}
D3 => {
if sample_size != 1 {
return Err(Tde::InvalidSampleCount(sample_size));
}
H::D3(width, height, depth)
}
})
}
pub fn map_texture_view_dimension(dimension: wgt::TextureViewDimension) -> hal::image::ViewKind {
use hal::image::ViewKind as H;
use wgt::TextureViewDimension::*;
match dimension {
D1 => H::D1,
D2 => H::D2,
D2Array => H::D2Array,
Cube => H::Cube,
CubeArray => H::CubeArray,
D3 => H::D3,
}
}
pub(crate) fn map_buffer_state(usage: resource::BufferUse) -> hal::buffer::State {
use crate::resource::BufferUse as W;
use hal::buffer::Access as A;
let mut access = A::empty();
if usage.contains(W::MAP_READ) {
access |= A::HOST_READ;
}
if usage.contains(W::MAP_WRITE) {
access |= A::HOST_WRITE;
}
if usage.contains(W::COPY_SRC) {
access |= A::TRANSFER_READ;
}
if usage.contains(W::COPY_DST) {
access |= A::TRANSFER_WRITE;
}
if usage.contains(W::INDEX) {
access |= A::INDEX_BUFFER_READ;
}
if usage.contains(W::VERTEX) {
access |= A::VERTEX_BUFFER_READ;
}
if usage.contains(W::UNIFORM) {
access |= A::UNIFORM_READ | A::SHADER_READ;
}
if usage.contains(W::STORAGE_LOAD) {
access |= A::SHADER_READ;
}
if usage.contains(W::STORAGE_STORE) {
access |= A::SHADER_WRITE;
}
if usage.contains(W::INDIRECT) {
access |= A::INDIRECT_COMMAND_READ;
}
access
}
pub(crate) fn map_texture_state(
usage: resource::TextureUse,
aspects: hal::format::Aspects,
) -> hal::image::State {
use crate::resource::TextureUse as W;
use hal::image::{Access as A, Layout as L};
let is_color = aspects.contains(hal::format::Aspects::COLOR);
let layout = match usage {
W::UNINITIALIZED => return (A::empty(), L::Undefined),
W::COPY_SRC => L::TransferSrcOptimal,
W::COPY_DST => L::TransferDstOptimal,
W::SAMPLED if is_color => L::ShaderReadOnlyOptimal,
W::ATTACHMENT_READ | W::ATTACHMENT_WRITE if is_color => L::ColorAttachmentOptimal,
_ if is_color => L::General,
W::ATTACHMENT_WRITE => L::DepthStencilAttachmentOptimal,
_ => L::DepthStencilReadOnlyOptimal,
};
let mut access = A::empty();
if usage.contains(W::COPY_SRC) {
access |= A::TRANSFER_READ;
}
if usage.contains(W::COPY_DST) {
access |= A::TRANSFER_WRITE;
}
if usage.contains(W::SAMPLED) {
access |= A::SHADER_READ;
}
if usage.contains(W::ATTACHMENT_READ) {
access |= if is_color {
A::COLOR_ATTACHMENT_READ
} else {
A::DEPTH_STENCIL_ATTACHMENT_READ
};
}
if usage.contains(W::ATTACHMENT_WRITE) {
access |= if is_color {
A::COLOR_ATTACHMENT_WRITE
} else {
A::DEPTH_STENCIL_ATTACHMENT_WRITE
};
}
if usage.contains(W::STORAGE_LOAD) {
access |= A::SHADER_READ;
}
if usage.contains(W::STORAGE_STORE) {
access |= A::SHADER_WRITE;
}
(access, layout)
}
pub fn map_load_store_ops<V>(channel: &PassChannel<V>) -> hal::pass::AttachmentOps {
hal::pass::AttachmentOps {
load: match channel.load_op {
LoadOp::Clear => hal::pass::AttachmentLoadOp::Clear,
LoadOp::Load => hal::pass::AttachmentLoadOp::Load,
},
store: match channel.store_op {
StoreOp::Clear => hal::pass::AttachmentStoreOp::DontCare,
StoreOp::Store => hal::pass::AttachmentStoreOp::Store,
},
}
}
pub fn map_color_f32(color: &wgt::Color) -> hal::pso::ColorValue {
[
color.r as f32,
color.g as f32,
color.b as f32,
color.a as f32,
]
}
pub fn map_color_i32(color: &wgt::Color) -> [i32; 4] {
[
color.r as i32,
color.g as i32,
color.b as i32,
color.a as i32,
]
}
pub fn map_color_u32(color: &wgt::Color) -> [u32; 4] {
[
color.r as u32,
color.g as u32,
color.b as u32,
color.a as u32,
]
}
pub fn map_filter(filter: wgt::FilterMode) -> hal::image::Filter {
match filter {
wgt::FilterMode::Nearest => hal::image::Filter::Nearest,
wgt::FilterMode::Linear => hal::image::Filter::Linear,
}
}
pub fn map_wrap(address: wgt::AddressMode) -> hal::image::WrapMode {
use hal::image::WrapMode as W;
use wgt::AddressMode as Am;
match address {
Am::ClampToEdge => W::Clamp,
Am::Repeat => W::Tile,
Am::MirrorRepeat => W::Mirror,
}
}
pub fn map_rasterization_state_descriptor(
desc: &wgt::RasterizationStateDescriptor,
) -> hal::pso::Rasterizer {
use hal::pso;
pso::Rasterizer {
depth_clamping: desc.clamp_depth,
polygon_mode: pso::PolygonMode::Fill,
cull_face: match desc.cull_mode {
wgt::CullMode::None => pso::Face::empty(),
wgt::CullMode::Front => pso::Face::FRONT,
wgt::CullMode::Back => pso::Face::BACK,
},
front_face: match desc.front_face {
wgt::FrontFace::Ccw => pso::FrontFace::CounterClockwise,
wgt::FrontFace::Cw => pso::FrontFace::Clockwise,
},
depth_bias: if desc.depth_bias != 0
|| desc.depth_bias_slope_scale != 0.0
|| desc.depth_bias_clamp != 0.0
{
Some(pso::State::Static(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,
line_width: pso::State::Static(1.0),
}
}
pub fn map_index_format(index_format: wgt::IndexFormat) -> hal::IndexType {
match index_format {
wgt::IndexFormat::Uint16 => hal::IndexType::U16,
wgt::IndexFormat::Uint32 => hal::IndexType::U32,
}
}