mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-10-04 08:56:32 +00:00
macos: enable Metal shader logging
This enables the compile options and Xcode configuration so that logging in Metal shaders shows up in our Xcode debug console. This doesn't add any log messages, but makes it so that when we iterate on the shaders in the future, we can add and see logs to help us out.
This commit is contained in:
6
.github/workflows/test.yml
vendored
6
.github/workflows/test.yml
vendored
@@ -196,6 +196,9 @@ jobs:
|
|||||||
name: ghostty
|
name: ghostty
|
||||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||||
|
|
||||||
|
- name: XCode Select
|
||||||
|
run: sudo xcode-select -s /Applications/Xcode_16.0.app
|
||||||
|
|
||||||
- name: Test All
|
- name: Test All
|
||||||
run: |
|
run: |
|
||||||
# OpenGL
|
# OpenGL
|
||||||
@@ -352,6 +355,9 @@ jobs:
|
|||||||
name: ghostty
|
name: ghostty
|
||||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||||
|
|
||||||
|
- name: XCode Select
|
||||||
|
run: sudo xcode-select -s /Applications/Xcode_16.0.app
|
||||||
|
|
||||||
- name: test
|
- name: test
|
||||||
run: nix develop -c zig build test
|
run: nix develop -c zig build test
|
||||||
|
|
||||||
|
11
build.zig
11
build.zig
@@ -1384,10 +1384,21 @@ fn addMetallib(
|
|||||||
b: *std.Build,
|
b: *std.Build,
|
||||||
step: *std.Build.Step.Compile,
|
step: *std.Build.Step.Compile,
|
||||||
) !void {
|
) !void {
|
||||||
|
const optimize = step.root_module.optimize.?;
|
||||||
|
|
||||||
const metal_step = MetallibStep.create(b, .{
|
const metal_step = MetallibStep.create(b, .{
|
||||||
.name = "Ghostty",
|
.name = "Ghostty",
|
||||||
.target = step.root_module.resolved_target.?,
|
.target = step.root_module.resolved_target.?,
|
||||||
.sources = &.{b.path("src/renderer/shaders/cell.metal")},
|
.sources = &.{b.path("src/renderer/shaders/cell.metal")},
|
||||||
|
.logging = switch (optimize) {
|
||||||
|
.Debug,
|
||||||
|
=> true,
|
||||||
|
|
||||||
|
.ReleaseFast,
|
||||||
|
.ReleaseSmall,
|
||||||
|
.ReleaseSafe,
|
||||||
|
=> false,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
metal_step.output.addStepDependencies(&step.step);
|
metal_step.output.addStepDependencies(&step.step);
|
||||||
|
@@ -55,6 +55,23 @@
|
|||||||
isEnabled = "YES">
|
isEnabled = "YES">
|
||||||
</CommandLineArgument>
|
</CommandLineArgument>
|
||||||
</CommandLineArguments>
|
</CommandLineArguments>
|
||||||
|
<EnvironmentVariables>
|
||||||
|
<EnvironmentVariable
|
||||||
|
key = "MTL_LOG_BUFFER_SIZE"
|
||||||
|
value = "4096"
|
||||||
|
isEnabled = "YES">
|
||||||
|
</EnvironmentVariable>
|
||||||
|
<EnvironmentVariable
|
||||||
|
key = "MTL_LOG_LEVEL"
|
||||||
|
value = "MTLLogLevelDebug"
|
||||||
|
isEnabled = "YES">
|
||||||
|
</EnvironmentVariable>
|
||||||
|
<EnvironmentVariable
|
||||||
|
key = "MTL_LOG_TO_STDERR"
|
||||||
|
value = "1"
|
||||||
|
isEnabled = "YES">
|
||||||
|
</EnvironmentVariable>
|
||||||
|
</EnvironmentVariables>
|
||||||
<AdditionalOptions>
|
<AdditionalOptions>
|
||||||
<AdditionalOption
|
<AdditionalOption
|
||||||
key = "NSZombieEnabled"
|
key = "NSZombieEnabled"
|
||||||
|
@@ -16,6 +16,9 @@ pub const Options = struct {
|
|||||||
|
|
||||||
/// The Metal source files.
|
/// The Metal source files.
|
||||||
sources: []const LazyPath,
|
sources: []const LazyPath,
|
||||||
|
|
||||||
|
/// Whether to enable Metal shader logging.
|
||||||
|
logging: bool = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
step: *Step,
|
step: *Step,
|
||||||
@@ -42,7 +45,20 @@ pub fn create(b: *std.Build, opts: Options) *MetallibStep {
|
|||||||
b,
|
b,
|
||||||
b.fmt("metal {s}", .{opts.name}),
|
b.fmt("metal {s}", .{opts.name}),
|
||||||
);
|
);
|
||||||
run_ir.addArgs(&.{ "xcrun", "-sdk", sdk, "metal", "-o" });
|
run_ir.addArgs(&.{
|
||||||
|
"xcrun",
|
||||||
|
"-sdk",
|
||||||
|
sdk,
|
||||||
|
"metal",
|
||||||
|
"-std=metal3.2",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (opts.logging) run_ir.addArgs(&.{
|
||||||
|
// https://developer.apple.com/documentation/metal/logging_shader_debug_messages
|
||||||
|
"-fmetal-enable-logging",
|
||||||
|
});
|
||||||
|
|
||||||
|
run_ir.addArgs(&.{"-o"});
|
||||||
const output_ir = run_ir.addOutputFileArg(b.fmt("{s}.ir", .{opts.name}));
|
const output_ir = run_ir.addOutputFileArg(b.fmt("{s}.ir", .{opts.name}));
|
||||||
run_ir.addArgs(&.{"-c"});
|
run_ir.addArgs(&.{"-c"});
|
||||||
for (opts.sources) |source| run_ir.addFileArg(source);
|
for (opts.sources) |source| run_ir.addFileArg(source);
|
||||||
|
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
using namespace metal;
|
using namespace metal;
|
||||||
|
|
||||||
|
constant os_log logger("com.mitchellh.ghostty", "cell");
|
||||||
|
|
||||||
enum Padding : uint8_t {
|
enum Padding : uint8_t {
|
||||||
EXTEND_LEFT = 1u,
|
EXTEND_LEFT = 1u,
|
||||||
EXTEND_RIGHT = 2u,
|
EXTEND_RIGHT = 2u,
|
||||||
@@ -79,9 +81,7 @@ struct FullScreenVertexOut {
|
|||||||
float4 position [[position]];
|
float4 position [[position]];
|
||||||
};
|
};
|
||||||
|
|
||||||
vertex FullScreenVertexOut full_screen_vertex(
|
vertex FullScreenVertexOut full_screen_vertex(uint vid [[vertex_id]]) {
|
||||||
uint vid [[vertex_id]]
|
|
||||||
) {
|
|
||||||
FullScreenVertexOut out;
|
FullScreenVertexOut out;
|
||||||
|
|
||||||
float4 position;
|
float4 position;
|
||||||
@@ -112,12 +112,11 @@ vertex FullScreenVertexOut full_screen_vertex(
|
|||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
#pragma mark - Cell BG Shader
|
#pragma mark - Cell BG Shader
|
||||||
|
|
||||||
fragment float4 cell_bg_fragment(
|
fragment float4 cell_bg_fragment(FullScreenVertexOut in [[stage_in]],
|
||||||
FullScreenVertexOut in [[stage_in]],
|
|
||||||
constant uchar4* cells [[buffer(0)]],
|
constant uchar4* cells [[buffer(0)]],
|
||||||
constant Uniforms& uniforms [[buffer(1)]]
|
constant Uniforms& uniforms [[buffer(1)]]) {
|
||||||
) {
|
int2 grid_pos = int2(
|
||||||
int2 grid_pos = int2(floor((in.position.xy - uniforms.grid_padding.wx) / uniforms.cell_size));
|
floor((in.position.xy - uniforms.grid_padding.wx) / uniforms.cell_size));
|
||||||
|
|
||||||
// Clamp x position, extends edge bg colors in to padding on sides.
|
// Clamp x position, extends edge bg colors in to padding on sides.
|
||||||
if (grid_pos.x < 0) {
|
if (grid_pos.x < 0) {
|
||||||
@@ -197,12 +196,12 @@ struct CellTextVertexOut {
|
|||||||
float2 tex_coord;
|
float2 tex_coord;
|
||||||
};
|
};
|
||||||
|
|
||||||
vertex CellTextVertexOut cell_text_vertex(
|
vertex CellTextVertexOut cell_text_vertex(uint vid [[vertex_id]],
|
||||||
uint vid [[vertex_id]],
|
|
||||||
CellTextVertexIn in [[stage_in]],
|
CellTextVertexIn in [[stage_in]],
|
||||||
constant Uniforms& uniforms [[buffer(1)]],
|
constant Uniforms& uniforms
|
||||||
constant uchar4 *bg_colors [[buffer(2)]]
|
[[buffer(1)]],
|
||||||
) {
|
constant uchar4* bg_colors
|
||||||
|
[[buffer(2)]]) {
|
||||||
// Convert the grid x, y into world space x, y by accounting for cell size
|
// Convert the grid x, y into world space x, y by accounting for cell size
|
||||||
float2 cell_pos = uniforms.cell_size * float2(in.grid_pos);
|
float2 cell_pos = uniforms.cell_size * float2(in.grid_pos);
|
||||||
|
|
||||||
@@ -287,36 +286,31 @@ vertex CellTextVertexOut cell_text_vertex(
|
|||||||
// and Powerline glyphs to be unaffected (else parts of the line would
|
// and Powerline glyphs to be unaffected (else parts of the line would
|
||||||
// have different colors as some parts are displayed via background colors).
|
// have different colors as some parts are displayed via background colors).
|
||||||
if (uniforms.min_contrast > 1.0f && in.mode == MODE_TEXT) {
|
if (uniforms.min_contrast > 1.0f && in.mode == MODE_TEXT) {
|
||||||
float4 bg_color = float4(bg_colors[in.grid_pos.y * uniforms.grid_size.x + in.grid_pos.x]) / 255.0f;
|
float4 bg_color =
|
||||||
|
float4(
|
||||||
|
bg_colors[in.grid_pos.y * uniforms.grid_size.x + in.grid_pos.x]) /
|
||||||
|
255.0f;
|
||||||
out.color = contrasted_color(uniforms.min_contrast, out.color, bg_color);
|
out.color = contrasted_color(uniforms.min_contrast, out.color, bg_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this cell is the cursor cell, then we need to change the color.
|
// If this cell is the cursor cell, then we need to change the color.
|
||||||
if (
|
if (in.mode != MODE_TEXT_CURSOR &&
|
||||||
in.mode != MODE_TEXT_CURSOR &&
|
(in.grid_pos.x == uniforms.cursor_pos.x ||
|
||||||
(
|
uniforms.cursor_wide && in.grid_pos.x == uniforms.cursor_pos.x + 1) &&
|
||||||
in.grid_pos.x == uniforms.cursor_pos.x ||
|
in.grid_pos.y == uniforms.cursor_pos.y) {
|
||||||
uniforms.cursor_wide &&
|
|
||||||
in.grid_pos.x == uniforms.cursor_pos.x + 1
|
|
||||||
) &&
|
|
||||||
in.grid_pos.y == uniforms.cursor_pos.y
|
|
||||||
) {
|
|
||||||
out.color = float4(uniforms.cursor_color) / 255.0f;
|
out.color = float4(uniforms.cursor_color) / 255.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
fragment float4 cell_text_fragment(
|
fragment float4 cell_text_fragment(CellTextVertexOut in [[stage_in]],
|
||||||
CellTextVertexOut in [[stage_in]],
|
texture2d<float> textureGrayscale
|
||||||
texture2d<float> textureGrayscale [[texture(0)]],
|
[[texture(0)]],
|
||||||
texture2d<float> textureColor [[texture(1)]]
|
texture2d<float> textureColor
|
||||||
) {
|
[[texture(1)]]) {
|
||||||
constexpr sampler textureSampler(
|
constexpr sampler textureSampler(coord::pixel, address::clamp_to_edge,
|
||||||
coord::pixel,
|
filter::nearest);
|
||||||
address::clamp_to_edge,
|
|
||||||
filter::nearest
|
|
||||||
);
|
|
||||||
|
|
||||||
switch (in.mode) {
|
switch (in.mode) {
|
||||||
default:
|
default:
|
||||||
@@ -367,12 +361,10 @@ struct ImageVertexOut {
|
|||||||
float2 tex_coord;
|
float2 tex_coord;
|
||||||
};
|
};
|
||||||
|
|
||||||
vertex ImageVertexOut image_vertex(
|
vertex ImageVertexOut image_vertex(uint vid [[vertex_id]],
|
||||||
uint vid [[vertex_id]],
|
|
||||||
ImageVertexIn in [[stage_in]],
|
ImageVertexIn in [[stage_in]],
|
||||||
texture2d<uint> image [[texture(0)]],
|
texture2d<uint> image [[texture(0)]],
|
||||||
constant Uniforms& uniforms [[buffer(1)]]
|
constant Uniforms& uniforms [[buffer(1)]]) {
|
||||||
) {
|
|
||||||
// The size of the image in pixels
|
// The size of the image in pixels
|
||||||
float2 image_size = float2(image.get_width(), image.get_height());
|
float2 image_size = float2(image.get_width(), image.get_height());
|
||||||
|
|
||||||
@@ -409,10 +401,8 @@ vertex ImageVertexOut image_vertex(
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
fragment float4 image_fragment(
|
fragment float4 image_fragment(ImageVertexOut in [[stage_in]],
|
||||||
ImageVertexOut in [[stage_in]],
|
texture2d<uint> image [[texture(0)]]) {
|
||||||
texture2d<uint> image [[texture(0)]]
|
|
||||||
) {
|
|
||||||
constexpr sampler textureSampler(address::clamp_to_edge, filter::linear);
|
constexpr sampler textureSampler(address::clamp_to_edge, filter::linear);
|
||||||
|
|
||||||
// Ehhhhh our texture is in RGBA8Uint but our color attachment is
|
// Ehhhhh our texture is in RGBA8Uint but our color attachment is
|
||||||
@@ -426,4 +416,3 @@ fragment float4 image_fragment(
|
|||||||
result.rgb *= result.a;
|
result.rgb *= result.a;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user