Add include_spv!() macro, donated by Ralith (#26)
This commit is contained in:
parent
994cc9a03c
commit
5795fa7943
5 changed files with 49 additions and 24 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -702,7 +702,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
name = "pixels"
|
name = "pixels"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
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)",
|
"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)",
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pixels-mocks 0.1.0",
|
"pixels-mocks 0.1.0",
|
||||||
|
|
|
@ -11,7 +11,6 @@ categories = ["graphics", "rendering"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
byteorder = "1.3"
|
|
||||||
wgpu = { git = "https://github.com/gfx-rs/wgpu-rs", rev = "012d08d64de924da93289c2b51fb06b22d7348cf" }
|
wgpu = { git = "https://github.com/gfx-rs/wgpu-rs", rev = "012d08d64de924da93289c2b51fb06b22d7348cf" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -16,14 +16,15 @@ use std::error::Error as StdError;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
pub use crate::macros::*;
|
||||||
|
pub use crate::render_pass::{BoxedRenderPass, Device, Queue, RenderPass};
|
||||||
|
use crate::renderers::Renderer;
|
||||||
pub use wgpu;
|
pub use wgpu;
|
||||||
use wgpu::{Extent3d, TextureView};
|
use wgpu::{Extent3d, TextureView};
|
||||||
|
|
||||||
|
mod macros;
|
||||||
mod render_pass;
|
mod render_pass;
|
||||||
pub use render_pass::{BoxedRenderPass, Device, Queue, RenderPass};
|
|
||||||
|
|
||||||
mod renderers;
|
mod renderers;
|
||||||
use renderers::Renderer;
|
|
||||||
|
|
||||||
type RenderPassFactory = Box<dyn Fn(Device, Queue, &TextureView, &Extent3d) -> BoxedRenderPass>;
|
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::fmt;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use wgpu::{self, Extent3d, TextureView};
|
use wgpu::{self, Extent3d, TextureView};
|
||||||
|
|
||||||
|
use crate::include_spv;
|
||||||
use crate::render_pass::{BoxedRenderPass, Device, Queue, RenderPass};
|
use crate::render_pass::{BoxedRenderPass, Device, Queue, RenderPass};
|
||||||
|
|
||||||
/// Renderer implements [`RenderPass`].
|
/// Renderer implements [`RenderPass`].
|
||||||
|
@ -24,24 +24,8 @@ impl Renderer {
|
||||||
texture_view: &TextureView,
|
texture_view: &TextureView,
|
||||||
texture_size: &Extent3d,
|
texture_size: &Extent3d,
|
||||||
) -> BoxedRenderPass {
|
) -> BoxedRenderPass {
|
||||||
let vert_spv = include_bytes!("../shaders/vert.spv");
|
let vs_module = device.create_shader_module(include_spv!("../shaders/vert.spv"));
|
||||||
let mut vert = Vec::new();
|
let fs_module = device.create_shader_module(include_spv!("../shaders/frag.spv"));
|
||||||
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);
|
|
||||||
|
|
||||||
// Create a texture sampler with nearest neighbor
|
// Create a texture sampler with nearest neighbor
|
||||||
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
|
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
|
||||||
|
|
Loading…
Add table
Reference in a new issue