shaders.lua 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. -- Compile bgfx shader files. Substitution for scripts/shader.mk.
  2. --
  3. -- Usage:
  4. --
  5. -- add_rules("@bgfx/shaders")
  6. --
  7. -- -- generate binary file:
  8. -- add_files("shader.vert", {type = "vertex", output_dir = "shaders", output_name = "shader.vert.bin", profiles = {glsl = "330"}})
  9. -- -- generate header file:
  10. -- add_files("vs_shader.sc", {type = "vertex", output_dir = "shaders", output_name = "vs_shader.h", profiles = {glsl = "330"}})
  11. -- -- generate header file exporting variable "vertex_src":
  12. -- add_files("vs_shader.sc", {type = "vertex", output_dir = "shaders", output_name = "vs_shader.h", array_name = "vertex_src", profiles = {glsl = "330"}})
  13. -- -- force to generate header file with default variable name:
  14. -- add_files("vs_shader.sc", {type = "vertex", output_dir = "shaders", output_name = "vs_shader.inc", array_name = true, profiles = {glsl = "330"}})
  15. rule("shaders")
  16. set_extensions(".sc", ".vert", ".frag", ".comp")
  17. on_buildcmd_file(function (target, batchcmds, shaderfile, opt)
  18. import("lib.detect.find_program")
  19. import("core.base.option")
  20. batchcmds:show_progress(opt.progress, "${color.build.object}compiling.shaderc %s", shaderfile)
  21. -- get bgfx shaderc
  22. local shaderc = find_program("shadercRelease") or find_program("shadercDebug")
  23. assert(shaderc, "bgfx shaderc not found! please check your bgfx installation.")
  24. -- determine arguments for shaderc from fileconfig
  25. local fileconfig = target:fileconfig(shaderfile)
  26. local output_filename
  27. if fileconfig and fileconfig.output_name then
  28. output_filename = fileconfig.output_name
  29. else
  30. local filename = path.filename(shaderfile)
  31. output_filename = filename:match("^(.*)%.sc$") or filename
  32. if fileconfig and fileconfig.array_name then
  33. output_filename = output_filename .. ".h"
  34. else
  35. output_filename = output_filename .. ".bin"
  36. end
  37. end
  38. local output_dir
  39. if fileconfig and fileconfig.output_dir then
  40. output_dir = fileconfig.output_dir
  41. else
  42. output_dir = "shaders"
  43. end
  44. local vardef_filename
  45. if fileconfig and fileconfig.vardef then
  46. vardef_filename = fileconfig.vardef
  47. else
  48. vardef_filename = path.join(path.directory(shaderfile), "varying.def.sc")
  49. end
  50. -- determine platform-specific shaderc arguments
  51. local bgfx_platforms = {
  52. windows = "windows",
  53. macosx = "osx",
  54. linux = "linux"
  55. }
  56. local bgfx_types = {
  57. "vertex",
  58. "fragment",
  59. "compute"
  60. }
  61. local bgfx_default_profiles = {
  62. windows = {
  63. vertex = {dx11 = "s_5_0", glsl = "120"},
  64. fragment = {dx11 = "s_5_0", glsl = "120"},
  65. compute = {dx11 = "s_5_0", glsl = "430"},
  66. },
  67. macosx = {
  68. vertex = {metal = "metal", glsl = "120"},
  69. fragment = {metal = "metal", glsl = "120"},
  70. compute = {metal = "metal", glsl = "430"}
  71. },
  72. linux = {
  73. vertex = {glsl = "120", spirv = "spirv"},
  74. fragment = {glsl = "120", spirv = "spirv"},
  75. compute = {glsl = "430", spirv = "spirv"}
  76. }
  77. }
  78. local shader_type
  79. if fileconfig and fileconfig.type then
  80. if table.contains(bgfx_types, fileconfig.type) then
  81. shader_type = fileconfig.type
  82. else
  83. raise("unsupported shader type " .. fileconfig.type)
  84. end
  85. elseif shaderfile:match("^vs_.*%.sc$") or shaderfile:match("%.vert$") then
  86. shader_type = "vertex"
  87. elseif shaderfile:match("^fs_.*%.sc$") or shaderfile:match("%.frag$") then
  88. shader_type = "fragment"
  89. elseif shaderfile:match("^cs_.*%.sc$") or shaderfile:match("%.comp$") then
  90. shader_type = "compute"
  91. else
  92. raise("cannot determine shader type from file name " .. path.filename(shaderfile))
  93. end
  94. -- build command args
  95. local args = {
  96. "-f", shaderfile,
  97. "--type", shader_type,
  98. "--varyingdef", vardef_filename,
  99. "--platform", bgfx_platforms[target:plat()],
  100. }
  101. if fileconfig and fileconfig.array_name then
  102. table.insert(args, "--bin2c")
  103. if fileconfig.array_name ~= true then
  104. table.insert(args, fileconfig.array_name)
  105. end
  106. end
  107. -- print(target:pkg("bgfx"):installdir())
  108. for _, includedir in ipairs(target:get("includedirs")) do
  109. table.insert(args, "-i")
  110. table.insert(args, includedir)
  111. end
  112. local mtime = 0
  113. local shader_profiles
  114. if fileconfig and fileconfig.profiles then
  115. shader_profiles = fileconfig.profiles
  116. else
  117. shader_profiles = bgfx_default_profiles[target:plat()][shader_type]
  118. end
  119. for folder, profile in pairs(shader_profiles) do
  120. -- set output dir
  121. local outputdir = path.join(target:targetdir(), output_dir, folder)
  122. batchcmds:mkdir(outputdir)
  123. local binary = path.join(outputdir, output_filename)
  124. -- compiling
  125. local real_args = {}
  126. table.join2(real_args, args)
  127. table.insert(real_args, "-o")
  128. table.insert(real_args, binary)
  129. table.insert(real_args, "--profile")
  130. table.insert(real_args, profile)
  131. if option.get("verbose") then
  132. batchcmds:show(shaderc .. " " .. os.args(real_args))
  133. end
  134. batchcmds:vrunv(shaderc, real_args)
  135. if (mtime == 0) then mtime = os.mtime(binary) end
  136. end
  137. -- add deps
  138. batchcmds:add_depfiles(shaderfile)
  139. batchcmds:set_depmtime(mtime)
  140. end)