package An official xmake package repository https://xrepo.xmake.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
4.7 KiB

-- Compile bgfx shader files. Substitution for scripts/shader.mk.
--
-- Usage:
--
-- add_rules("@bgfx/shaders")
-- add_files("shader.vert", {type = "vertex", output_dir = "shaders", output_name = "shader.vert.bin", profiles = {glsl = "330"}})
rule("shaders")
set_extensions(".vert", ".frag", ".comp")
on_buildcmd_file(function (target, batchcmds, shaderfile, opt)
import("lib.detect.find_program")
import("core.base.option")
batchcmds:show_progress(opt.progress, "${color.build.object}compiling.shaderc %s", shaderfile)
-- get bgfx shaderc
local shaderc = find_program("shadercRelease") or find_program("shadercDebug")
assert(shaderc, "bgfx shaderc not found! please check your bgfx installation.")
-- determine arguments for shaderc from fileconfig
local fileconfig = target:fileconfig(shaderfile)
local output_filename
if fileconfig and fileconfig.output_name then
output_filename = fileconfig.output_name
else
output_filename = path.filename(shaderfile) .. ".bin"
end
local output_dir
if fileconfig and fileconfig.output_dir then
output_dir = fileconfig.output_dir
else
output_dir = "shaders"
end
local vardef_filename
if fileconfig and fileconfig.vardef then
vardef_filename = fileconfig.vardef
else
vardef_filename = path.join(
path.directory(shaderfile),
path.basename(shaderfile) .. ".varying.def.sc")
end
local shader_type
if fileconfig and fileconfig.type then
if table.contains(bgfx_types, fileconfig.type) then
shader_type = fileconfig.type
else
raise("unsupported shader type " .. fileconfig.type)
end
elseif shaderfile:match("%.vert$") then
shader_type = "vertex"
elseif shaderfile:match("%.frag$") then
shader_type = "fragment"
elseif shaderfile:match("%.comp$") then
shader_type = "compute"
else
raise("cannot determine shader type from file name " .. path.filename(shaderfile))
end
-- determine platform-specific shaderc arguments
local bgfx_platforms = {
windows = "windows",
macosx = "osx",
linux = "linux"
}
local bgfx_types = {
"vertex",
"fragment",
"compute"
}
local bgfx_default_profiles = {
windows = {
vertex = {dx9 = "vs_3_0", dx11 = "vs_5_0", glsl = "120"},
fragment = {dx9 = "ps_3_0", dx11 = "ps_5_0", glsl = "120"},
compute = {dx11 = "cs_5_0", glsl = "430"},
},
macosx = {
vertex = {metal = "metal", glsl = "120"},
fragment = {metal = "metal", glsl = "120"},
compute = {metal = "metal", glsl = "430"}
},
linux = {
vertex = {glsl = "120", spirv = "spirv"},
fragment = {glsl = "120", spirv = "spirv"},
compute = {glsl = "430", spirv = "spirv"}
}
}
-- build command args
local args = {
"-f", shaderfile,
"--type", shader_type,
"--varyingdef", vardef_filename,
"--platform", bgfx_platforms[target:plat()],
}
for _, includedir in ipairs(target:get("includedirs")) do
table.insert(args, "-i")
table.insert(args, includedir)
end
local mtime = 0
local shader_profiles
if fileconfig and fileconfig.profiles then
shader_profiles = fileconfig.profiles
else
shader_profiles = bgfx_default_profiles[target:plat()][shader_type]
end
for folder, profile in pairs(shader_profiles) do
-- set output dir
local outputdir = path.join(target:targetdir(), output_dir, folder)
batchcmds:mkdir(outputdir)
local binary = path.join(outputdir, output_filename)
-- compiling
local real_args = {}
table.join2(real_args, args)
table.insert(real_args, "-o")
table.insert(real_args, binary)
table.insert(real_args, "--profile")
table.insert(real_args, profile)
if option.get("verbose") then
batchcmds:show(shaderc .. " " .. os.args(real_args))
end
batchcmds:vrunv(shaderc, real_args)
if (mtime == 0) then mtime = os.mtime(binary) end
end
-- add deps
batchcmds:add_depfiles(shaderfile)
batchcmds:set_depmtime(mtime)
end)