use std::mem::size_of;
-use crate::{flags_def, fourcc, FourCC};
+use crate::{FourCC, flags_def, fourcc};
const DDS_FOURCC: FourCC = fourcc!("DDS ");
const DX10_FOURCC: FourCC = fourcc!("DX10");
pub fn release(mut self) -> Release<T> {
#[cold]
#[inline(never)]
- unsafe fn release_slow<T>(ptr: NonNull<Inner<T>>) -> T { unsafe {
- // Ref-counting operations imply a full memory barrier on x86, but not in general. So
- // insert an acquire barrier on the slow path to ensure all modifications to inner are
- // visible before we call drop.
- std::sync::atomic::fence(Ordering::Acquire);
-
- // SAFETY: Was created by Box::leak in the constructor, so it's valid to recreate a box.
- let mut inner = Box::from_raw(ptr.as_ptr());
- // extract the value from the container so we can return it.
- let value = ManuallyDrop::take(&mut inner.value);
- // since the contained value is wrapped in `ManuallyDrop` it won't be dropped here.
- drop(inner);
-
- value
- }}
+ unsafe fn release_slow<T>(ptr: NonNull<Inner<T>>) -> T {
+ unsafe {
+ // Ref-counting operations imply a full memory barrier on x86, but not in general. So
+ // insert an acquire barrier on the slow path to ensure all modifications to inner are
+ // visible before we call drop.
+ std::sync::atomic::fence(Ordering::Acquire);
+
+ // SAFETY: Was created by Box::leak in the constructor, so it's valid to recreate a box.
+ let mut inner = Box::from_raw(ptr.as_ptr());
+ // extract the value from the container so we can return it.
+ let value = ManuallyDrop::take(&mut inner.value);
+ // since the contained value is wrapped in `ManuallyDrop` it won't be dropped here.
+ drop(inner);
+
+ value
+ }
+ }
// SAFETY: `release` consumes `self` so it's impossible to call twice on the same instance,
// release is also the only function able to invalidate the pointer. Hence the pointer is
sync::atomic::{AtomicI32, Ordering},
};
-use crate::{waiter, PhantomUnsend};
+use crate::{PhantomUnsend, waiter};
#[cfg(debug_assertions)]
#[inline(always)]
use std::{marker::PhantomData, mem::size_of, ptr::NonNull};
use crate::{
- align_offset, mod_inverse_u32, static_assert, virtual_commit, virtual_free, virtual_reserve,
- Widen,
+ Widen, align_offset, mod_inverse_u32, static_assert, virtual_commit, virtual_free,
+ virtual_reserve,
};
/// Each handle uses `GEN_BITS` bits of per-slot generation counter. Looking up
mod tests {
use std::sync::atomic::{AtomicU32, Ordering};
- use super::{Handle, Pool, MAX_CAP};
+ use super::{Handle, MAX_CAP, Pool};
#[test]
fn lookup_null() {
-use crate::{mul_full_width_u64, Widen};
+use crate::{Widen, mul_full_width_u64};
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct Pcg64 {
/// dereferenced for the duration of the returned borrow. This is trivially the
/// case if no such pointers exist, for example immediately after [`Arc::new`].
#[inline]
- pub unsafe fn get_mut_unchecked(&mut self) -> &mut T { unsafe {
- // We are careful to *not* create a reference covering the "count" fields, as
- // this would alias with concurrent access to the reference counts.
- &mut (*self.ptr.as_ptr()).value
- }}
+ pub unsafe fn get_mut_unchecked(&mut self) -> &mut T {
+ unsafe {
+ // We are careful to *not* create a reference covering the "count" fields, as
+ // this would alias with concurrent access to the reference counts.
+ &mut (*self.ptr.as_ptr()).value
+ }
+ }
#[inline]
fn from_inner(ptr: NonNull<Inner<T>>) -> Self {
/// Any other [`Rc`] or [`Arc`] pointers to the same allocation must not be dereferenced for the duration of the
/// returned borrow. This is trivially the case if no such pointers exist, for example immediately after
/// [`Arc::new`].
- pub unsafe fn get_mut_unchecked(&mut self) -> &mut T { unsafe {
- // We are careful to *not* create a reference covering the "count" fields, as
- // this would alias with concurrent access to the reference counts.
- &mut (*self.ptr.as_ptr()).value
- }}
+ pub unsafe fn get_mut_unchecked(&mut self) -> &mut T {
+ unsafe {
+ // We are careful to *not* create a reference covering the "count" fields, as
+ // this would alias with concurrent access to the reference counts.
+ &mut (*self.ptr.as_ptr()).value
+ }
+ }
fn from_inner(ptr: NonNull<Inner<T>>) -> Self {
Self {
/// Panics if changing page permissions for the range fails.
#[cold]
#[inline(never)]
-pub unsafe fn virtual_commit(ptr: *mut std::ffi::c_void, size: usize) { unsafe {
- let result = libc::mprotect(ptr, size, libc::PROT_READ | libc::PROT_WRITE);
- assert!(result == 0);
-}}
+pub unsafe fn virtual_commit(ptr: *mut std::ffi::c_void, size: usize) {
+ unsafe {
+ let result = libc::mprotect(ptr, size, libc::PROT_READ | libc::PROT_WRITE);
+ assert!(result == 0);
+ }
+}
/// Release a reserved or comitted virtual memory range.
///
/// - `size` must be within range of that reservation.
#[cold]
#[inline(never)]
-pub unsafe fn virtual_free(ptr: *mut std::ffi::c_void, size: usize) -> Result<(), MapError> { unsafe {
- let result = libc::munmap(ptr, size);
- if result != 0 {
- Err(MapError::MapFailed)
- } else {
- Ok(())
+pub unsafe fn virtual_free(ptr: *mut std::ffi::c_void, size: usize) -> Result<(), MapError> {
+ unsafe {
+ let result = libc::munmap(ptr, size);
+ if result != 0 {
+ Err(MapError::MapFailed)
+ } else {
+ Ok(())
+ }
}
-}}
+}
/// Turn ptr into a slice
#[inline]
- unsafe fn buffer_as_slice(&self) -> &[T] { unsafe {
- slice::from_raw_parts(self.ptr(), self.cap())
- }}
+ unsafe fn buffer_as_slice(&self) -> &[T] {
+ unsafe { slice::from_raw_parts(self.ptr(), self.cap()) }
+ }
/// Turn ptr into a mut slice
#[inline]
- unsafe fn buffer_as_mut_slice(&mut self) -> &mut [T] { unsafe {
- slice::from_raw_parts_mut(self.ptr(), self.cap())
- }}
+ unsafe fn buffer_as_mut_slice(&mut self) -> &mut [T] {
+ unsafe { slice::from_raw_parts_mut(self.ptr(), self.cap()) }
+ }
/// Moves an element out of the buffer
#[inline]
- unsafe fn buffer_read(&mut self, off: usize) -> T { unsafe {
- ptr::read(self.ptr().add(off))
- }}
+ unsafe fn buffer_read(&mut self, off: usize) -> T {
+ unsafe { ptr::read(self.ptr().add(off)) }
+ }
/// Writes an element into the buffer, moving it.
#[inline]
- unsafe fn buffer_write(&mut self, off: usize, value: T) { unsafe {
- ptr::write(self.ptr().add(off), value);
- }}
+ unsafe fn buffer_write(&mut self, off: usize, value: T) {
+ unsafe {
+ ptr::write(self.ptr().add(off), value);
+ }
+ }
pub fn len(&self) -> usize {
count(self.tail, self.head, self.cap())
/// Copies a contiguous block of memory len long from src to dst
#[inline]
- unsafe fn copy(&self, dst: usize, src: usize, len: usize) { unsafe {
- debug_assert!(
- dst + len <= self.cap(),
- "cpy dst={} src={} len={} cap={}",
- dst,
- src,
- len,
- self.cap()
- );
- debug_assert!(
- src + len <= self.cap(),
- "cpy dst={} src={} len={} cap={}",
- dst,
- src,
- len,
- self.cap()
- );
- ptr::copy(self.ptr().add(src), self.ptr().add(dst), len);
- }}
+ unsafe fn copy(&self, dst: usize, src: usize, len: usize) {
+ unsafe {
+ debug_assert!(
+ dst + len <= self.cap(),
+ "cpy dst={} src={} len={} cap={}",
+ dst,
+ src,
+ len,
+ self.cap()
+ );
+ debug_assert!(
+ src + len <= self.cap(),
+ "cpy dst={} src={} len={} cap={}",
+ dst,
+ src,
+ len,
+ self.cap()
+ );
+ ptr::copy(self.ptr().add(src), self.ptr().add(dst), len);
+ }
+ }
/// Copies a contiguous block of memory len long from src to dst
#[inline]
- unsafe fn copy_nonoverlapping(&self, dst: usize, src: usize, len: usize) { unsafe {
- debug_assert!(
- dst + len <= self.cap(),
- "cno dst={} src={} len={} cap={}",
- dst,
- src,
- len,
- self.cap()
- );
- debug_assert!(
- src + len <= self.cap(),
- "cno dst={} src={} len={} cap={}",
- dst,
- src,
- len,
- self.cap()
- );
- ptr::copy_nonoverlapping(self.ptr().add(src), self.ptr().add(dst), len);
- }}
+ unsafe fn copy_nonoverlapping(&self, dst: usize, src: usize, len: usize) {
+ unsafe {
+ debug_assert!(
+ dst + len <= self.cap(),
+ "cno dst={} src={} len={} cap={}",
+ dst,
+ src,
+ len,
+ self.cap()
+ );
+ debug_assert!(
+ src + len <= self.cap(),
+ "cno dst={} src={} len={} cap={}",
+ dst,
+ src,
+ len,
+ self.cap()
+ );
+ ptr::copy_nonoverlapping(self.ptr().add(src), self.ptr().add(dst), len);
+ }
+ }
/// Frobs the head and tail sections around to handle the fact that we
/// just reallocated. Unsafe because it trusts old_capacity.
#[inline]
- unsafe fn handle_capacity_increase(&mut self, old_capacity: usize) { unsafe {
- let new_capacity = self.cap();
-
- // Move the shortest contiguous section of the ring buffer
- // T H
- // [o o o o o o o . ]
- // T H
- // A [o o o o o o o . . . . . . . . . ]
- // H T
- // [o o . o o o o o ]
- // T H
- // B [. . . o o o o o o o . . . . . . ]
- // H T
- // [o o o o o . o o ]
- // H T
- // C [o o o o o . . . . . . . . . o o ]
-
- if self.tail <= self.head {
- // A
- // Nop
- } else if self.head < old_capacity - self.tail {
- // B
- self.copy_nonoverlapping(old_capacity, 0, self.head);
- self.head += old_capacity;
- debug_assert!(self.head > self.tail);
- } else {
- // C
- let new_tail = new_capacity - (old_capacity - self.tail);
- self.copy_nonoverlapping(new_tail, self.tail, old_capacity - self.tail);
- self.tail = new_tail;
- debug_assert!(self.head < self.tail);
- }
- debug_assert!(self.head < self.cap());
- debug_assert!(self.tail < self.cap());
- debug_assert!(self.cap().count_ones() == 1);
- }}
+ unsafe fn handle_capacity_increase(&mut self, old_capacity: usize) {
+ unsafe {
+ let new_capacity = self.cap();
+
+ // Move the shortest contiguous section of the ring buffer
+ // T H
+ // [o o o o o o o . ]
+ // T H
+ // A [o o o o o o o . . . . . . . . . ]
+ // H T
+ // [o o . o o o o o ]
+ // T H
+ // B [. . . o o o o o o o . . . . . . ]
+ // H T
+ // [o o o o o . o o ]
+ // H T
+ // C [o o o o o . . . . . . . . . o o ]
+
+ if self.tail <= self.head {
+ // A
+ // Nop
+ } else if self.head < old_capacity - self.tail {
+ // B
+ self.copy_nonoverlapping(old_capacity, 0, self.head);
+ self.head += old_capacity;
+ debug_assert!(self.head > self.tail);
+ } else {
+ // C
+ let new_tail = new_capacity - (old_capacity - self.tail);
+ self.copy_nonoverlapping(new_tail, self.tail, old_capacity - self.tail);
+ self.tail = new_tail;
+ debug_assert!(self.head < self.tail);
+ }
+ debug_assert!(self.head < self.cap());
+ debug_assert!(self.tail < self.cap());
+ debug_assert!(self.cap().count_ones() == 1);
+ }
+ }
pub fn reserve_exact(&mut self, additional: usize) {
self.reserve(additional);
}
#[inline]
- unsafe fn append_elements(&mut self, other: *const [T]) { unsafe {
- let count = (*other).len();
- self.reserve(count);
- let len = self.len();
- ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count);
- self.len += count;
- }}
+ unsafe fn append_elements(&mut self, other: *const [T]) {
+ unsafe {
+ let count = (*other).len();
+ self.reserve(count);
+ let len = self.len();
+ ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count);
+ self.len += count;
+ }
+ }
pub fn clear(&mut self) {
self.truncate(0)
use std::collections::hash_map::Entry;
-use crate::{font::GlyphBitmapBox, FontCollection, GlyphIndex, Oversample, Packer};
+use crate::{FontCollection, GlyphIndex, Oversample, Packer, font::GlyphBitmapBox};
pub use narcissus_core::FiniteF32;
-use narcissus_core::{default, Widen};
+use narcissus_core::{Widen, default};
use rustc_hash::FxHashMap;
use stb_truetype_sys::rectpack::Rect;
sync::atomic::{AtomicU32, AtomicU64, Ordering},
};
-use narcissus_core::{default, BitIter, Mutex, Widen};
+use narcissus_core::{BitIter, Mutex, Widen, default};
use vulkan_sys as vk;
-use crate::{tlsf, vk_check, MemoryLocation};
+use crate::{MemoryLocation, tlsf, vk_check};
-use super::{VulkanDevice, VulkanFrame, VULKAN_CONSTANTS};
+use super::{VULKAN_CONSTANTS, VulkanDevice, VulkanFrame};
type Tlsf = tlsf::Tlsf<VulkanSuperBlockInfo>;
Some((memory, mapped_ptr))
}
- unsafe fn free_super_block(&self, user_data: &VulkanSuperBlockInfo) { unsafe {
- self.device_fn
- .free_memory(self.device, user_data.memory, None);
+ unsafe fn free_super_block(&self, user_data: &VulkanSuperBlockInfo) {
+ unsafe {
+ self.device_fn
+ .free_memory(self.device, user_data.memory, None);
- let memory_type_index = user_data.memory_type_index.widen();
- let memory_heap_index =
- self.physical_device_memory_properties.memory_types[memory_type_index].heap_index;
- let size = self.allocator.tlsf_super_block_size[memory_heap_index.widen()];
+ let memory_type_index = user_data.memory_type_index.widen();
+ let memory_heap_index =
+ self.physical_device_memory_properties.memory_types[memory_type_index].heap_index;
+ let size = self.allocator.tlsf_super_block_size[memory_heap_index.widen()];
- self.allocator.stats.free(memory_heap_index, size);
- }}
+ self.allocator.stats.free(memory_heap_index, size);
+ }
+ }
pub fn allocate_memory(
&self,
};
use narcissus_core::{
- default, is_aligned_to,
+ Arc, Arena, HybridArena, Mutex, PhantomUnsend, Pool, Widen, default, is_aligned_to,
manual_arc::{self, ManualArc},
raw_window::AsRawWindow,
- Arc, Arena, HybridArena, Mutex, PhantomUnsend, Pool, Widen,
};
use physical_device_features::VulkanPhysicalDeviceFeatures;
use vulkan_sys::{self as vk};
use crate::{
- frame_counter::FrameCounter, mapped_buffer::TransientBindGroup, Bind, BindDesc,
- BindGroupLayout, BindingType, Buffer, BufferAddress, BufferArg, BufferDesc, BufferImageCopy,
- BufferUsageFlags, CmdEncoder, ComputePipelineDesc, Device, Extent2d, Extent3d, Frame,
- GlobalBarrier, GpuConcurrent, GraphicsPipelineDesc, Image, ImageBarrier, ImageBlit, ImageDesc,
- ImageDimension, ImageLayout, ImageTiling, ImageViewDesc, IndexType, MemoryLocation, Offset2d,
- Offset3d, PersistentBuffer, Pipeline, PipelineLayout, Sampler, SamplerAddressMode,
+ Bind, BindDesc, BindGroupLayout, BindingType, Buffer, BufferAddress, BufferArg, BufferDesc,
+ BufferImageCopy, BufferUsageFlags, CmdEncoder, ComputePipelineDesc, Device, Extent2d, Extent3d,
+ Frame, GlobalBarrier, GpuConcurrent, GraphicsPipelineDesc, Image, ImageBarrier, ImageBlit,
+ ImageDesc, ImageDimension, ImageLayout, ImageTiling, ImageViewDesc, IndexType, MemoryLocation,
+ Offset2d, Offset3d, PersistentBuffer, Pipeline, PipelineLayout, Sampler, SamplerAddressMode,
SamplerCompareOp, SamplerDesc, SamplerFilter, ShaderStageFlags, SpecConstant,
SwapchainConfigurator, SwapchainImage, SwapchainOutOfDateError, ThreadToken, TransientBuffer,
- TypedBind,
+ TypedBind, frame_counter::FrameCounter, mapped_buffer::TransientBindGroup,
};
mod allocator;
});
if let Some(required_subgroup_size) = pipeline_desc.shader.required_subgroup_size {
- assert!(self
- .physical_device_properties
- .required_subgroup_size_stages()
- .contains(vk::ShaderStageFlags::COMPUTE));
+ assert!(
+ self.physical_device_properties
+ .required_subgroup_size_stages()
+ .contains(vk::ShaderStageFlags::COMPUTE)
+ );
assert!(
required_subgroup_size >= self.physical_device_properties.min_subgroup_size()
&& required_subgroup_size
use std::{
- collections::{hash_map::Entry, HashMap, HashSet},
+ collections::{HashMap, HashSet, hash_map::Entry},
ffi::CStr,
};
use narcissus_core::{
- default,
+ HybridArena, Mutex, Pool, Widen, default,
raw_window::{AsRawWindow, RawWindow},
- HybridArena, Mutex, Pool, Widen,
};
use vulkan_sys as vk;
use crate::{
+ ColorSpace, Frame, Image, ImageFormat, PresentMode, SwapchainConfigurator, SwapchainImage,
+ SwapchainOutOfDateError,
backend::vulkan::{
- from_vulkan_image_usage_flags, vk_vec, vulkan_color_space, vulkan_format,
- vulkan_image_usage_flags, vulkan_present_mode, VulkanImageHolder, VulkanImageSwapchain,
+ VulkanImageHolder, VulkanImageSwapchain, from_vulkan_image_usage_flags, vk_vec,
+ vulkan_color_space, vulkan_format, vulkan_image_usage_flags, vulkan_present_mode,
},
- vk_check, ColorSpace, Frame, Image, ImageFormat, PresentMode, SwapchainConfigurator,
- SwapchainImage, SwapchainOutOfDateError,
+ vk_check,
};
-use super::{VulkanDevice, VulkanFrame, VULKAN_CONSTANTS};
+use super::{VULKAN_CONSTANTS, VulkanDevice, VulkanFrame};
#[derive(Default)]
struct VulkanPresentInfo {
..default()
};
let mut surface = vk::SurfaceKHR::null();
- vk_check!(self
- .wsi
- .xcb_surface_fn
- .as_ref()
- .unwrap()
- .create_xcb_surface(self.instance, &create_info, None, &mut surface));
+ vk_check!(
+ self.wsi
+ .xcb_surface_fn
+ .as_ref()
+ .unwrap()
+ .create_xcb_surface(self.instance, &create_info, None, &mut surface)
+ );
surface
}
RawWindow::Xlib(xlib) => {
..default()
};
let mut surface = vk::SurfaceKHR::null();
- vk_check!(self
- .wsi
- .xlib_surface_fn
- .as_ref()
- .unwrap()
- .create_xlib_surface(self.instance, &create_info, None, &mut surface));
+ vk_check!(
+ self.wsi
+ .xlib_surface_fn
+ .as_ref()
+ .unwrap()
+ .create_xlib_surface(self.instance, &create_info, None, &mut surface)
+ );
surface
}
RawWindow::Wayland(wayland) => {
..default()
};
let mut surface = vk::SurfaceKHR::null();
- vk_check!(self
- .wsi
- .wayland_surface_fn
- .as_ref()
- .unwrap()
- .create_wayland_surface(self.instance, &create_info, None, &mut surface));
+ vk_check!(
+ self.wsi
+ .wayland_surface_fn
+ .as_ref()
+ .unwrap()
+ .create_wayland_surface(
+ self.instance,
+ &create_info,
+ None,
+ &mut surface
+ )
+ );
surface
}
});
assert!(available_present_modes.contains(&present_mode));
assert!((!supported_usage_flags.as_raw() & usage_flags.as_raw()) == 0);
- assert!(supported_surface_formats
- .iter()
- .any(|&supported_format| { supported_format == surface_format }));
+ assert!(
+ supported_surface_formats
+ .iter()
+ .any(|&supported_format| { supported_format == surface_format })
+ );
let present_mode = vulkan_present_mode(present_mode);
let usage_flags = vulkan_image_usage_flags(usage_flags);
use backend::vulkan;
use mapped_buffer::TransientBindGroup;
use narcissus_core::{
- default, flags_def, raw_window::AsRawWindow, thread_token_def, Handle, PhantomUnsend,
+ Handle, PhantomUnsend, default, flags_def, raw_window::AsRawWindow, thread_token_def,
};
mod backend;
/// This function will propagate undefined values from T, for example, padding
/// bytes, so it's vital that no Rust reference to the written memory exists
/// after writing a `T` which contains undefined values.
-unsafe fn copy_from_with_offset<T: ?Sized>(ptr: NonNull<u8>, len: usize, offset: usize, src: &T) { unsafe {
- let size = std::mem::size_of_val(src);
-
- let Some(end) = offset.checked_add(size) else {
- overflow()
- };
-
- if end > len {
- overflow()
+unsafe fn copy_from_with_offset<T: ?Sized>(ptr: NonNull<u8>, len: usize, offset: usize, src: &T) {
+ unsafe {
+ let size = std::mem::size_of_val(src);
+
+ let Some(end) = offset.checked_add(size) else {
+ overflow()
+ };
+
+ if end > len {
+ overflow()
+ }
+
+ // SAFETY:
+ // * Taking a pointer of `T` as bytes is always valid, even when it contains
+ // padding. So long as we never materialize a reference to those undef bytes
+ // and directly copy through the pointer instead.
+ //
+ // * The number of bytes we're reading from src is directly derived from its
+ // size in bytes.
+ //
+ // * We check the length of the buffer is sufficient for `size` plus `offset`
+ // bytes above.
+ //
+ // * `src` and `dst` cannot overlap because it's not possible to make a
+ // reference to the bytes from the transient buffer.
+ let count = size;
+ let src = src as *const _ as *const u8;
+ let src = src.add(offset);
+ let dst = ptr.as_ptr();
+ std::ptr::copy_nonoverlapping(src, dst, count)
}
-
- // SAFETY:
- // * Taking a pointer of `T` as bytes is always valid, even when it contains
- // padding. So long as we never materialize a reference to those undef bytes
- // and directly copy through the pointer instead.
- //
- // * The number of bytes we're reading from src is directly derived from its
- // size in bytes.
- //
- // * We check the length of the buffer is sufficient for `size` plus `offset`
- // bytes above.
- //
- // * `src` and `dst` cannot overlap because it's not possible to make a
- // reference to the bytes from the transient buffer.
- let count = size;
- let src = src as *const _ as *const u8;
- let src = src.add(offset);
- let dst = ptr.as_ptr();
- std::ptr::copy_nonoverlapping(src, dst, count)
-}}
+}
/// Persistent mapped buffer.
///
ops::{Index, IndexMut},
};
-use narcissus_core::{default, linear_log_binning, static_assert, Widen};
+use narcissus_core::{Widen, default, linear_log_binning, static_assert};
// The log2 of the size of the 'linear' bin.
pub const LINEAR_LOG2: u32 = 9; // 2^9 = 512
// handle special cases: severe overflow / underflow
if a.abs() >= 104.0 {
- if a > 0.0 {
- f32::INFINITY
- } else {
- 0.0
- }
+ if a > 0.0 { f32::INFINITY } else { 0.0 }
} else {
r
}
pub use mat3::Mat3;
pub use mat4::Mat4;
pub use perlin::{perlin_noise3, perlin_noise3_wrap, perlin_noise3_wrap_seed};
-pub use point2::{point2, Point2};
-pub use point3::{point3, Point3};
+pub use point2::{Point2, point2};
+pub use point3::{Point3, point3};
pub use quat::Quat;
pub use sin_cos_pi::{cos_pi_f32, sin_cos_pi_f32, sin_pi_f32};
pub use tan_pi::tan_pi_f32;
-pub use vec2::{vec2, Vec2};
-pub use vec3::{vec3, Vec3};
-pub use vec4::{vec4, Vec4};
+pub use vec2::{Vec2, vec2};
+pub use vec3::{Vec3, vec3};
+pub use vec4::{Vec4, vec4};
/// Unit type for an angle expressed in radians.
#[derive(Clone, Copy, PartialEq, PartialOrd, Debug, Default)]
// With avx512 the compiler tends to emit masked moves anyway, so don't bother being clever.
#[cfg(any(target_feature = "avx512f", not(target_feature = "sse4.1")))]
{
- if t {
- y
- } else {
- x
- }
+ if t { y } else { x }
}
#[cfg(all(target_feature = "sse4.1", not(target_feature = "avx512f")))]
-use crate::{sin_cos_pi_f32, HalfTurn, Point2, Point3, Vec2, Vec3};
+use crate::{HalfTurn, Point2, Point3, Vec2, Vec3, sin_cos_pi_f32};
/// 3x3 matrix.
#[derive(Clone, Copy, PartialEq)]
-use crate::{sin_cos_pi_f32, tan_pi_f32, HalfTurn, Point2, Point3, Vec2, Vec3, Vec4};
+use crate::{HalfTurn, Point2, Point3, Vec2, Vec3, Vec4, sin_cos_pi_f32, tan_pi_f32};
/// 4x4 matrix.
///
// SAFETY: Requires SSE2.
#[inline]
#[target_feature(enable = "sse2")]
- unsafe fn transpose_sse2(self) -> Mat4 { unsafe {
- use std::arch::x86_64::_MM_TRANSPOSE4_PS;
- let [mut row0, mut row1, mut row2, mut row3] = self.as_m128_array();
- _MM_TRANSPOSE4_PS(&mut row0, &mut row1, &mut row2, &mut row3);
- Mat4::from_m128_array([row0, row1, row2, row3])
- }}
+ unsafe fn transpose_sse2(self) -> Mat4 {
+ unsafe {
+ use std::arch::x86_64::_MM_TRANSPOSE4_PS;
+ let [mut row0, mut row1, mut row2, mut row3] = self.as_m128_array();
+ _MM_TRANSPOSE4_PS(&mut row0, &mut row1, &mut row2, &mut row3);
+ Mat4::from_m128_array([row0, row1, row2, row3])
+ }
+ }
/// Returns the transpose of `self`.
#[must_use]
#[allow(dead_code)]
#[inline]
#[target_feature(enable = "sse4.1")]
- unsafe fn transform_vec4_sse41(&self, vec: Vec4) -> Vec4 { unsafe {
- use std::arch::x86_64::{_mm_hadd_ps, _mm_mul_ps};
+ unsafe fn transform_vec4_sse41(&self, vec: Vec4) -> Vec4 {
+ unsafe {
+ use std::arch::x86_64::{_mm_hadd_ps, _mm_mul_ps};
- let vec = vec.into();
- let rows = self.as_m128_array();
+ let vec = vec.into();
+ let rows = self.as_m128_array();
- let values = _mm_hadd_ps(
- _mm_hadd_ps(_mm_mul_ps(rows[0], vec), _mm_mul_ps(rows[1], vec)),
- _mm_hadd_ps(_mm_mul_ps(rows[2], vec), _mm_mul_ps(rows[3], vec)),
- );
+ let values = _mm_hadd_ps(
+ _mm_hadd_ps(_mm_mul_ps(rows[0], vec), _mm_mul_ps(rows[1], vec)),
+ _mm_hadd_ps(_mm_mul_ps(rows[2], vec), _mm_mul_ps(rows[3], vec)),
+ );
- values.into()
- }}
+ values.into()
+ }
+ }
/// Transforms the given [`Vec4`] `vec` by `self`.
#[must_use]
#[allow(dead_code)]
#[inline]
#[target_feature(enable = "avx2")]
-unsafe fn mul_mat4_avx2(lhs: Mat4, rhs: Mat4) -> Mat4 { unsafe {
- use std::arch::x86_64::{
- __m128, __m256, _mm256_add_ps, _mm256_broadcast_ps, _mm256_loadu_ps, _mm256_mul_ps,
- _mm256_shuffle_ps, _mm256_storeu_ps, _mm256_zeroupper,
- };
+unsafe fn mul_mat4_avx2(lhs: Mat4, rhs: Mat4) -> Mat4 {
+ unsafe {
+ use std::arch::x86_64::{
+ __m128, __m256, _mm256_add_ps, _mm256_broadcast_ps, _mm256_loadu_ps, _mm256_mul_ps,
+ _mm256_shuffle_ps, _mm256_storeu_ps, _mm256_zeroupper,
+ };
+
+ #[inline(always)]
+ unsafe fn two_linear_combine(a: __m256, m: &[__m128; 4]) -> __m256 {
+ unsafe {
+ let m0 = _mm256_broadcast_ps(&m[0]);
+ let m1 = _mm256_broadcast_ps(&m[1]);
+ let m2 = _mm256_broadcast_ps(&m[2]);
+ let m3 = _mm256_broadcast_ps(&m[3]);
+ let r = _mm256_mul_ps(_mm256_shuffle_ps(a, a, 0x00), m0);
+ let r = _mm256_add_ps(r, _mm256_mul_ps(_mm256_shuffle_ps(a, a, 0x55), m1));
+ let r = _mm256_add_ps(r, _mm256_mul_ps(_mm256_shuffle_ps(a, a, 0xaa), m2));
+ _mm256_add_ps(r, _mm256_mul_ps(_mm256_shuffle_ps(a, a, 0xff), m3))
+ }
+ }
- #[inline(always)]
- unsafe fn two_linear_combine(a: __m256, m: &[__m128; 4]) -> __m256 { unsafe {
- let m0 = _mm256_broadcast_ps(&m[0]);
- let m1 = _mm256_broadcast_ps(&m[1]);
- let m2 = _mm256_broadcast_ps(&m[2]);
- let m3 = _mm256_broadcast_ps(&m[3]);
- let r = _mm256_mul_ps(_mm256_shuffle_ps(a, a, 0x00), m0);
- let r = _mm256_add_ps(r, _mm256_mul_ps(_mm256_shuffle_ps(a, a, 0x55), m1));
- let r = _mm256_add_ps(r, _mm256_mul_ps(_mm256_shuffle_ps(a, a, 0xaa), m2));
- _mm256_add_ps(r, _mm256_mul_ps(_mm256_shuffle_ps(a, a, 0xff), m3))
- }}
-
- _mm256_zeroupper();
-
- let a0 = _mm256_loadu_ps(&lhs.0[0]);
- let a1 = _mm256_loadu_ps(&lhs.0[8]);
- let rhs = rhs.as_m128_array();
+ _mm256_zeroupper();
- let x0 = two_linear_combine(a0, &rhs);
- let x1 = two_linear_combine(a1, &rhs);
+ let a0 = _mm256_loadu_ps(&lhs.0[0]);
+ let a1 = _mm256_loadu_ps(&lhs.0[8]);
+ let rhs = rhs.as_m128_array();
- let mut result = Mat4::IDENTITY;
- _mm256_storeu_ps(&mut result.0[0], x0);
- _mm256_storeu_ps(&mut result.0[8], x1);
- result
-}}
+ let x0 = two_linear_combine(a0, &rhs);
+ let x1 = two_linear_combine(a1, &rhs);
+
+ let mut result = Mat4::IDENTITY;
+ _mm256_storeu_ps(&mut result.0[0], x0);
+ _mm256_storeu_ps(&mut result.0[8], x1);
+ result
+ }
+}
impl std::ops::Mul for Mat4 {
type Output = Mat4;
-use crate::{impl_affine, impl_shared, Vec2};
+use crate::{Vec2, impl_affine, impl_shared};
/// Type representing a point in a 2d affine space.
#[derive(Clone, Copy, PartialEq, PartialOrd, Default, Debug)]
-use crate::{impl_affine, impl_shared, Vec3};
+use crate::{Vec3, impl_affine, impl_shared};
/// Type representing a point in a 3d affine space.
#[derive(Clone, Copy, PartialEq, PartialOrd, Default, Debug)]
-use crate::{sin_cos_pi_f32, HalfTurn, Vec3};
+use crate::{HalfTurn, Vec3, sin_cos_pi_f32};
#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(C)]
let r = if i & 1 == 1 { 1.0 / -r } else { r };
// Handle integer arguments.
- if a == a.floor() {
- a * e
- } else {
- r
- }
+ if a == a.floor() { a * e } else { r }
}
#[cfg(test)]
-use crate::{impl_shared, impl_vector, Point2};
+use crate::{Point2, impl_shared, impl_vector};
#[derive(Clone, Copy, PartialEq, PartialOrd, Default, Debug)]
#[repr(C)]
-use crate::{impl_shared, impl_vector, Point3};
+use crate::{Point3, impl_shared, impl_vector};
#[derive(Clone, Copy, PartialEq, PartialOrd, Default, Debug)]
#[repr(C)]
use core::ffi::c_int;
use std::{
- ffi::{c_char, c_void, CStr, CString},
+ ffi::{CStr, CString, c_char, c_void},
marker::PhantomData,
num::NonZeroI32,
path::Path,
static SQLITE_GLOBAL_INIT: OnceLock<()> = OnceLock::new();
#[cold]
-unsafe fn initialize() { unsafe {
- let ret = ffi::sqlite3_initialize();
- if ret != sqlite_sys::SQLITE_OK {
- panic!("error initializing sqlite: {:?}", Error::new(ret));
- }
-
- #[cfg(debug_assertions)]
- {
- extern "C" fn log(_user: *mut c_void, _result: c_int, msg: *const c_char) {
- let msg = unsafe { CStr::from_ptr(msg) };
- let msg = msg.to_string_lossy();
- println!("sqlite3: {}", msg);
+unsafe fn initialize() {
+ unsafe {
+ let ret = ffi::sqlite3_initialize();
+ if ret != sqlite_sys::SQLITE_OK {
+ panic!("error initializing sqlite: {:?}", Error::new(ret));
}
- let ret = ffi::sqlite3_config(
- ffi::SQLITE_CONFIG_LOG,
- log as extern "C" fn(*mut c_void, i32, *const i8),
- std::ptr::null_mut::<c_void>(),
- );
- if ret != sqlite_sys::SQLITE_OK {
- panic!("error installing sqlite logger: {:?}", Error::new(ret));
+ #[cfg(debug_assertions)]
+ {
+ extern "C" fn log(_user: *mut c_void, _result: c_int, msg: *const c_char) {
+ let msg = unsafe { CStr::from_ptr(msg) };
+ let msg = msg.to_string_lossy();
+ println!("sqlite3: {}", msg);
+ }
+
+ let ret = ffi::sqlite3_config(
+ ffi::SQLITE_CONFIG_LOG,
+ log as extern "C" fn(*mut c_void, i32, *const i8),
+ std::ptr::null_mut::<c_void>(),
+ );
+ if ret != sqlite_sys::SQLITE_OK {
+ panic!("error installing sqlite logger: {:?}", Error::new(ret));
+ }
}
}
-}}
+}
fn check_initalized() {
SQLITE_GLOBAL_INIT.get_or_init(|| unsafe { initialize() });
-
#[allow(dead_code)]
unsafe extern "C" {
pub fn blake3_compress_in_place_avx512(
pub mod portable;
mod slice;
-use platform::{Platform, MAX_SIMD_DEGREE, MAX_SIMD_DEGREE_OR_2};
+use platform::{MAX_SIMD_DEGREE, MAX_SIMD_DEGREE_OR_2, Platform};
/// The number of bytes in a [`Hash`](struct.Hash.html), 32.
pub const OUT_LEN: usize = 32;
-use crate::{portable, CVWords, IncrementCounter, BLOCK_LEN, OUT_LEN};
+use crate::{BLOCK_LEN, CVWords, IncrementCounter, OUT_LEN, portable};
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
pub const MAX_SIMD_DEGREE: usize = 16;
use crate::{
- counter_high, counter_low, slice, CVBytes, CVWords, IncrementCounter, BLOCK_LEN, IV,
- MSG_SCHEDULE, OUT_LEN,
+ BLOCK_LEN, CVBytes, CVWords, IV, IncrementCounter, MSG_SCHEDULE, OUT_LEN, counter_high,
+ counter_low, slice,
};
#[inline(always)]
-use crate::{slice, CVBytes, CVWords, IncrementCounter, Refs, BLOCK_LEN, CHUNK_LEN, OUT_LEN};
+use crate::{BLOCK_LEN, CHUNK_LEN, CVBytes, CVWords, IncrementCounter, OUT_LEN, Refs, slice};
use rand::prelude::*;
// Interesting input lengths to run tests on.
use std::{
- ffi::{c_void, CStr, CString},
+ ffi::{CStr, CString, c_void},
mem::MaybeUninit,
os::raw::c_char,
};
use std::{
convert::{TryFrom, TryInto},
- ffi::{c_void, CStr},
+ ffi::{CStr, c_void},
marker::PhantomData,
- mem::{transmute, MaybeUninit},
+ mem::{MaybeUninit, transmute},
os::raw::c_char,
};
}
fn vulkan_instance_version_not_supported() {
- panic!("calling an instance function not supported by the version requested in `InstanceFunctions::new`")
+ panic!(
+ "calling an instance function not supported by the version requested in `InstanceFunctions::new`"
+ )
}
fn vulkan_device_version_not_supported() {
- panic!("calling a device function not supported by the version requested in `DeviceFunctions::new`")
+ panic!(
+ "calling a device function not supported by the version requested in `DeviceFunctions::new`"
+ )
}
pub struct GlobalFunctions {
}
impl GlobalFunctions {
- pub unsafe fn new(get_proc_addr: *mut c_void) -> Self { unsafe {
- let get_instance_proc_addr = transmute::<_, FnGetInstanceProcAddr>(get_proc_addr);
- Self {
- get_instance_proc_addr,
- enumerate_instance_version: transmute::<_, _>(get_instance_proc_addr(
- Instance::null(),
- c"vkEnumerateInstanceVersion".as_ptr(),
- )),
- enumerate_instance_extension_properties: transmute::<_, _>(get_instance_proc_addr(
- Instance::null(),
- c"vkEnumerateInstanceExtensionProperties".as_ptr(),
- )),
- enumerate_instance_layer_properties: transmute::<_, _>(get_instance_proc_addr(
- Instance::null(),
- c"vkEnumerateInstanceLayerProperties".as_ptr(),
- )),
- create_instance: transmute::<_, _>(
- get_instance_proc_addr(Instance::null(), c"vkCreateInstance".as_ptr())
- .expect("failed to load vkCreateInstance"),
- ),
+ pub unsafe fn new(get_proc_addr: *mut c_void) -> Self {
+ unsafe {
+ let get_instance_proc_addr = transmute::<_, FnGetInstanceProcAddr>(get_proc_addr);
+ Self {
+ get_instance_proc_addr,
+ enumerate_instance_version: transmute::<_, _>(get_instance_proc_addr(
+ Instance::null(),
+ c"vkEnumerateInstanceVersion".as_ptr(),
+ )),
+ enumerate_instance_extension_properties: transmute::<_, _>(get_instance_proc_addr(
+ Instance::null(),
+ c"vkEnumerateInstanceExtensionProperties".as_ptr(),
+ )),
+ enumerate_instance_layer_properties: transmute::<_, _>(get_instance_proc_addr(
+ Instance::null(),
+ c"vkEnumerateInstanceLayerProperties".as_ptr(),
+ )),
+ create_instance: transmute::<_, _>(
+ get_instance_proc_addr(Instance::null(), c"vkCreateInstance".as_ptr())
+ .expect("failed to load vkCreateInstance"),
+ ),
+ }
}
- }}
+ }
#[inline]
pub unsafe fn get_instance_proc_addr(
use std::f32::consts::SQRT_2;
-use narcissus_core::{box_assume_init, default, random::Pcg64, zeroed_box, BitIter};
-use narcissus_maths::{clamp, perlin_noise3, sin_pi_f32, vec3, Deg, HalfTurn, Mat4, Point3, Vec3};
+use narcissus_core::{BitIter, box_assume_init, default, random::Pcg64, zeroed_box};
+use narcissus_maths::{Deg, HalfTurn, Mat4, Point3, Vec3, clamp, perlin_noise3, sin_pi_f32, vec3};
use crate::spring::simple_spring_damper_exact;
use std::path::Path;
-use narcissus_core::{obj, Widen};
-use narcissus_maths::{vec2, vec3, vec4, Vec2, Vec3};
+use narcissus_core::{Widen, obj};
+use narcissus_maths::{Vec2, Vec3, vec2, vec3, vec4};
use shark_shaders::pipelines::Vertex;
use narcissus_core::random::Pcg64;
use narcissus_gpu::{
- create_device, Access, BufferDesc, BufferUsageFlags, DeviceExt, GlobalBarrier, MemoryLocation,
- ShaderStageFlags, ThreadToken,
+ Access, BufferDesc, BufferUsageFlags, DeviceExt, GlobalBarrier, MemoryLocation,
+ ShaderStageFlags, ThreadToken, create_device,
};
use shark_shaders::pipelines::{
- calcuate_workgroup_count, calculate_spine_size, Pipelines, RadixSortDownsweepConstants,
- RadixSortUpsweepConstants,
+ Pipelines, RadixSortDownsweepConstants, RadixSortUpsweepConstants, calcuate_workgroup_count,
+ calculate_spine_size,
};
fn gpu_sort(values: &mut [u32]) {