2
0
Эх сурвалжийг харах

Add Nazara Shading language (nzsl) (#6889)

* Add NZSL

* Fix nzsl
Jérôme Leclercq 4 сар өмнө
parent
commit
39bcc15e12

+ 46 - 0
packages/n/nzsl/rules/archive_shaders.lua

@@ -0,0 +1,46 @@
+-- Merge binary shaders to archivess
+rule("archive.shaders")
+	set_extensions(".nzsla")
+	add_deps("@nzsl/find_nzsl")
+	add_deps("@nzsl/compile.shaders", { order = true })
+
+	before_buildcmd_file(function (target, batchcmds, sourcefile, opt)
+		local nzsla = target:data("nzsla")
+		local runenvs = target:data("nzsl_runenv")
+		assert(nzsla, "nzsla not found! please install nzsl package with nzsla enabled")
+
+		local fileconfig = target:fileconfig(sourcefile)
+
+		batchcmds:show_progress(opt.progress, "${color.build.object}archiving.shaders %s", sourcefile)
+		local argv = { "--archive" }
+
+		if fileconfig.compress then
+			if type(fileconfig.compress) == "string" then
+				table.insert(argv, "--compress=" .. fileconfig.compress)
+			else
+				table.insert(argv, "--compress")
+			end
+		end
+
+		local outputfile = sourcefile
+		if fileconfig.header then
+			table.insert(argv, "--header")
+			if type(fileconfig.header) == "string" then
+				outputfile = outputfile .. fileconfig.header
+			end
+		end
+
+		table.insert(argv, "--output=" .. outputfile)
+
+		for _, shaderfile in ipairs(fileconfig.files) do
+			table.insert(argv, shaderfile)
+			batchcmds:add_depfiles(shaderfile)
+		end
+
+		batchcmds:vrunv(nzsla.program, argv, { curdir = ".", envs = runenvs })
+
+		-- add deps
+		batchcmds:add_depvalues(nzsla.version)
+		batchcmds:set_depmtime(os.mtime(outputfile))
+		batchcmds:set_depcache(target:dependfile(sourcefile))
+end)

+ 74 - 0
packages/n/nzsl/rules/compile_shaders.lua

@@ -0,0 +1,74 @@
+-- Compile shaders to includables headers
+rule("compile.shaders")
+	set_extensions(".nzsl", ".nzslb")
+	add_deps("@nzsl/find_nzsl")
+
+	on_config(function (target)
+		local archives = {}
+
+		for _, sourcebatch in pairs(target:sourcebatches()) do
+			local rulename = sourcebatch.rulename
+			if rulename == "@nzsl/compile.shaders" then
+				for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+					local fileconfig = target:fileconfig(sourcefile)
+					if fileconfig and fileconfig.archive then
+						local archivefiles = archives[fileconfig.archive]
+						if not archivefiles then
+							archivefiles = {}
+							archives[fileconfig.archive] = archivefiles
+						end
+						table.insert(archivefiles, path.join(path.directory(sourcefile), path.basename(sourcefile) .. ".nzslb"))
+					end
+				end
+			end
+		end
+
+		if not table.empty(archives) then
+			assert(target:rule("@nzsl/archive.shaders"), "you must add the @nzsl/archive.shaders rule to the target")
+			for archive, archivefiles in table.orderpairs(archives) do
+				local args = { rule = "@nzsl/archive.shaders", always_added = true, compress = true, files = archivefiles }
+				if archive:endswith(".nzsla.h") or archive:endswith(".nzsla.hpp") then
+					args.header = path.extension(archive)
+					archive = archive:sub(1, -#args.header - 1) -- foo.nzsla.h => foo.nzsla
+				end
+
+				target:add("files", archive, args)
+			end
+		end
+	end)
+
+	before_buildcmd_file(function (target, batchcmds, shaderfile, opt)
+		local outputdir = target:data("nzsl_includedirs")
+		local nzslc = target:data("nzslc")
+		local runenvs = target:data("nzsl_runenv")
+		assert(nzslc, "nzslc not found! please install nzsl package with nzslc enabled")
+
+		local fileconfig = target:fileconfig(shaderfile) or {}
+		local header = fileconfig.archive == nil
+
+		-- add commands
+		batchcmds:show_progress(opt.progress, "${color.build.object}compiling.shader %s", shaderfile)
+		local argv = { "--compile=nzslb" .. (header and "-header" or ""), "--partial", "--optimize" }
+		if outputdir then
+			batchcmds:mkdir(outputdir)
+			table.insert(argv, "--output=" .. outputdir)
+		end
+
+		-- handle --log-format
+		local kind = target:data("plugin.project.kind") or ""
+		if kind:match("vs") then
+			table.insert(argv, "--log-format=vs")
+		end
+
+		table.insert(argv, shaderfile)
+
+		batchcmds:vrunv(nzslc.program, argv, { curdir = ".", envs = runenvs })
+
+		local outputfile = path.join(outputdir or path.directory(shaderfile), path.basename(shaderfile) .. ".nzslb" .. (header and ".h" or ""))
+
+		-- add deps
+		batchcmds:add_depfiles(shaderfile)
+		batchcmds:add_depvalues(nzslc.version)
+		batchcmds:set_depmtime(os.mtime(outputfile))
+		batchcmds:set_depcache(target:dependfile(outputfile))
+	end)

+ 47 - 0
packages/n/nzsl/rules/find_nzsl.lua

@@ -0,0 +1,47 @@
+-- Merge binary shaders to archivess
+rule("find_nzsl")
+	on_config(function(target)
+		import("core.project.project")
+		import("core.tool.toolchain")
+		import("lib.detect.find_tool")
+
+		-- on windows+asan/mingw we need run envs because of .dll dependencies which may be not part of the PATH
+		local envs
+		if is_plat("windows") then
+			local msvc = target:toolchain("msvc")
+			if msvc and msvc:check() then
+				envs = msvc:runenvs()
+			end
+		elseif is_plat("mingw") then
+			local mingw = target:toolchain("mingw")
+			if mingw and mingw:check() then
+				envs = mingw:runenvs()
+			end
+		end
+		target:data_set("nzsl_envs", envs)
+
+		-- find nzsl binaries
+		local nzsl = project.required_package("nzsl~host") or project.required_package("nzsl")
+		local nzsldir
+		if nzsl then
+			nzsldir = path.join(nzsl:installdir(), "bin")
+			local osenvs = os.getenvs()
+			envs = envs or {}
+			for env, values in pairs(nzsl:get("envs")) do
+				local flatval = path.joinenv(values)
+				local oldenv = envs[env] or osenvs[env]
+				if not oldenv or oldenv == "" then
+					envs[env] = flatval
+				elseif not oldenv:startswith(flatval) then
+					envs[env] = flatval .. path.envsep() .. oldenv
+				end
+			end
+		end
+
+		local nzsla = find_tool("nzsla", { version = true, paths = nzsldir, envs = envs })
+		local nzslc = find_tool("nzslc", { version = true, paths = nzsldir, envs = envs })
+
+		target:data_set("nzsla", nzsla)
+		target:data_set("nzslc", nzslc)
+		target:data_set("nzsl_runenv", envs)
+	end)

+ 119 - 0
packages/n/nzsl/xmake.lua

@@ -0,0 +1,119 @@
+package("nzsl")
+    set_homepage("https://github.com/NazaraEngine/ShaderLang")
+    set_description("NZSL is a shader language inspired by Rust and C++ which compiles to GLSL or SPIRV")
+    set_license("MIT")
+
+    add_urls("https://github.com/NazaraEngine/ShaderLang/archive/refs/tags/$(version).tar.gz",
+             "https://github.com/NazaraEngine/ShaderLang.git")
+
+    add_versions("v1.0.0", "ef434fec5d32ddf64f2f7c7691a4d96a6ac24cab4cc6c091d46a542c86825359")
+
+    set_policy("package.strict_compatibility", true)
+
+    add_deps("nazarautils")
+    add_deps("fast_float", "frozen", "ordered_map", {private = true})
+
+    add_configs("cbinding", {description = "Builds the C binding library (CNZSL)", default = false, type = "boolean"})
+    add_configs("nzsla", {description = "Includes standalone archiver", default = true, type = "boolean"})
+    add_configs("nzslc", {description = "Includes standalone compiler", default = true, type = "boolean"})
+    add_configs("symbols", {description = "Enable debug symbols in release", default = false, type = "boolean"})
+
+    if is_plat("windows", "linux", "mingw", "macosx", "bsd") then
+        add_configs("fs_watcher", {description = "Includes filesystem watcher", default = true, type = "boolean"})
+    end
+
+    if is_plat("wasm") then
+        add_configs("shared", {description = "Build shared library.", default = false, type = "boolean", readonly = true})
+    end
+
+    on_load(function (package)
+        package:addenv("PATH", "bin")
+        if not package:config("shared") then
+            package:add("defines", "NZSL_STATIC")
+            package:add("deps", "fmt")
+        end
+        if package:config("fs_watcher") then
+            package:add("deps", "efsw")
+        end
+        if package:config("nzsla") then
+            package:add("deps", "lz4", {private = package:config("shared")})
+        end
+        if package:config("nzslc") then
+            package:add("deps", "cxxopts >=3.1.1", "nlohmann_json", {private = true})
+        end
+    end)
+
+    on_install(function (package)
+        local configs = {}
+        configs.cbinding = package:config("cbinding")
+        configs.fs_watcher = package:config("fs_watcher") or false
+        configs.erronwarn = false
+        configs.examples = false
+        configs.tests = false
+        configs.with_nzsla = package:config("nzsla") or false
+        configs.with_nzslc = package:config("nzslc") or false
+
+        -- enable unitybuild for faster compilation except on MinGW (doesn't like big object even with /bigobj)
+        if not os.getenv("NAZARA_DISABLE_UNITYBUILD") then
+            configs.unitybuild = not package:is_plat("mingw")
+        end
+
+        if package:is_debug() then
+            configs.mode = "debug"
+        elseif package:config("symbols") then
+            configs.mode = "releasedbg"
+        else
+            configs.mode = "release"
+        end
+
+        import("package.tools.xmake").install(package, configs)
+        package:add("linkorders", "cnzsl", "nzsl")
+    end)
+
+    on_test(function (package)
+        if (package:config("nzsla") or package:config("nzslc")) and not package:is_cross() then
+            local envs
+            if package:is_plat("windows") then
+                import("core.tool.toolchain")
+                local msvc = package:toolchain("msvc")
+                if msvc and msvc:check() then
+                    envs = msvc:runenvs()
+                end
+            elseif package:is_plat("mingw") then
+                import("core.tool.toolchain")
+                local mingw = package:toolchain("mingw")
+                if mingw and mingw:check() then
+                    envs = mingw:runenvs()
+                end
+            end
+            if package:config("nzsla") then
+                os.vrunv("nzsla", {"--version"}, {envs = envs})
+            end
+            if package:config("nzslc") then
+                os.vrunv("nzslc", {"--version"}, {envs = envs})
+            end
+        end
+        if not package:is_binary() then
+            assert(package:check_cxxsnippets({test = [[
+                void test() {
+                    nzsl::Ast::ModulePtr shaderModule = nzsl::Parse(R"(
+                        [nzsl_version("1.0")]
+                        module;
+
+                        struct FragOut
+                        {
+                            value: vec4[f32]
+                        }
+
+                        [entry(frag)]
+                        fn fragShader() -> FragOut
+                        {
+                            let output: FragOut;
+                            output.value = vec4[f32](0.0, 0.0, 1.0, 1.0);
+                            return output;
+                        }
+                    )");
+                }
+            ]]}, {configs = {languages = "c++17"}, includes = "NZSL/Parser.hpp"}))
+        end
+    end)