Add include_spv!() macro, donated by Ralith (#26)
This commit is contained in:
parent
994cc9a03c
commit
5795fa7943
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -702,7 +702,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
name = "pixels"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pixels-mocks 0.1.0",
|
||||
|
|
|
@ -11,7 +11,6 @@ categories = ["graphics", "rendering"]
|
|||
license = "MIT"
|
||||
|
||||
[dependencies]
|
||||
byteorder = "1.3"
|
||||
wgpu = { git = "https://github.com/gfx-rs/wgpu-rs", rev = "012d08d64de924da93289c2b51fb06b22d7348cf" }
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -16,14 +16,15 @@ use std::error::Error as StdError;
|
|||
use std::fmt;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub use crate::macros::*;
|
||||
pub use crate::render_pass::{BoxedRenderPass, Device, Queue, RenderPass};
|
||||
use crate::renderers::Renderer;
|
||||
pub use wgpu;
|
||||
use wgpu::{Extent3d, TextureView};
|
||||
|
||||
mod macros;
|
||||
mod render_pass;
|
||||
pub use render_pass::{BoxedRenderPass, Device, Queue, RenderPass};
|
||||
|
||||
mod renderers;
|
||||
use renderers::Renderer;
|
||||
|
||||
type RenderPassFactory = Box<dyn Fn(Device, Queue, &TextureView, &Extent3d) -> BoxedRenderPass>;
|
||||
|
||||
|
|
42
src/macros.rs
Normal file
42
src/macros.rs
Normal file
|
@ -0,0 +1,42 @@
|
|||
//! Provides a macro and type for including SPIR-V shaders in const data.
|
||||
//!
|
||||
//! In an ideal world, a shader will be compiled at build-time directly into the executable. This
|
||||
//! is opposed to the typical method of including a shader, which reads a GLSL source code file
|
||||
//! from the file system at start, compiles it, and sends it to the GPU. That process adds a
|
||||
//! non-trivial amount of time to startup, and additional error handling code at runtime.
|
||||
//!
|
||||
//! This macro moves all of that complexity to build-time. At least for the SPIR-V part of the
|
||||
//! shader pipeline. (`gfx-hal` backends have their own SPIR-V-to-native compilers at runtime.)
|
||||
//!
|
||||
//! Cribbed with permission from Ralith
|
||||
//! See: https://github.com/MaikKlein/ash/pull/245
|
||||
|
||||
/// Include correctly aligned and typed precompiled SPIR-V
|
||||
///
|
||||
/// Does not account for endianness mismatches between the SPIR-V file and the target. See
|
||||
/// [`wgpu::read_spirv`] for a more general solution.
|
||||
#[macro_export]
|
||||
macro_rules! include_spv {
|
||||
($path:expr) => {
|
||||
&$crate::Align4(*include_bytes!($path)) as &$crate::Spirv
|
||||
};
|
||||
}
|
||||
|
||||
/// Type returned by `include_spv`, convertible to `&[u32]`
|
||||
///
|
||||
/// The definition of this type is unstable.
|
||||
pub type Spirv = Align4<[u8]>;
|
||||
|
||||
impl std::ops::Deref for Spirv {
|
||||
type Target = [u32];
|
||||
fn deref(&self) -> &[u32] {
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
unsafe {
|
||||
std::slice::from_raw_parts(self.0.as_ptr() as *const u32, self.0.len() / 4)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(align(4))]
|
||||
#[doc(hidden)]
|
||||
pub struct Align4<T: ?Sized>(pub T);
|
|
@ -1,8 +1,8 @@
|
|||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use std::fmt;
|
||||
use std::rc::Rc;
|
||||
use wgpu::{self, Extent3d, TextureView};
|
||||
|
||||
use crate::include_spv;
|
||||
use crate::render_pass::{BoxedRenderPass, Device, Queue, RenderPass};
|
||||
|
||||
/// Renderer implements [`RenderPass`].
|
||||
|
@ -24,24 +24,8 @@ impl Renderer {
|
|||
texture_view: &TextureView,
|
||||
texture_size: &Extent3d,
|
||||
) -> BoxedRenderPass {
|
||||
let vert_spv = include_bytes!("../shaders/vert.spv");
|
||||
let mut vert = Vec::new();
|
||||
vert.resize_with(
|
||||
vert_spv.len() / std::mem::size_of::<u32>(),
|
||||
Default::default,
|
||||
);
|
||||
LittleEndian::read_u32_into(vert_spv, &mut vert);
|
||||
|
||||
let frag_spv = include_bytes!("../shaders/frag.spv");
|
||||
let mut frag = Vec::new();
|
||||
frag.resize_with(
|
||||
frag_spv.len() / std::mem::size_of::<u32>(),
|
||||
Default::default,
|
||||
);
|
||||
LittleEndian::read_u32_into(frag_spv, &mut frag);
|
||||
|
||||
let vs_module = device.create_shader_module(&vert);
|
||||
let fs_module = device.create_shader_module(&frag);
|
||||
let vs_module = device.create_shader_module(include_spv!("../shaders/vert.spv"));
|
||||
let fs_module = device.create_shader_module(include_spv!("../shaders/frag.spv"));
|
||||
|
||||
// Create a texture sampler with nearest neighbor
|
||||
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
|
||||
|
|
Loading…
Reference in a new issue