renderer/vulkan: revert built-in SPV precompile until cross-shader bug found
Even with image_vert + image_frag runtime-compiled while the
other 7 used precompiled SPV, kitty images still rendered at
full-window size. That rules out the SPV bytes for those two
shaders specifically — the bug is some cross-shader interaction
the precompile path triggers that runtime glslang doesn't.
Hypotheses worth chasing later:
- Auto-map binding numbers depend on glslang TLS state. Build-
time spawns a fresh process per shader → fresh state each
time. Runtime compiles 9 sequentially → shared TLS pool
accumulates assignments. Final bindings/locations could
diverge in ways that affect a specific pipeline's draw.
- ProcessDeferred's SetupBuiltinSymbolTable might cache cross-
compile and produce different inlined builtins between
"fresh process" and "Nth call in same process".
- The std140 layout we verified matches IS correct — host
Globals struct ↔ SPV decorate offsets line up. So it's not
a UBO layout mismatch.
Going back to all-runtime Module.init via glslang. ~5 MB
heaptrack-only leak comes back; user-visible image rendering
correctness restored.
VulkanSpv.zig + src/vulkan_spvgen.zig + the build step stay in
the tree (small build overhead, no runtime cost since the
generated module isn't imported). A future investigation can
turn it back on by adding back the @import("vulkan_spv") + 9
Module.initFromSpirv calls once we understand the cross-shader
issue.
Co-Authored-By: claude-flow <ruv@ruv.net>
pull/12846/head
parent
99d26181ed
commit
de590c2a25
|
|
@ -30,19 +30,11 @@ const DescriptorPool = vulkan.DescriptorPool;
|
|||
const Pipeline = @import("Pipeline.zig");
|
||||
const math = @import("../../math.zig");
|
||||
|
||||
/// Build-time-precompiled SPIR-V blobs for the 9 built-in
|
||||
/// shaders. Generated by `src/build/VulkanSpv.zig`. Each decl
|
||||
/// is `[]const u32` backed by a comptime-aligned u8 array
|
||||
/// (align(@alignOf(u32))) so the underlying storage is on a
|
||||
/// 4-byte boundary — Module.initFromSpirv can consume the
|
||||
/// slices directly without alignment surgery.
|
||||
///
|
||||
/// Skipping the runtime glslang call path for built-ins
|
||||
/// eliminates the per-process TPoolAllocator high-water-mark
|
||||
/// leak that the first-surface compile otherwise leaves
|
||||
/// behind (~5 MB heaptrack delta). Custom (user) shaders still
|
||||
/// go through glslang at runtime via shadertoy.spirvFromGlsl.
|
||||
const vulkan_spv = @import("vulkan_spv");
|
||||
// Build-time-precompiled SPIR-V blobs are generated by
|
||||
// `src/build/VulkanSpv.zig` and exposed as the `vulkan_spv`
|
||||
// module — currently UNUSED at runtime; see the long
|
||||
// explanation in `Shaders.init` for why we went back to
|
||||
// runtime glslang compilation for built-ins.
|
||||
|
||||
const log = std.log.scoped(.vulkan);
|
||||
|
||||
|
|
@ -920,16 +912,33 @@ pub const Shaders = struct {
|
|||
// runtime via shadertoy.spirvFromGlsl, and the per-frame
|
||||
// shadertoy post-pipeline below still allocates via
|
||||
// `alloc`, so the parameter is still load-bearing.
|
||||
// All built-ins runtime-compiled via glslang. The build-
|
||||
// time SPV precompile path (commits c921c4b2e / 99d26181e)
|
||||
// saves ~5 MB of TPoolAllocator leak per heaptrack but
|
||||
// somehow corrupts kitty image rendering (images fill the
|
||||
// whole window). The diagnostic in 7c045d694... showed
|
||||
// even runtime-compiling image_vert + image_frag while
|
||||
// leaving the other 7 precompiled DIDN'T fix it — so the
|
||||
// bug isn't local to those shaders' SPV, it's some cross-
|
||||
// shader interaction (descriptor binding cross-talk?
|
||||
// ProcessDeferred state divergence between fresh-process
|
||||
// build-time vs sequential-compile runtime?) we don't
|
||||
// understand yet.
|
||||
//
|
||||
// VulkanSpv.zig + src/vulkan_spvgen.zig + the generated
|
||||
// vulkan_spv import stay in tree so a future investigation
|
||||
// can flip the swap back on. ~5 MB cosmetic leak is the
|
||||
// wrong trade-off vs visibly broken images.
|
||||
var modules: Modules = .{
|
||||
.bg_color_frag = try Module.initFromSpirv(device, vulkan_spv.bg_color_frag, .fragment),
|
||||
.bg_image_frag = try Module.initFromSpirv(device, vulkan_spv.bg_image_frag, .fragment),
|
||||
.bg_image_vert = try Module.initFromSpirv(device, vulkan_spv.bg_image_vert, .vertex),
|
||||
.cell_bg_frag = try Module.initFromSpirv(device, vulkan_spv.cell_bg_frag, .fragment),
|
||||
.cell_text_frag = try Module.initFromSpirv(device, vulkan_spv.cell_text_frag, .fragment),
|
||||
.cell_text_vert = try Module.initFromSpirv(device, vulkan_spv.cell_text_vert, .vertex),
|
||||
.full_screen_vert = try Module.initFromSpirv(device, vulkan_spv.full_screen_vert, .vertex),
|
||||
.image_frag = try Module.initFromSpirv(device, vulkan_spv.image_frag, .fragment),
|
||||
.image_vert = try Module.initFromSpirv(device, vulkan_spv.image_vert, .vertex),
|
||||
.bg_color_frag = try Module.init(alloc, device, source.bg_color_frag, .fragment),
|
||||
.bg_image_frag = try Module.init(alloc, device, source.bg_image_frag, .fragment),
|
||||
.bg_image_vert = try Module.init(alloc, device, source.bg_image_vert, .vertex),
|
||||
.cell_bg_frag = try Module.init(alloc, device, source.cell_bg_frag, .fragment),
|
||||
.cell_text_frag = try Module.init(alloc, device, source.cell_text_frag, .fragment),
|
||||
.cell_text_vert = try Module.init(alloc, device, source.cell_text_vert, .vertex),
|
||||
.full_screen_vert = try Module.init(alloc, device, source.full_screen_vert, .vertex),
|
||||
.image_frag = try Module.init(alloc, device, source.image_frag, .fragment),
|
||||
.image_vert = try Module.init(alloc, device, source.image_vert, .vertex),
|
||||
};
|
||||
errdefer {
|
||||
inline for (.{
|
||||
|
|
|
|||
Loading…
Reference in New Issue