More work on slangc compilation

This commit is contained in:
Kovid Goyal
2026-06-29 08:30:25 +05:30
parent 71fd4d3c57
commit 3f89d0a94b
4 changed files with 83 additions and 15 deletions

View File

@@ -0,0 +1,28 @@
#language slang 2026
// Copyright (C) 2026 Kovid Goyal <kovid at kovidgoyal.net>
// Distributed under terms of the GPLv3 license.
module alpha_blend;
// Alpha blend two colors returning the resulting color pre-multiplied by its alpha
// and its alpha. See https://en.wikipedia.org/wiki/Alpha_compositing
public float4 alpha_blend(float4 over, float4 under) {
float alpha = lerp(under.a, 1.0f, over.a);
float3 combined_color = lerp(under.rgb * under.a, over.rgb, over.a);
return float4(combined_color, alpha);
}
// Same as alpha_blend() except that it assumes over and under are both premultiplied.
public float4 alpha_blend_premul(float4 over, float4 under) {
float inv_over_alpha = 1.0f - over.a;
float alpha = over.a + under.a * inv_over_alpha;
return float4(over.rgb + under.rgb * inv_over_alpha, alpha);
}
// Same as alpha_blend_premul with under_alpha = 1 outputs a blended color
// with alpha 1 which is effectively pre-multiplied since alpha is 1
public float4 alpha_blend_premul(float4 over, float3 under) {
float inv_over_alpha = 1.0f - over.a;
return float4(over.rgb + under.rgb * inv_over_alpha, 1.0f);
}

View File

@@ -13,7 +13,7 @@ struct VSOutput
[shader("vertex")]
VSOutput main(
VSOutput vertex_main(
uint vertex_id : SV_VertexID,
uniform float4 src_rect,
uniform float4 dest_rect,
@@ -25,3 +25,11 @@ VSOutput main(
return output;
}
Sampler2D image;
[shader("fragment")]
float4 fragment_main(float2 texcoord : TEXCOORD) : SV_Target
{
float4 color = image.Sample(texcoord);
return color;
}

View File

@@ -178,7 +178,7 @@ def iter_entry_point_shaders(sources: dict[str, SlangFile], build_dir: str, dest
def commands_to_compile_to_spirv(sources: dict[str, SlangFile], build_dir: str, dest_dir: str, built_files: list[str]) -> Iterator[Command]:
for base_dest, slang_module, cmd, sfile in iter_entry_point_shaders(sources, build_dir, dest_dir):
dest = f'{base_dest}.spv'
cmd += ['-target', 'spirv', '-o', dest]
cmd += ['-target', 'spirv', '-capability', 'vk_mem_model', '-fvk-use-entrypoint-name', '-o', dest]
output_mtime = safe_mtime(dest)
module_mtime = os.path.getmtime(slang_module)
needs_build = output_mtime < module_mtime
@@ -189,19 +189,17 @@ def commands_to_compile_to_spirv(sources: dict[str, SlangFile], build_dir: str,
def commands_to_compile_to_glsl(sources: dict[str, SlangFile], build_dir: str, dest_dir: str, built_glsl_files: list[str]) -> Iterator[Command]:
for base_dest, slang_module, cmd, sfile in iter_entry_point_shaders(sources, build_dir, dest_dir):
output_mtime = future()
dest_files = []
cmd.extend(('-line-directive-mode', 'none'))
for ep in sfile.entry_points:
dest = f'{base_dest}.{ep.stage.name}.glsl'
cmd += ['-entry', ep.name, '-stage', ep.stage.name, '-target', 'glsl', '-profile', 'glsl_330', '-o', dest]
dest_files.append(dest)
output_mtime = min(output_mtime, safe_mtime(dest))
module_mtime = os.path.getmtime(slang_module)
needs_build = output_mtime < module_mtime
if needs_build:
built_glsl_files.extend(dest_files)
yield Command(needs_build, f'Linking |{os.path.basename(slang_module)}| to GLSL ...', cmd)
for ep in sfile.entry_points:
c = list(cmd)
c.extend(('-line-directive-mode', 'none', '-target', 'glsl', '-profile', 'glsl_330'))
dest = f'{base_dest}.{ep.stage.name}.glsl'
c += ['-entry', ep.name, '-stage', ep.stage.name, '-o', dest]
output_mtime = safe_mtime(dest)
needs_build = output_mtime < module_mtime
if needs_build:
built_glsl_files.append(dest)
yield Command(needs_build, f'Linking |{os.path.basename(slang_module)}| to GLSL {ep.stage} shader ...', c)
def fixup_opengl_code(glsl_code: str) -> str:
@@ -234,7 +232,7 @@ def fixup_opengl_code(glsl_code: str) -> str:
line = '#version 330 core'
elif line.startswith('#extension ') or line in ('layout(row_major) buffer;', 'layout(push_constant)'):
line = '// ' + line
elif line.startswith('layout(location ='):
elif line.startswith('layout(location =') or line.startswith('layout(binding ='):
line = '// ' + line
else:
words = line.split()

34
kitty/shaders/utils.slang Normal file
View File

@@ -0,0 +1,34 @@
#language slang 2026
// Copyright (C) 2026 Kovid Goyal <kovid at kovidgoyal.net>
// Distributed under terms of the GPLv3 license.
module utils;
// Return 0 if x < 1 otherwise 1
__generic<T : __BuiltinFloatingPointType, int N = 1>
vector<T, N> zero_or_one(vector<T, N> x) {
return step((vector<T, N>)1.0f, x);
}
// condition must be zero or one. When 1 thenval is returned otherwise elseval
__generic<T : __BuiltinFloatingPointType, int N = 1>
vector<T, N> if_one_then(vector<T, N> condition, vector<T, N> thenval, vector<T, N> elseval) {
return lerp(elseval, thenval, condition);
}
// a < b ? thenval : elseval
__generic<T : __BuiltinFloatingPointType, int N = 1>
vector<T, N> if_less_than(vector<T, N> a, vector<T, N> b, vector<T, N> thenval, vector<T, N> elseval) {
return lerp(thenval, elseval, step(b, a));
}
// Replaces vec4(rgb * a, a)
float4 vec4_premul(float3 rgb, float a) {
return float4(rgb * a, a);
}
// Overloaded variation replacing vec4(rgba.rgb * rgba.a, rgba.a)
float4 vec4_premul(float4 rgba) {
return float4(rgba.rgb * rgba.a, rgba.a);
}