diff --git a/build.zig b/build.zig index f66b5da..90ce479 100644 --- a/build.zig +++ b/build.zig @@ -10,6 +10,7 @@ gltf2ozz: ozz.GltfToOzz, options: *std.Build.Step.Options, cookShaders: bool, +backlogRoot: []const u8, // list of all shaders discovered under // content/_shaders/def reflectShaderPathList: [][]u8 = undefined, @@ -33,6 +34,7 @@ const ozz = @import("ozz"); pub const InitOptions = struct { import_name: []const u8 = "Backlog", + backlogRoot: []const u8 = "./BacklogEngine", target: Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, }; @@ -49,6 +51,7 @@ pub fn init(b: *std.Build, opts: InitOptions) BuildSystem { .target = opts.target, .optimize = opts.optimize, .nw_mod = nwdep.module("Backlog"), + .backlogRoot = opts.backlogRoot, .spirvReflect = SpirvReflect.SpirvGenerator2.init(nwdep.builder, .{}), .options = createGameOptions(b), .gltf2ozz = ozz.GltfToOzz.init(nwdep.builder, .{}), @@ -126,7 +129,13 @@ pub fn addProgram(self: *BuildSystem, opts: AddProgramOptions) *std.Build.Step.C mod.addImport("Backlog", self.nw_mod); exe.root_module.addOptions("BacklogOptions", self.options); - if (self.cookShaders) {} + if (self.cookShaders) { + const cookShadersScript = b.fmt("{s}/tools/scripts/cookShaders.py", .{self.backlogRoot}); + const cookShadersCommand = b.addSystemCommand(&[_][]const u8{"python"}); + cookShadersCommand.addArg(cookShadersScript); + + run_exe.dependOn(&cookShadersCommand.step); + } // I want to generate definitions from the spirv-reflect-tool during pre-build. // diff --git a/engine/platform/build.zig b/engine/platform/build.zig index 5fa02e2..fadd8e0 100644 --- a/engine/platform/build.zig +++ b/engine/platform/build.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const sdl3 = @import("sdl3"); // pub fn addLib(b: *std.Build, exe: *std.Build.Step.Compile, comptime packagePath: []const u8, cflags: []const []const u8) void { // _ = b; @@ -29,6 +30,9 @@ pub fn build(b: *std.Build) void { .root_source_file = b.path("src/platform.zig"), }); + const test_vert = sdl3.addShaderDefinition(b, "../../lib/sdl3", optimize, "test.vert", b.path("shaders/test.vert.json")); + mod.addImport("test.vert", test_vert); + const tests = b.addTest(.{ .target = target, .optimize = optimize, diff --git a/engine/platform/build.zig.zon b/engine/platform/build.zig.zon index a19ae44..4ab99b8 100644 --- a/engine/platform/build.zig.zon +++ b/engine/platform/build.zig.zon @@ -4,6 +4,7 @@ .dependencies = .{ .core = .{ .path = "../core" }, .sdl3 = .{ .path = "../../lib/sdl3" }, + .shaderTypes = .{ .path = "../../lib/sdl3/shaderTypes" }, }, .paths = .{ "", diff --git a/engine/platform/shaders/test.vert.hlsl b/engine/platform/shaders/test.vert.hlsl new file mode 100644 index 0000000..66931b6 --- /dev/null +++ b/engine/platform/shaders/test.vert.hlsl @@ -0,0 +1,46 @@ +struct Input +{ + uint VertexIndex : SV_VertexID; +}; + +struct Output +{ + float4 Color : TEXCOORD0; + float4 Position : SV_Position; +}; + +struct Scene +{ + float4 color; +}; + +StructuredBuffer test: register(t0, space0); + +Output main(Input input) +{ + Output output; + float2 pos; + if (input.VertexIndex == 0) + { + pos = (-1.0f).xx; + output.Color = test[0].color; + } + else + { + if (input.VertexIndex == 1) + { + pos = float2(1.0f, -1.0f); + output.Color = test[1].color; + } + else + { + if (input.VertexIndex == 2) + { + pos = float2(0.0f, 1.0f); + output.Color = test[2].color; + } + } + } + output.Position = float4(pos, 0.0f, 1.0f); + return output; +} diff --git a/engine/platform/shaders/test.vert.json b/engine/platform/shaders/test.vert.json new file mode 100644 index 0000000..ac9907b --- /dev/null +++ b/engine/platform/shaders/test.vert.json @@ -0,0 +1,54 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "vert" + } + ], + "types" : { + "_6" : { + "name" : "Scene", + "members" : [ + { + "name" : "color", + "type" : "vec4", + "offset" : 0 + } + ] + }, + "_5" : { + "name" : "type.StructuredBuffer.Scene", + "members" : [ + { + "name" : "_m0", + "type" : "_6", + "array" : [ + 0 + ], + "array_size_is_literal" : [ + true + ], + "offset" : 0, + "array_stride" : 16 + } + ] + } + }, + "outputs" : [ + { + "type" : "vec4", + "name" : "out.var.TEXCOORD0", + "location" : 0 + } + ], + "ssbos" : [ + { + "type" : "_5", + "name" : "test", + "readonly" : true, + "block_size" : 0, + "set" : 0, + "binding" : 0 + } + ] +} \ No newline at end of file diff --git a/engine/platform/src/platform.zig b/engine/platform/src/platform.zig index 4b80441..a7f2b96 100644 --- a/engine/platform/src/platform.zig +++ b/engine/platform/src/platform.zig @@ -1,5 +1,6 @@ const std = @import("std"); const core = @import("core"); +const test_vert = @import("test.vert"); // controls glfw and general windowing // graphics depends on this one @@ -21,6 +22,7 @@ pub fn setWindowSettings(params: windowing.PlatformParams) void { pub fn start_module(comptime programSpec: anytype, args: anytype, allocator: std.mem.Allocator) !void { _ = args; _ = programSpec; + core.engine_log("shader compile test sizeof Scene = {d}", .{@sizeOf(test_vert.Scene)}); if (core.isUtility()) { return; } diff --git a/engine/rend/shaders/sample.frag.json b/engine/rend/shaders/sample.frag.json new file mode 100644 index 0000000..4a19cc2 --- /dev/null +++ b/engine/rend/shaders/sample.frag.json @@ -0,0 +1,22 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "frag" + } + ], + "inputs" : [ + { + "type" : "vec4", + "name" : "in.var.TEXCOORD0", + "location" : 0 + } + ], + "outputs" : [ + { + "type" : "vec4", + "name" : "out.var.SV_Target0", + "location" : 0 + } + ] +} \ No newline at end of file diff --git a/engine/rend/shaders/sample.vert.json b/engine/rend/shaders/sample.vert.json new file mode 100644 index 0000000..93c9ed7 --- /dev/null +++ b/engine/rend/shaders/sample.vert.json @@ -0,0 +1,54 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "vert" + } + ], + "types" : { + "_6" : { + "name" : "Scene", + "members" : [ + { + "name" : "color", + "type" : "vec3", + "offset" : 0 + } + ] + }, + "_5" : { + "name" : "type.StructuredBuffer.Scene", + "members" : [ + { + "name" : "_m0", + "type" : "_6", + "array" : [ + 0 + ], + "array_size_is_literal" : [ + true + ], + "offset" : 0, + "array_stride" : 16 + } + ] + } + }, + "outputs" : [ + { + "type" : "vec4", + "name" : "out.var.TEXCOORD0", + "location" : 0 + } + ], + "ssbos" : [ + { + "type" : "_5", + "name" : "test", + "readonly" : true, + "block_size" : 0, + "set" : 0, + "binding" : 0 + } + ] +} \ No newline at end of file diff --git a/lib/sdl3/build.zig b/lib/sdl3/build.zig index 4684ca1..8123858 100644 --- a/lib/sdl3/build.zig +++ b/lib/sdl3/build.zig @@ -1,5 +1,29 @@ const std = @import("std"); +pub fn addShaderDefinition( + b: *std.Build, + comptime sdl3Path: []const u8, + optimize: std.builtin.OptimizeMode, + shaderName: []const u8, + jsonPath: std.Build.LazyPath, +) *std.Build.Module { + const reflectedZig = b.addSystemCommand(&[_][]const u8{"python"}); + reflectedZig.addArg(sdl3Path ++ "/spvreflect/spvreflect.py"); + reflectedZig.addFileArg(jsonPath); + reflectedZig.addArg("--output"); + + const reflectedZigOut = reflectedZig.addOutputFileArg(b.fmt("reflected/{s}.zig", .{shaderName})); + const module = b.createModule(.{ .root_source_file = reflectedZigOut, .optimize = optimize }); + + const dep = b.dependency("shaderTypes", .{ + .target = b.graph.host, + .optimize = optimize, + }); + module.addImport("shaderTypes", dep.module("shaderTypes")); + + return module; +} + pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); @@ -31,6 +55,9 @@ pub fn build(b: *std.Build) void { tests.root_module.addImport("sdl3", mod); + const vertexDefinitions = addShaderDefinition(b, ".", optimize, "hello-triangle.vert", b.path("content/hello-triangle.vert.json")); + tests.root_module.addImport("hello-triangle.vert", vertexDefinitions); + const runArtifact = b.addRunArtifact(tests); test_step.dependOn(&runArtifact.step); diff --git a/lib/sdl3/build.zig.zon b/lib/sdl3/build.zig.zon index fc6b3f8..a5e9ee0 100644 --- a/lib/sdl3/build.zig.zon +++ b/lib/sdl3/build.zig.zon @@ -4,6 +4,7 @@ .fingerprint=0x6188f62f190b5e67, .dependencies = .{ .sdl = .{ .path = "SDL/" }, + .shaderTypes = .{ .path = "shaderTypes/" }, }, .paths = .{ "", diff --git a/lib/sdl3/buildshaders.py b/lib/sdl3/buildshaders.py index c843a7e..cbcfe4f 100644 --- a/lib/sdl3/buildshaders.py +++ b/lib/sdl3/buildshaders.py @@ -38,17 +38,32 @@ def cookAll(): ('msl', []), ] + spvs = [] + for fmt in outputFormats: outdir = os.path.join(cookedRoot, fmt[0]) for f in inputFiles: basefile = f[:-5] - outfile = os.path.join(outdir, os.path.basename(basefile) + '.' + fmt[0] ) + outfile = os.path.abspath(os.path.join(outdir, os.path.basename(basefile) + '.' + fmt[0] )) os.makedirs(os.path.dirname(outfile), exist_ok=True) - cmd = [shadercross, f] + \ - fmt[1] + [ '-o', outfile ] + cmd = [shadercross, f] + fmt[1] + [ '-o', outfile ] + + if 'spv' == fmt[0]: + spvs.append((outfile, os.path.dirname(f))) print(cmd) subprocess.run(cmd) + # run spirv-cross and generate .json files + for f in spvs: + basefile = f[0][:-4] + # outdir = os.path.join(cookedRoot, '_def') + outfile = os.path.join(f[1], os.path.basename(basefile) + '.json' ) + os.makedirs(os.path.dirname(outfile), exist_ok=True) + + cmd = ['spirv-cross', f[0], '--reflect', '--output', outfile ] + print(cmd) + subprocess.run(cmd) + if __name__ == '__main__': cookAll() diff --git a/lib/sdl3/content/_cooked/_def/hello-triangle.vert.json b/lib/sdl3/content/_cooked/_def/hello-triangle.vert.json index 93c9ed7..ac9907b 100644 --- a/lib/sdl3/content/_cooked/_def/hello-triangle.vert.json +++ b/lib/sdl3/content/_cooked/_def/hello-triangle.vert.json @@ -11,7 +11,7 @@ "members" : [ { "name" : "color", - "type" : "vec3", + "type" : "vec4", "offset" : 0 } ] diff --git a/lib/sdl3/content/_cooked/dxil/hello-triangle.vert.dxil b/lib/sdl3/content/_cooked/dxil/hello-triangle.vert.dxil index fdabb15..a29b0fe 100644 Binary files a/lib/sdl3/content/_cooked/dxil/hello-triangle.vert.dxil and b/lib/sdl3/content/_cooked/dxil/hello-triangle.vert.dxil differ diff --git a/lib/sdl3/content/_cooked/msl/hello-triangle.vert.msl b/lib/sdl3/content/_cooked/msl/hello-triangle.vert.msl index 15b45b2..564cda3 100644 --- a/lib/sdl3/content/_cooked/msl/hello-triangle.vert.msl +++ b/lib/sdl3/content/_cooked/msl/hello-triangle.vert.msl @@ -5,7 +5,7 @@ using namespace metal; struct Scene { - float3 color; + float4 color; }; struct type_StructuredBuffer_Scene @@ -13,8 +13,8 @@ struct type_StructuredBuffer_Scene Scene _m0[1]; }; -constant float2 _31 = {}; -constant float4 _32 = {}; +constant float2 _30 = {}; +constant float4 _31 = {}; struct main0_out { @@ -25,42 +25,42 @@ struct main0_out vertex main0_out main0(const device type_StructuredBuffer_Scene& test [[buffer(0)]], uint gl_VertexIndex [[vertex_id]]) { main0_out out = {}; - float4 _71; - float2 _72; + float4 _58; + float2 _59; if (gl_VertexIndex == 0u) { - _71 = float4(test._m0[0u].color, 1.0); - _72 = float2(-1.0); + _58 = test._m0[0u].color; + _59 = float2(-1.0); } else { - float4 _69; - float2 _70; + float4 _56; + float2 _57; if (gl_VertexIndex == 1u) { - _69 = float4(test._m0[1u].color, 1.0); - _70 = float2(1.0, -1.0); + _56 = test._m0[1u].color; + _57 = float2(1.0, -1.0); } else { - bool _57 = gl_VertexIndex == 2u; - float4 _66; - if (_57) + bool _48 = gl_VertexIndex == 2u; + float4 _53; + if (_48) { - _66 = float4(test._m0[2u].color, 1.0); + _53 = test._m0[2u].color; } else { - _66 = _32; + _53 = _31; } - _69 = _66; - _70 = select(_31, float2(0.0, 1.0), bool2(_57)); + _56 = _53; + _57 = select(_30, float2(0.0, 1.0), bool2(_48)); } - _71 = _69; - _72 = _70; + _58 = _56; + _59 = _57; } - out.out_var_TEXCOORD0 = _71; - out.gl_Position = float4(_72, 0.0, 1.0); + out.out_var_TEXCOORD0 = _58; + out.gl_Position = float4(_59, 0.0, 1.0); return out; } diff --git a/lib/sdl3/content/_cooked/spv/hello-triangle.vert.spv b/lib/sdl3/content/_cooked/spv/hello-triangle.vert.spv index 8e1453e..203031d 100644 Binary files a/lib/sdl3/content/_cooked/spv/hello-triangle.vert.spv and b/lib/sdl3/content/_cooked/spv/hello-triangle.vert.spv differ diff --git a/lib/sdl3/content/hello-triangle.frag.json b/lib/sdl3/content/hello-triangle.frag.json new file mode 100644 index 0000000..4a19cc2 --- /dev/null +++ b/lib/sdl3/content/hello-triangle.frag.json @@ -0,0 +1,22 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "frag" + } + ], + "inputs" : [ + { + "type" : "vec4", + "name" : "in.var.TEXCOORD0", + "location" : 0 + } + ], + "outputs" : [ + { + "type" : "vec4", + "name" : "out.var.SV_Target0", + "location" : 0 + } + ] +} \ No newline at end of file diff --git a/lib/sdl3/content/hello-triangle.vert.hlsl b/lib/sdl3/content/hello-triangle.vert.hlsl index 46f617c..66931b6 100644 --- a/lib/sdl3/content/hello-triangle.vert.hlsl +++ b/lib/sdl3/content/hello-triangle.vert.hlsl @@ -11,7 +11,7 @@ struct Output struct Scene { - float3 color; + float4 color; }; StructuredBuffer test: register(t0, space0); @@ -23,21 +23,21 @@ Output main(Input input) if (input.VertexIndex == 0) { pos = (-1.0f).xx; - output.Color = float4(test[0].color, 1.0f); + output.Color = test[0].color; } else { if (input.VertexIndex == 1) { pos = float2(1.0f, -1.0f); - output.Color = float4(test[1].color, 1.0f); + output.Color = test[1].color; } else { if (input.VertexIndex == 2) { pos = float2(0.0f, 1.0f); - output.Color = float4(test[2].color, 1.0f); + output.Color = test[2].color; } } } diff --git a/lib/sdl3/content/hello-triangle.vert.json b/lib/sdl3/content/hello-triangle.vert.json new file mode 100644 index 0000000..ac9907b --- /dev/null +++ b/lib/sdl3/content/hello-triangle.vert.json @@ -0,0 +1,54 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "vert" + } + ], + "types" : { + "_6" : { + "name" : "Scene", + "members" : [ + { + "name" : "color", + "type" : "vec4", + "offset" : 0 + } + ] + }, + "_5" : { + "name" : "type.StructuredBuffer.Scene", + "members" : [ + { + "name" : "_m0", + "type" : "_6", + "array" : [ + 0 + ], + "array_size_is_literal" : [ + true + ], + "offset" : 0, + "array_stride" : 16 + } + ] + } + }, + "outputs" : [ + { + "type" : "vec4", + "name" : "out.var.TEXCOORD0", + "location" : 0 + } + ], + "ssbos" : [ + { + "type" : "_5", + "name" : "test", + "readonly" : true, + "block_size" : 0, + "set" : 0, + "binding" : 0 + } + ] +} \ No newline at end of file diff --git a/lib/sdl3/shaderTypes/build.zig b/lib/sdl3/shaderTypes/build.zig new file mode 100644 index 0000000..1854e86 --- /dev/null +++ b/lib/sdl3/shaderTypes/build.zig @@ -0,0 +1,14 @@ +const std = @import("std"); + +pub fn build(b: *std.Build) void { + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + + const mod = b.addModule("shaderTypes", .{ + .target = target, + .optimize = optimize, + .root_source_file = b.path("shaderTypes.zig"), + }); + + _ = mod; +} diff --git a/lib/sdl3/shaderTypes/build.zig.zon b/lib/sdl3/shaderTypes/build.zig.zon new file mode 100644 index 0000000..16e4290 --- /dev/null +++ b/lib/sdl3/shaderTypes/build.zig.zon @@ -0,0 +1,9 @@ +.{ + .name = .shaderTypes, + .version = "0.0.0", + .dependencies = .{}, + .paths = .{ + "", + }, + .fingerprint = 0x1079649dca1ffcc3, +} diff --git a/lib/sdl3/shaderTypes/shaderTypes.zig b/lib/sdl3/shaderTypes/shaderTypes.zig new file mode 100644 index 0000000..dc0eff2 --- /dev/null +++ b/lib/sdl3/shaderTypes/shaderTypes.zig @@ -0,0 +1,94 @@ +// Copyright (c) peterino2@github.com +// +// just struct definitions + +const std = @import("std"); + +pub const vec2 = extern struct { + x: f32, + y: f32, + + pub fn from(o: anytype) @This() { + return .{ + .x = o.x, + .y = o.y, + }; + } +}; + +pub const int = i32; +pub const uint = u32; + +pub const u8vec4 = [4]u8; + +pub const vec3 = extern struct { + x: f32, + y: f32, + z: f32, + + pub fn from(o: anytype) @This() { + return .{ + .x = o.x, + .y = o.y, + .z = o.z, + .pad = 0, + }; + } +}; + +pub const vec4 = extern struct { + x: f32, + y: f32, + z: f32, + w: f32, + + pub fn from(o: anytype) @This() { + return .{ + .x = o.x, + .y = o.y, + .z = o.z, + .w = o.w, + }; + } +}; + +pub const mat4 = [4][4]f32; + +pub const float = f32; + +pub fn CheckFieldDetails( + comptime T: type, + comptime fieldName: []const u8, + expectedOffset: usize, + expectedSize: usize, +) void { + const offset = @offsetOf(T, fieldName); + const size = @sizeOf(@TypeOf(@field(std.mem.zeroes(T), fieldName))); + if (offset != expectedOffset) { + const msg = std.fmt.comptimePrint( + "Unexpected field offset, {s} was expected at offset {d} but found at offset {d}", + .{ fieldName, expectedOffset, offset }, + ); + @compileError(msg); + } + + if (size != expectedSize) { + const msg = std.fmt.comptimePrint( + "Unexpected field size, '{s}' was expected with size {d} but found at size {d}", + .{ fieldName, expectedSize, size }, + ); + @compileError(msg); + } +} + +pub fn ValidateGeneratedStruct(comptime T: type) void { + for (@field(T, "FieldDetails")) |detail| { + CheckFieldDetails(T, detail.name, detail.offset, detail.size); + } +} + +pub const FieldDetail = struct { + name: []const u8, + size: usize, + offset: usize, +}; diff --git a/lib/sdl3/spvreflect/reflected.zig b/lib/sdl3/spvreflect/reflected.zig new file mode 100644 index 0000000..f7588ae --- /dev/null +++ b/lib/sdl3/spvreflect/reflected.zig @@ -0,0 +1,15 @@ +pub const shaderTypes = @import("shaderTypes"); + +pub const int = shaderTypes.int; +pub const uint = shaderTypes.uint; + +pub const vec2 = shaderTypes.vec2; +pub const u8vec4 = shaderTypes.u8vec4; +pub const vec3 = shaderTypes.vec3; +pub const vec4 = shaderTypes.vec4; +pub const mat4 = shaderTypes.mat4; +pub const float = shaderTypes.float; + +pub const Scene = struct { + color: vec4, +}; diff --git a/lib/sdl3/spvreflect/spvreflect.py b/lib/sdl3/spvreflect/spvreflect.py index f7a6404..e0909f6 100644 --- a/lib/sdl3/spvreflect/spvreflect.py +++ b/lib/sdl3/spvreflect/spvreflect.py @@ -1,5 +1,7 @@ - import os +import argparse +import subprocess +import json # quick and dirty dependency-free script to # build and output reflected zig files for @@ -8,3 +10,68 @@ import os # usage: # python spvreflect defs.json + +def generate(): + print() + parser = argparse.ArgumentParser() + parser.add_argument('input', type=str, help="input file") + parser.add_argument('-o', '--output', type=str, help="output file") + args = parser.parse_args() + + infile = os.path.abspath(args.input) + outfile = 'reflected.zig' + if args.output is not None: + outfile = args.output + + reflect = None + + with open(infile) as f: + reflect = json.load(f) + print(reflect) + + + ostring = "pub const shaderTypes = @import(\"shaderTypes\");\n" + ostring += """ +pub const int = shaderTypes.int; +pub const uint = shaderTypes.uint; + +pub const vec2 = shaderTypes.vec2; +pub const u8vec4 = shaderTypes.u8vec4; +pub const vec3 = shaderTypes.vec3; +pub const vec4 = shaderTypes.vec4; +pub const mat4 = shaderTypes.mat4; +pub const float = shaderTypes.float; + +""" + + types = reflect['types'] + for t in types: + name = types[t]['name']; + + if 'type.StructuredBuffer' in name: + continue + + if name.startswith("type.StructuredBuffer"): + name = name[len("type.StructuredBuffer"):] + + zs = f"pub const {name} = " + 'struct {\n' + + for member in types[t]['members']: + zs += member['name'] + ':' + member['type'] + ',\n' + + zs += "};\n" + + print(zs) + + ostring += zs + + + with open(outfile, 'w') as f: + f.write(ostring) + + subprocess.run(['zig', 'fmt', outfile]) + +if __name__ == '__main__': + generate() + + pass diff --git a/lib/sdl3/src/samples/hello-triangle.zig b/lib/sdl3/src/samples/hello-triangle.zig index 90b3ddc..1859fc3 100644 --- a/lib/sdl3/src/samples/hello-triangle.zig +++ b/lib/sdl3/src/samples/hello-triangle.zig @@ -139,6 +139,7 @@ pub fn loadShader( .num_uniform_buffers = num_uniform_buffers, // The number of uniform buffers defined in the shader. .props = 0, }; + std.debug.print("hello_triangle_vert.Scene => sizeof() = {d}", .{@sizeOf(hello_triangle_vert.Scene)}); return self.device.createGPUShader(&sci); } @@ -182,9 +183,9 @@ pub fn draw(self: *@This(), dt: f64) void { var b: [*][4]f32 = @ptrCast(@alignCast(buffer)); - b[0] = .{ @floatCast(std.math.sin(self.totalTime * 3 * 2 + 0.8) * 0.2 + 0.8), 0.4, 0.4, 0.0 }; - b[1] = .{ 0.4, @floatCast(std.math.sin(self.totalTime * 2 * 2 + 0.3) * 0.2 + 0.8), 0.4, 0.0 }; - b[2] = .{ 0.4, 0.4, @floatCast(std.math.sin(self.totalTime * 4 * 2) * 0.2 + 0.8), 0.0 }; + b[0] = .{ @floatCast(std.math.sin(self.totalTime * 3 * 2 + 0.8) * 0.2 + 0.8), 0.4, 0.4, 1.0 }; + b[1] = .{ 0.4, @floatCast(std.math.sin(self.totalTime * 2 * 2 + 0.3) * 0.2 + 0.8), 0.4, 1.0 }; + b[2] = .{ 0.4, 0.4, @floatCast(std.math.sin(self.totalTime * 4 * 2) * 0.2 + 0.8), 1.0 }; self.device.unmapGPUTransferBuffer(self.colorBufferTransfer); } @@ -233,6 +234,7 @@ pub fn main() !void { defer app.destroy(); } +const hello_triangle_vert = @import("hello-triangle.vert"); const sdl3 = @import("sdl3"); const gpu = sdl3.gpu; const sdl_event = sdl3.events; diff --git a/projects/build.zig b/projects/build.zig index 4722c8b..71c10c4 100644 --- a/projects/build.zig +++ b/projects/build.zig @@ -8,6 +8,7 @@ pub fn build(b: *std.Build) void { var blbuild = Backlog.init(b, .{ .target = target, .optimize = optimize, + .backlogRoot = "../", }); _ = blbuild.addProgram(.{ diff --git a/projects/content/_shaders/dxil/test.vert.dxil b/projects/content/_shaders/dxil/test.vert.dxil new file mode 100644 index 0000000..a29b0fe Binary files /dev/null and b/projects/content/_shaders/dxil/test.vert.dxil differ diff --git a/projects/content/_shaders/msl/test.vert.msl b/projects/content/_shaders/msl/test.vert.msl new file mode 100644 index 0000000..564cda3 --- /dev/null +++ b/projects/content/_shaders/msl/test.vert.msl @@ -0,0 +1,66 @@ +#include +#include + +using namespace metal; + +struct Scene +{ + float4 color; +}; + +struct type_StructuredBuffer_Scene +{ + Scene _m0[1]; +}; + +constant float2 _30 = {}; +constant float4 _31 = {}; + +struct main0_out +{ + float4 out_var_TEXCOORD0 [[user(locn0)]]; + float4 gl_Position [[position]]; +}; + +vertex main0_out main0(const device type_StructuredBuffer_Scene& test [[buffer(0)]], uint gl_VertexIndex [[vertex_id]]) +{ + main0_out out = {}; + float4 _58; + float2 _59; + if (gl_VertexIndex == 0u) + { + _58 = test._m0[0u].color; + _59 = float2(-1.0); + } + else + { + float4 _56; + float2 _57; + if (gl_VertexIndex == 1u) + { + _56 = test._m0[1u].color; + _57 = float2(1.0, -1.0); + } + else + { + bool _48 = gl_VertexIndex == 2u; + float4 _53; + if (_48) + { + _53 = test._m0[2u].color; + } + else + { + _53 = _31; + } + _56 = _53; + _57 = select(_30, float2(0.0, 1.0), bool2(_48)); + } + _58 = _56; + _59 = _57; + } + out.out_var_TEXCOORD0 = _58; + out.gl_Position = float4(_59, 0.0, 1.0); + return out; +} + diff --git a/projects/content/_shaders/spv/test.vert.spv b/projects/content/_shaders/spv/test.vert.spv new file mode 100644 index 0000000..203031d Binary files /dev/null and b/projects/content/_shaders/spv/test.vert.spv differ diff --git a/tools/scripts/cookShaders.py b/tools/scripts/cookShaders.py index 05479cf..3ce5054 100644 --- a/tools/scripts/cookShaders.py +++ b/tools/scripts/cookShaders.py @@ -56,7 +56,8 @@ def discoverShaders(): shaderRoot = os.path.abspath(os.path.join(modRoot, 'shaders/')) if os.path.isdir(os.path.join(modRoot, 'shaders/')): for x in os.listdir(shaderRoot): - rv.append(os.path.abspath(os.path.join(shaderRoot, x))) + if x.endswith(".hlsl"): + rv.append(os.path.abspath(os.path.join(shaderRoot, x))) return rv @@ -87,19 +88,18 @@ def cookList(inputFiles): cmd = [shadercross, f] + fmt[1] + [ '-o', outfile ] if 'spv' == fmt[0]: - spvs.append(outfile) + spvs.append((outfile, os.path.dirname(f))) print(cmd) subprocess.run(cmd) # run spirv-cross and generate .json files for f in spvs: - basefile = f[:-4] - outdir = os.path.join(cookedRoot, '_def') - outfile = os.path.join(outdir, os.path.basename(basefile) + '.json' ) + basefile = f[0][:-4] + outfile = os.path.join(f[1], os.path.basename(basefile) + '.json' ) os.makedirs(os.path.dirname(outfile), exist_ok=True) - cmd = ['spirv-cross', f, '--reflect', '--output', outfile ] + cmd = ['spirv-cross', f[0], '--reflect', '--output', outfile ] print(cmd) subprocess.run(cmd)