Import Oxide engine (Stages 0–10) under MIT license

Full project snapshot migrated to new Gitea remote without history:
engine, editor, physics, script, examples, tests, docs, and assets.
Relicensed from GPLv3 to MIT and updated repo URLs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Homer Simpson
2026-07-05 20:41:02 +02:00
parent 2afb56b329
commit 9eead719b0
157 changed files with 47270 additions and 2 deletions
+94
View File
@@ -0,0 +1,94 @@
//! GPU acquisition: instance, adapter, device, queue.
use super::RenderError;
/// A handle to the GPU: instance, adapter, and the device/queue pair every
/// rendering operation goes through.
///
/// Created either for a window surface (via [`RenderContext`]) or headless
/// with [`Gpu::headless`] for offscreen rendering and tests.
///
/// [`RenderContext`]: super::RenderContext
pub struct Gpu {
instance: wgpu::Instance,
adapter: wgpu::Adapter,
device: wgpu::Device,
queue: wgpu::Queue,
}
impl Gpu {
/// Acquires an adapter and device from an existing `instance`, preferring
/// an adapter that can present to `compatible_surface` when one is given.
///
/// `force_fallback_adapter` requests a software adapter (e.g. llvmpipe),
/// used as a last resort when no hardware adapter works.
pub(crate) fn with_instance(
instance: wgpu::Instance,
compatible_surface: Option<&wgpu::Surface<'_>>,
force_fallback_adapter: bool,
) -> Result<Self, RenderError> {
let adapter = pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::HighPerformance,
force_fallback_adapter,
compatible_surface,
}))?;
log::info!(
"GPU adapter: {} ({:?})",
adapter.get_info().name,
adapter.get_info().backend
);
let (device, queue) =
pollster::block_on(adapter.request_device(&wgpu::DeviceDescriptor {
label: Some("oxide.device"),
..Default::default()
}))?;
Ok(Self {
instance,
adapter,
device,
queue,
})
}
/// Acquires the GPU without any surface, for offscreen rendering and
/// automated tests.
///
/// Tries a hardware adapter first, then falls back to a software adapter
/// (e.g. llvmpipe) so headless rendering also works on machines without a
/// usable GPU.
pub fn headless() -> Result<Self, RenderError> {
// `from_env` keeps backend/flags overridable via WGPU_* env vars.
let instance =
wgpu::Instance::new(wgpu::InstanceDescriptor::new_without_display_handle_from_env());
match Self::with_instance(instance, None, false) {
Ok(gpu) => Ok(gpu),
Err(hardware_err) => {
log::warn!("no hardware GPU adapter ({hardware_err}); trying software fallback");
let instance = wgpu::Instance::new(
wgpu::InstanceDescriptor::new_without_display_handle_from_env(),
);
Self::with_instance(instance, None, true)
}
}
}
/// The wgpu instance the adapter was created from.
pub fn instance(&self) -> &wgpu::Instance {
&self.instance
}
/// The physical adapter in use.
pub fn adapter(&self) -> &wgpu::Adapter {
&self.adapter
}
/// The logical device used to create GPU resources.
pub fn device(&self) -> &wgpu::Device {
&self.device
}
/// The queue used to submit command buffers.
pub fn queue(&self) -> &wgpu::Queue {
&self.queue
}
}