mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
basics of setting up webgpu are up
This commit is contained in:
@ -13,6 +13,8 @@ pub fn build(b: *std.build.Builder) void {
|
|||||||
exe.setTarget(target);
|
exe.setTarget(target);
|
||||||
exe.setBuildMode(mode);
|
exe.setBuildMode(mode);
|
||||||
exe.install();
|
exe.install();
|
||||||
|
exe.addPackagePath("gpu", "vendor/mach/gpu/src/main.zig");
|
||||||
|
exe.addPackagePath("dawn", "vendor/mach/gpu-dawn/src/dawn/c.zig");
|
||||||
exe.addPackagePath("glfw", "vendor/mach/glfw/src/main.zig");
|
exe.addPackagePath("glfw", "vendor/mach/glfw/src/main.zig");
|
||||||
glfw.link(b, exe, .{});
|
glfw.link(b, exe, .{});
|
||||||
gpu_dawn.link(b, exe, if (target.getCpuArch() == .aarch64) .{
|
gpu_dawn.link(b, exe, if (target.getCpuArch() == .aarch64) .{
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
, gdb
|
, gdb
|
||||||
, pkg-config
|
, pkg-config
|
||||||
, scdoc
|
, scdoc
|
||||||
|
, vulkan-loader
|
||||||
, vttest
|
, vttest
|
||||||
, zig
|
, zig
|
||||||
|
|
||||||
@ -26,5 +27,5 @@
|
|||||||
libX11
|
libX11
|
||||||
];
|
];
|
||||||
|
|
||||||
LD_LIBRARY_PATH = "${libGL}/lib";
|
LD_LIBRARY_PATH = "${vulkan-loader}/lib:${libGL}/lib";
|
||||||
}
|
}
|
||||||
|
15
src/main.zig
15
src/main.zig
@ -1,16 +1,19 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const dawn = @import("dawn");
|
||||||
const glfw = @import("glfw");
|
const glfw = @import("glfw");
|
||||||
|
const gpu = @import("gpu");
|
||||||
|
|
||||||
|
const setup = @import("setup.zig");
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
try glfw.init(.{});
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
var allocator = gpa.allocator();
|
||||||
|
|
||||||
|
const s = try setup.setup(allocator);
|
||||||
defer glfw.terminate();
|
defer glfw.terminate();
|
||||||
|
|
||||||
// Create our window
|
|
||||||
const window = try glfw.Window.create(640, 480, "ghostty", null, null, .{});
|
|
||||||
defer window.destroy();
|
|
||||||
|
|
||||||
// Wait for the user to close the window.
|
// Wait for the user to close the window.
|
||||||
while (!window.shouldClose()) {
|
while (!s.window.shouldClose()) {
|
||||||
try glfw.pollEvents();
|
try glfw.pollEvents();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
144
src/setup.zig
Normal file
144
src/setup.zig
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const dawn = @import("dawn");
|
||||||
|
const glfw = @import("glfw");
|
||||||
|
const gpu = @import("gpu");
|
||||||
|
const c = dawn.c;
|
||||||
|
|
||||||
|
const Setup = struct {
|
||||||
|
native_instance: gpu.NativeInstance,
|
||||||
|
backend_type: gpu.Adapter.BackendType,
|
||||||
|
device: gpu.Device,
|
||||||
|
window: glfw.Window,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn setup(allocator: std.mem.Allocator) !Setup {
|
||||||
|
const backend_type = try detectBackendType(allocator);
|
||||||
|
std.log.info("detected backend type: {}", .{backend_type});
|
||||||
|
|
||||||
|
// Initialize glfw
|
||||||
|
try glfw.init(.{});
|
||||||
|
errdefer glfw.terminate();
|
||||||
|
|
||||||
|
// Create the window and discover adapters using it (esp. for OpenGL)
|
||||||
|
var hints = glfwWindowHintsForBackend(backend_type);
|
||||||
|
hints.cocoa_retina_framebuffer = true;
|
||||||
|
const window = try glfw.Window.create(640, 480, "ghostty", null, null, hints);
|
||||||
|
|
||||||
|
const backend_procs = dawn.c.machDawnNativeGetProcs();
|
||||||
|
dawn.c.dawnProcSetProcs(backend_procs);
|
||||||
|
|
||||||
|
const instance = dawn.c.machDawnNativeInstance_init();
|
||||||
|
var native_instance = gpu.NativeInstance.wrap(dawn.c.machDawnNativeInstance_get(instance).?);
|
||||||
|
const gpu_interface = native_instance.interface();
|
||||||
|
|
||||||
|
// Discovers e.g. OpenGL adapters.
|
||||||
|
try discoverAdapters(instance, window, backend_type);
|
||||||
|
|
||||||
|
// Request an adapter.
|
||||||
|
const backend_adapter = switch (gpu_interface.waitForAdapter(&.{
|
||||||
|
.power_preference = .high_performance,
|
||||||
|
})) {
|
||||||
|
.adapter => |v| v,
|
||||||
|
.err => |err| {
|
||||||
|
std.debug.print("failed to get adapter: error={} {s}\n", .{ err.code, err.message });
|
||||||
|
std.process.exit(1);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Print which adapter we are going to use.
|
||||||
|
const props = backend_adapter.properties;
|
||||||
|
std.debug.print("found {s} backend on {s} adapter: {s}, {s}\n", .{
|
||||||
|
gpu.Adapter.backendTypeName(props.backend_type),
|
||||||
|
gpu.Adapter.typeName(props.adapter_type),
|
||||||
|
props.name,
|
||||||
|
props.driver_description,
|
||||||
|
});
|
||||||
|
|
||||||
|
const device = switch (backend_adapter.waitForDevice(&.{})) {
|
||||||
|
.device => |v| v,
|
||||||
|
.err => |err| {
|
||||||
|
std.debug.print("failed to get device: error={} {s}\n", .{ err.code, err.message });
|
||||||
|
std.process.exit(1);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return Setup{
|
||||||
|
.native_instance = native_instance,
|
||||||
|
.backend_type = backend_type,
|
||||||
|
.device = device,
|
||||||
|
.window = window,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn detectBackendType(allocator: std.mem.Allocator) !gpu.Adapter.BackendType {
|
||||||
|
const GPU_BACKEND = std.process.getEnvVarOwned(allocator, "GPU_BACKEND") catch |err| switch (err) {
|
||||||
|
error.EnvironmentVariableNotFound => @as(?[]u8, null),
|
||||||
|
else => |e| return e,
|
||||||
|
};
|
||||||
|
if (GPU_BACKEND) |backend| {
|
||||||
|
defer allocator.free(backend);
|
||||||
|
if (std.ascii.eqlIgnoreCase(backend, "d3d11")) return .d3d11;
|
||||||
|
if (std.ascii.eqlIgnoreCase(backend, "d3d12")) return .d3d12;
|
||||||
|
if (std.ascii.eqlIgnoreCase(backend, "metal")) return .metal;
|
||||||
|
if (std.ascii.eqlIgnoreCase(backend, "null")) return .nul;
|
||||||
|
if (std.ascii.eqlIgnoreCase(backend, "opengl")) return .opengl;
|
||||||
|
if (std.ascii.eqlIgnoreCase(backend, "opengles")) return .opengles;
|
||||||
|
if (std.ascii.eqlIgnoreCase(backend, "vulkan")) return .vulkan;
|
||||||
|
@panic("unknown GPU_BACKEND value");
|
||||||
|
}
|
||||||
|
|
||||||
|
const target = @import("builtin").target;
|
||||||
|
if (target.isDarwin()) return .metal;
|
||||||
|
if (target.os.tag == .windows) return .d3d12;
|
||||||
|
return .vulkan;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn glfwWindowHintsForBackend(backend: gpu.Adapter.BackendType) glfw.Window.Hints {
|
||||||
|
return switch (backend) {
|
||||||
|
.opengl => .{
|
||||||
|
// Ask for OpenGL 4.4 which is what the GL backend requires for
|
||||||
|
// compute shaders and texture views.
|
||||||
|
.context_version_major = 4,
|
||||||
|
.context_version_minor = 4,
|
||||||
|
.opengl_forward_compat = true,
|
||||||
|
.opengl_profile = .opengl_core_profile,
|
||||||
|
},
|
||||||
|
.opengles => .{
|
||||||
|
.context_version_major = 3,
|
||||||
|
.context_version_minor = 1,
|
||||||
|
.client_api = .opengl_es_api,
|
||||||
|
.context_creation_api = .egl_context_api,
|
||||||
|
},
|
||||||
|
else => .{
|
||||||
|
// Without this GLFW will initialize a GL context on the window,
|
||||||
|
// which prevents using the window with other APIs (by crashing in weird ways).
|
||||||
|
.client_api = .no_api,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn discoverAdapters(
|
||||||
|
instance: c.MachDawnNativeInstance,
|
||||||
|
window: glfw.Window,
|
||||||
|
backend: gpu.Adapter.BackendType,
|
||||||
|
) !void {
|
||||||
|
switch (backend) {
|
||||||
|
.opengl => {
|
||||||
|
try glfw.makeContextCurrent(window);
|
||||||
|
const adapter_options = c.MachDawnNativeAdapterDiscoveryOptions_OpenGL{
|
||||||
|
.getProc = @ptrCast(fn ([*c]const u8) callconv(.C) ?*anyopaque, glfw.getProcAddress),
|
||||||
|
};
|
||||||
|
_ = c.machDawnNativeInstance_discoverAdapters(instance, @enumToInt(backend), &adapter_options);
|
||||||
|
},
|
||||||
|
.opengles => {
|
||||||
|
try glfw.makeContextCurrent(window);
|
||||||
|
const adapter_options = c.MachDawnNativeAdapterDiscoveryOptions_OpenGLES{
|
||||||
|
.getProc = @ptrCast(fn ([*c]const u8) callconv(.C) ?*anyopaque, glfw.getProcAddress),
|
||||||
|
};
|
||||||
|
_ = c.machDawnNativeInstance_discoverAdapters(instance, @enumToInt(backend), &adapter_options);
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
c.machDawnNativeInstance_discoverDefaultAdapters(instance);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user