We can build them with cargo and a build script.
"narcissus-gpu",
"narcissus-image",
"narcissus-maths",
+ "shark-shaders",
]
+[[package]]
+name = "shark-shaders"
+version = "0.1.0"
+
[[package]]
name = "sqlite-sys"
version = "0.1.0"
members = [
"title/shark",
+ "title/shark-shaders",
"external/blake3-smol",
"external/renderdoc-sys",
"external/sdl2-sys",
--- /dev/null
+[package]
+name = "shark-shaders"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
--- /dev/null
+use std::io::Write;
+use std::process::Command;
+
+const SHADER_ROOT: &str = "shaders";
+
+#[derive(Clone, Copy)]
+enum ShaderStage {
+ Vertex,
+ Fragment,
+}
+
+impl ShaderStage {
+ fn name(self) -> &'static str {
+ match self {
+ ShaderStage::Vertex => "vert",
+ ShaderStage::Fragment => "frag",
+ }
+ }
+}
+
+#[derive(Clone, Copy)]
+struct Shader {
+ stage: ShaderStage,
+ name: &'static str,
+}
+
+const SHADERS: [Shader; 4] = [
+ Shader {
+ stage: ShaderStage::Vertex,
+ name: "basic",
+ },
+ Shader {
+ stage: ShaderStage::Fragment,
+ name: "basic",
+ },
+ Shader {
+ stage: ShaderStage::Vertex,
+ name: "text",
+ },
+ Shader {
+ stage: ShaderStage::Fragment,
+ name: "text",
+ },
+];
+
+fn main() {
+ let out_dir = std::env::var("OUT_DIR").unwrap();
+ let debug = match std::env::var("DEBUG").unwrap().as_str() {
+ "true" | "2" | "1" => "",
+ _ => "0",
+ };
+
+ let commands = SHADERS.map(|shader| {
+ Command::new("glslang")
+ .args(["--target-env", "vulkan1.3"])
+ .arg(&format!("-g{debug}"))
+ .args([
+ "-o",
+ &format!("{out_dir}/{}.{}.spv", shader.name, shader.stage.name()),
+ ])
+ .arg(&format!(
+ "{SHADER_ROOT}/{}.{}.glsl",
+ shader.name,
+ shader.stage.name()
+ ))
+ .spawn()
+ .unwrap()
+ });
+
+ let dst_path = std::path::Path::new(&out_dir).join("shaders.rs");
+ let mut file = std::fs::File::create(dst_path).unwrap();
+
+ writeln!(
+ file,
+ "#[repr(align(4))]\nstruct SpirvBytes<const LEN: usize>([u8; LEN]);"
+ )
+ .unwrap();
+
+ for shader in SHADERS {
+ writeln!(
+ file,
+ "pub const {}_{}_SPV: &'static [u8] = &SpirvBytes(*include_bytes!(\"{out_dir}/{}.{}.spv\")).0;",
+ shader.name.to_ascii_uppercase(),
+ shader.stage.name().to_ascii_uppercase(),
+ shader.name,
+ shader.stage.name()
+ )
+ .unwrap();
+ }
+
+ for mut command in commands {
+ let status = command.wait().unwrap();
+ assert!(status.success());
+ }
+
+ for shader in SHADERS {
+ println!(
+ "cargo::rerun-if-changed={SHADER_ROOT}/{}.{}.glsl",
+ shader.name,
+ shader.stage.name()
+ )
+ }
+
+ println!("cargo::rerun-if-changed=build.rs");
+}
layout(location = 0) out vec4 outColor;
void main() {
- float NdotL = max(dot(normal, vec3(0.0, 1.0, 0.0)), 0.1f);
+ float NdotL = max(dot(normal, vec3(0.0, 1.0, 0.0)), 0.1);
vec3 rgb = texture(sampler2D(tex, texSampler), vec2(texcoord.x, texcoord.y)).rgb;
outColor = vec4(rgb * NdotL, 1.0);
}
--- /dev/null
+include!(concat!(env!("OUT_DIR"), "/shaders.rs"));
narcissus-font = { path = "../../engine/narcissus-font" }
narcissus-maths = { path = "../../engine/narcissus-maths" }
narcissus-image = { path = "../../engine/narcissus-image" }
-narcissus-gpu = { path = "../../engine/narcissus-gpu" }
\ No newline at end of file
+narcissus-gpu = { path = "../../engine/narcissus-gpu" }
+
+shark-shaders = { path = "../shark-shaders" }
\ No newline at end of file
-use narcissus_core::{default, include_bytes_align};
+use narcissus_core::default;
use narcissus_gpu::{
Bind, BindGroupLayout, BindGroupLayoutDesc, BindGroupLayoutEntryDesc, BindingType, BlendMode,
BufferUsageFlags, CmdEncoder, CompareOp, CullingMode, Device, DeviceExt, Frame, FrontFace,
};
use narcissus_maths::{Affine3, Mat4};
-const VERT_SPV: &[u8] = include_bytes_align!(4, "../shaders/basic.vert.spv");
-const FRAG_SPV: &[u8] = include_bytes_align!(4, "../shaders/basic.frag.spv");
-
#[allow(unused)]
#[repr(C)]
pub struct BasicUniforms {
let pipeline = device.create_graphics_pipeline(&GraphicsPipelineDesc {
vertex_shader: ShaderDesc {
entry: c"main",
- code: VERT_SPV,
+ code: shark_shaders::BASIC_VERT_SPV,
},
fragment_shader: ShaderDesc {
entry: c"main",
- code: FRAG_SPV,
+ code: shark_shaders::BASIC_FRAG_SPV,
},
bind_group_layouts: &[uniforms_bind_group_layout, storage_bind_group_layout],
layout: GraphicsPipelineLayout {
-use narcissus_core::{default, include_bytes_align};
+use narcissus_core::default;
use narcissus_font::{TouchedGlyph, TouchedGlyphIndex};
use narcissus_gpu::{
Bind, BindGroupLayout, BindGroupLayoutDesc, BindGroupLayoutEntryDesc, BindingType, BlendMode,
PolygonMode, Sampler, SamplerAddressMode, SamplerDesc, SamplerFilter, ShaderDesc,
ShaderStageFlags, ThreadToken, Topology, TypedBind,
};
-
-const VERT_SPV: &[u8] = include_bytes_align!(4, "../shaders/text.vert.spv");
-const FRAG_SPV: &[u8] = include_bytes_align!(4, "../shaders/text.frag.spv");
+use shark_shaders;
#[allow(unused)]
#[repr(C)]
let pipeline = device.create_graphics_pipeline(&GraphicsPipelineDesc {
vertex_shader: ShaderDesc {
entry: c"main",
- code: VERT_SPV,
+ code: shark_shaders::TEXT_VERT_SPV,
},
fragment_shader: ShaderDesc {
entry: c"main",
- code: FRAG_SPV,
+ code: shark_shaders::TEXT_FRAG_SPV,
},
bind_group_layouts: &[bind_group_layout],
layout: GraphicsPipelineLayout {
+++ /dev/null
-#!/bin/bash
-
-pushd "${0%/*}"
-glslc --target-env=vulkan1.3 -O -fshader-stage=vert -o basic.vert.spv basic.vert.glsl
-glslc --target-env=vulkan1.3 -O -fshader-stage=frag -o basic.frag.spv basic.frag.glsl
-glslc --target-env=vulkan1.3 -O -fshader-stage=vert -o text.vert.spv text.vert.glsl
-glslc --target-env=vulkan1.3 -O -fshader-stage=frag -o text.frag.spv text.frag.glsl
-echo "built shaders"
-popd