mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2025-02-16 09:02:25 +00:00
Rework vertex attributes system
This commit is contained in:
parent
3749f26063
commit
3f4b9e126b
@ -188,11 +188,8 @@ fn write_entry_point(doc: &parse::Spirv, instruction: &parse::Instruction) -> St
|
||||
|
||||
let (ty, f_call) = match *execution {
|
||||
enums::ExecutionModel::ExecutionModelVertex => {
|
||||
let mut input_types = Vec::new();
|
||||
let mut attributes = Vec::new();
|
||||
|
||||
// TODO: sort types by location
|
||||
|
||||
for interface in interface.iter() {
|
||||
for i in doc.instructions.iter() {
|
||||
match i {
|
||||
@ -204,30 +201,41 @@ fn write_entry_point(doc: &parse::Spirv, instruction: &parse::Instruction) -> St
|
||||
continue;
|
||||
}
|
||||
|
||||
input_types.push(type_from_id(doc, result_type_id));
|
||||
let name = name_from_id(doc, result_id);
|
||||
let loc = match location_decoration(doc, result_id) {
|
||||
Some(l) => l,
|
||||
None => panic!("vertex attribute `{}` is missing a location", name)
|
||||
};
|
||||
attributes.push((loc, name));
|
||||
attributes.push((loc, name, format_from_id(doc, result_type_id)));
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let input = {
|
||||
let input = input_types.join(", ");
|
||||
if input.is_empty() { input } else { input + "," }
|
||||
};
|
||||
// Checking for overlapping attributes.
|
||||
for (offset, &(loc, ref name, (_, loc_len))) in attributes.iter().enumerate() {
|
||||
for &(loc2, ref name2, (_, loc_len2)) in attributes.iter().skip(offset + 1) {
|
||||
if loc == loc2 || (loc < loc2 && loc + loc_len as u32 > loc2) ||
|
||||
(loc2 < loc && loc2 + loc_len2 as u32 > loc)
|
||||
{
|
||||
panic!("The locations of vertex attributes `{}` and `{}` overlap",
|
||||
name, name2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let attributes = attributes.iter().map(|&(loc, ref name)| {
|
||||
format!("({}, ::std::borrow::Cow::Borrowed(\"{}\"))", loc, name)
|
||||
let attributes = attributes.iter().map(|&(loc, ref name, (ref ty, num_locs))| {
|
||||
assert!(num_locs >= 1);
|
||||
|
||||
format!("::vulkano::pipeline::shader::ShaderInterfaceDefEntry {{
|
||||
location: {} .. {},
|
||||
format: ::vulkano::format::Format::{},
|
||||
name: Some(::std::borrow::Cow::Borrowed(\"{}\"))
|
||||
}}", loc, loc as usize + num_locs, ty, name)
|
||||
}).collect::<Vec<_>>().join(", ");
|
||||
|
||||
let t = format!("::vulkano::pipeline::shader::VertexShaderEntryPoint<(), ({input}), Layout>",
|
||||
input = input);
|
||||
let t = "::vulkano::pipeline::shader::VertexShaderEntryPoint<(), Vec<::vulkano::pipeline::shader::ShaderInterfaceDefEntry>, Layout>".to_owned();
|
||||
let f = format!("vertex_shader_entry_point(::std::ffi::CStr::from_ptr(NAME.as_ptr() as *const _), Layout, vec![{}])", attributes);
|
||||
(t, f)
|
||||
},
|
||||
@ -295,6 +303,56 @@ fn write_entry_point(doc: &parse::Spirv, instruction: &parse::Instruction) -> St
|
||||
f_call = f_call)
|
||||
}
|
||||
|
||||
/// Returns the vulkano `Format` and number of occupied locations from an id.
|
||||
fn format_from_id(doc: &parse::Spirv, searched: u32) -> (String, usize) {
|
||||
for instruction in doc.instructions.iter() {
|
||||
match instruction {
|
||||
&parse::Instruction::TypeInt { result_id, width, signedness } if result_id == searched => {
|
||||
return ("R32Sint".to_owned(), 1);
|
||||
},
|
||||
&parse::Instruction::TypeFloat { result_id, width } if result_id == searched => {
|
||||
return ("R32Sfloat".to_owned(), 1);
|
||||
},
|
||||
&parse::Instruction::TypeVector { result_id, component_id, count } if result_id == searched => {
|
||||
let (format, sz) = format_from_id(doc, component_id);
|
||||
assert!(format.starts_with("R32"));
|
||||
assert_eq!(sz, 1);
|
||||
let format = if count == 1 {
|
||||
format
|
||||
} else if count == 2 {
|
||||
format!("R32G32{}", &format[3..])
|
||||
} else if count == 3 {
|
||||
format!("R32G32B32{}", &format[3..])
|
||||
} else if count == 4 {
|
||||
format!("R32G32B32A32{}", &format[3..])
|
||||
} else {
|
||||
panic!("Found vector type with more than 4 elements")
|
||||
};
|
||||
return (format, sz);
|
||||
},
|
||||
&parse::Instruction::TypeMatrix { result_id, column_type_id, column_count } if result_id == searched => {
|
||||
let (format, sz) = format_from_id(doc, column_type_id);
|
||||
return (format, sz * column_count as usize);
|
||||
},
|
||||
&parse::Instruction::TypeArray { result_id, type_id, length_id } if result_id == searched => {
|
||||
let (format, sz) = format_from_id(doc, type_id);
|
||||
let len = doc.instructions.iter().filter_map(|e| {
|
||||
match e { &parse::Instruction::Constant { result_id, ref data, .. } if result_id == length_id => Some(data.clone()), _ => None }
|
||||
}).next().expect("failed to find array length");
|
||||
let len = len.iter().rev().fold(0u64, |a, &b| (a << 32) | b as u64);
|
||||
return (format, sz * len as usize);
|
||||
},
|
||||
&parse::Instruction::TypePointer { result_id, type_id, .. } if result_id == searched => {
|
||||
return format_from_id(doc, type_id);
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
||||
panic!("Type #{} not found or invalid", searched)
|
||||
}
|
||||
|
||||
// TODO: remove when no longer necessary
|
||||
// TODO: struct definitions don't use this function, so irrelevant elements should be removed
|
||||
fn type_from_id(doc: &parse::Spirv, searched: u32) -> String {
|
||||
for instruction in doc.instructions.iter() {
|
||||
|
@ -769,7 +769,7 @@ impl InnerCommandBufferBuilder {
|
||||
pub unsafe fn draw<V, Pv, Pl, L, Rp, Pc>(mut self, pipeline: &Arc<GraphicsPipeline<Pv, Pl, Rp>>,
|
||||
vertices: V, dynamic: &DynamicState,
|
||||
sets: L, push_constants: &Pc) -> InnerCommandBufferBuilder
|
||||
where Pv: 'static + VertexDefinition + VertexSource<V>, L: DescriptorSetsCollection + Send + Sync,
|
||||
where Pv: 'static + VertexSource<V>, L: DescriptorSetsCollection + Send + Sync,
|
||||
Pl: 'static + PipelineLayout + Send + Sync, Rp: 'static + Send + Sync,
|
||||
Pc: 'static + Clone + Send + Sync
|
||||
{
|
||||
@ -812,7 +812,7 @@ impl InnerCommandBufferBuilder {
|
||||
vertices: V, indices: Ib, dynamic: &DynamicState,
|
||||
sets: L, push_constants: &Pc) -> InnerCommandBufferBuilder
|
||||
where L: DescriptorSetsCollection + Send + Sync,
|
||||
Pv: 'static + VertexDefinition + VertexSource<V>,
|
||||
Pv: 'static + VertexSource<V>,
|
||||
Pl: 'static + PipelineLayout + Send + Sync, Rp: 'static + Send + Sync,
|
||||
Ib: Into<BufferSlice<'a, [I], Ibb>>, I: 'static + Index, Ibb: Buffer + 'static,
|
||||
Pc: 'static + Clone + Send + Sync
|
||||
@ -869,7 +869,7 @@ impl InnerCommandBufferBuilder {
|
||||
pub unsafe fn draw_indirect<I, V, Pv, Pl, L, Rp, Pc>(mut self, buffer: &Arc<I>, pipeline: &Arc<GraphicsPipeline<Pv, Pl, Rp>>,
|
||||
vertices: V, dynamic: &DynamicState,
|
||||
sets: L, push_constants: &Pc) -> InnerCommandBufferBuilder
|
||||
where Pv: 'static + VertexDefinition + VertexSource<V>, L: DescriptorSetsCollection + Send + Sync,
|
||||
where Pv: 'static + VertexSource<V>, L: DescriptorSetsCollection + Send + Sync,
|
||||
Pl: 'static + PipelineLayout + Send + Sync, Rp: 'static + Send + Sync, Pc: 'static + Clone + Send + Sync,
|
||||
I: 'static + TypedBuffer<Content = [DrawIndirectCommand]>
|
||||
{
|
||||
@ -962,7 +962,7 @@ impl InnerCommandBufferBuilder {
|
||||
|
||||
fn bind_gfx_pipeline_state<V, Pl, L, Rp, Pc>(&mut self, pipeline: &Arc<GraphicsPipeline<V, Pl, Rp>>,
|
||||
dynamic: &DynamicState, sets: L, push_constants: &Pc)
|
||||
where V: 'static + VertexDefinition + Send + Sync, L: DescriptorSetsCollection + Send + Sync,
|
||||
where V: 'static + Send + Sync, L: DescriptorSetsCollection + Send + Sync,
|
||||
Pl: 'static + PipelineLayout + Send + Sync, Rp: 'static + Send + Sync, Pc: 'static + Clone + Send + Sync
|
||||
{
|
||||
unsafe {
|
||||
|
@ -325,7 +325,7 @@ impl PrimaryCommandBufferBuilderInlineDraw {
|
||||
pub fn draw<V, L, Pv, Pl, Rp, Pc>(self, pipeline: &Arc<GraphicsPipeline<Pv, Pl, Rp>>,
|
||||
vertices: V, dynamic: &DynamicState, sets: L, push_constants: &Pc)
|
||||
-> PrimaryCommandBufferBuilderInlineDraw
|
||||
where Pv: VertexDefinition + VertexSource<V> + 'static, Pl: PipelineLayout + 'static + Send + Sync, Rp: 'static + Send + Sync,
|
||||
where Pv: VertexSource<V> + 'static, Pl: PipelineLayout + 'static + Send + Sync, Rp: 'static + Send + Sync,
|
||||
L: DescriptorSetsCollection + Send + Sync, Pc: 'static + Clone + Send + Sync
|
||||
{
|
||||
// FIXME: check subpass
|
||||
@ -343,7 +343,7 @@ impl PrimaryCommandBufferBuilderInlineDraw {
|
||||
pub fn draw_indexed<'a, V, L, Pv, Pl, Rp, I, Ib, Ibb, Pc>(self, pipeline: &Arc<GraphicsPipeline<Pv, Pl, Rp>>,
|
||||
vertices: V, indices: Ib, dynamic: &DynamicState,
|
||||
sets: L, push_constants: &Pc) -> PrimaryCommandBufferBuilderInlineDraw
|
||||
where Pv: 'static + VertexDefinition + VertexSource<V> + Send + Sync, Pl: 'static + PipelineLayout + Send + Sync, Rp: 'static + Send + Sync,
|
||||
where Pv: 'static + VertexSource<V> + Send + Sync, Pl: 'static + PipelineLayout + Send + Sync, Rp: 'static + Send + Sync,
|
||||
Ib: Into<BufferSlice<'a, [I], Ibb>>, I: 'static + Index, Ibb: Buffer + 'static + Send + Sync,
|
||||
L: DescriptorSetsCollection + Send + Sync, Pc: 'static + Clone + Send + Sync
|
||||
{
|
||||
@ -587,7 +587,7 @@ impl<R> SecondaryGraphicsCommandBufferBuilder<R>
|
||||
pub fn draw<V, L, Pv, Pl, Rp, Pc>(self, pipeline: &Arc<GraphicsPipeline<Pv, Pl, Rp>>,
|
||||
vertices: V, dynamic: &DynamicState, sets: L, push_constants: &Pc)
|
||||
-> SecondaryGraphicsCommandBufferBuilder<R>
|
||||
where Pv: VertexDefinition + VertexSource<V> + 'static, Pl: PipelineLayout + 'static + Send + Sync,
|
||||
where Pv: VertexSource<V> + 'static, Pl: PipelineLayout + 'static + Send + Sync,
|
||||
Rp: RenderPass + RenderPassDesc + 'static + Send + Sync, L: DescriptorSetsCollection + Send + Sync,
|
||||
R: RenderPassCompatible<Rp>, Pc: 'static + Clone + Send + Sync
|
||||
{
|
||||
@ -608,7 +608,7 @@ impl<R> SecondaryGraphicsCommandBufferBuilder<R>
|
||||
pub fn draw_indexed<'a, V, L, Pv, Pl, Rp, I, Ib, Ibb, Pc>(self, pipeline: &Arc<GraphicsPipeline<Pv, Pl, Rp>>,
|
||||
vertices: V, indices: Ib, dynamic: &DynamicState,
|
||||
sets: L, push_constants: &Pc) -> SecondaryGraphicsCommandBufferBuilder<R>
|
||||
where Pv: 'static + VertexDefinition + VertexSource<V>, Pl: 'static + PipelineLayout + Send + Sync,
|
||||
where Pv: 'static + VertexSource<V>, Pl: 'static + PipelineLayout + Send + Sync,
|
||||
Rp: RenderPass + RenderPassDesc + 'static + Send + Sync,
|
||||
Ib: Into<BufferSlice<'a, [I], Ibb>>, I: 'static + Index, Ibb: Buffer + 'static,
|
||||
L: DescriptorSetsCollection + Send + Sync, Pc: 'static + Clone + Send + Sync
|
||||
@ -630,7 +630,7 @@ impl<R> SecondaryGraphicsCommandBufferBuilder<R>
|
||||
pub fn draw_indirect<I, V, Pv, Pl, L, Rp, Pc>(self, buffer: &Arc<I>, pipeline: &Arc<GraphicsPipeline<Pv, Pl, Rp>>,
|
||||
vertices: V, dynamic: &DynamicState,
|
||||
sets: L, push_constants: &Pc) -> SecondaryGraphicsCommandBufferBuilder<R>
|
||||
where Pv: 'static + VertexDefinition + VertexSource<V>, L: DescriptorSetsCollection + Send + Sync,
|
||||
where Pv: 'static + VertexSource<V>, L: DescriptorSetsCollection + Send + Sync,
|
||||
Pl: 'static + PipelineLayout + Send + Sync, Rp: RenderPass + RenderPassDesc + 'static + Send + Sync,
|
||||
Pc: 'static + Clone + Send + Sync,
|
||||
I: 'static + TypedBuffer<Content = [DrawIndirectCommand]>
|
||||
|
@ -128,7 +128,7 @@ unsafe impl Data for u8 {
|
||||
}
|
||||
|
||||
macro_rules! formats {
|
||||
($($name:ident => $vk:ident [$($f_ty:tt)*] {$($d_ty:tt)*},)+) => (
|
||||
($($name:ident => $vk:ident [$sz:expr] [$($f_ty:tt)*] {$($d_ty:tt)*},)+) => (
|
||||
/// An enumeration of all the possible formats.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
#[repr(u32)]
|
||||
@ -146,6 +146,17 @@ macro_rules! formats {
|
||||
.. other functions ..
|
||||
*/
|
||||
|
||||
/// Returns the size in bytes of an element of this format. Returns `None` if the
|
||||
/// size is irrelevant (for example for compressed formats).
|
||||
#[inline]
|
||||
pub fn size(&self) -> Option<usize> {
|
||||
match *self {
|
||||
$(
|
||||
Format::$name => $sz,
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the `Format` corresponding to a Vulkan constant.
|
||||
#[doc(hidden)]
|
||||
pub fn from_num(val: u32) -> Option<Format> {
|
||||
@ -350,190 +361,190 @@ macro_rules! formats {
|
||||
}
|
||||
|
||||
formats! {
|
||||
R4G4UnormPack8 => FORMAT_R4G4_UNORM_PACK8 [float=2] {u8},
|
||||
R4G4B4A4UnormPack16 => FORMAT_R4G4B4A4_UNORM_PACK16 [float=4] {u16},
|
||||
B4G4R4A4UnormPack16 => FORMAT_B4G4R4A4_UNORM_PACK16 [float=4] {u16},
|
||||
R5G6B5UnormPack16 => FORMAT_R5G6B5_UNORM_PACK16 [float=3] {u16},
|
||||
B5G6R5UnormPack16 => FORMAT_B5G6R5_UNORM_PACK16 [float=3] {u16},
|
||||
R5G5B5A1UnormPack16 => FORMAT_R5G5B5A1_UNORM_PACK16 [float=4] {u16},
|
||||
B5G5R5A1UnormPack16 => FORMAT_B5G5R5A1_UNORM_PACK16 [float=4] {u16},
|
||||
A1R5G5B5UnormPack16 => FORMAT_A1R5G5B5_UNORM_PACK16 [float=4] {u16},
|
||||
R8Unorm => FORMAT_R8_UNORM [float=1] {u8},
|
||||
R8Snorm => FORMAT_R8_SNORM [float=1] {i8},
|
||||
R8Uscaled => FORMAT_R8_USCALED [float=1] {u8},
|
||||
R8Sscaled => FORMAT_R8_SSCALED [float=1] {i8},
|
||||
R8Uint => FORMAT_R8_UINT [uint=1] {u8},
|
||||
R8Sint => FORMAT_R8_SINT [sint=1] {i8},
|
||||
R8Srgb => FORMAT_R8_SRGB [float=1] {u8},
|
||||
R8G8Unorm => FORMAT_R8G8_UNORM [float=2] {[u8; 2]},
|
||||
R8G8Snorm => FORMAT_R8G8_SNORM [float=2] {[i8; 2]},
|
||||
R8G8Uscaled => FORMAT_R8G8_USCALED [float=2] {[u8; 2]},
|
||||
R8G8Sscaled => FORMAT_R8G8_SSCALED [float=2] {[i8; 2]},
|
||||
R8G8Uint => FORMAT_R8G8_UINT [uint=2] {[u8; 2]},
|
||||
R8G8Sint => FORMAT_R8G8_SINT [sint=2] {[i8; 2]},
|
||||
R8G8Srgb => FORMAT_R8G8_SRGB [float=2] {[u8; 2]},
|
||||
R8G8B8Unorm => FORMAT_R8G8B8_UNORM [float=3] {[u8; 3]},
|
||||
R8G8B8Snorm => FORMAT_R8G8B8_SNORM [float=3] {[i8; 3]},
|
||||
R8G8B8Uscaled => FORMAT_R8G8B8_USCALED [float=3] {[u8; 3]},
|
||||
R8G8B8Sscaled => FORMAT_R8G8B8_SSCALED [float=3] {[i8; 3]},
|
||||
R8G8B8Uint => FORMAT_R8G8B8_UINT [uint=3] {[u8; 3]},
|
||||
R8G8B8Sint => FORMAT_R8G8B8_SINT [sint=3] {[i8; 3]},
|
||||
R8G8B8Srgb => FORMAT_R8G8B8_SRGB [float=3] {[u8; 3]},
|
||||
B8G8R8Unorm => FORMAT_B8G8R8_UNORM [float=3] {[u8; 3]},
|
||||
B8G8R8Snorm => FORMAT_B8G8R8_SNORM [float=3] {[i8; 3]},
|
||||
B8G8R8Uscaled => FORMAT_B8G8R8_USCALED [float=3] {[u8; 3]},
|
||||
B8G8R8Sscaled => FORMAT_B8G8R8_SSCALED [float=3] {[i8; 3]},
|
||||
B8G8R8Uint => FORMAT_B8G8R8_UINT [uint=3] {[u8; 3]},
|
||||
B8G8R8Sint => FORMAT_B8G8R8_SINT [sint=3] {[i8; 3]},
|
||||
B8G8R8Srgb => FORMAT_B8G8R8_SRGB [float=3] {[u8; 3]},
|
||||
R8G8B8A8Unorm => FORMAT_R8G8B8A8_UNORM [float=4] {[u8; 4]},
|
||||
R8G8B8A8Snorm => FORMAT_R8G8B8A8_SNORM [float=4] {[i8; 4]},
|
||||
R8G8B8A8Uscaled => FORMAT_R8G8B8A8_USCALED [float=4] {[u8; 4]},
|
||||
R8G8B8A8Sscaled => FORMAT_R8G8B8A8_SSCALED [float=4] {[i8; 4]},
|
||||
R8G8B8A8Uint => FORMAT_R8G8B8A8_UINT [uint=4] {[u8; 4]},
|
||||
R8G8B8A8Sint => FORMAT_R8G8B8A8_SINT [sint=4] {[i8; 4]},
|
||||
R8G8B8A8Srgb => FORMAT_R8G8B8A8_SRGB [float=4] {[u8; 4]},
|
||||
B8G8R8A8Unorm => FORMAT_B8G8R8A8_UNORM [float=4] {[u8; 4]},
|
||||
B8G8R8A8Snorm => FORMAT_B8G8R8A8_SNORM [float=4] {[i8; 4]},
|
||||
B8G8R8A8Uscaled => FORMAT_B8G8R8A8_USCALED [float=4] {[u8; 4]},
|
||||
B8G8R8A8Sscaled => FORMAT_B8G8R8A8_SSCALED [float=4] {[i8; 4]},
|
||||
B8G8R8A8Uint => FORMAT_B8G8R8A8_UINT [uint=4] {[u8; 4]},
|
||||
B8G8R8A8Sint => FORMAT_B8G8R8A8_SINT [sint=4] {[i8; 4]},
|
||||
B8G8R8A8Srgb => FORMAT_B8G8R8A8_SRGB [float=4] {[u8; 4]},
|
||||
A8B8G8R8UnormPack32 => FORMAT_A8B8G8R8_UNORM_PACK32 [float=4] {[u8; 4]},
|
||||
A8B8G8R8SnormPack32 => FORMAT_A8B8G8R8_SNORM_PACK32 [float=4] {[i8; 4]},
|
||||
A8B8G8R8UscaledPack32 => FORMAT_A8B8G8R8_USCALED_PACK32 [float=4] {[u8; 4]},
|
||||
A8B8G8R8SscaledPack32 => FORMAT_A8B8G8R8_SSCALED_PACK32 [float=4] {[i8; 4]},
|
||||
A8B8G8R8UintPack32 => FORMAT_A8B8G8R8_UINT_PACK32 [uint=4] {[u8; 4]},
|
||||
A8B8G8R8SintPack32 => FORMAT_A8B8G8R8_SINT_PACK32 [sint=4] {[i8; 4]},
|
||||
A8B8G8R8SrgbPack32 => FORMAT_A8B8G8R8_SRGB_PACK32 [float=4] {[u8; 4]},
|
||||
A2R10G10B10UnormPack32 => FORMAT_A2R10G10B10_UNORM_PACK32 [float=4] {u32},
|
||||
A2R10G10B10SnormPack32 => FORMAT_A2R10G10B10_SNORM_PACK32 [float=4] {u32},
|
||||
A2R10G10B10UscaledPack32 => FORMAT_A2R10G10B10_USCALED_PACK32 [float=4] {u32},
|
||||
A2R10G10B10SscaledPack32 => FORMAT_A2R10G10B10_SSCALED_PACK32 [float=4] {u32},
|
||||
A2R10G10B10UintPack32 => FORMAT_A2R10G10B10_UINT_PACK32 [uint=4] {u32},
|
||||
A2R10G10B10SintPack32 => FORMAT_A2R10G10B10_SINT_PACK32 [sint=4] {u32},
|
||||
A2B10G10R10UnormPack32 => FORMAT_A2B10G10R10_UNORM_PACK32 [float=4] {u32},
|
||||
A2B10G10R10SnormPack32 => FORMAT_A2B10G10R10_SNORM_PACK32 [float=4] {u32},
|
||||
A2B10G10R10UscaledPack32 => FORMAT_A2B10G10R10_USCALED_PACK32 [float=4] {u32},
|
||||
A2B10G10R10SscaledPack32 => FORMAT_A2B10G10R10_SSCALED_PACK32 [float=4] {u32},
|
||||
A2B10G10R10UintPack32 => FORMAT_A2B10G10R10_UINT_PACK32 [uint=4] {u32},
|
||||
A2B10G10R10SintPack32 => FORMAT_A2B10G10R10_SINT_PACK32 [sint=4] {u32},
|
||||
R16Unorm => FORMAT_R16_UNORM [float=1] {u16},
|
||||
R16Snorm => FORMAT_R16_SNORM [float=1] {i16},
|
||||
R16Uscaled => FORMAT_R16_USCALED [float=1] {u16},
|
||||
R16Sscaled => FORMAT_R16_SSCALED [float=1] {i16},
|
||||
R16Uint => FORMAT_R16_UINT [uint=1] {u16},
|
||||
R16Sint => FORMAT_R16_SINT [sint=1] {i16},
|
||||
R16Sfloat => FORMAT_R16_SFLOAT [float=1] {},
|
||||
R16G16Unorm => FORMAT_R16G16_UNORM [float=2] {[u16; 2]},
|
||||
R16G16Snorm => FORMAT_R16G16_SNORM [float=2] {[i16; 2]},
|
||||
R16G16Uscaled => FORMAT_R16G16_USCALED [float=2] {[u16; 2]},
|
||||
R16G16Sscaled => FORMAT_R16G16_SSCALED [float=2] {[i16; 2]},
|
||||
R16G16Uint => FORMAT_R16G16_UINT [uint=2] {[u16; 2]},
|
||||
R16G16Sint => FORMAT_R16G16_SINT [sint=2] {[i16; 2]},
|
||||
R16G16Sfloat => FORMAT_R16G16_SFLOAT [float=2] {},
|
||||
R16G16B16Unorm => FORMAT_R16G16B16_UNORM [float=3] {[u16; 3]},
|
||||
R16G16B16Snorm => FORMAT_R16G16B16_SNORM [float=3] {[i16; 3]},
|
||||
R16G16B16Uscaled => FORMAT_R16G16B16_USCALED [float=3] {[u16; 3]},
|
||||
R16G16B16Sscaled => FORMAT_R16G16B16_SSCALED [float=3] {[i16; 3]},
|
||||
R16G16B16Uint => FORMAT_R16G16B16_UINT [uint=3] {[u16; 3]},
|
||||
R16G16B16Sint => FORMAT_R16G16B16_SINT [sint=3] {[i16; 3]},
|
||||
R16G16B16Sfloat => FORMAT_R16G16B16_SFLOAT [float=3] {},
|
||||
R16G16B16A16Unorm => FORMAT_R16G16B16A16_UNORM [float=4] {[u16; 4]},
|
||||
R16G16B16A16Snorm => FORMAT_R16G16B16A16_SNORM [float=4] {[i16; 4]},
|
||||
R16G16B16A16Uscaled => FORMAT_R16G16B16A16_USCALED [float=4] {[u16; 4]},
|
||||
R16G16B16A16Sscaled => FORMAT_R16G16B16A16_SSCALED [float=4] {[i16; 4]},
|
||||
R16G16B16A16Uint => FORMAT_R16G16B16A16_UINT [uint=4] {[u16; 4]},
|
||||
R16G16B16A16Sint => FORMAT_R16G16B16A16_SINT [sint=4] {[i16; 4]},
|
||||
R16G16B16A16Sfloat => FORMAT_R16G16B16A16_SFLOAT [float=4] {},
|
||||
R32Uint => FORMAT_R32_UINT [uint=1] {u32},
|
||||
R32Sint => FORMAT_R32_SINT [sint=1] {i32},
|
||||
R32Sfloat => FORMAT_R32_SFLOAT [float=1] {f32},
|
||||
R32G32Uint => FORMAT_R32G32_UINT [uint=2] {[u32; 2]},
|
||||
R32G32Sint => FORMAT_R32G32_SINT [sint=2] {[i32; 2]},
|
||||
R32G32Sfloat => FORMAT_R32G32_SFLOAT [float=2] {[f32; 2]},
|
||||
R32G32B32Uint => FORMAT_R32G32B32_UINT [uint=3] {[u32; 3]},
|
||||
R32G32B32Sint => FORMAT_R32G32B32_SINT [sint=3] {[i32; 3]},
|
||||
R32G32B32Sfloat => FORMAT_R32G32B32_SFLOAT [float=3] {[f32; 3]},
|
||||
R32G32B32A32Uint => FORMAT_R32G32B32A32_UINT [uint=4] {[u32; 4]},
|
||||
R32G32B32A32Sint => FORMAT_R32G32B32A32_SINT [sint=4] {[i32; 4]},
|
||||
R32G32B32A32Sfloat => FORMAT_R32G32B32A32_SFLOAT [float=4] {[f32; 4]},
|
||||
R64Uint => FORMAT_R64_UINT [uint=1] {u64},
|
||||
R64Sint => FORMAT_R64_SINT [sint=1] {i64},
|
||||
R64Sfloat => FORMAT_R64_SFLOAT [float=1] {f64},
|
||||
R64G64Uint => FORMAT_R64G64_UINT [uint=2] {[u64; 2]},
|
||||
R64G64Sint => FORMAT_R64G64_SINT [sint=2] {[i64; 2]},
|
||||
R64G64Sfloat => FORMAT_R64G64_SFLOAT [float=2] {[f64; 2]},
|
||||
R64G64B64Uint => FORMAT_R64G64B64_UINT [uint=3] {[u64; 3]},
|
||||
R64G64B64Sint => FORMAT_R64G64B64_SINT [sint=3] {[i64; 3]},
|
||||
R64G64B64Sfloat => FORMAT_R64G64B64_SFLOAT [float=3] {[f64; 3]},
|
||||
R64G64B64A64Uint => FORMAT_R64G64B64A64_UINT [uint=4] {[u64; 4]},
|
||||
R64G64B64A64Sint => FORMAT_R64G64B64A64_SINT [sint=4] {[i64; 4]},
|
||||
R64G64B64A64Sfloat => FORMAT_R64G64B64A64_SFLOAT [float=4] {[f64; 4]},
|
||||
B10G11R11UfloatPack32 => FORMAT_B10G11R11_UFLOAT_PACK32 [float=3] {u32},
|
||||
E5B9G9R9UfloatPack32 => FORMAT_E5B9G9R9_UFLOAT_PACK32 [float=3] {u32},
|
||||
D16Unorm => FORMAT_D16_UNORM [depth] {},
|
||||
X8_D24UnormPack32 => FORMAT_X8_D24_UNORM_PACK32 [depth] {},
|
||||
D32Sfloat => FORMAT_D32_SFLOAT [depth] {},
|
||||
S8Uint => FORMAT_S8_UINT [stencil] {},
|
||||
D16Unorm_S8Uint => FORMAT_D16_UNORM_S8_UINT [depthstencil] {},
|
||||
D24Unorm_S8Uint => FORMAT_D24_UNORM_S8_UINT [depthstencil] {},
|
||||
D32Sfloat_S8Uint => FORMAT_D32_SFLOAT_S8_UINT [depthstencil] {},
|
||||
BC1_RGBUnormBlock => FORMAT_BC1_RGB_UNORM_BLOCK [compressed=texture_compression_bc] {},
|
||||
BC1_RGBSrgbBlock => FORMAT_BC1_RGB_SRGB_BLOCK [compressed=texture_compression_bc] {},
|
||||
BC1_RGBAUnormBlock => FORMAT_BC1_RGBA_UNORM_BLOCK [compressed=texture_compression_bc] {},
|
||||
BC1_RGBASrgbBlock => FORMAT_BC1_RGBA_SRGB_BLOCK [compressed=texture_compression_bc] {},
|
||||
BC2UnormBlock => FORMAT_BC2_UNORM_BLOCK [compressed=texture_compression_bc] {},
|
||||
BC2SrgbBlock => FORMAT_BC2_SRGB_BLOCK [compressed=texture_compression_bc] {},
|
||||
BC3UnormBlock => FORMAT_BC3_UNORM_BLOCK [compressed=texture_compression_bc] {},
|
||||
BC3SrgbBlock => FORMAT_BC3_SRGB_BLOCK [compressed=texture_compression_bc] {},
|
||||
BC4UnormBlock => FORMAT_BC4_UNORM_BLOCK [compressed=texture_compression_bc] {},
|
||||
BC4SnormBlock => FORMAT_BC4_SNORM_BLOCK [compressed=texture_compression_bc] {},
|
||||
BC5UnormBlock => FORMAT_BC5_UNORM_BLOCK [compressed=texture_compression_bc] {},
|
||||
BC5SnormBlock => FORMAT_BC5_SNORM_BLOCK [compressed=texture_compression_bc] {},
|
||||
BC6HUfloatBlock => FORMAT_BC6H_UFLOAT_BLOCK [compressed=texture_compression_bc] {},
|
||||
BC6HSfloatBlock => FORMAT_BC6H_SFLOAT_BLOCK [compressed=texture_compression_bc] {},
|
||||
BC7UnormBlock => FORMAT_BC7_UNORM_BLOCK [compressed=texture_compression_bc] {},
|
||||
BC7SrgbBlock => FORMAT_BC7_SRGB_BLOCK [compressed=texture_compression_bc] {},
|
||||
ETC2_R8G8B8UnormBlock => FORMAT_ETC2_R8G8B8_UNORM_BLOCK [compressed=texture_compression_etc2] {},
|
||||
ETC2_R8G8B8SrgbBlock => FORMAT_ETC2_R8G8B8_SRGB_BLOCK [compressed=texture_compression_etc2] {},
|
||||
ETC2_R8G8B8A1UnormBlock => FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK [compressed=texture_compression_etc2] {},
|
||||
ETC2_R8G8B8A1SrgbBlock => FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK [compressed=texture_compression_etc2] {},
|
||||
ETC2_R8G8B8A8UnormBlock => FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK [compressed=texture_compression_etc2] {},
|
||||
ETC2_R8G8B8A8SrgbBlock => FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK [compressed=texture_compression_etc2] {},
|
||||
EAC_R11UnormBlock => FORMAT_EAC_R11_UNORM_BLOCK [compressed=texture_compression_etc2] {},
|
||||
EAC_R11SnormBlock => FORMAT_EAC_R11_SNORM_BLOCK [compressed=texture_compression_etc2] {},
|
||||
EAC_R11G11UnormBlock => FORMAT_EAC_R11G11_UNORM_BLOCK [compressed=texture_compression_etc2] {},
|
||||
EAC_R11G11SnormBlock => FORMAT_EAC_R11G11_SNORM_BLOCK [compressed=texture_compression_etc2] {},
|
||||
ASTC_4x4UnormBlock => FORMAT_ASTC_4x4_UNORM_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_4x4SrgbBlock => FORMAT_ASTC_4x4_SRGB_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_5x4UnormBlock => FORMAT_ASTC_5x4_UNORM_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_5x4SrgbBlock => FORMAT_ASTC_5x4_SRGB_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_5x5UnormBlock => FORMAT_ASTC_5x5_UNORM_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_5x5SrgbBlock => FORMAT_ASTC_5x5_SRGB_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_6x5UnormBlock => FORMAT_ASTC_6x5_UNORM_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_6x5SrgbBlock => FORMAT_ASTC_6x5_SRGB_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_6x6UnormBlock => FORMAT_ASTC_6x6_UNORM_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_6x6SrgbBlock => FORMAT_ASTC_6x6_SRGB_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_8x5UnormBlock => FORMAT_ASTC_8x5_UNORM_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_8x5SrgbBlock => FORMAT_ASTC_8x5_SRGB_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_8x6UnormBlock => FORMAT_ASTC_8x6_UNORM_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_8x6SrgbBlock => FORMAT_ASTC_8x6_SRGB_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_8x8UnormBlock => FORMAT_ASTC_8x8_UNORM_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_8x8SrgbBlock => FORMAT_ASTC_8x8_SRGB_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_10x5UnormBlock => FORMAT_ASTC_10x5_UNORM_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_10x5SrgbBlock => FORMAT_ASTC_10x5_SRGB_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_10x6UnormBlock => FORMAT_ASTC_10x6_UNORM_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_10x6SrgbBlock => FORMAT_ASTC_10x6_SRGB_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_10x8UnormBlock => FORMAT_ASTC_10x8_UNORM_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_10x8SrgbBlock => FORMAT_ASTC_10x8_SRGB_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_10x10UnormBlock => FORMAT_ASTC_10x10_UNORM_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_10x10SrgbBlock => FORMAT_ASTC_10x10_SRGB_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_12x10UnormBlock => FORMAT_ASTC_12x10_UNORM_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_12x10SrgbBlock => FORMAT_ASTC_12x10_SRGB_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_12x12UnormBlock => FORMAT_ASTC_12x12_UNORM_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_12x12SrgbBlock => FORMAT_ASTC_12x12_SRGB_BLOCK [compressed=texture_compression_astc_ldr] {},
|
||||
R4G4UnormPack8 => FORMAT_R4G4_UNORM_PACK8 [Some(1)] [float=2] {u8},
|
||||
R4G4B4A4UnormPack16 => FORMAT_R4G4B4A4_UNORM_PACK16 [Some(2)] [float=4] {u16},
|
||||
B4G4R4A4UnormPack16 => FORMAT_B4G4R4A4_UNORM_PACK16 [Some(2)] [float=4] {u16},
|
||||
R5G6B5UnormPack16 => FORMAT_R5G6B5_UNORM_PACK16 [Some(2)] [float=3] {u16},
|
||||
B5G6R5UnormPack16 => FORMAT_B5G6R5_UNORM_PACK16 [Some(2)] [float=3] {u16},
|
||||
R5G5B5A1UnormPack16 => FORMAT_R5G5B5A1_UNORM_PACK16 [Some(2)] [float=4] {u16},
|
||||
B5G5R5A1UnormPack16 => FORMAT_B5G5R5A1_UNORM_PACK16 [Some(2)] [float=4] {u16},
|
||||
A1R5G5B5UnormPack16 => FORMAT_A1R5G5B5_UNORM_PACK16 [Some(2)] [float=4] {u16},
|
||||
R8Unorm => FORMAT_R8_UNORM [Some(1)] [float=1] {u8},
|
||||
R8Snorm => FORMAT_R8_SNORM [Some(1)] [float=1] {i8},
|
||||
R8Uscaled => FORMAT_R8_USCALED [Some(1)] [float=1] {u8},
|
||||
R8Sscaled => FORMAT_R8_SSCALED [Some(1)] [float=1] {i8},
|
||||
R8Uint => FORMAT_R8_UINT [Some(1)] [uint=1] {u8},
|
||||
R8Sint => FORMAT_R8_SINT [Some(1)] [sint=1] {i8},
|
||||
R8Srgb => FORMAT_R8_SRGB [Some(1)] [float=1] {u8},
|
||||
R8G8Unorm => FORMAT_R8G8_UNORM [Some(2)] [float=2] {[u8; 2]},
|
||||
R8G8Snorm => FORMAT_R8G8_SNORM [Some(2)] [float=2] {[i8; 2]},
|
||||
R8G8Uscaled => FORMAT_R8G8_USCALED [Some(2)] [float=2] {[u8; 2]},
|
||||
R8G8Sscaled => FORMAT_R8G8_SSCALED [Some(2)] [float=2] {[i8; 2]},
|
||||
R8G8Uint => FORMAT_R8G8_UINT [Some(2)] [uint=2] {[u8; 2]},
|
||||
R8G8Sint => FORMAT_R8G8_SINT [Some(2)] [sint=2] {[i8; 2]},
|
||||
R8G8Srgb => FORMAT_R8G8_SRGB [Some(2)] [float=2] {[u8; 2]},
|
||||
R8G8B8Unorm => FORMAT_R8G8B8_UNORM [Some(3)] [float=3] {[u8; 3]},
|
||||
R8G8B8Snorm => FORMAT_R8G8B8_SNORM [Some(3)] [float=3] {[i8; 3]},
|
||||
R8G8B8Uscaled => FORMAT_R8G8B8_USCALED [Some(3)] [float=3] {[u8; 3]},
|
||||
R8G8B8Sscaled => FORMAT_R8G8B8_SSCALED [Some(3)] [float=3] {[i8; 3]},
|
||||
R8G8B8Uint => FORMAT_R8G8B8_UINT [Some(3)] [uint=3] {[u8; 3]},
|
||||
R8G8B8Sint => FORMAT_R8G8B8_SINT [Some(3)] [sint=3] {[i8; 3]},
|
||||
R8G8B8Srgb => FORMAT_R8G8B8_SRGB [Some(3)] [float=3] {[u8; 3]},
|
||||
B8G8R8Unorm => FORMAT_B8G8R8_UNORM [Some(3)] [float=3] {[u8; 3]},
|
||||
B8G8R8Snorm => FORMAT_B8G8R8_SNORM [Some(3)] [float=3] {[i8; 3]},
|
||||
B8G8R8Uscaled => FORMAT_B8G8R8_USCALED [Some(3)] [float=3] {[u8; 3]},
|
||||
B8G8R8Sscaled => FORMAT_B8G8R8_SSCALED [Some(3)] [float=3] {[i8; 3]},
|
||||
B8G8R8Uint => FORMAT_B8G8R8_UINT [Some(3)] [uint=3] {[u8; 3]},
|
||||
B8G8R8Sint => FORMAT_B8G8R8_SINT [Some(3)] [sint=3] {[i8; 3]},
|
||||
B8G8R8Srgb => FORMAT_B8G8R8_SRGB [Some(3)] [float=3] {[u8; 3]},
|
||||
R8G8B8A8Unorm => FORMAT_R8G8B8A8_UNORM [Some(4)] [float=4] {[u8; 4]},
|
||||
R8G8B8A8Snorm => FORMAT_R8G8B8A8_SNORM [Some(4)] [float=4] {[i8; 4]},
|
||||
R8G8B8A8Uscaled => FORMAT_R8G8B8A8_USCALED [Some(4)] [float=4] {[u8; 4]},
|
||||
R8G8B8A8Sscaled => FORMAT_R8G8B8A8_SSCALED [Some(4)] [float=4] {[i8; 4]},
|
||||
R8G8B8A8Uint => FORMAT_R8G8B8A8_UINT [Some(4)] [uint=4] {[u8; 4]},
|
||||
R8G8B8A8Sint => FORMAT_R8G8B8A8_SINT [Some(4)] [sint=4] {[i8; 4]},
|
||||
R8G8B8A8Srgb => FORMAT_R8G8B8A8_SRGB [Some(4)] [float=4] {[u8; 4]},
|
||||
B8G8R8A8Unorm => FORMAT_B8G8R8A8_UNORM [Some(4)] [float=4] {[u8; 4]},
|
||||
B8G8R8A8Snorm => FORMAT_B8G8R8A8_SNORM [Some(4)] [float=4] {[i8; 4]},
|
||||
B8G8R8A8Uscaled => FORMAT_B8G8R8A8_USCALED [Some(4)] [float=4] {[u8; 4]},
|
||||
B8G8R8A8Sscaled => FORMAT_B8G8R8A8_SSCALED [Some(4)] [float=4] {[i8; 4]},
|
||||
B8G8R8A8Uint => FORMAT_B8G8R8A8_UINT [Some(4)] [uint=4] {[u8; 4]},
|
||||
B8G8R8A8Sint => FORMAT_B8G8R8A8_SINT [Some(4)] [sint=4] {[i8; 4]},
|
||||
B8G8R8A8Srgb => FORMAT_B8G8R8A8_SRGB [Some(4)] [float=4] {[u8; 4]},
|
||||
A8B8G8R8UnormPack32 => FORMAT_A8B8G8R8_UNORM_PACK32 [Some(4)] [float=4] {[u8; 4]},
|
||||
A8B8G8R8SnormPack32 => FORMAT_A8B8G8R8_SNORM_PACK32 [Some(4)] [float=4] {[i8; 4]},
|
||||
A8B8G8R8UscaledPack32 => FORMAT_A8B8G8R8_USCALED_PACK32 [Some(4)] [float=4] {[u8; 4]},
|
||||
A8B8G8R8SscaledPack32 => FORMAT_A8B8G8R8_SSCALED_PACK32 [Some(4)] [float=4] {[i8; 4]},
|
||||
A8B8G8R8UintPack32 => FORMAT_A8B8G8R8_UINT_PACK32 [Some(4)] [uint=4] {[u8; 4]},
|
||||
A8B8G8R8SintPack32 => FORMAT_A8B8G8R8_SINT_PACK32 [Some(4)] [sint=4] {[i8; 4]},
|
||||
A8B8G8R8SrgbPack32 => FORMAT_A8B8G8R8_SRGB_PACK32 [Some(4)] [float=4] {[u8; 4]},
|
||||
A2R10G10B10UnormPack32 => FORMAT_A2R10G10B10_UNORM_PACK32 [Some(4)] [float=4] {u32},
|
||||
A2R10G10B10SnormPack32 => FORMAT_A2R10G10B10_SNORM_PACK32 [Some(4)] [float=4] {u32},
|
||||
A2R10G10B10UscaledPack32 => FORMAT_A2R10G10B10_USCALED_PACK32 [Some(4)] [float=4] {u32},
|
||||
A2R10G10B10SscaledPack32 => FORMAT_A2R10G10B10_SSCALED_PACK32 [Some(4)] [float=4] {u32},
|
||||
A2R10G10B10UintPack32 => FORMAT_A2R10G10B10_UINT_PACK32 [Some(4)] [uint=4] {u32},
|
||||
A2R10G10B10SintPack32 => FORMAT_A2R10G10B10_SINT_PACK32 [Some(4)] [sint=4] {u32},
|
||||
A2B10G10R10UnormPack32 => FORMAT_A2B10G10R10_UNORM_PACK32 [Some(4)] [float=4] {u32},
|
||||
A2B10G10R10SnormPack32 => FORMAT_A2B10G10R10_SNORM_PACK32 [Some(4)] [float=4] {u32},
|
||||
A2B10G10R10UscaledPack32 => FORMAT_A2B10G10R10_USCALED_PACK32 [Some(4)] [float=4] {u32},
|
||||
A2B10G10R10SscaledPack32 => FORMAT_A2B10G10R10_SSCALED_PACK32 [Some(4)] [float=4] {u32},
|
||||
A2B10G10R10UintPack32 => FORMAT_A2B10G10R10_UINT_PACK32 [Some(4)] [uint=4] {u32},
|
||||
A2B10G10R10SintPack32 => FORMAT_A2B10G10R10_SINT_PACK32 [Some(4)] [sint=4] {u32},
|
||||
R16Unorm => FORMAT_R16_UNORM [Some(2)] [float=1] {u16},
|
||||
R16Snorm => FORMAT_R16_SNORM [Some(2)] [float=1] {i16},
|
||||
R16Uscaled => FORMAT_R16_USCALED [Some(2)] [float=1] {u16},
|
||||
R16Sscaled => FORMAT_R16_SSCALED [Some(2)] [float=1] {i16},
|
||||
R16Uint => FORMAT_R16_UINT [Some(2)] [uint=1] {u16},
|
||||
R16Sint => FORMAT_R16_SINT [Some(2)] [sint=1] {i16},
|
||||
R16Sfloat => FORMAT_R16_SFLOAT [Some(2)] [float=1] {},
|
||||
R16G16Unorm => FORMAT_R16G16_UNORM [Some(4)] [float=2] {[u16; 2]},
|
||||
R16G16Snorm => FORMAT_R16G16_SNORM [Some(4)] [float=2] {[i16; 2]},
|
||||
R16G16Uscaled => FORMAT_R16G16_USCALED [Some(4)] [float=2] {[u16; 2]},
|
||||
R16G16Sscaled => FORMAT_R16G16_SSCALED [Some(4)] [float=2] {[i16; 2]},
|
||||
R16G16Uint => FORMAT_R16G16_UINT [Some(4)] [uint=2] {[u16; 2]},
|
||||
R16G16Sint => FORMAT_R16G16_SINT [Some(4)] [sint=2] {[i16; 2]},
|
||||
R16G16Sfloat => FORMAT_R16G16_SFLOAT [Some(4)] [float=2] {},
|
||||
R16G16B16Unorm => FORMAT_R16G16B16_UNORM [Some(6)] [float=3] {[u16; 3]},
|
||||
R16G16B16Snorm => FORMAT_R16G16B16_SNORM [Some(6)] [float=3] {[i16; 3]},
|
||||
R16G16B16Uscaled => FORMAT_R16G16B16_USCALED [Some(6)] [float=3] {[u16; 3]},
|
||||
R16G16B16Sscaled => FORMAT_R16G16B16_SSCALED [Some(6)] [float=3] {[i16; 3]},
|
||||
R16G16B16Uint => FORMAT_R16G16B16_UINT [Some(6)] [uint=3] {[u16; 3]},
|
||||
R16G16B16Sint => FORMAT_R16G16B16_SINT [Some(6)] [sint=3] {[i16; 3]},
|
||||
R16G16B16Sfloat => FORMAT_R16G16B16_SFLOAT [Some(6)] [float=3] {},
|
||||
R16G16B16A16Unorm => FORMAT_R16G16B16A16_UNORM [Some(8)] [float=4] {[u16; 4]},
|
||||
R16G16B16A16Snorm => FORMAT_R16G16B16A16_SNORM [Some(8)] [float=4] {[i16; 4]},
|
||||
R16G16B16A16Uscaled => FORMAT_R16G16B16A16_USCALED [Some(8)] [float=4] {[u16; 4]},
|
||||
R16G16B16A16Sscaled => FORMAT_R16G16B16A16_SSCALED [Some(8)] [float=4] {[i16; 4]},
|
||||
R16G16B16A16Uint => FORMAT_R16G16B16A16_UINT [Some(8)] [uint=4] {[u16; 4]},
|
||||
R16G16B16A16Sint => FORMAT_R16G16B16A16_SINT [Some(8)] [sint=4] {[i16; 4]},
|
||||
R16G16B16A16Sfloat => FORMAT_R16G16B16A16_SFLOAT [Some(8)] [float=4] {},
|
||||
R32Uint => FORMAT_R32_UINT [Some(4)] [uint=1] {u32},
|
||||
R32Sint => FORMAT_R32_SINT [Some(4)] [sint=1] {i32},
|
||||
R32Sfloat => FORMAT_R32_SFLOAT [Some(4)] [float=1] {f32},
|
||||
R32G32Uint => FORMAT_R32G32_UINT [Some(8)] [uint=2] {[u32; 2]},
|
||||
R32G32Sint => FORMAT_R32G32_SINT [Some(8)] [sint=2] {[i32; 2]},
|
||||
R32G32Sfloat => FORMAT_R32G32_SFLOAT [Some(8)] [float=2] {[f32; 2]},
|
||||
R32G32B32Uint => FORMAT_R32G32B32_UINT [Some(12)] [uint=3] {[u32; 3]},
|
||||
R32G32B32Sint => FORMAT_R32G32B32_SINT [Some(12)] [sint=3] {[i32; 3]},
|
||||
R32G32B32Sfloat => FORMAT_R32G32B32_SFLOAT [Some(12)] [float=3] {[f32; 3]},
|
||||
R32G32B32A32Uint => FORMAT_R32G32B32A32_UINT [Some(16)] [uint=4] {[u32; 4]},
|
||||
R32G32B32A32Sint => FORMAT_R32G32B32A32_SINT [Some(16)] [sint=4] {[i32; 4]},
|
||||
R32G32B32A32Sfloat => FORMAT_R32G32B32A32_SFLOAT [Some(16)] [float=4] {[f32; 4]},
|
||||
R64Uint => FORMAT_R64_UINT [Some(8)] [uint=1] {u64},
|
||||
R64Sint => FORMAT_R64_SINT [Some(8)] [sint=1] {i64},
|
||||
R64Sfloat => FORMAT_R64_SFLOAT [Some(8)] [float=1] {f64},
|
||||
R64G64Uint => FORMAT_R64G64_UINT [Some(16)] [uint=2] {[u64; 2]},
|
||||
R64G64Sint => FORMAT_R64G64_SINT [Some(16)] [sint=2] {[i64; 2]},
|
||||
R64G64Sfloat => FORMAT_R64G64_SFLOAT [Some(16)] [float=2] {[f64; 2]},
|
||||
R64G64B64Uint => FORMAT_R64G64B64_UINT [Some(24)] [uint=3] {[u64; 3]},
|
||||
R64G64B64Sint => FORMAT_R64G64B64_SINT [Some(24)] [sint=3] {[i64; 3]},
|
||||
R64G64B64Sfloat => FORMAT_R64G64B64_SFLOAT [Some(24)] [float=3] {[f64; 3]},
|
||||
R64G64B64A64Uint => FORMAT_R64G64B64A64_UINT [Some(32)] [uint=4] {[u64; 4]},
|
||||
R64G64B64A64Sint => FORMAT_R64G64B64A64_SINT [Some(32)] [sint=4] {[i64; 4]},
|
||||
R64G64B64A64Sfloat => FORMAT_R64G64B64A64_SFLOAT [Some(32)] [float=4] {[f64; 4]},
|
||||
B10G11R11UfloatPack32 => FORMAT_B10G11R11_UFLOAT_PACK32 [Some(4)] [float=3] {u32},
|
||||
E5B9G9R9UfloatPack32 => FORMAT_E5B9G9R9_UFLOAT_PACK32 [Some(4)] [float=3] {u32},
|
||||
D16Unorm => FORMAT_D16_UNORM [Some(2)] [depth] {},
|
||||
X8_D24UnormPack32 => FORMAT_X8_D24_UNORM_PACK32 [Some(4)] [depth] {},
|
||||
D32Sfloat => FORMAT_D32_SFLOAT [Some(4)] [depth] {},
|
||||
S8Uint => FORMAT_S8_UINT [Some(1)] [stencil] {},
|
||||
D16Unorm_S8Uint => FORMAT_D16_UNORM_S8_UINT [None] [depthstencil] {},
|
||||
D24Unorm_S8Uint => FORMAT_D24_UNORM_S8_UINT [None] [depthstencil] {},
|
||||
D32Sfloat_S8Uint => FORMAT_D32_SFLOAT_S8_UINT [None] [depthstencil] {},
|
||||
BC1_RGBUnormBlock => FORMAT_BC1_RGB_UNORM_BLOCK [None] [compressed=texture_compression_bc] {},
|
||||
BC1_RGBSrgbBlock => FORMAT_BC1_RGB_SRGB_BLOCK [None] [compressed=texture_compression_bc] {},
|
||||
BC1_RGBAUnormBlock => FORMAT_BC1_RGBA_UNORM_BLOCK [None] [compressed=texture_compression_bc] {},
|
||||
BC1_RGBASrgbBlock => FORMAT_BC1_RGBA_SRGB_BLOCK [None] [compressed=texture_compression_bc] {},
|
||||
BC2UnormBlock => FORMAT_BC2_UNORM_BLOCK [None] [compressed=texture_compression_bc] {},
|
||||
BC2SrgbBlock => FORMAT_BC2_SRGB_BLOCK [None] [compressed=texture_compression_bc] {},
|
||||
BC3UnormBlock => FORMAT_BC3_UNORM_BLOCK [None] [compressed=texture_compression_bc] {},
|
||||
BC3SrgbBlock => FORMAT_BC3_SRGB_BLOCK [None] [compressed=texture_compression_bc] {},
|
||||
BC4UnormBlock => FORMAT_BC4_UNORM_BLOCK [None] [compressed=texture_compression_bc] {},
|
||||
BC4SnormBlock => FORMAT_BC4_SNORM_BLOCK [None] [compressed=texture_compression_bc] {},
|
||||
BC5UnormBlock => FORMAT_BC5_UNORM_BLOCK [None] [compressed=texture_compression_bc] {},
|
||||
BC5SnormBlock => FORMAT_BC5_SNORM_BLOCK [None] [compressed=texture_compression_bc] {},
|
||||
BC6HUfloatBlock => FORMAT_BC6H_UFLOAT_BLOCK [None] [compressed=texture_compression_bc] {},
|
||||
BC6HSfloatBlock => FORMAT_BC6H_SFLOAT_BLOCK [None] [compressed=texture_compression_bc] {},
|
||||
BC7UnormBlock => FORMAT_BC7_UNORM_BLOCK [None] [compressed=texture_compression_bc] {},
|
||||
BC7SrgbBlock => FORMAT_BC7_SRGB_BLOCK [None] [compressed=texture_compression_bc] {},
|
||||
ETC2_R8G8B8UnormBlock => FORMAT_ETC2_R8G8B8_UNORM_BLOCK [None] [compressed=texture_compression_etc2] {},
|
||||
ETC2_R8G8B8SrgbBlock => FORMAT_ETC2_R8G8B8_SRGB_BLOCK [None] [compressed=texture_compression_etc2] {},
|
||||
ETC2_R8G8B8A1UnormBlock => FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK [None] [compressed=texture_compression_etc2] {},
|
||||
ETC2_R8G8B8A1SrgbBlock => FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK [None] [compressed=texture_compression_etc2] {},
|
||||
ETC2_R8G8B8A8UnormBlock => FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK [None] [compressed=texture_compression_etc2] {},
|
||||
ETC2_R8G8B8A8SrgbBlock => FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK [None] [compressed=texture_compression_etc2] {},
|
||||
EAC_R11UnormBlock => FORMAT_EAC_R11_UNORM_BLOCK [None] [compressed=texture_compression_etc2] {},
|
||||
EAC_R11SnormBlock => FORMAT_EAC_R11_SNORM_BLOCK [None] [compressed=texture_compression_etc2] {},
|
||||
EAC_R11G11UnormBlock => FORMAT_EAC_R11G11_UNORM_BLOCK [None] [compressed=texture_compression_etc2] {},
|
||||
EAC_R11G11SnormBlock => FORMAT_EAC_R11G11_SNORM_BLOCK [None] [compressed=texture_compression_etc2] {},
|
||||
ASTC_4x4UnormBlock => FORMAT_ASTC_4x4_UNORM_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_4x4SrgbBlock => FORMAT_ASTC_4x4_SRGB_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_5x4UnormBlock => FORMAT_ASTC_5x4_UNORM_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_5x4SrgbBlock => FORMAT_ASTC_5x4_SRGB_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_5x5UnormBlock => FORMAT_ASTC_5x5_UNORM_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_5x5SrgbBlock => FORMAT_ASTC_5x5_SRGB_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_6x5UnormBlock => FORMAT_ASTC_6x5_UNORM_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_6x5SrgbBlock => FORMAT_ASTC_6x5_SRGB_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_6x6UnormBlock => FORMAT_ASTC_6x6_UNORM_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_6x6SrgbBlock => FORMAT_ASTC_6x6_SRGB_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_8x5UnormBlock => FORMAT_ASTC_8x5_UNORM_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_8x5SrgbBlock => FORMAT_ASTC_8x5_SRGB_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_8x6UnormBlock => FORMAT_ASTC_8x6_UNORM_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_8x6SrgbBlock => FORMAT_ASTC_8x6_SRGB_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_8x8UnormBlock => FORMAT_ASTC_8x8_UNORM_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_8x8SrgbBlock => FORMAT_ASTC_8x8_SRGB_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_10x5UnormBlock => FORMAT_ASTC_10x5_UNORM_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_10x5SrgbBlock => FORMAT_ASTC_10x5_SRGB_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_10x6UnormBlock => FORMAT_ASTC_10x6_UNORM_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_10x6SrgbBlock => FORMAT_ASTC_10x6_SRGB_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_10x8UnormBlock => FORMAT_ASTC_10x8_UNORM_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_10x8SrgbBlock => FORMAT_ASTC_10x8_SRGB_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_10x10UnormBlock => FORMAT_ASTC_10x10_UNORM_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_10x10SrgbBlock => FORMAT_ASTC_10x10_SRGB_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_12x10UnormBlock => FORMAT_ASTC_12x10_UNORM_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_12x10SrgbBlock => FORMAT_ASTC_12x10_SRGB_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_12x12UnormBlock => FORMAT_ASTC_12x12_UNORM_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
ASTC_12x12SrgbBlock => FORMAT_ASTC_12x12_SRGB_BLOCK [None] [compressed=texture_compression_astc_ldr] {},
|
||||
}
|
||||
|
||||
pub unsafe trait FormatDesc {
|
||||
|
@ -90,7 +90,7 @@ pub struct GraphicsPipeline<VertexDefinition, Layout, RenderP> {
|
||||
}
|
||||
|
||||
impl<Vdef, L, Rp> GraphicsPipeline<Vdef, L, Rp>
|
||||
where Vdef: VertexDefinition, L: PipelineLayout, Rp: RenderPass + RenderPassDesc
|
||||
where L: PipelineLayout, Rp: RenderPass + RenderPassDesc
|
||||
{
|
||||
/// Builds a new graphics pipeline object.
|
||||
#[inline]
|
||||
@ -99,7 +99,8 @@ impl<Vdef, L, Rp> GraphicsPipeline<Vdef, L, Rp>
|
||||
params: GraphicsPipelineParams<'a, Vdef, Vsp, Vi, Vl, (), (), (), (), Fs, Fo, Fl,
|
||||
L, Rp>)
|
||||
-> Result<Arc<GraphicsPipeline<Vdef, L, Rp>>, GraphicsPipelineCreationError>
|
||||
where L: PipelineLayout + PipelineLayoutSuperset<Vl> + PipelineLayoutSuperset<Fl>,
|
||||
where Vdef: VertexDefinition<Vi>,
|
||||
L: PipelineLayout + PipelineLayoutSuperset<Vl> + PipelineLayoutSuperset<Fl>,
|
||||
Vl: PipelineLayoutDesc, Fl: PipelineLayoutDesc
|
||||
{
|
||||
GraphicsPipeline::new_inner::<_, _, _, (), (), (), (), _, _, _>(device, params)
|
||||
@ -111,7 +112,8 @@ impl<Vdef, L, Rp> GraphicsPipeline<Vdef, L, Rp>
|
||||
(device: &Arc<Device>,
|
||||
params: GraphicsPipelineParams<'a, Vdef, Vsp, Vi, Vl, Gsp, Gi, Go, Gl, Fs, Fo, Fl, L, Rp>)
|
||||
-> Result<Arc<GraphicsPipeline<Vdef, L, Rp>>, GraphicsPipelineCreationError>
|
||||
where L: PipelineLayout + PipelineLayoutSuperset<Vl> + PipelineLayoutSuperset<Fl>,
|
||||
where Vdef: VertexDefinition<Vi>,
|
||||
L: PipelineLayout + PipelineLayoutSuperset<Vl> + PipelineLayoutSuperset<Fl>,
|
||||
Vl: PipelineLayoutDesc, Fl: PipelineLayoutDesc
|
||||
{
|
||||
GraphicsPipeline::new_inner(device, params)
|
||||
@ -121,7 +123,8 @@ impl<Vdef, L, Rp> GraphicsPipeline<Vdef, L, Rp>
|
||||
(device: &Arc<Device>,
|
||||
params: GraphicsPipelineParams<'a, Vdef, Vsp, Vi, Vl, Gsp, Gi, Go, Gl, Fs, Fo, Fl, L, Rp>)
|
||||
-> Result<Arc<GraphicsPipeline<Vdef, L, Rp>>, GraphicsPipelineCreationError>
|
||||
where L: PipelineLayout + PipelineLayoutSuperset<Vl> + PipelineLayoutSuperset<Fl>,
|
||||
where Vdef: VertexDefinition<Vi>,
|
||||
L: PipelineLayout + PipelineLayoutSuperset<Vl> + PipelineLayoutSuperset<Fl>,
|
||||
Vl: PipelineLayoutDesc, Fl: PipelineLayoutDesc
|
||||
{
|
||||
let vk = device.pointers();
|
||||
@ -177,12 +180,14 @@ impl<Vdef, L, Rp> GraphicsPipeline<Vdef, L, Rp>
|
||||
};
|
||||
|
||||
// Vertex bindings.
|
||||
let binding_descriptions = {
|
||||
let (binding_descriptions, attribute_descriptions) = {
|
||||
let (buffers_iter, attribs_iter) = params.vertex_input.definition(params.vertex_shader.input_definition());
|
||||
|
||||
let mut binding_descriptions = SmallVec::<[_; 8]>::new();
|
||||
for (num, (stride, rate)) in params.vertex_input.buffers().enumerate() {
|
||||
for (num, stride, rate) in buffers_iter {
|
||||
if stride > device.physical_device().limits().max_vertex_input_binding_stride() as usize {
|
||||
return Err(GraphicsPipelineCreationError::MaxVertexInputBindingStrideExceeded {
|
||||
binding: num,
|
||||
binding: num as usize,
|
||||
max: device.physical_device().limits().max_vertex_input_binding_stride() as usize,
|
||||
obtained: stride,
|
||||
});
|
||||
@ -195,7 +200,28 @@ impl<Vdef, L, Rp> GraphicsPipeline<Vdef, L, Rp>
|
||||
});
|
||||
}
|
||||
|
||||
binding_descriptions
|
||||
let mut attribute_descriptions = SmallVec::<[_; 8]>::new();
|
||||
for (loc, binding, info) in attribs_iter {
|
||||
// TODO: check attribute format support
|
||||
|
||||
if info.offset > device.physical_device().limits().max_vertex_input_attribute_offset() as usize {
|
||||
return Err(GraphicsPipelineCreationError::MaxVertexInputAttributeOffsetExceeded {
|
||||
max: device.physical_device().limits().max_vertex_input_attribute_offset() as usize,
|
||||
obtained: info.offset,
|
||||
});
|
||||
}
|
||||
|
||||
debug_assert!(binding_descriptions.iter().find(|b| b.binding == binding).is_some());
|
||||
|
||||
attribute_descriptions.push(vk::VertexInputAttributeDescription {
|
||||
location: loc as u32,
|
||||
binding: binding as u32,
|
||||
format: info.format as u32,
|
||||
offset: info.offset as u32,
|
||||
});
|
||||
}
|
||||
|
||||
(binding_descriptions, attribute_descriptions)
|
||||
};
|
||||
|
||||
if binding_descriptions.len() > device.physical_device().limits()
|
||||
@ -207,41 +233,6 @@ impl<Vdef, L, Rp> GraphicsPipeline<Vdef, L, Rp>
|
||||
});
|
||||
}
|
||||
|
||||
// Vertex attributes.
|
||||
// TODO: check vertex attribute formats somewhere (match and support)?
|
||||
let attribute_descriptions = {
|
||||
let mut attribute_descriptions = SmallVec::<[_; 8]>::new();
|
||||
|
||||
for &(loc, ref name) in params.vertex_shader.attributes().iter() {
|
||||
let (binding, info) = match params.vertex_input.attrib(name) {
|
||||
Some(i) => i,
|
||||
None => return Err(GraphicsPipelineCreationError::MissingVertexAttribute {
|
||||
name: name.clone().into_owned()
|
||||
})
|
||||
};
|
||||
|
||||
// TODO: check attribute format support
|
||||
|
||||
if info.offset > device.physical_device().limits().max_vertex_input_attribute_offset() as usize {
|
||||
return Err(GraphicsPipelineCreationError::MaxVertexInputAttributeOffsetExceeded {
|
||||
max: device.physical_device().limits().max_vertex_input_attribute_offset() as usize,
|
||||
obtained: info.offset,
|
||||
});
|
||||
}
|
||||
|
||||
debug_assert!(binding < params.vertex_input.buffers().len());
|
||||
|
||||
attribute_descriptions.push(vk::VertexInputAttributeDescription {
|
||||
location: loc as u32,
|
||||
binding: binding as u32,
|
||||
format: info.format as u32,
|
||||
offset: info.offset as u32,
|
||||
});
|
||||
}
|
||||
|
||||
attribute_descriptions
|
||||
};
|
||||
|
||||
if attribute_descriptions.len() > device.physical_device().limits()
|
||||
.max_vertex_input_attributes() as usize
|
||||
{
|
||||
@ -631,9 +622,7 @@ impl<Vdef, L, Rp> GraphicsPipeline<Vdef, L, Rp>
|
||||
}
|
||||
}
|
||||
|
||||
impl<Mv, L, Rp> GraphicsPipeline<Mv, L, Rp>
|
||||
where Mv: VertexDefinition
|
||||
{
|
||||
impl<Mv, L, Rp> GraphicsPipeline<Mv, L, Rp> {
|
||||
/// Returns the vertex definition used in the constructor.
|
||||
#[inline]
|
||||
pub fn vertex_definition(&self) -> &Mv {
|
||||
|
@ -10,10 +10,13 @@
|
||||
use std::borrow::Cow;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use std::ops::Range;
|
||||
use std::ptr;
|
||||
use std::sync::Arc;
|
||||
use std::ffi::CStr;
|
||||
use std::vec::IntoIter as VecIntoIter;
|
||||
|
||||
use format::Format;
|
||||
use pipeline::input_assembly::PrimitiveTopology;
|
||||
|
||||
use device::Device;
|
||||
@ -70,14 +73,14 @@ impl ShaderModule {
|
||||
}
|
||||
|
||||
pub unsafe fn vertex_shader_entry_point<'a, S, V, L>(&'a self, name: &'a CStr, layout: L,
|
||||
attributes: Vec<(u32, Cow<'static, str>)>)
|
||||
vertex_input: V)
|
||||
-> VertexShaderEntryPoint<'a, S, V, L>
|
||||
{
|
||||
VertexShaderEntryPoint {
|
||||
module: self,
|
||||
name: name,
|
||||
vertex_input: vertex_input,
|
||||
layout: layout,
|
||||
attributes: attributes,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
@ -174,9 +177,9 @@ impl Drop for ShaderModule {
|
||||
pub struct VertexShaderEntryPoint<'a, S, V, L> {
|
||||
module: &'a ShaderModule,
|
||||
name: &'a CStr,
|
||||
attributes: Vec<(u32, Cow<'static, str>)>,
|
||||
vertex_input: V,
|
||||
layout: L,
|
||||
marker: PhantomData<(S, V)>,
|
||||
marker: PhantomData<S>,
|
||||
}
|
||||
|
||||
impl<'a, S, V, L> VertexShaderEntryPoint<'a, S, V, L> {
|
||||
@ -195,10 +198,9 @@ impl<'a, S, V, L> VertexShaderEntryPoint<'a, S, V, L> {
|
||||
&self.layout
|
||||
}
|
||||
|
||||
// TODO: change API
|
||||
#[inline]
|
||||
pub fn attributes(&self) -> &[(u32, Cow<'static, str>)] {
|
||||
&self.attributes
|
||||
pub fn input_definition(&self) -> &V {
|
||||
&self.vertex_input
|
||||
}
|
||||
}
|
||||
|
||||
@ -363,13 +365,83 @@ impl<'a, S, L> ComputeShaderEntryPoint<'a, S, L> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Structs that contain the definition of an interface between two shader stages, or between
|
||||
/// the outside and a shader stage.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// - Must only provide one entry per location.
|
||||
/// - The format must not be larger than 128 bits.
|
||||
///
|
||||
pub unsafe trait ShaderInterfaceDef {
|
||||
/// Iterator returned by `elements`.
|
||||
type Iter: ExactSizeIterator<Item = ShaderInterfaceDefEntry>;
|
||||
|
||||
/// Iterates over the elements of the interface.
|
||||
fn elements(&self) -> Self::Iter;
|
||||
}
|
||||
|
||||
pub unsafe trait PossibleMatchShaderInterface<I>: ShaderInterfaceDef where I: ShaderInterfaceDef {
|
||||
// FIXME: temporary ; remove as it is unsafe
|
||||
unsafe impl ShaderInterfaceDef for Vec<ShaderInterfaceDefEntry> {
|
||||
type Iter = VecIntoIter<ShaderInterfaceDefEntry>;
|
||||
|
||||
#[inline]
|
||||
fn elements(&self) -> Self::Iter {
|
||||
self.clone().into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
/// Entry of a shader interface definition.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ShaderInterfaceDefEntry {
|
||||
/// Range of locations covered by the element.
|
||||
pub location: Range<u32>,
|
||||
/// Format of a each location of the element.
|
||||
pub format: Format,
|
||||
/// Name of the element, or `None` if the name is unknown.
|
||||
pub name: Option<Cow<'static, str>>,
|
||||
}
|
||||
|
||||
/// Extension trait for `ShaderInterfaceDef` that specifies that the interface is potentially
|
||||
/// compatible with another one.
|
||||
pub unsafe trait ShaderInterfaceDefMatch<I>: ShaderInterfaceDef where I: ShaderInterfaceDef {
|
||||
/// Returns true if the two definitions match.
|
||||
// TODO: return a descriptive error instead
|
||||
fn matches(&self, other: &I) -> bool;
|
||||
}
|
||||
|
||||
// TODO: turn this into a default impl that can be specialized
|
||||
unsafe impl<T, I> ShaderInterfaceDefMatch<I> for T
|
||||
where T: ShaderInterfaceDef, I: ShaderInterfaceDef
|
||||
{
|
||||
fn matches(&self, other: &I) -> bool {
|
||||
if self.elements().len() != other.elements().len() {
|
||||
return false;
|
||||
}
|
||||
|
||||
for a in self.elements() {
|
||||
for loc in a.location.clone() {
|
||||
let b = match other.elements().find(|e| loc >= e.location.start && loc < e.location.end) {
|
||||
None => return false,
|
||||
Some(b) => b,
|
||||
};
|
||||
|
||||
if a.format != b.format {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: enforce this?
|
||||
/*match (a.name, b.name) {
|
||||
(Some(ref an), Some(ref bn)) => if an != bn { return false },
|
||||
_ => ()
|
||||
};*/
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait to describe structs that contain specialization data for shaders.
|
||||
///
|
||||
/// It is implemented on `()` for shaders that don't have any specialization constant.
|
||||
|
@ -8,25 +8,30 @@
|
||||
// according to those terms.
|
||||
|
||||
//! # Vertex sources definition
|
||||
//!
|
||||
//!
|
||||
//! When you create a graphics pipeline object, you need to pass an object which indicates the
|
||||
//! layout of the vertex buffer(s) that will serve as input for the vertex shader. This is done
|
||||
//! by passing an implementation of the `Definition` trait.
|
||||
//!
|
||||
//!
|
||||
//! In addition to this, the object that you pass when you create the graphics pipeline must also
|
||||
//! implement the `Source` trait. This trait has a template parameter which corresponds to the
|
||||
//! list of vertex buffers.
|
||||
//!
|
||||
//! The vulkano library provides some structs that already implement these traits.
|
||||
//! The most common situation is a single vertex buffer and no instancing, in which case you can
|
||||
//! pass a `SingleBufferDefinition` when you create the pipeline.
|
||||
//!
|
||||
//!
|
||||
//! # Implementing `Vertex`
|
||||
//!
|
||||
//!
|
||||
//! The implementations of the `Definition` trait that are provided by vulkano (like
|
||||
//! `SingleBufferDefinition`) require you to use a buffer whose content is `[V]` where `V`
|
||||
//! implements the `Vertex` trait.
|
||||
//!
|
||||
//!
|
||||
//! The `Vertex` trait is unsafe, but can be implemented on a struct with the `impl_vertex!`
|
||||
//! macro.
|
||||
//!
|
||||
//!
|
||||
//! # Example
|
||||
//!
|
||||
//!
|
||||
//! ```ignore // TODO:
|
||||
//! # #[macro_use] extern crate vulkano
|
||||
//! # fn main() {
|
||||
@ -67,6 +72,7 @@ use std::vec::IntoIter as VecIntoIter;
|
||||
use buffer::Buffer;
|
||||
use buffer::TypedBuffer;
|
||||
use format::Format;
|
||||
use pipeline::shader::ShaderInterfaceDef;
|
||||
use vk;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
@ -78,39 +84,74 @@ pub enum InputRate {
|
||||
|
||||
/// Describes an individual `Vertex`. In other words a collection of attributes that can be read
|
||||
/// from a vertex shader.
|
||||
///
|
||||
/// At this stage, the vertex is in a "raw" format. For example a `[f32; 4]` can match both a
|
||||
/// `vec4` or a `float[4]`. The way the things are binded depends on the shader.
|
||||
pub unsafe trait Vertex: 'static + Send + Sync {
|
||||
/// Returns the characteristics of a vertex attribute.
|
||||
fn attrib(name: &str) -> Option<AttributeInfo>;
|
||||
/// Returns the characteristics of a vertex member by its name.
|
||||
fn member(name: &str) -> Option<VertexMemberInfo>;
|
||||
}
|
||||
|
||||
/// Information about a member of a vertex struct.
|
||||
pub struct VertexMemberInfo {
|
||||
/// Offset of the member in bytes from the start of the struct.
|
||||
pub offset: usize,
|
||||
/// Type of data. This is used to check that the interface is matching.
|
||||
pub ty: VertexMemberTy,
|
||||
/// Number of consecutive elements of that type.
|
||||
pub array_size: usize,
|
||||
}
|
||||
|
||||
/// Type of a member of a vertex struct.
|
||||
pub enum VertexMemberTy {
|
||||
I8,
|
||||
U8,
|
||||
I16,
|
||||
U16,
|
||||
I32,
|
||||
U32,
|
||||
F32,
|
||||
F64,
|
||||
}
|
||||
|
||||
impl VertexMemberTy {
|
||||
/// Returns true if a combination of `(type, array_size)` matches a format.
|
||||
#[inline]
|
||||
pub fn matches(&self, array_size: usize, format: Format) -> bool {
|
||||
true // FIXME:
|
||||
}
|
||||
}
|
||||
|
||||
/// Information about a single attribute within a vertex.
|
||||
/// TODO: change that API
|
||||
pub struct AttributeInfo {
|
||||
/// Number of bytes between the start of a vertex and the location of attribute.
|
||||
pub offset: usize,
|
||||
/// Data type of the attribute.
|
||||
/// VertexMember type of the attribute.
|
||||
pub format: Format,
|
||||
}
|
||||
|
||||
/// Trait for types that contain a definition of the vertex input used by a graphics pipeline.
|
||||
pub unsafe trait Definition: 'static + Send + Sync {
|
||||
/// Iterator used to enumerate the list of buffers.
|
||||
type InfoIter: ExactSizeIterator<Item = (usize, InputRate)>;
|
||||
/// Trait for types that describe the definition of the vertex input used by a graphics pipeline.
|
||||
pub unsafe trait Definition<I>: 'static + Send + Sync {
|
||||
/// Iterator that returns the offset, the stride (in bytes) and input rate of each buffer.
|
||||
type BuffersIter: ExactSizeIterator<Item = (u32, usize, InputRate)>;
|
||||
/// Iterator that returns the attribute location, buffer id, and infos.
|
||||
type AttribsIter: ExactSizeIterator<Item = (u32, u32, AttributeInfo)>;
|
||||
|
||||
/// Returns information about an attribute, and the index of the buffer (within the iterator
|
||||
/// returned by `buffers`) in which the attribute is found.
|
||||
fn attrib(&self, name: &str) -> Option<(usize, AttributeInfo)>;
|
||||
|
||||
/// Produces an iterator that returns the stride (in bytes) and input rate of each buffer.
|
||||
fn buffers(&self) -> Self::InfoIter;
|
||||
/// Builds the vertex definition to use to link this definition to a vertex shader's input
|
||||
/// interface.
|
||||
// TODO: return error if problem
|
||||
fn definition(&self, interface: &I) -> (Self::BuffersIter, Self::AttribsIter);
|
||||
}
|
||||
|
||||
/// Extension for `Definition` trait. The `L` parameter is an acceptable vertex source for this
|
||||
/// Extension trait of `Definition`. The `L` parameter is an acceptable vertex source for this
|
||||
/// vertex definition.
|
||||
pub unsafe trait Source<L>: Definition {
|
||||
pub unsafe trait Source<L>: 'static + Send + Sync {
|
||||
/// Iterator used by `decode`.
|
||||
type Iter: ExactSizeIterator<Item = Arc<Buffer>>;
|
||||
|
||||
/// Checks and returns the list of buffers, number of vertices and number of instances.
|
||||
// TODO: return error if problem
|
||||
fn decode(&self, L) -> (Self::Iter, usize, usize);
|
||||
}
|
||||
|
||||
@ -122,17 +163,30 @@ impl<T> SingleBufferDefinition<T> {
|
||||
pub fn new() -> SingleBufferDefinition<T> { SingleBufferDefinition(PhantomData) }
|
||||
}
|
||||
|
||||
unsafe impl<T> Definition for SingleBufferDefinition<T> where T: Vertex {
|
||||
type InfoIter = OptionIntoIter<(usize, InputRate)>;
|
||||
unsafe impl<T, I> Definition<I> for SingleBufferDefinition<T>
|
||||
where T: Vertex, I: ShaderInterfaceDef
|
||||
{
|
||||
type BuffersIter = OptionIntoIter<(u32, usize, InputRate)>;
|
||||
type AttribsIter = VecIntoIter<(u32, u32, AttributeInfo)>;
|
||||
|
||||
#[inline]
|
||||
fn attrib(&self, name: &str) -> Option<(usize, AttributeInfo)> {
|
||||
<T as Vertex>::attrib(name).map(|info| (0, info))
|
||||
}
|
||||
fn definition(&self, interface: &I) -> (Self::BuffersIter, Self::AttribsIter) {
|
||||
let attrib = {
|
||||
let mut attribs = Vec::with_capacity(interface.elements().len());
|
||||
for e in interface.elements() {
|
||||
let infos = <T as Vertex>::member(e.name.as_ref().unwrap()).expect("missing vertex attrib");
|
||||
assert!(infos.ty.matches(infos.array_size, e.format));
|
||||
|
||||
#[inline]
|
||||
fn buffers(&self) -> Self::InfoIter {
|
||||
Some((mem::size_of::<T>(), InputRate::Vertex)).into_iter()
|
||||
let mut offset = infos.offset;
|
||||
for loc in e.location.clone() {
|
||||
attribs.push((loc, 0, AttributeInfo { offset: offset, format: e.format }));
|
||||
offset += e.format.size().unwrap();
|
||||
}
|
||||
}
|
||||
attribs
|
||||
}.into_iter(); // TODO: meh
|
||||
|
||||
let buffers = Some((0, mem::size_of::<T>(), InputRate::Vertex)).into_iter();
|
||||
(buffers, attrib)
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,26 +211,40 @@ impl<T, U> TwoBuffersDefinition<T, U> {
|
||||
pub fn new() -> TwoBuffersDefinition<T, U> { TwoBuffersDefinition(PhantomData) }
|
||||
}
|
||||
|
||||
unsafe impl<T, U> Definition for TwoBuffersDefinition<T, U> where T: Vertex, U: Vertex {
|
||||
type InfoIter = VecIntoIter<(usize, InputRate)>;
|
||||
unsafe impl<T, U, I> Definition<I> for TwoBuffersDefinition<T, U>
|
||||
where T: Vertex, U: Vertex, I: ShaderInterfaceDef
|
||||
{
|
||||
type BuffersIter = VecIntoIter<(u32, usize, InputRate)>;
|
||||
type AttribsIter = VecIntoIter<(u32, u32, AttributeInfo)>;
|
||||
|
||||
#[inline]
|
||||
fn attrib(&self, name: &str) -> Option<(usize, AttributeInfo)> {
|
||||
if let Some(a) = <T as Vertex>::attrib(name) {
|
||||
Some((0, a))
|
||||
} else if let Some(a) = <U as Vertex>::attrib(name) {
|
||||
Some((1, a))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn definition(&self, interface: &I) -> (Self::BuffersIter, Self::AttribsIter) {
|
||||
let attrib = {
|
||||
let mut attribs = Vec::with_capacity(interface.elements().len());
|
||||
for e in interface.elements() {
|
||||
let (infos, buf_offset) = if let Some(infos) = <T as Vertex>::member(e.name.as_ref().unwrap()) {
|
||||
(infos, 0)
|
||||
} else if let Some(infos) = <U as Vertex>::member(e.name.as_ref().unwrap()) {
|
||||
(infos, 1)
|
||||
} else {
|
||||
panic!("missing vertex attrib")
|
||||
};
|
||||
assert!(infos.ty.matches(infos.array_size, e.format));
|
||||
|
||||
#[inline]
|
||||
fn buffers(&self) -> Self::InfoIter {
|
||||
vec![
|
||||
(mem::size_of::<T>(), InputRate::Vertex),
|
||||
(mem::size_of::<U>(), InputRate::Vertex)
|
||||
].into_iter()
|
||||
let mut offset = infos.offset;
|
||||
for loc in e.location.clone() {
|
||||
attribs.push((loc, buf_offset, AttributeInfo { offset: offset, format: e.format }));
|
||||
offset += e.format.size().unwrap();
|
||||
}
|
||||
}
|
||||
attribs
|
||||
}.into_iter(); // TODO: meh
|
||||
|
||||
let buffers = vec![
|
||||
(0, mem::size_of::<T>(), InputRate::Vertex),
|
||||
(1, mem::size_of::<U>(), InputRate::Vertex)
|
||||
].into_iter();
|
||||
|
||||
(buffers, attrib)
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,26 +272,40 @@ impl<T, U> OneVertexOneInstanceDefinition<T, U> {
|
||||
pub fn new() -> OneVertexOneInstanceDefinition<T, U> { OneVertexOneInstanceDefinition(PhantomData) }
|
||||
}
|
||||
|
||||
unsafe impl<T, U> Definition for OneVertexOneInstanceDefinition<T, U> where T: Vertex, U: Vertex {
|
||||
type InfoIter = VecIntoIter<(usize, InputRate)>;
|
||||
unsafe impl<T, U, I> Definition<I> for OneVertexOneInstanceDefinition<T, U>
|
||||
where T: Vertex, U: Vertex, I: ShaderInterfaceDef
|
||||
{
|
||||
type BuffersIter = VecIntoIter<(u32, usize, InputRate)>;
|
||||
type AttribsIter = VecIntoIter<(u32, u32, AttributeInfo)>;
|
||||
|
||||
#[inline]
|
||||
fn attrib(&self, name: &str) -> Option<(usize, AttributeInfo)> {
|
||||
if let Some(a) = <T as Vertex>::attrib(name) {
|
||||
Some((0, a))
|
||||
} else if let Some(a) = <U as Vertex>::attrib(name) {
|
||||
Some((1, a))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn definition(&self, interface: &I) -> (Self::BuffersIter, Self::AttribsIter) {
|
||||
let attrib = {
|
||||
let mut attribs = Vec::with_capacity(interface.elements().len());
|
||||
for e in interface.elements() {
|
||||
let (infos, buf_offset) = if let Some(infos) = <T as Vertex>::member(e.name.as_ref().unwrap()) {
|
||||
(infos, 0)
|
||||
} else if let Some(infos) = <U as Vertex>::member(e.name.as_ref().unwrap()) {
|
||||
(infos, 1)
|
||||
} else {
|
||||
panic!("missing vertex attrib")
|
||||
};
|
||||
assert!(infos.ty.matches(infos.array_size, e.format));
|
||||
|
||||
#[inline]
|
||||
fn buffers(&self) -> Self::InfoIter {
|
||||
vec![
|
||||
(mem::size_of::<T>(), InputRate::Vertex),
|
||||
(mem::size_of::<U>(), InputRate::Instance)
|
||||
].into_iter()
|
||||
let mut offset = infos.offset;
|
||||
for loc in e.location.clone() {
|
||||
attribs.push((loc, buf_offset, AttributeInfo { offset: offset, format: e.format }));
|
||||
offset += e.format.size().unwrap();
|
||||
}
|
||||
}
|
||||
attribs
|
||||
}.into_iter(); // TODO: meh
|
||||
|
||||
let buffers = vec![
|
||||
(0, mem::size_of::<T>(), InputRate::Vertex),
|
||||
(1, mem::size_of::<U>(), InputRate::Instance)
|
||||
].into_iter();
|
||||
|
||||
(buffers, attrib)
|
||||
}
|
||||
}
|
||||
|
||||
@ -249,21 +331,30 @@ macro_rules! impl_vertex {
|
||||
($out:ident $(, $member:ident)*) => (
|
||||
unsafe impl $crate::pipeline::vertex::Vertex for $out {
|
||||
#[inline(always)]
|
||||
fn attrib(name: &str) -> Option<$crate::pipeline::vertex::AttributeInfo> {
|
||||
fn member(name: &str) -> Option<$crate::pipeline::vertex::VertexMemberInfo> {
|
||||
use $crate::format::Format;
|
||||
use $crate::pipeline::vertex::VertexMemberInfo;
|
||||
use $crate::pipeline::vertex::VertexMemberTy;
|
||||
use $crate::pipeline::vertex::VertexMember;
|
||||
|
||||
$(
|
||||
if name == stringify!($member) {
|
||||
return Some($crate::pipeline::vertex::AttributeInfo {
|
||||
let (ty, array_size) = unsafe {
|
||||
#[inline] fn f<T: VertexMember>(_: &T) -> (VertexMemberTy, usize)
|
||||
{ T::format() }
|
||||
let dummy = 0usize as *const $out;
|
||||
f(&(&*dummy).$member)
|
||||
};
|
||||
|
||||
return Some(VertexMemberInfo {
|
||||
offset: unsafe {
|
||||
let dummy = 0usize as *const $out;
|
||||
let member = (&(&*dummy).$member) as *const _;
|
||||
member as usize
|
||||
},
|
||||
|
||||
format: unsafe {
|
||||
#[inline] fn f<T: $crate::pipeline::vertex::Data>(_: &T) -> $crate::format::Format { T::format() }
|
||||
let dummy = 0usize as *const $out;
|
||||
f(&(&*dummy).$member)
|
||||
},
|
||||
ty: ty,
|
||||
array_size: array_size,
|
||||
});
|
||||
}
|
||||
)*
|
||||
@ -274,134 +365,97 @@ macro_rules! impl_vertex {
|
||||
)
|
||||
}
|
||||
|
||||
/// Trait for data types that can be used as vertex attributes. Used by the `impl_vertex!` macro.
|
||||
pub unsafe trait Data {
|
||||
/// Returns the format of the attribute.
|
||||
fn format() -> Format;
|
||||
/// Trait for data types that can be used as vertex members. Used by the `impl_vertex!` macro.
|
||||
pub unsafe trait VertexMember {
|
||||
/// Returns the format and array size of the member.
|
||||
fn format() -> (VertexMemberTy, usize);
|
||||
}
|
||||
|
||||
unsafe impl Data for f32 {
|
||||
unsafe impl VertexMember for i8 {
|
||||
#[inline]
|
||||
fn format() -> Format {
|
||||
Format::R32Sfloat
|
||||
fn format() -> (VertexMemberTy, usize) {
|
||||
(VertexMemberTy::I8, 1)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Data for [f32; 1] {
|
||||
unsafe impl VertexMember for u8 {
|
||||
#[inline]
|
||||
fn format() -> Format {
|
||||
Format::R32Sfloat
|
||||
fn format() -> (VertexMemberTy, usize) {
|
||||
(VertexMemberTy::U8, 1)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Data for [f32; 2] {
|
||||
unsafe impl VertexMember for i16 {
|
||||
#[inline]
|
||||
fn format() -> Format {
|
||||
Format::R32G32Sfloat
|
||||
fn format() -> (VertexMemberTy, usize) {
|
||||
(VertexMemberTy::I16, 1)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Data for [f32; 3] {
|
||||
unsafe impl VertexMember for u16 {
|
||||
#[inline]
|
||||
fn format() -> Format {
|
||||
Format::R32G32B32Sfloat
|
||||
fn format() -> (VertexMemberTy, usize) {
|
||||
(VertexMemberTy::U16, 1)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Data for [f32; 4] {
|
||||
unsafe impl VertexMember for i32 {
|
||||
#[inline]
|
||||
fn format() -> Format {
|
||||
Format::R32G32B32A32Sfloat
|
||||
fn format() -> (VertexMemberTy, usize) {
|
||||
(VertexMemberTy::I32, 1)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Data for (f32,) {
|
||||
unsafe impl VertexMember for u32 {
|
||||
#[inline]
|
||||
fn format() -> Format {
|
||||
Format::R32Sfloat
|
||||
fn format() -> (VertexMemberTy, usize) {
|
||||
(VertexMemberTy::U32, 1)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Data for (f32, f32) {
|
||||
unsafe impl VertexMember for f32 {
|
||||
#[inline]
|
||||
fn format() -> Format {
|
||||
Format::R32G32Sfloat
|
||||
fn format() -> (VertexMemberTy, usize) {
|
||||
(VertexMemberTy::F32, 1)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Data for (f32, f32, f32) {
|
||||
unsafe impl VertexMember for f64 {
|
||||
#[inline]
|
||||
fn format() -> Format {
|
||||
Format::R32G32B32Sfloat
|
||||
fn format() -> (VertexMemberTy, usize) {
|
||||
(VertexMemberTy::F64, 1)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Data for (f32, f32, f32, f32) {
|
||||
#[inline]
|
||||
fn format() -> Format {
|
||||
Format::R32G32B32A32Sfloat
|
||||
}
|
||||
macro_rules! impl_vm_array {
|
||||
($sz:expr) => (
|
||||
unsafe impl<T> VertexMember for [T; $sz]
|
||||
where T: VertexMember
|
||||
{
|
||||
#[inline]
|
||||
fn format() -> (VertexMemberTy, usize) {
|
||||
let (ty, sz) = <T as VertexMember>::format();
|
||||
(ty, sz * $sz)
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
unsafe impl Data for u32 {
|
||||
#[inline]
|
||||
fn format() -> Format {
|
||||
Format::R32Uint
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Data for [u32; 1] {
|
||||
#[inline]
|
||||
fn format() -> Format {
|
||||
Format::R32Uint
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Data for [u32; 2] {
|
||||
#[inline]
|
||||
fn format() -> Format {
|
||||
Format::R32G32Uint
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Data for [u32; 3] {
|
||||
#[inline]
|
||||
fn format() -> Format {
|
||||
Format::R32G32B32Uint
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Data for [u32; 4] {
|
||||
#[inline]
|
||||
fn format() -> Format {
|
||||
Format::R32G32B32A32Uint
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Data for (u32,) {
|
||||
#[inline]
|
||||
fn format() -> Format {
|
||||
Format::R32Uint
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Data for (u32, u32) {
|
||||
#[inline]
|
||||
fn format() -> Format {
|
||||
Format::R32G32Uint
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Data for (u32, u32, u32) {
|
||||
#[inline]
|
||||
fn format() -> Format {
|
||||
Format::R32G32B32Uint
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Data for (u32, u32, u32, u32) {
|
||||
#[inline]
|
||||
fn format() -> Format {
|
||||
Format::R32G32B32A32Uint
|
||||
}
|
||||
}
|
||||
impl_vm_array!(1);
|
||||
impl_vm_array!(2);
|
||||
impl_vm_array!(3);
|
||||
impl_vm_array!(4);
|
||||
impl_vm_array!(5);
|
||||
impl_vm_array!(6);
|
||||
impl_vm_array!(7);
|
||||
impl_vm_array!(8);
|
||||
impl_vm_array!(9);
|
||||
impl_vm_array!(10);
|
||||
impl_vm_array!(11);
|
||||
impl_vm_array!(12);
|
||||
impl_vm_array!(13);
|
||||
impl_vm_array!(14);
|
||||
impl_vm_array!(15);
|
||||
impl_vm_array!(16);
|
||||
impl_vm_array!(32);
|
||||
impl_vm_array!(64);
|
||||
|
Loading…
Reference in New Issue
Block a user