aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--adapters/fparkan-render-vulkan/Cargo.toml1
-rw-r--r--adapters/fparkan-render-vulkan/build.rs92
-rw-r--r--adapters/fparkan-render-vulkan/src/shader_manifest.rs36
3 files changed, 123 insertions, 6 deletions
diff --git a/adapters/fparkan-render-vulkan/Cargo.toml b/adapters/fparkan-render-vulkan/Cargo.toml
index 2d6db04..e8f9817 100644
--- a/adapters/fparkan-render-vulkan/Cargo.toml
+++ b/adapters/fparkan-render-vulkan/Cargo.toml
@@ -4,6 +4,7 @@ version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
+build = "build.rs"
[dependencies]
ash = "0.38"
diff --git a/adapters/fparkan-render-vulkan/build.rs b/adapters/fparkan-render-vulkan/build.rs
new file mode 100644
index 0000000..d66c022
--- /dev/null
+++ b/adapters/fparkan-render-vulkan/build.rs
@@ -0,0 +1,92 @@
+//! Build-time shader tool metadata for Vulkan reports.
+
+use std::env;
+use std::path::Path;
+use std::process::Command;
+
+const SHADER_COMPILER_NAME: &str = "glslangValidator";
+const SPIRV_VALIDATOR_NAME: &str = "spirv-val";
+
+fn main() {
+ println!("cargo:rerun-if-env-changed=PATH");
+ println!("cargo:rerun-if-env-changed=FPARKAN_GLSLANG_VALIDATOR");
+ println!("cargo:rerun-if-env-changed=FPARKAN_SPIRV_VAL");
+
+ emit_tool_metadata(
+ "FPARKAN_BUILD_SHADER_COMPILER",
+ &tool_path("FPARKAN_GLSLANG_VALIDATOR", SHADER_COMPILER_NAME),
+ );
+ emit_tool_metadata(
+ "FPARKAN_BUILD_SPIRV_VALIDATOR",
+ &tool_path("FPARKAN_SPIRV_VAL", SPIRV_VALIDATOR_NAME),
+ );
+}
+
+fn tool_path(env_var: &str, fallback: &str) -> String {
+ env::var(env_var).unwrap_or_else(|_| fallback.to_string())
+}
+
+fn emit_tool_metadata(prefix: &str, tool: &str) {
+ let Some(path) = resolve_tool(tool) else {
+ return;
+ };
+ println!("cargo:rerun-if-changed={}", path.display());
+ let Some(version) = tool_version(&path) else {
+ return;
+ };
+ let Some(binary_sha256) = tool_sha256(&path) else {
+ return;
+ };
+ let name = path
+ .file_name()
+ .and_then(|value| value.to_str())
+ .unwrap_or(tool)
+ .to_string();
+ println!("cargo:rustc-env={prefix}_NAME={name}");
+ println!("cargo:rustc-env={prefix}_VERSION={version}");
+ println!("cargo:rustc-env={prefix}_SHA256={binary_sha256}");
+}
+
+fn resolve_tool(tool: &str) -> Option<std::path::PathBuf> {
+ let candidate = Path::new(tool);
+ if candidate.components().count() > 1 {
+ return candidate.is_file().then(|| candidate.to_path_buf());
+ }
+ let output = Command::new("which").arg(tool).output().ok()?;
+ if !output.status.success() {
+ return None;
+ }
+ let path = String::from_utf8(output.stdout).ok()?;
+ let path = path.trim();
+ (!path.is_empty()).then(|| path.into())
+}
+
+fn tool_version(path: &Path) -> Option<String> {
+ let output = Command::new(path).arg("--version").output().ok()?;
+ if !output.status.success() {
+ return None;
+ }
+ let stdout = String::from_utf8(output.stdout).ok()?;
+ stdout
+ .lines()
+ .find(|line| !line.trim().is_empty())
+ .map(str::trim)
+ .map(|line| {
+ line.strip_prefix("Glslang Version: ")
+ .unwrap_or(line)
+ .to_string()
+ })
+}
+
+fn tool_sha256(path: &Path) -> Option<String> {
+ let output = Command::new("shasum")
+ .args(["-a", "256"])
+ .arg(path)
+ .output()
+ .ok()?;
+ if !output.status.success() {
+ return None;
+ }
+ let stdout = String::from_utf8(output.stdout).ok()?;
+ stdout.split_whitespace().next().map(ToString::to_string)
+}
diff --git a/adapters/fparkan-render-vulkan/src/shader_manifest.rs b/adapters/fparkan-render-vulkan/src/shader_manifest.rs
index 5c589cb..80b47a6 100644
--- a/adapters/fparkan-render-vulkan/src/shader_manifest.rs
+++ b/adapters/fparkan-render-vulkan/src/shader_manifest.rs
@@ -37,6 +37,30 @@ const TRIANGLE_FRAGMENT_COMPILE_COMMAND: &str =
const TRIANGLE_FRAGMENT_VALIDATE_COMMAND: &str =
"spirv-val --target-env vulkan1.0 adapters/fparkan-render-vulkan/shaders/triangle.frag.spv";
+fn shader_compiler_name() -> &'static str {
+ option_env!("FPARKAN_BUILD_SHADER_COMPILER_NAME").unwrap_or(SHADER_COMPILER_NAME)
+}
+
+fn shader_compiler_version() -> &'static str {
+ option_env!("FPARKAN_BUILD_SHADER_COMPILER_VERSION").unwrap_or(SHADER_COMPILER_VERSION)
+}
+
+fn shader_compiler_binary_sha256() -> &'static str {
+ option_env!("FPARKAN_BUILD_SHADER_COMPILER_SHA256").unwrap_or(SHADER_COMPILER_BINARY_SHA256)
+}
+
+fn spirv_validator_name() -> &'static str {
+ option_env!("FPARKAN_BUILD_SPIRV_VALIDATOR_NAME").unwrap_or(SPIRV_VALIDATOR_NAME)
+}
+
+fn spirv_validator_version() -> &'static str {
+ option_env!("FPARKAN_BUILD_SPIRV_VALIDATOR_VERSION").unwrap_or(SPIRV_VALIDATOR_VERSION)
+}
+
+fn spirv_validator_binary_sha256() -> &'static str {
+ option_env!("FPARKAN_BUILD_SPIRV_VALIDATOR_SHA256").unwrap_or(SPIRV_VALIDATOR_BINARY_SHA256)
+}
+
/// Shader tool metadata pinned in the Stage 0 manifest.
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct VulkanShaderToolManifest {
@@ -247,14 +271,14 @@ pub fn validate_shader_manifest(
schema: SHADER_MANIFEST_SCHEMA,
target_env: SHADER_TARGET_ENV,
compiler: VulkanShaderToolManifest {
- name: SHADER_COMPILER_NAME,
- version: SHADER_COMPILER_VERSION,
- binary_sha256: SHADER_COMPILER_BINARY_SHA256,
+ name: shader_compiler_name(),
+ version: shader_compiler_version(),
+ binary_sha256: shader_compiler_binary_sha256(),
},
validator: VulkanShaderToolManifest {
- name: SPIRV_VALIDATOR_NAME,
- version: SPIRV_VALIDATOR_VERSION,
- binary_sha256: SPIRV_VALIDATOR_BINARY_SHA256,
+ name: spirv_validator_name(),
+ version: spirv_validator_version(),
+ binary_sha256: spirv_validator_binary_sha256(),
},
modules: reports,
manifest_hash: sha256_hex(&sha256(normalized.as_bytes())),