mod bind_group_builder;
mod render_pass;
mod render_pipeline_builder;
mod sampler_builder;
mod texture;
#[cfg(feature = "image")]
pub use self::texture::image::{
ImageHolder, ImageReadMapping, WithDeviceQueuePair,
format_from_image_color_type as texture_format_from_image_color_type,
};
pub use self::{
bind_group_builder::{Builder as BindGroupBuilder, LayoutBuilder as BindGroupLayoutBuilder},
render_pass::{
Builder as RenderPassBuilder,
ColorAttachmentDescriptorBuilder as RenderPassColorAttachmentDescriptorBuilder,
},
render_pipeline_builder::RenderPipelineBuilder,
sampler_builder::SamplerBuilder,
texture::{
Builder as TextureBuilder, Texture, TextureId, TextureView, TextureViewId, ToTextureView,
descriptor_eq as texture_descriptor_eq, extent_3d_eq,
format_size_bytes as texture_format_size_bytes, reshaper::Reshaper as TextureReshaper,
row_padded_buffer::RowPaddedBuffer,
},
};
#[doc(inline)]
pub use wgpu::{
Adapter, AdapterInfo, AddressMode, Backend, Backends, BindGroup, BindGroupDescriptor,
BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry,
BindingResource, BindingType, BlendComponent, BlendFactor, BlendOperation, BlendState, Buffer,
BufferAddress, BufferAsyncError, BufferBinding, BufferBindingType, BufferDescriptor,
BufferSize, BufferSlice, BufferUsages, BufferView, BufferViewMut, COPY_BUFFER_ALIGNMENT,
COPY_BYTES_PER_ROW_ALIGNMENT, Color, ColorTargetState, ColorWrites, CommandBuffer,
CommandBufferDescriptor, CommandEncoder, CommandEncoderDescriptor, CompareFunction,
ComputePass, ComputePassDescriptor, ComputePipeline, ComputePipelineDescriptor, DepthBiasState,
DepthStencilState, Device, DeviceDescriptor, DeviceType, DownlevelCapabilities, DownlevelFlags,
DynamicOffset, Error, Extent3d, Face, Features, FilterMode, FragmentState, FrontFace,
ImageSubresourceRange, IndexFormat, Instance, Label, Limits, LoadOp, MAP_ALIGNMENT, MapMode,
MipmapFilterMode, MultisampleState, Operations, Origin3d, PipelineLayout,
PipelineLayoutDescriptor, PipelineStatisticsTypes, PollType, PolygonMode, PowerPreference,
PresentMode, PrimitiveState, PrimitiveTopology, QUERY_RESOLVE_BUFFER_ALIGNMENT,
QUERY_SET_MAX_QUERIES, QUERY_SIZE, QuerySet, QuerySetDescriptor, QueryType, Queue,
RenderBundle, RenderBundleDepthStencil, RenderBundleDescriptor, RenderBundleEncoder,
RenderBundleEncoderDescriptor, RenderPass, RenderPassColorAttachment,
RenderPassDepthStencilAttachment, RenderPassDescriptor, RenderPipeline,
RenderPipelineDescriptor, RequestAdapterOptions, RequestAdapterOptionsBase, RequestDeviceError,
Sampler, SamplerBorderColor, SamplerDescriptor, ShaderLocation, ShaderModel, ShaderModule,
ShaderModuleDescriptor, ShaderSource, ShaderStages, StencilFaceState, StencilOperation,
StencilState, StorageTextureAccess, Surface, SurfaceConfiguration, SurfaceStatus,
SurfaceTexture, TexelCopyBufferInfo, TexelCopyBufferLayout, TexelCopyTextureInfo,
Texture as TextureHandle, TextureAspect, TextureDescriptor, TextureDimension, TextureFormat,
TextureFormatFeatureFlags, TextureFormatFeatures, TextureSampleType, TextureUsages,
TextureView as TextureViewHandle, TextureViewDescriptor, TextureViewDimension,
UncapturedErrorHandler, VERTEX_ALIGNMENT, VertexAttribute, VertexBufferLayout, VertexFormat,
VertexState, VertexStepMode, include_wgsl,
util::{self, BufferInitDescriptor},
vertex_attr_array,
};
use wgpu::{MemoryHints, Trace};
pub const DEFAULT_POWER_PREFERENCE: PowerPreference = PowerPreference::HighPerformance;
pub const DEFAULT_BACKENDS: Backends = Backends::PRIMARY.union(Backends::GL);
#[cfg(feature = "spirv")]
pub fn shader_from_spirv_bytes(device: &wgpu::Device, bytes: &[u8]) -> wgpu::ShaderModule {
let source = util::make_spirv(bytes);
let desc = ShaderModuleDescriptor {
label: Some("nannou_shader_module"),
source,
};
device.create_shader_module(desc)
}
pub fn clear_texture(
texture: &TextureViewHandle,
clear_color: Color,
encoder: &mut CommandEncoder,
) {
RenderPassBuilder::new()
.color_attachment(texture, |builder| {
builder.load_op(LoadOp::Clear(clear_color))
})
.begin(encoder);
}
pub fn default_device_descriptor() -> DeviceDescriptor<'static> {
let required_features = Features::default();
let required_limits = Limits::default();
DeviceDescriptor {
label: Some("nannou_device"),
required_features,
required_limits,
memory_hints: MemoryHints::default(),
trace: Trace::Off,
experimental_features: wgpu::ExperimentalFeatures::disabled(),
}
}
pub fn resolve_texture(
src_texture: &TextureViewHandle,
dst_texture: &TextureViewHandle,
encoder: &mut CommandEncoder,
) {
RenderPassBuilder::new()
.color_attachment(src_texture, |color| {
color
.load_op(LoadOp::Load)
.resolve_target_handle(Some(dst_texture))
})
.begin(encoder);
}
pub fn create_pipeline_layout(
device: &wgpu::Device,
label: Option<&str>,
bind_group_layouts: &[&wgpu::BindGroupLayout],
immediate_size: u32,
) -> wgpu::PipelineLayout {
let bind_group_layouts: Vec<_> = bind_group_layouts.iter().copied().map(Some).collect();
let descriptor = wgpu::PipelineLayoutDescriptor {
label,
bind_group_layouts: &bind_group_layouts,
immediate_size,
};
device.create_pipeline_layout(&descriptor)
}
pub fn sampler_filtering(desc: &SamplerDescriptor) -> bool {
match (desc.mag_filter, desc.min_filter, desc.mipmap_filter) {
(FilterMode::Nearest, FilterMode::Nearest, MipmapFilterMode::Nearest) => false,
_ => true,
}
}
pub fn compute_row_padding(bytes_per_row: u32) -> u32 {
COPY_BYTES_PER_ROW_ALIGNMENT - (bytes_per_row % COPY_BYTES_PER_ROW_ALIGNMENT)
}
pub mod bytes {
pub unsafe fn from_slice<T>(slice: &[T]) -> &[u8]
where
T: Copy + Sized,
{
let len = slice.len() * std::mem::size_of::<T>();
let ptr = slice.as_ptr() as *const u8;
unsafe { std::slice::from_raw_parts(ptr, len) }
}
pub unsafe fn from<T>(t: &T) -> &[u8]
where
T: Copy + Sized,
{
let len = std::mem::size_of::<T>();
let ptr = t as *const T as *const u8;
unsafe { std::slice::from_raw_parts(ptr, len) }
}
pub unsafe fn to_slice<T>(slice: &[u8]) -> &[T]
where
T: Copy + Sized,
{
let size = std::mem::size_of::<T>();
let align = std::mem::align_of::<T>();
assert_eq!(slice.len() % size, 0, "incorrect buffer size");
assert_eq!(
slice.as_ptr() as usize % align,
0,
"incorrect buffer alignment"
);
let len = slice.len() / size;
let ptr = slice.as_ptr() as *const T;
unsafe { std::slice::from_raw_parts(ptr, len) }
}
}