From 806c7942e8928b204ef4f18a936bb2eb56a5f9ee Mon Sep 17 00:00:00 2001 From: Peter Li Date: Sun, 13 Apr 2025 17:41:16 -0700 Subject: [PATCH] saving --- build.zig | 11 +- engine/platform/build.zig | 4 + engine/platform/build.zig.zon | 1 + engine/platform/shaders/test.vert.hlsl | 46 +++++++++ engine/platform/shaders/test.vert.json | 54 ++++++++++ engine/platform/src/platform.zig | 2 + engine/rend/shaders/sample.frag.json | 22 ++++ engine/rend/shaders/sample.vert.json | 54 ++++++++++ lib/sdl3/build.zig | 27 +++++ lib/sdl3/build.zig.zon | 1 + lib/sdl3/buildshaders.py | 21 +++- .../_cooked/_def/hello-triangle.vert.json | 2 +- .../_cooked/dxil/hello-triangle.vert.dxil | Bin 3780 -> 3800 bytes .../_cooked/msl/hello-triangle.vert.msl | 44 ++++---- .../_cooked/spv/hello-triangle.vert.spv | Bin 1848 -> 1568 bytes lib/sdl3/content/hello-triangle.frag.json | 22 ++++ lib/sdl3/content/hello-triangle.vert.hlsl | 8 +- lib/sdl3/content/hello-triangle.vert.json | 54 ++++++++++ lib/sdl3/shaderTypes/build.zig | 14 +++ lib/sdl3/shaderTypes/build.zig.zon | 9 ++ lib/sdl3/shaderTypes/shaderTypes.zig | 94 ++++++++++++++++++ lib/sdl3/spvreflect/reflected.zig | 15 +++ lib/sdl3/spvreflect/spvreflect.py | 69 ++++++++++++- lib/sdl3/src/samples/hello-triangle.zig | 8 +- projects/build.zig | 1 + projects/content/_shaders/dxil/test.vert.dxil | Bin 0 -> 3800 bytes projects/content/_shaders/msl/test.vert.msl | 66 ++++++++++++ projects/content/_shaders/spv/test.vert.spv | Bin 0 -> 1568 bytes tools/scripts/cookShaders.py | 12 +-- 29 files changed, 620 insertions(+), 41 deletions(-) create mode 100644 engine/platform/shaders/test.vert.hlsl create mode 100644 engine/platform/shaders/test.vert.json create mode 100644 engine/rend/shaders/sample.frag.json create mode 100644 engine/rend/shaders/sample.vert.json create mode 100644 lib/sdl3/content/hello-triangle.frag.json create mode 100644 lib/sdl3/content/hello-triangle.vert.json create mode 100644 lib/sdl3/shaderTypes/build.zig create mode 100644 lib/sdl3/shaderTypes/build.zig.zon create mode 100644 lib/sdl3/shaderTypes/shaderTypes.zig create mode 100644 lib/sdl3/spvreflect/reflected.zig create mode 100644 projects/content/_shaders/dxil/test.vert.dxil create mode 100644 projects/content/_shaders/msl/test.vert.msl create mode 100644 projects/content/_shaders/spv/test.vert.spv 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 fdabb150dc7d441e281506f448f4a779bb5a950f..a29b0fe9191aca62d43e89d0f1c9ba7a4024cda1 100644 GIT binary patch delta 445 zcmX>idqY;zCBn(s#p+R7hBTMJ{F>}9w=!j;7#SECZfumi$;?=``7`rIX3P0o=ahV8 z*t9k3xb>UKEh}!iM0onhurn|uFfcM42dW0~flLMgphgy;xRdjNdx|^^4Er|UWp`#} z%$cmnn_Zv5WGGYktz)zM9NR~4bPgKc*|3CB;*1fGi$PKYg8~QJ1*sU`)?PK10~t*M zJ!(9MFw_SWCK#L!kT}@E$kd=9;ZQ2TCa%u5n3K_9mIBLS&SryI4m@D91=IU2ti2O> zLS#G?xsEs-Z4_DJz!Oq0ZC6?wDkdDHVPst@0cY)amtXvu6aBUPd!;Rpkxg8}_)4@$ zpSxG^t!?vWmg5D^EsY0toD*4;**F-Q5*Us;nkU}NaAN3D<2aacNZ}4hnfaW#ss?OY ze2X_QCoOnnz-6NV;#>f67+Rb7J6^UK{Fo8hRG+-yaYHi$58F|R7Zwi`7@8do*{t|1 zI1VHP^fdN4i!y~uhyaxYv^I#cg%|*(!Z;!l6M6)jSr{A*9K00yoD@Yq9gr~eU=Uzo zULx{HLBz?CzY9hBT?2~rLcTVHw2Ku`y8}Yr0i?YNNnTOp-2omq9w7#ngAAIj76PpS NE0|3jfC0+D000HuhhG2y 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 8e1453ee4a2459f9368105a056a570033ddb7d41..203031d5bdf08c772e442955a70395a92e847e7f 100644 GIT binary patch literal 1568 zcmZ9L*-leY6o$7QR2;y{FMIbl??m+Q^TT)A6qSVw=6YqQ-eF>k+I3y;1 z-|1PVaVM*5{{OYt*)5l5kEC=cr8Jz@`1RCMsfd(w-|R>_`p9#UlivP*yW8ApwGZ0lE9o%xeJ^2GbDvOZb>4QmXlocQ zW$h1{@hYBtonF@bxYupIdcON~YwP8+g*;cuXO7u6=yks1$PGl_IrTmIVom2>-oguyftG?XhGv>=zfe%VaL9Vy9fO`m6K>WjOn{8=kDLXlFnkgGjT?#Jcn)&Igi#J zBX$98?-W`rYnKabzpXKSv9-n54{Y(n@4snl%K2V=C)#3OMB?ssYSZCJbT3mPX8ay;aib&4(*ZC+&ppVr#i2o^b;+Y%#4t|fod4%n^^1F%|9O5h^b;O*Q t=3X$n|Fg%4c~8Vvu#Nflwu}3(Vq0r2{;#X--ghszw(s7$KXfi3e*xuCT%`a2 literal 1848 zcmZ9MX-`v85QYzwsRqOY7^emTzUYj;!bCZIxL2I|f~c)a_Hc=xJr2(>>K(0XAl)IpmzI+e8yQR-XtbJN*5dR*yG45%CuGCLK#+WB!dXe>soPEfi zi0MZbGtRsNaPzkITgvt$HUtv;x`6B+)GNdc!mS~u?yl_9dChqSZcgt|`&qd8#e0c7 z2OkDG4_EF38-nZW9h=)8rqQkCU5lw(OWAtrk=y*Cx8ArurEE_ZGyhUnzk(dQ7)Ew? zl6{ZB?Zf<&OlNP_@!0DxETixle4X_Yr0+L;jk}y<-uX{zUx9o6;IC~Ax(b;`d4b8C z_ZsAkz9nPj)^G=Y587W+!<~-j80-L>$T52jzZ*Gbe;Z_X_f^Pv{k8iBe$$J6+LOJ- zEH{yz&o}5SezzWH(RLfU0~x0rv)o0FS&S{tat~d5^mrdx%oErovRHAJ2RT-pWeUuA z{k6v|_GwS{7PCA=b{4-4XL$toIE%JvNX$6pnB_5Y%wlYDmKk*I(f2H}m?y9~WU=Bb z^EpWC3=$o$nS6wxdJ(#arV2x+Zcf_LCzz6 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 0000000000000000000000000000000000000000..a29b0fe9191aca62d43e89d0f1c9ba7a4024cda1 GIT binary patch literal 3800 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..203031d5bdf08c772e442955a70395a92e847e7f GIT binary patch literal 1568 zcmZ9L*-leY6o$7QR2;y{FMIbl??m+Q^TT)A6qSVw=6YqQ-eF>k+I3y;1 z-|1PVaVM*5{{OYt*)5l5kEC=cr8Jz@`1RCMsfd(w-|R>_`p9#UlivP*yW8ApwGZ0lE9o%xeJ^2GbDvOZb>4QmXlocQ zW$h1{@hYBtonF@bxYupIdcON~YwP8+g*;cuXO7u6=yks1$PGl_IrTmIVom2>-oguyftG?XhGv>=zfe%VaL9Vy9fO`m6K>WjOn{8=kDLXlFnkgGjT?#Jcn)&Igi#J zBX$98?-W`rYnKabzpXKSv9-n54{Y(n@4snl%K2V=C)#3OMB?ssYSZCJbT3mPX8ay;aib&4(*ZC+&ppVr#i2o^b;+Y%#4t|fod4%n^^1F%|9O5h^b;O*Q t=3X$n|Fg%4c~8Vvu#Nflwu}3(Vq0r2{;#X--ghszw(s7$KXfi3e*xuCT%`a2 literal 0 HcmV?d00001 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)