mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-29 04:27:30 -06:00
Merge upstream/main into pr/overlay-windows (#1027 landed)
GPU handles(): only output-device proofs stay on the CPU; Show All Masks now renders zoom windows (upstream); proof-boundary tolerance in the GPU equivalence test; device-profile draft test. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
+31
-9
@@ -35,6 +35,8 @@ pub mod backend;
|
||||
mod ctx;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
mod exit;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub mod faces;
|
||||
#[cfg(all(feature = "denoise", not(target_arch = "wasm32")))]
|
||||
pub mod nn;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
@@ -239,9 +241,9 @@ pub fn wait_idle(timeout: std::time::Duration) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
/// Why GPU compute that has a device of its own (denoise) is switched off by the user's settings, or `None`: the
|
||||
/// Why GPU compute that has a device of its own (denoise, faces) is switched off by the user's settings, or `None`: the
|
||||
/// environment switches and the rendering preference, but not a render-device failure (the devices are separate).
|
||||
#[cfg(all(feature = "denoise", not(target_arch = "wasm32")))]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub(crate) fn switched_off() -> Option<String> {
|
||||
if env_disabled() {
|
||||
return Some(if backend::env_off() { "disabled by LIGHTCRAFT_GPU_BACKEND=off" } else { "disabled by LIGHTCRAFT_GPU=0" }.into());
|
||||
@@ -437,6 +439,15 @@ pub fn render(src: &Arc<Rgb32f>, info: &SourceInfo, s: &DevelopSettings, req: &R
|
||||
try_render(src, info, s, req, stages).ok()
|
||||
}
|
||||
|
||||
/// Whether the GPU renders requests of this kind at all (a given render can still fall back to
|
||||
/// the CPU): the kernel writes 8-bit output, so high-bit-depth exports render on the CPU, and so do
|
||||
/// soft proofs against an output-device profile (`device_proof`: its 3D table is CPU-side) and
|
||||
/// Visualize HDR, which needs the float HDR render. [`try_render`] follows it, and the loupe sizes
|
||||
/// its slider-drag drafts by it (issue #330), so the two can't drift apart.
|
||||
pub fn handles(depth: lightcraft_pipeline::OutputDepth, device_proof: bool, overlay: lightcraft_pipeline::Overlay) -> bool {
|
||||
depth == lightcraft_pipeline::OutputDepth::U8 && !device_proof && overlay != lightcraft_pipeline::Overlay::HdrRange
|
||||
}
|
||||
|
||||
/// [`render`], reporting why this render made no GPU image: [`Fallback::NotTried`] when the GPU
|
||||
/// was not used (callers can ask [`unavailable_reason`]), [`Fallback::Failed`] with the reason
|
||||
/// when the GPU render failed and the CPU must render it. The reason belongs to this call, unlike
|
||||
@@ -453,13 +464,8 @@ pub fn try_render(
|
||||
// sections switched off with their eye render as if at their defaults (issue #316)
|
||||
let effective = s.effective();
|
||||
let s: &DevelopSettings = &effective;
|
||||
// the kernel writes 8-bit output: high-bit-depth exports render on the CPU, and so do soft
|
||||
// proofs against an output-device profile (its 3D table); Visualize HDR needs the float HDR render: CPU too
|
||||
if !enabled()
|
||||
|| req.depth != lightcraft_pipeline::OutputDepth::U8
|
||||
|| req.proof.is_some_and(|p| lightcraft_pipeline::proof_profile(p.profile).is_some())
|
||||
|| req.overlay == lightcraft_pipeline::Overlay::HdrRange
|
||||
{
|
||||
let device_proof = req.proof.is_some_and(|p| lightcraft_pipeline::proof_profile(p.profile).is_some());
|
||||
if !enabled() || !handles(req.depth, device_proof, req.overlay) {
|
||||
return Err(Fallback::NotTried);
|
||||
}
|
||||
let s = &*lightcraft_pipeline::settings_for(s, req);
|
||||
@@ -533,3 +539,19 @@ pub fn try_render(
|
||||
Err(Fallback::NotTried)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use lightcraft_pipeline::{OutputDepth, Overlay};
|
||||
|
||||
// Given a request the 8-bit kernel can't draw (high bit depth, a soft proof, Visualize HDR),
|
||||
// the GPU doesn't take it; the loupe and diagnostic overlays it can draw stay on the GPU
|
||||
#[test]
|
||||
fn the_gpu_handles_8_bit_unproofed_renders_without_the_hdr_range() {
|
||||
assert!(super::handles(OutputDepth::U8, false, Overlay::None));
|
||||
assert!(super::handles(OutputDepth::U8, false, Overlay::Spots(50)));
|
||||
assert!(!super::handles(OutputDepth::U16, false, Overlay::None));
|
||||
assert!(!super::handles(OutputDepth::U8, true, Overlay::None));
|
||||
assert!(!super::handles(OutputDepth::U8, false, Overlay::HdrRange));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user