Headless pictures draw on the GPU, with the viewport's pipelines (CPU rasterizer as last tier) (#1555)
Thanks @jyviko.
This commit is contained in:
1 parent
48322f6464
commit
1a0b33fcf3
54 files changed
+3525
-1998
No files matched your search
+24
-14
@@ -1,7 +1,9 @@
|
||||
//! GPU evaluation of display tessellation plans: the surface point and normal at every
|
||||
//! vertex's parameters, in a compute shader (`tess.wgsl`), the GPU twin of
|
||||
//! [`TessPlan::evaluate`]. Shared edge nodes keep their exact positions, so faces still meet
|
||||
//! exactly; evaluation runs in f32.
|
||||
//! SolidCraft's GPU work: the viewport's render pipelines ([`view`]), pictures drawn with them
|
||||
//! offscreen ([`capture`]), and display tessellation plans evaluated in a compute shader.
|
||||
//!
|
||||
//! Plan evaluation: the surface point and normal at every vertex's parameters, in a compute
|
||||
//! shader (`tess.wgsl`), the GPU twin of [`TessPlan::evaluate`]. Shared edge nodes keep their
|
||||
//! exact positions, so faces still meet exactly; evaluation runs in f32.
|
||||
//!
|
||||
//! Use [`TessGpu::new`] with the application's device, or [`TessGpu::headless`] (native only)
|
||||
//! to open one without a window, as the CLI and tests do. A viewport draws a plan straight from
|
||||
@@ -17,6 +19,12 @@ use solidcraft_geom::Vec3;
|
||||
use solidcraft_geom::tess::{EvalCurve, EvalSurface, TessPlan};
|
||||
use wgpu::util::DeviceExt;
|
||||
|
||||
pub mod capture;
|
||||
mod pbr;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub mod select;
|
||||
pub mod view;
|
||||
|
||||
/// The tessellation compute shader (WGSL).
|
||||
pub const SHADER: &str = include_str!("tess.wgsl");
|
||||
|
||||
@@ -30,17 +38,15 @@ fn popped(f: impl std::future::Future<Output = Option<wgpu::Error>>) -> Option<w
|
||||
}
|
||||
}
|
||||
|
||||
/// An adapter and device without a window (native only). The environment may pick the backend
|
||||
/// and the D3D12 shader compiler (`WGPU_BACKEND`, `WGPU_DX12_COMPILER`).
|
||||
/// An adapter and device without a window (native only): the adapter [`select::pick`] chooses
|
||||
/// under the `SOLIDCRAFT_GPU` policy. The environment may narrow the backends and pick the D3D12
|
||||
/// shader compiler (`WGPU_BACKEND`, `WGPU_DX12_COMPILER`).
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn open_headless() -> Result<(wgpu::Adapter, wgpu::Device, wgpu::Queue)> {
|
||||
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor::new_without_display_handle_from_env());
|
||||
let adapter = pollster::block_on(
|
||||
instance.request_adapter(&wgpu::RequestAdapterOptions { power_preference: wgpu::PowerPreference::HighPerformance, ..Default::default() }),
|
||||
)
|
||||
.map_err(|_| GpuError::NoAdapter)?;
|
||||
let policy = select::Policy::from_env().map_err(GpuError::Policy)?;
|
||||
let (adapter, _) = select::pick(policy).ok_or(GpuError::NoAdapter(policy.name()))?;
|
||||
let (device, queue) = pollster::block_on(adapter.request_device(&wgpu::DeviceDescriptor {
|
||||
label: Some("solidcraft compute"),
|
||||
label: Some("solidcraft headless"),
|
||||
required_limits: wgpu::Limits::downlevel_defaults().using_resolution(adapter.limits()),
|
||||
..Default::default()
|
||||
}))
|
||||
@@ -54,12 +60,16 @@ const WORKGROUP: u32 = 64;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum GpuError {
|
||||
#[error("no GPU adapter is available")]
|
||||
NoAdapter,
|
||||
#[error("no GPU adapter qualifies under the `{0}` policy (SOLIDCRAFT_GPU); `solidcraft-cli gpu` lists the adapters this machine offers")]
|
||||
NoAdapter(&'static str),
|
||||
#[error("{0}")]
|
||||
Policy(String),
|
||||
#[error("the GPU device could not be opened: {0}")]
|
||||
Device(String),
|
||||
#[error("the GPU evaluation failed: {0}")]
|
||||
Failed(String),
|
||||
#[error("the GPU render failed: {0}")]
|
||||
Render(String),
|
||||
#[error("the GPU tessellation pipeline could not be created: {0}")]
|
||||
Pipeline(String),
|
||||
#[error("not supported yet: {0}")]
|
||||
|
||||
Reference in new issue
Block a user