build(vulkan-shaders): source tool metadata at build time
This commit is contained in:
@@ -4,6 +4,7 @@ version.workspace = true
|
|||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ash = "0.38"
|
ash = "0.38"
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
@@ -37,6 +37,30 @@ const TRIANGLE_FRAGMENT_COMPILE_COMMAND: &str =
|
|||||||
const TRIANGLE_FRAGMENT_VALIDATE_COMMAND: &str =
|
const TRIANGLE_FRAGMENT_VALIDATE_COMMAND: &str =
|
||||||
"spirv-val --target-env vulkan1.0 adapters/fparkan-render-vulkan/shaders/triangle.frag.spv";
|
"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.
|
/// Shader tool metadata pinned in the Stage 0 manifest.
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||||
pub struct VulkanShaderToolManifest {
|
pub struct VulkanShaderToolManifest {
|
||||||
@@ -247,14 +271,14 @@ pub fn validate_shader_manifest(
|
|||||||
schema: SHADER_MANIFEST_SCHEMA,
|
schema: SHADER_MANIFEST_SCHEMA,
|
||||||
target_env: SHADER_TARGET_ENV,
|
target_env: SHADER_TARGET_ENV,
|
||||||
compiler: VulkanShaderToolManifest {
|
compiler: VulkanShaderToolManifest {
|
||||||
name: SHADER_COMPILER_NAME,
|
name: shader_compiler_name(),
|
||||||
version: SHADER_COMPILER_VERSION,
|
version: shader_compiler_version(),
|
||||||
binary_sha256: SHADER_COMPILER_BINARY_SHA256,
|
binary_sha256: shader_compiler_binary_sha256(),
|
||||||
},
|
},
|
||||||
validator: VulkanShaderToolManifest {
|
validator: VulkanShaderToolManifest {
|
||||||
name: SPIRV_VALIDATOR_NAME,
|
name: spirv_validator_name(),
|
||||||
version: SPIRV_VALIDATOR_VERSION,
|
version: spirv_validator_version(),
|
||||||
binary_sha256: SPIRV_VALIDATOR_BINARY_SHA256,
|
binary_sha256: spirv_validator_binary_sha256(),
|
||||||
},
|
},
|
||||||
modules: reports,
|
modules: reports,
|
||||||
manifest_hash: sha256_hex(&sha256(normalized.as_bytes())),
|
manifest_hash: sha256_hex(&sha256(normalized.as_bytes())),
|
||||||
|
|||||||
Reference in New Issue
Block a user