diff --git a/build.zig b/build.zig index 5abfb3c..ad1fa60 100644 --- a/build.zig +++ b/build.zig @@ -127,13 +127,7 @@ fn buildNzsl(b: *Build, target: Build.ResolvedTarget, optimize: std.builtin.Opti lib.addSystemIncludePath(ordered_map.path("include")); lib.addSystemIncludePath(fast_float.path("include")); - // const includeFlag = std.fmt.allocPrint(b.allocator, "\"-isystem {s}\"", .{upstream.path("include").getPath(b)}) catch unreachable; - // defer b.allocator.free(includeFlag); - const flags = [_][]const u8{ - // includeFlag - //"-I=" ++ .upstream.path(), - if (shared) "-DCNZSL_DYNAMIC" else "-DCNZSL_STATIC", if (shared) "-DNZSL_DYNAMIC" else "-DNZSL_STATIC", diff --git a/build.zig.bak b/build.zig.bak deleted file mode 100644 index b3a1a85..0000000 --- a/build.zig.bak +++ /dev/null @@ -1,91 +0,0 @@ -const std = @import("std"); - -// Although this function looks imperative, note that its job is to -// declaratively construct a build graph that will be executed by an external -// runner. -pub fn build(b: *std.Build) void { - // Standard target options allows the person running `zig build` to choose - // what target to build for. Here we do not override the defaults, which - // means any target is allowed, and the default is native. Other options - // for restricting supported target set are available. - const target = b.standardTargetOptions(.{}); - - // Standard optimization options allow the person running `zig build` to select - // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not - // set a preferred release mode, allowing the user to decide how to optimize. - const optimize = b.standardOptimizeOption(.{}); - - const lib = b.addStaticLibrary(.{ - .name = "nzsl-zig", - // In this case the main source file is merely a path, however, in more - // complicated build scripts, this could be a generated file. - .root_source_file = b.path("src/root.zig"), - .target = target, - .optimize = optimize, - }); - - // This declares intent for the library to be installed into the standard - // location when the user invokes the "install" step (the default step when - // running `zig build`). - b.installArtifact(lib); - - const exe = b.addExecutable(.{ - .name = "nzsl-zig", - .root_source_file = b.path("src/main.zig"), - .target = target, - .optimize = optimize, - }); - - // This declares intent for the executable to be installed into the - // standard location when the user invokes the "install" step (the default - // step when running `zig build`). - b.installArtifact(exe); - - // This *creates* a Run step in the build graph, to be executed when another - // step is evaluated that depends on it. The next line below will establish - // such a dependency. - const run_cmd = b.addRunArtifact(exe); - - // By making the run step depend on the install step, it will be run from the - // installation directory rather than directly from within the cache directory. - // This is not necessary, however, if the application depends on other installed - // files, this ensures they will be present and in the expected location. - run_cmd.step.dependOn(b.getInstallStep()); - - // This allows the user to pass arguments to the application in the build - // command itself, like this: `zig build run -- arg1 arg2 etc` - if (b.args) |args| { - run_cmd.addArgs(args); - } - - // This creates a build step. It will be visible in the `zig build --help` menu, - // and can be selected like this: `zig build run` - // This will evaluate the `run` step rather than the default, which is "install". - const run_step = b.step("run", "Run the app"); - run_step.dependOn(&run_cmd.step); - - // Creates a step for unit testing. This only builds the test executable - // but does not run it. - const lib_unit_tests = b.addTest(.{ - .root_source_file = b.path("src/root.zig"), - .target = target, - .optimize = optimize, - }); - - const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests); - - const exe_unit_tests = b.addTest(.{ - .root_source_file = b.path("src/main.zig"), - .target = target, - .optimize = optimize, - }); - - const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests); - - // Similar to creating the run step earlier, this exposes a `test` step to - // the `zig build --help` menu, providing a way for the user to request - // running the unit tests. - const test_step = b.step("test", "Run unit tests"); - test_step.dependOn(&run_lib_unit_tests.step); - test_step.dependOn(&run_exe_unit_tests.step); -} diff --git a/build.zig.zon b/build.zig.zon index d26c720..178b595 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -16,9 +16,8 @@ // internet connectivity. .dependencies = .{ .nzsl_source = .{ - .url = "https://github.com/NazaraEngine/ShaderLang/archive/ddbc7b179b2fdcb82dcd20e4aa8a85dfede0891b.tar.gz", - .hash = "12208c569d8bc21e0412c17da081ee7944c1c3b2de9c6bcfa1863ded4af2faad0cf0", - .lazy = true, + .url = "https://github.com/REMqb/ShaderLang/archive/2a939b32e1dfd318964a6f03d442c565d51815b9.tar.gz", + .hash = "1220bb61ec2a696eeaac96d3d419bcbe91979706c14f76a4ca696c06e28f9b4f7fc0", }, .NazaraUtils = .{ .url = "https://github.com/NazaraEngine/NazaraUtils/archive/cbdb331a9610fa52f51e7c86576cc9e2e7235691.tar.gz", diff --git a/examples/mandelbrot.zig b/examples/mandelbrot.zig index 230c84e..ae986bb 100644 --- a/examples/mandelbrot.zig +++ b/examples/mandelbrot.zig @@ -2,13 +2,26 @@ const std= @import("std"); const nzsl = @import("nzslzig"); pub fn main() !void { - const mandelbrotModule = try nzsl.parseFromFile("./mandelbrot.nzsl"); + const mandelbrotModule = try nzsl.parseFromFile("examples/mandelbrot.nzsl"); defer mandelbrotModule.release(); const glslWriter = nzsl.GlslWriter.create(); defer glslWriter.release(); - const output = try glslWriter.generate(mandelbrotModule); + const state = nzsl.WriterStates.create(); + defer state.release(); + + state.setOption(nzsl.hashOption("foo"), 42); + state.setOption(nzsl.hashOption("foo"), 42.3); + state.setOption(nzsl.hashOption("foo"), true); + state.setOption(nzsl.hashOption("foo"), .{true, false}); + state.setOption(nzsl.hashOption("foo"), .{12, 24}); + state.setOption(nzsl.hashOption("foo"), .{12.4, 24}); + + const mappings = nzsl.GlslBindingMapping.create(); + defer mappings.release(); + + const output = try glslWriter.generate(mandelbrotModule, mappings); defer output.release(); } \ No newline at end of file diff --git a/src/lib.zig b/src/lib.zig index 813556e..d9ef6f3 100644 --- a/src/lib.zig +++ b/src/lib.zig @@ -1,13 +1,33 @@ -//const nzsl = @cImport({ -// @cInclude("CNZSL/CNZSL.h"); -//}); +// const cnzsl = @cImport({ +// @cInclude("CNZSL/CNZSL.h"); +// }); const std = @import("std"); -const cnzsl = @import("cimport.zig"); +const cnzsl = @import("nzsl-c.zig"); + +pub const DebugLevel = cnzsl.nzslDebugLevel; +pub const OptionHash = cnzsl.nzslOptionHash; pub fn parseSource(source: []const u8) !Module { - const module = Module{.instance = null}; + return parseSourceWithFilePath(source, ""); +} - if(cnzsl.nzslParserParseSource(module.instance, source.ptr, source.len) != 0) { +pub fn parseSourceWithFilePath(source: []const u8, filePath: []const u8) !Module { + const module = Module.create(); + + if(cnzsl.nzslParserParseSourceWithFilePath(module.instance, source.ptr, source.len, filePath.ptr, filePath.len) != 0) { + defer module.release(); + std.log.err("Error while parsing source({s}): {s}", .{ filePath, module.getLastError() }); + + return error.FailedToParse; + } + + return module; +} + +pub fn parseFromFile(filePath: []const u8) !Module { + const module = Module.create(); + + if(cnzsl.nzslParserParseFromFile(module.instance, filePath.ptr, filePath.len) != 0) { defer module.release(); std.log.err("Error while parsing source: {s}", .{ module.getLastError() }); @@ -17,45 +37,13 @@ pub fn parseSource(source: []const u8) !Module { return module; } -pub fn parseSourceWithFilePath(source: []const u8, filePath: []const u8) !Module { - const module: ?*cnzsl.nzslModule = null; - - if(cnzsl.nzslParserParseSourceWithFilePath(module, source.ptr, source.len, filePath.ptr, filePath.len) != 0) { - defer cnzsl.nzslModuleDestroy(module); - std.log.err("Error while parsing source: {s}", .{ module.getLastError() }); - - return error.FailedToParse; - } - - if (module == null) { - std.log.err("Error while parsing source: Unknown error", .{ }); - return error.FailedToParse; - } - - return .{.instance = module}; -} - -pub fn parseFromFile(filePath: []const u8) !Module { - const module: ?*cnzsl.nzslModule = null; - - if(cnzsl.nzslParserParseFromFile(module, filePath.ptr, filePath.len) != 0) { - defer cnzsl.nzslModuleDestroy(module); - std.log.err("Error while parsing source: {s}", .{ cnzsl.nzslModuleGetLastError(module) }); - - return error.FailedToParse; - } - - if (module == null) { - std.log.err("Error while parsing source: Unknown error", .{ }); - return error.FailedToParse; - } - - return .{.instance = module}; -} - pub const Module = struct { instance: *cnzsl.nzslModule, + pub fn create() Module { + return .{.instance = cnzsl.nzslModuleCreate() orelse unreachable}; + } + pub fn release(self: Module) void { cnzsl.nzslModuleDestroy(self.instance); } @@ -76,10 +64,10 @@ pub const GlslWriter = struct { cnzsl.nzslGlslWriterDestroy(self.instance); } - pub fn generate(self: GlslWriter, module: Module) !GlslOutput { + pub fn generate(self: GlslWriter, module: Module, bindingMapping: GlslBindingMapping) !GlslOutput { var output: ?*cnzsl.nzslGlslOutput = null; - output = cnzsl.nzslGlslWriterGenerate(self.instance, module.instance, null, null); + output = cnzsl.nzslGlslWriterGenerate(self.instance, module.instance, bindingMapping.instance, null); if(output == null) { std.log.err("Failed to generate glsl output: {s}", .{ self.getLastError() }); @@ -95,6 +83,23 @@ pub const GlslWriter = struct { } }; +pub const GlslBindingMapping = struct { + instance: *cnzsl.nzslGlslBindingMapping, + + pub fn create() GlslBindingMapping { + return .{.instance = cnzsl.nzslGlslBindingMappingCreate() orelse unreachable}; + } + + pub fn release(self: GlslBindingMapping) void { + cnzsl.nzslGlslBindingMappingDestroy(self.instance); + } + + pub fn setBinding(self: GlslBindingMapping, setIndex: u32, bindingIndex: u32, glBinding: c_uint) void { + cnzsl.nzslGlslBindingMappingSetBinding(self.instance, setIndex, bindingIndex, glBinding); + } + +}; + pub const GlslOutput = struct { instance: *cnzsl.nzslGlslOutput, @@ -102,3 +107,51 @@ pub const GlslOutput = struct { cnzsl.nzslGlslOutputDestroy(self.instance); } }; + +pub fn hashOption(str: [*c]const u8) OptionHash { + return cnzsl.nzslHashOption(str); +} + +pub const WriterStates = struct { + instance: *cnzsl.nzslWriterStates, + + pub fn create() WriterStates { + return .{.instance = cnzsl.nzslWriterStatesCreate() orelse unreachable}; + } + + pub fn enableOptimization(self: WriterStates, enable: bool) void { + cnzsl.nzslWriterStatesEnableOptimization(self.instance, enable); + } + pub fn enableSanitization(self: WriterStates, enable: bool) void { + cnzsl.nzslWriterStatesEnableSanitization(self.instance, enable); + } + pub fn setDebugLevel(self: WriterStates, debugLevel: DebugLevel) void { + cnzsl.nzslWriterStatesSetDebugLevel(self.instance, debugLevel); + } + pub fn setOption(self: WriterStates, optionHash: OptionHash, value: anytype) void { + switch (@TypeOf(value)) { + inline bool => cnzsl.nzslWriterStatesSetOption_bool(self.instance, optionHash, @intFromBool(value)), + inline cnzsl.nzslBool => cnzsl.nzslWriterStatesSetOption_bool(self.instance, optionHash, value), + inline [2]bool, [2]bool, [2]cnzsl.nzslBool => cnzsl.nzslWriterStatesSetOption_vec2bool(self.instance, optionHash, value.ptr), + inline [3]bool, [3]cnzsl.nzslBool => cnzsl.nzslWriterStatesSetOption_vec3bool(self.instance, optionHash, value.ptr), + inline [4]bool, [4]cnzsl.nzslBool => cnzsl.nzslWriterStatesSetOption_vec4bool(self.instance, optionHash, value.ptr), + inline comptime_float, f32 => cnzsl.nzslWriterStatesSetOption_f32(self.instance, optionHash, value), + inline [2]f32 => cnzsl.nzslWriterStatesSetOption_vec2f32(self.instance, optionHash, value.ptr), + inline [3]f32 => cnzsl.nzslWriterStatesSetOption_vec3f32(self.instance, optionHash, value.ptr), + inline [4]f32 => cnzsl.nzslWriterStatesSetOption_vec4f32(self.instance, optionHash, value.ptr), + inline comptime_int, i32 => cnzsl.nzslWriterStatesSetOption_i32(self.instance, optionHash, value), + inline [2]i32 => cnzsl.nzslWriterStatesSetOption_vec2i32(self.instance, optionHash, value.ptr), + inline [3]i32 => cnzsl.nzslWriterStatesSetOption_vec3i32(self.instance, optionHash, value.ptr), + inline [4]i32 => cnzsl.nzslWriterStatesSetOption_vec4i32(self.instance, optionHash, value.ptr), + inline u32 => cnzsl.nzslWriterStatesSetOption_u32(self.instance, optionHash, value), + inline [2]u32 => cnzsl.nzslWriterStatesSetOption_vec2u32(self.instance, optionHash, value.ptr), + inline [3]u32 => cnzsl.nzslWriterStatesSetOption_vec3u32(self.instance, optionHash, value.ptr), + inline [4]u32 => cnzsl.nzslWriterStatesSetOption_vec4u32(self.instance, optionHash, value.ptr), + else => std.debug.panic("Unsupported type {}", .{@TypeOf(value)}) + } + } + + pub fn release(self: WriterStates) void { + cnzsl.nzslWriterStatesDestroy(self.instance); + } +}; \ No newline at end of file diff --git a/src/nzsl-c.zig b/src/nzsl-c.zig index 09278f3..f53d3f9 100644 --- a/src/nzsl-c.zig +++ b/src/nzsl-c.zig @@ -1,3 +1,3 @@ pub usingnamespace @cImport({ @cInclude("CNZSL/CNZSL.h"); -}); \ No newline at end of file +});