mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
Revert "renderer/metal: move shaders to cached state"
This reverts commit bef83446d1cff42946c2a242e3c645350d00c574.
This commit is contained in:
@ -106,6 +106,10 @@ image_placements: ImagePlacementList = .{},
|
|||||||
image_bg_end: u32 = 0,
|
image_bg_end: u32 = 0,
|
||||||
image_text_end: u32 = 0,
|
image_text_end: u32 = 0,
|
||||||
|
|
||||||
|
/// Metal state
|
||||||
|
shaders: Shaders, // Compiled shaders
|
||||||
|
buf_instance: InstanceBuffer, // MTLBuffer
|
||||||
|
|
||||||
/// Metal objects
|
/// Metal objects
|
||||||
device: objc.Object, // MTLDevice
|
device: objc.Object, // MTLDevice
|
||||||
queue: objc.Object, // MTLCommandQueue
|
queue: objc.Object, // MTLCommandQueue
|
||||||
@ -259,6 +263,10 @@ pub fn surfaceInit(surface: *apprt.Surface) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(alloc: Allocator, options: renderer.Options) !Metal {
|
pub fn init(alloc: Allocator, options: renderer.Options) !Metal {
|
||||||
|
var arena = ArenaAllocator.init(alloc);
|
||||||
|
defer arena.deinit();
|
||||||
|
const arena_alloc = arena.allocator();
|
||||||
|
|
||||||
const ViewInfo = struct {
|
const ViewInfo = struct {
|
||||||
view: objc.Object,
|
view: objc.Object,
|
||||||
scaleFactor: f64,
|
scaleFactor: f64,
|
||||||
@ -362,9 +370,26 @@ pub fn init(alloc: Allocator, options: renderer.Options) !Metal {
|
|||||||
});
|
});
|
||||||
errdefer font_shaper.deinit();
|
errdefer font_shaper.deinit();
|
||||||
|
|
||||||
|
// Vertex buffers
|
||||||
|
var buf_instance = try InstanceBuffer.initFill(device, &.{
|
||||||
|
0, 1, 3, // Top-left triangle
|
||||||
|
1, 2, 3, // Bottom-right triangle
|
||||||
|
});
|
||||||
|
errdefer buf_instance.deinit();
|
||||||
|
|
||||||
|
// Load our custom shaders
|
||||||
|
const custom_shaders: []const [:0]const u8 = shadertoy.loadFromFiles(
|
||||||
|
arena_alloc,
|
||||||
|
options.config.custom_shaders.items,
|
||||||
|
.msl,
|
||||||
|
) catch |err| err: {
|
||||||
|
log.warn("error loading custom shaders err={}", .{err});
|
||||||
|
break :err &.{};
|
||||||
|
};
|
||||||
|
|
||||||
// If we have custom shaders then setup our state
|
// If we have custom shaders then setup our state
|
||||||
var custom_shader_state: ?CustomShaderState = state: {
|
var custom_shader_state: ?CustomShaderState = state: {
|
||||||
if (options.config.custom_shaders.items.len == 0) break :state null;
|
if (custom_shaders.len == 0) break :state null;
|
||||||
|
|
||||||
// Build our sampler for our texture
|
// Build our sampler for our texture
|
||||||
var sampler = try mtl_sampler.Sampler.init(device);
|
var sampler = try mtl_sampler.Sampler.init(device);
|
||||||
@ -394,6 +419,10 @@ pub fn init(alloc: Allocator, options: renderer.Options) !Metal {
|
|||||||
};
|
};
|
||||||
errdefer if (custom_shader_state) |*state| state.deinit();
|
errdefer if (custom_shader_state) |*state| state.deinit();
|
||||||
|
|
||||||
|
// Initialize our shaders
|
||||||
|
var shaders = try Shaders.init(alloc, device, custom_shaders);
|
||||||
|
errdefer shaders.deinit(alloc);
|
||||||
|
|
||||||
return Metal{
|
return Metal{
|
||||||
.alloc = alloc,
|
.alloc = alloc,
|
||||||
.config = options.config,
|
.config = options.config,
|
||||||
@ -422,6 +451,10 @@ pub fn init(alloc: Allocator, options: renderer.Options) !Metal {
|
|||||||
.font_group = options.font_group,
|
.font_group = options.font_group,
|
||||||
.font_shaper = font_shaper,
|
.font_shaper = font_shaper,
|
||||||
|
|
||||||
|
// Shaders
|
||||||
|
.shaders = shaders,
|
||||||
|
.buf_instance = buf_instance,
|
||||||
|
|
||||||
// Metal stuff
|
// Metal stuff
|
||||||
.device = device,
|
.device = device,
|
||||||
.queue = queue,
|
.queue = queue,
|
||||||
@ -451,10 +484,14 @@ pub fn deinit(self: *Metal) void {
|
|||||||
}
|
}
|
||||||
self.image_placements.deinit(self.alloc);
|
self.image_placements.deinit(self.alloc);
|
||||||
|
|
||||||
if (self.custom_shader_state) |*state| state.deinit();
|
self.buf_instance.deinit();
|
||||||
if (self.visible_resources) |*v| v.deinit(self.alloc);
|
if (self.visible_resources) |*v| v.deinit();
|
||||||
self.queue.msgSend(void, objc.sel("release"), .{});
|
self.queue.msgSend(void, objc.sel("release"), .{});
|
||||||
|
|
||||||
|
if (self.custom_shader_state) |*state| state.deinit();
|
||||||
|
|
||||||
|
self.shaders.deinit(self.alloc);
|
||||||
|
|
||||||
self.* = undefined;
|
self.* = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -815,19 +852,19 @@ pub fn drawFrame(self: *Metal, surface: *apprt.Surface) !void {
|
|||||||
defer encoder.msgSend(void, objc.sel("endEncoding"), .{});
|
defer encoder.msgSend(void, objc.sel("endEncoding"), .{});
|
||||||
|
|
||||||
// Draw background images first
|
// Draw background images first
|
||||||
try self.drawImagePlacements(encoder, self.image_placements.items[0..self.image_bg_end], resources);
|
try self.drawImagePlacements(encoder, self.image_placements.items[0..self.image_bg_end]);
|
||||||
|
|
||||||
// Then draw background cells
|
// Then draw background cells
|
||||||
try self.drawCells(encoder, &resources.buf_cells_bg, self.cells_bg, resources);
|
try self.drawCells(encoder, &resources.buf_cells_bg, self.cells_bg, resources);
|
||||||
|
|
||||||
// Then draw images under text
|
// Then draw images under text
|
||||||
try self.drawImagePlacements(encoder, self.image_placements.items[self.image_bg_end..self.image_text_end], resources);
|
try self.drawImagePlacements(encoder, self.image_placements.items[self.image_bg_end..self.image_text_end]);
|
||||||
|
|
||||||
// Then draw fg cells
|
// Then draw fg cells
|
||||||
try self.drawCells(encoder, &resources.buf_cells, self.cells, resources);
|
try self.drawCells(encoder, &resources.buf_cells, self.cells, resources);
|
||||||
|
|
||||||
// Then draw remaining images
|
// Then draw remaining images
|
||||||
try self.drawImagePlacements(encoder, self.image_placements.items[self.image_text_end..], resources);
|
try self.drawImagePlacements(encoder, self.image_placements.items[self.image_text_end..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have custom shaders AND we have a screen texture, then we
|
// If we have custom shaders AND we have a screen texture, then we
|
||||||
@ -878,7 +915,7 @@ pub fn drawFrame(self: *Metal, surface: *apprt.Surface) !void {
|
|||||||
);
|
);
|
||||||
defer encoder.msgSend(void, objc.sel("endEncoding"), .{});
|
defer encoder.msgSend(void, objc.sel("endEncoding"), .{});
|
||||||
|
|
||||||
for (resources.shaders.post_pipelines) |pipeline| {
|
for (self.shaders.post_pipelines) |pipeline| {
|
||||||
try self.drawPostShader(encoder, pipeline, &state);
|
try self.drawPostShader(encoder, pipeline, &state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1000,7 +1037,6 @@ fn drawImagePlacements(
|
|||||||
self: *Metal,
|
self: *Metal,
|
||||||
encoder: objc.Object,
|
encoder: objc.Object,
|
||||||
placements: []const mtl_image.Placement,
|
placements: []const mtl_image.Placement,
|
||||||
resources: *const VisibleResources,
|
|
||||||
) !void {
|
) !void {
|
||||||
if (placements.len == 0) return;
|
if (placements.len == 0) return;
|
||||||
|
|
||||||
@ -1008,7 +1044,7 @@ fn drawImagePlacements(
|
|||||||
encoder.msgSend(
|
encoder.msgSend(
|
||||||
void,
|
void,
|
||||||
objc.sel("setRenderPipelineState:"),
|
objc.sel("setRenderPipelineState:"),
|
||||||
.{resources.shaders.image_pipeline.value},
|
.{self.shaders.image_pipeline.value},
|
||||||
);
|
);
|
||||||
|
|
||||||
// Set our uniform, which is the only shared buffer
|
// Set our uniform, which is the only shared buffer
|
||||||
@ -1023,7 +1059,7 @@ fn drawImagePlacements(
|
|||||||
);
|
);
|
||||||
|
|
||||||
for (placements) |placement| {
|
for (placements) |placement| {
|
||||||
try self.drawImagePlacement(encoder, placement, resources);
|
try self.drawImagePlacement(encoder, placement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1031,7 +1067,6 @@ fn drawImagePlacement(
|
|||||||
self: *Metal,
|
self: *Metal,
|
||||||
encoder: objc.Object,
|
encoder: objc.Object,
|
||||||
p: mtl_image.Placement,
|
p: mtl_image.Placement,
|
||||||
resources: *const VisibleResources,
|
|
||||||
) !void {
|
) !void {
|
||||||
// Look up the image
|
// Look up the image
|
||||||
const image = self.images.get(p.image_id) orelse {
|
const image = self.images.get(p.image_id) orelse {
|
||||||
@ -1109,7 +1144,7 @@ fn drawImagePlacement(
|
|||||||
@intFromEnum(mtl.MTLPrimitiveType.triangle),
|
@intFromEnum(mtl.MTLPrimitiveType.triangle),
|
||||||
@as(c_ulong, 6),
|
@as(c_ulong, 6),
|
||||||
@intFromEnum(mtl.MTLIndexType.uint16),
|
@intFromEnum(mtl.MTLIndexType.uint16),
|
||||||
resources.buf_instance.buffer.value,
|
self.buf_instance.buffer.value,
|
||||||
@as(c_ulong, 0),
|
@as(c_ulong, 0),
|
||||||
@as(c_ulong, 1),
|
@as(c_ulong, 1),
|
||||||
},
|
},
|
||||||
@ -1138,7 +1173,7 @@ fn drawCells(
|
|||||||
encoder.msgSend(
|
encoder.msgSend(
|
||||||
void,
|
void,
|
||||||
objc.sel("setRenderPipelineState:"),
|
objc.sel("setRenderPipelineState:"),
|
||||||
.{resources.shaders.cell_pipeline.value},
|
.{self.shaders.cell_pipeline.value},
|
||||||
);
|
);
|
||||||
|
|
||||||
// Set our buffers
|
// Set our buffers
|
||||||
@ -1180,7 +1215,7 @@ fn drawCells(
|
|||||||
@intFromEnum(mtl.MTLPrimitiveType.triangle),
|
@intFromEnum(mtl.MTLPrimitiveType.triangle),
|
||||||
@as(c_ulong, 6),
|
@as(c_ulong, 6),
|
||||||
@intFromEnum(mtl.MTLIndexType.uint16),
|
@intFromEnum(mtl.MTLIndexType.uint16),
|
||||||
resources.buf_instance.buffer.value,
|
self.buf_instance.buffer.value,
|
||||||
@as(c_ulong, 0),
|
@as(c_ulong, 0),
|
||||||
@as(c_ulong, cells.items.len),
|
@as(c_ulong, cells.items.len),
|
||||||
},
|
},
|
||||||
@ -2183,65 +2218,34 @@ fn deinitMTLResource(obj: objc.Object) void {
|
|||||||
/// This is a performance optimization that makes it so that Ghostty
|
/// This is a performance optimization that makes it so that Ghostty
|
||||||
/// only uses GPU resources for views that are currently visible.
|
/// only uses GPU resources for views that are currently visible.
|
||||||
const VisibleResources = struct {
|
const VisibleResources = struct {
|
||||||
shaders: Shaders, // Compiled shaders
|
|
||||||
buf_cells: CellBuffer, // Vertex buffer for cells
|
buf_cells: CellBuffer, // Vertex buffer for cells
|
||||||
buf_cells_bg: CellBuffer, // Vertex buffer for background cells
|
buf_cells_bg: CellBuffer, // Vertex buffer for background cells
|
||||||
buf_instance: InstanceBuffer, // MTLBuffer
|
|
||||||
texture_greyscale: objc.Object, // MTLTexture
|
texture_greyscale: objc.Object, // MTLTexture
|
||||||
texture_color: objc.Object, // MTLTexture
|
texture_color: objc.Object, // MTLTexture
|
||||||
|
|
||||||
pub fn init(m: *Metal) !VisibleResources {
|
pub fn init(m: *Metal) !VisibleResources {
|
||||||
var arena = ArenaAllocator.init(m.alloc);
|
|
||||||
defer arena.deinit();
|
|
||||||
const arena_alloc = arena.allocator();
|
|
||||||
|
|
||||||
// Load our custom shaders
|
|
||||||
const custom_shaders: []const [:0]const u8 = shadertoy.loadFromFiles(
|
|
||||||
arena_alloc,
|
|
||||||
m.config.custom_shaders.items,
|
|
||||||
.msl,
|
|
||||||
) catch |err| err: {
|
|
||||||
log.warn("error loading custom shaders err={}", .{err});
|
|
||||||
break :err &.{};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Shaders
|
|
||||||
var shaders = try Shaders.init(m.alloc, m.device, custom_shaders);
|
|
||||||
errdefer shaders.deinit(m.alloc);
|
|
||||||
|
|
||||||
// Buffers
|
|
||||||
var buf_cells = try CellBuffer.init(m.device, 160 * 160);
|
var buf_cells = try CellBuffer.init(m.device, 160 * 160);
|
||||||
errdefer buf_cells.deinit();
|
errdefer buf_cells.deinit();
|
||||||
var buf_cells_bg = try CellBuffer.init(m.device, 160 * 160);
|
var buf_cells_bg = try CellBuffer.init(m.device, 160 * 160);
|
||||||
errdefer buf_cells_bg.deinit();
|
errdefer buf_cells_bg.deinit();
|
||||||
var buf_instance = try InstanceBuffer.initFill(m.device, &.{
|
|
||||||
0, 1, 3, // Top-left triangle
|
|
||||||
1, 2, 3, // Bottom-right triangle
|
|
||||||
});
|
|
||||||
errdefer buf_instance.deinit();
|
|
||||||
|
|
||||||
// Textures
|
|
||||||
const texture_greyscale = try initAtlasTexture(m.device, &m.font_group.atlas_greyscale);
|
const texture_greyscale = try initAtlasTexture(m.device, &m.font_group.atlas_greyscale);
|
||||||
errdefer deinitMTLResource(texture_greyscale);
|
errdefer deinitMTLResource(texture_greyscale);
|
||||||
const texture_color = try initAtlasTexture(m.device, &m.font_group.atlas_color);
|
const texture_color = try initAtlasTexture(m.device, &m.font_group.atlas_color);
|
||||||
errdefer deinitMTLResource(texture_color);
|
errdefer deinitMTLResource(texture_color);
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.shaders = shaders,
|
|
||||||
.buf_cells = buf_cells,
|
.buf_cells = buf_cells,
|
||||||
.buf_cells_bg = buf_cells_bg,
|
.buf_cells_bg = buf_cells_bg,
|
||||||
.buf_instance = buf_instance,
|
|
||||||
.texture_greyscale = texture_greyscale,
|
.texture_greyscale = texture_greyscale,
|
||||||
.texture_color = texture_color,
|
.texture_color = texture_color,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *VisibleResources, alloc: Allocator) void {
|
pub fn deinit(self: *VisibleResources) void {
|
||||||
self.buf_cells.deinit();
|
self.buf_cells.deinit();
|
||||||
self.buf_cells_bg.deinit();
|
self.buf_cells_bg.deinit();
|
||||||
self.buf_instance.deinit();
|
|
||||||
deinitMTLResource(self.texture_greyscale);
|
deinitMTLResource(self.texture_greyscale);
|
||||||
deinitMTLResource(self.texture_color);
|
deinitMTLResource(self.texture_color);
|
||||||
self.shaders.deinit(alloc);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user