#[derive(Clone, Copy, Default, Debug, PartialEq, Eq)]
struct ParsedValidation {
layout: bool,
gpu_api: bool,
timeline: bool,
scheme: bool,
}
fn env_truthy(name: &str) -> bool {
std::env::var(name)
.map(|v| matches!(v.to_ascii_lowercase().as_str(), "1" | "true" | "yes"))
.unwrap_or(false)
}
fn legacy_gpu_only_short_form(raw: &str) -> Option<bool> {
let t = raw.trim();
if t.is_empty() {
return None;
}
if matches!(t.to_ascii_lowercase().as_str(), "1" | "true" | "yes") {
Some(true)
} else {
None
}
}
fn parse_validation_list(raw: &str) -> ParsedValidation {
let mut out = ParsedValidation::default();
if let Some(true) = legacy_gpu_only_short_form(raw) {
out.gpu_api = true;
return out;
}
let normalized = raw.replace(';', ",");
for chunk in normalized.split(',') {
for part in chunk.split_whitespace() {
let p = part.trim();
if p.is_empty() {
continue;
}
match p.to_ascii_lowercase().as_str() {
"all" => {
out.layout = true;
out.gpu_api = true;
out.timeline = true;
out.scheme = true;
}
"layout" | "layouts" => out.layout = true,
"api" => out.gpu_api = true,
"timeline" => out.timeline = true,
"scheme" | "readback" => out.scheme = true,
_ => {}
}
}
}
out
}
fn from_goldy_validation_var() -> ParsedValidation {
std::env::var("GOLDY_VALIDATION")
.map(|s| parse_validation_list(&s))
.unwrap_or_default()
}
#[must_use]
pub fn layout_validation_enabled() -> bool {
if env_truthy("GOLDY_VALIDATE_LAYOUTS") {
return true;
}
from_goldy_validation_var().layout
}
#[cfg(any(feature = "vulkan", all(feature = "metal", target_os = "macos")))]
#[must_use]
pub(crate) fn gpu_api_validation_enabled() -> bool {
from_goldy_validation_var().gpu_api
}
#[cfg(feature = "vulkan")]
#[must_use]
pub(crate) fn timeline_validation_enabled() -> bool {
from_goldy_validation_var().timeline
}
#[must_use]
pub(crate) fn scheme_validation_enabled() -> bool {
from_goldy_validation_var().scheme
}
use std::cell::Cell;
thread_local! {
static TEST_CB_REUSE_DISABLED_OVERRIDE: Cell<Option<bool>> = const { Cell::new(None) };
}
#[doc(hidden)]
pub fn set_cb_reuse_override(disabled: bool) {
TEST_CB_REUSE_DISABLED_OVERRIDE.with(|c| c.set(Some(disabled)));
}
#[doc(hidden)]
pub fn clear_cb_reuse_override() {
TEST_CB_REUSE_DISABLED_OVERRIDE.with(|c| c.set(None));
}
#[must_use]
pub(crate) fn retained_cb_reuse_disabled() -> bool {
if let Some(disabled) = TEST_CB_REUSE_DISABLED_OVERRIDE.with(|c| c.get()) {
return disabled;
}
env_truthy("GOLDY_DISABLE_CB_REUSE") || crate::gpu_profiler::gpu_profile_enabled()
}
#[cfg(test)]
mod tests {
use super::parse_validation_list;
#[test]
fn parse_list_tokens() {
let p = parse_validation_list("layout,api");
assert!(p.layout);
assert!(p.gpu_api);
let p = parse_validation_list("layout");
assert!(p.layout);
assert!(!p.gpu_api);
let p = parse_validation_list("all");
assert!(p.layout);
assert!(p.gpu_api);
assert!(p.timeline);
assert!(p.scheme);
let p = parse_validation_list("timeline");
assert!(!p.layout);
assert!(!p.gpu_api);
assert!(p.timeline);
assert!(!p.scheme);
let p = parse_validation_list("scheme");
assert!(!p.layout);
assert!(!p.gpu_api);
assert!(!p.timeline);
assert!(p.scheme);
let p = parse_validation_list("readback");
assert!(p.scheme);
let p = parse_validation_list("api; api");
assert!(!p.layout);
assert!(p.gpu_api);
}
#[test]
fn parse_legacy_truthy_is_gpu_only() {
let p = parse_validation_list("1");
assert!(!p.layout);
assert!(p.gpu_api);
let p = parse_validation_list("true");
assert!(!p.layout);
assert!(p.gpu_api);
}
#[test]
fn parse_unknown_tokens_do_not_enable_api() {
let p = parse_validation_list("gpu,vulkan,metal,shader");
assert!(!p.layout);
assert!(!p.gpu_api);
}
}