mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
Merge pull request #2586 from emilazy/push-zrqyslkkznvo
renderer/metal: prefer low‐power GPUs
This commit is contained in:
@ -175,9 +175,9 @@ pub const GPUState = struct {
|
|||||||
instance: InstanceBuffer, // MTLBuffer
|
instance: InstanceBuffer, // MTLBuffer
|
||||||
|
|
||||||
pub fn init() !GPUState {
|
pub fn init() !GPUState {
|
||||||
const device = objc.Object.fromId(mtl.MTLCreateSystemDefaultDevice());
|
const device = try chooseDevice();
|
||||||
const queue = device.msgSend(objc.Object, objc.sel("newCommandQueue"), .{});
|
const queue = device.msgSend(objc.Object, objc.sel("newCommandQueue"), .{});
|
||||||
errdefer queue.msgSend(void, objc.sel("release"), .{});
|
errdefer queue.release();
|
||||||
|
|
||||||
var instance = try InstanceBuffer.initFill(device, &.{
|
var instance = try InstanceBuffer.initFill(device, &.{
|
||||||
0, 1, 3, // Top-left triangle
|
0, 1, 3, // Top-left triangle
|
||||||
@ -200,13 +200,33 @@ pub const GPUState = struct {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn chooseDevice() error{NoMetalDevice}!objc.Object {
|
||||||
|
const devices = objc.Object.fromId(mtl.MTLCopyAllDevices());
|
||||||
|
defer devices.release();
|
||||||
|
var chosen_device: ?objc.Object = null;
|
||||||
|
var iter = devices.iterate();
|
||||||
|
while (iter.next()) |device| {
|
||||||
|
// We want a GPU that’s connected to a display.
|
||||||
|
if (device.getProperty(bool, "isHeadless")) continue;
|
||||||
|
chosen_device = device;
|
||||||
|
// If the user has an eGPU plugged in, they probably want
|
||||||
|
// to use it. Otherwise, integrated GPUs are better for
|
||||||
|
// battery life and thermals.
|
||||||
|
if (device.getProperty(bool, "isRemovable") or
|
||||||
|
device.getProperty(bool, "isLowPower")) break;
|
||||||
|
}
|
||||||
|
const device = chosen_device orelse return error.NoMetalDevice;
|
||||||
|
return device.retain();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *GPUState) void {
|
pub fn deinit(self: *GPUState) void {
|
||||||
// Wait for all of our inflight draws to complete so that
|
// Wait for all of our inflight draws to complete so that
|
||||||
// we can cleanly deinit our GPU state.
|
// we can cleanly deinit our GPU state.
|
||||||
for (0..BufferCount) |_| self.frame_sema.wait();
|
for (0..BufferCount) |_| self.frame_sema.wait();
|
||||||
for (&self.frames) |*frame| frame.deinit();
|
for (&self.frames) |*frame| frame.deinit();
|
||||||
self.instance.deinit();
|
self.instance.deinit();
|
||||||
self.queue.msgSend(void, objc.sel("release"), .{});
|
self.queue.release();
|
||||||
|
self.device.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the next frame state to draw to. This will wait on the
|
/// Get the next frame state to draw to. This will wait on the
|
||||||
@ -269,13 +289,13 @@ pub const FrameState = struct {
|
|||||||
.size = 8,
|
.size = 8,
|
||||||
.format = .grayscale,
|
.format = .grayscale,
|
||||||
});
|
});
|
||||||
errdefer deinitMTLResource(grayscale);
|
errdefer grayscale.release();
|
||||||
const color = try initAtlasTexture(device, &.{
|
const color = try initAtlasTexture(device, &.{
|
||||||
.data = undefined,
|
.data = undefined,
|
||||||
.size = 8,
|
.size = 8,
|
||||||
.format = .rgba,
|
.format = .rgba,
|
||||||
});
|
});
|
||||||
errdefer deinitMTLResource(color);
|
errdefer color.release();
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.uniforms = uniforms,
|
.uniforms = uniforms,
|
||||||
@ -290,8 +310,8 @@ pub const FrameState = struct {
|
|||||||
self.uniforms.deinit();
|
self.uniforms.deinit();
|
||||||
self.cells.deinit();
|
self.cells.deinit();
|
||||||
self.cells_bg.deinit();
|
self.cells_bg.deinit();
|
||||||
deinitMTLResource(self.grayscale);
|
self.grayscale.release();
|
||||||
deinitMTLResource(self.color);
|
self.color.release();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -319,8 +339,8 @@ pub const CustomShaderState = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *CustomShaderState) void {
|
pub fn deinit(self: *CustomShaderState) void {
|
||||||
deinitMTLResource(self.front_texture);
|
self.front_texture.release();
|
||||||
deinitMTLResource(self.back_texture);
|
self.back_texture.release();
|
||||||
self.sampler.deinit();
|
self.sampler.deinit();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -2057,8 +2077,8 @@ pub fn setScreenSize(
|
|||||||
// Only free our previous texture if this isn't our first
|
// Only free our previous texture if this isn't our first
|
||||||
// time setting the custom shader state.
|
// time setting the custom shader state.
|
||||||
if (state.uniforms.resolution[0] > 0) {
|
if (state.uniforms.resolution[0] > 0) {
|
||||||
deinitMTLResource(state.front_texture);
|
state.front_texture.release();
|
||||||
deinitMTLResource(state.back_texture);
|
state.back_texture.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
state.uniforms.resolution = .{
|
state.uniforms.resolution = .{
|
||||||
@ -2982,7 +3002,7 @@ fn syncAtlasTexture(device: objc.Object, atlas: *const font.Atlas, texture: *obj
|
|||||||
const width = texture.getProperty(c_ulong, "width");
|
const width = texture.getProperty(c_ulong, "width");
|
||||||
if (atlas.size > width) {
|
if (atlas.size > width) {
|
||||||
// Free our old texture
|
// Free our old texture
|
||||||
deinitMTLResource(texture.*);
|
texture.*.release();
|
||||||
|
|
||||||
// Reallocate
|
// Reallocate
|
||||||
texture.* = try initAtlasTexture(device, atlas);
|
texture.* = try initAtlasTexture(device, atlas);
|
||||||
@ -3049,12 +3069,6 @@ fn initAtlasTexture(device: objc.Object, atlas: *const font.Atlas) !objc.Object
|
|||||||
return objc.Object.fromId(id);
|
return objc.Object.fromId(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deinitialize a metal resource (buffer, texture, etc.) and free the
|
|
||||||
/// memory associated with it.
|
|
||||||
fn deinitMTLResource(obj: objc.Object) void {
|
|
||||||
obj.msgSend(void, objc.sel("release"), .{});
|
|
||||||
}
|
|
||||||
|
|
||||||
test {
|
test {
|
||||||
_ = mtl_cell;
|
_ = mtl_cell;
|
||||||
}
|
}
|
||||||
|
@ -175,4 +175,4 @@ pub const MTLSize = extern struct {
|
|||||||
depth: c_ulong,
|
depth: c_ulong,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub extern "c" fn MTLCreateSystemDefaultDevice() ?*anyopaque;
|
pub extern "c" fn MTLCopyAllDevices() ?*anyopaque;
|
||||||
|
Reference in New Issue
Block a user