gen_texture_funcs.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. #!/usr/bin/python3
  2. # Copyright (C) 2009-2020, Panagiotis Christopoulos Charitos and contributors.
  3. # All rights reserved.
  4. # Code licensed under the BSD License.
  5. # http://www.anki3d.org/LICENSE
  6. import enum
  7. import copy
  8. signatures = """
  9. gvec4 texture(gsampler1D sampler, float P [,float bias] )
  10. gvec4 texture(gsampler2D sampler, vec2 P [,float bias] )
  11. gvec4 texture(gsampler3D sampler, vec3 P [, float bias] )
  12. gvec4 texture(gsamplerCube sampler, vec3 P[, float bias] )
  13. float texture(sampler1DShadow sampler, vec3 P [, float bias])
  14. float texture(sampler2DShadow sampler, vec3 P [, float bias])
  15. float texture(samplerCubeShadow sampler, vec4 P [, float bias] )
  16. gvec4 texture(gsampler2DArray sampler, vec3 P [, float bias] )
  17. gvec4 texture(gsamplerCubeArray sampler, vec4 P [, float bias] )
  18. gvec4 texture(gsampler1DArray sampler, vec2 P [, float bias] )
  19. float texture(sampler1DArrayShadow sampler, vec3 P [, float bias] )
  20. float texture(sampler2DArrayShadow sampler, vec4 P)
  21. float texture(samplerCubeArrayShadow sampler, vec4 P, float compare)
  22. gvec4 textureProj(gsampler1D sampler, vec2 P [, float bias] )
  23. gvec4 textureProj(gsampler1D sampler, vec4 P [, float bias] )
  24. gvec4 textureProj(gsampler2D sampler, vec3 P [, float bias] )
  25. gvec4 textureProj(gsampler2D sampler, vec4 P [, float bias] )
  26. gvec4 textureProj(gsampler3D sampler, vec4 P [, float bias] )
  27. float textureProj(sampler1DShadow sampler, vec4 P [, float bias] )
  28. float textureProj(sampler2DShadow sampler, vec4 P [, float bias] )
  29. gvec4 textureLod(gsampler1D sampler, float P, float lod)
  30. gvec4 textureLod(gsampler2D sampler, vec2 P, float lod)
  31. gvec4 textureLod(gsampler3D sampler, vec3 P, float lod)
  32. gvec4 textureLod(gsamplerCube sampler, vec3 P, float lod)
  33. float textureLod(sampler2DShadow sampler, vec3 P, float lod)
  34. float textureLod(sampler1DShadow sampler, vec3 P, float lod)
  35. gvec4 textureLod(gsampler1DArray sampler, vec2 P, float lod)
  36. float textureLod(sampler1DArrayShadow sampler, vec3 P, float lod)
  37. gvec4 textureLod(gsampler2DArray sampler, vec3 P, float lod)
  38. gvec4 textureLod(gsamplerCubeArray sampler, vec4 P, float lod)
  39. gvec4 textureProjLod(gsampler1D sampler, vec2 P, float lod)
  40. gvec4 textureProjLod(gsampler1D sampler, vec4 P, float lod)
  41. gvec4 textureProjLod(gsampler2D sampler, vec3 P, float lod)
  42. gvec4 textureProjLod(gsampler2D sampler, vec4 P, float lod)
  43. gvec4 textureProjLod(gsampler3D sampler, vec4 P, float lod)
  44. float textureProjLod(sampler1DShadow sampler, vec4 P, float lod)
  45. float textureProjLod(sampler2DShadow sampler, vec4 P, float lod)
  46. gvec4 textureGrad(gsampler1D sampler, float P, float dPdx, float dPdy)
  47. gvec4 textureGrad(gsampler2D sampler, vec2 P, vec2 dPdx, vec2 dPdy)
  48. gvec4 textureGrad(gsampler3D sampler, vec3 P, vec3 dPdx, vec3 dPdy)
  49. gvec4 textureGrad(gsamplerCube sampler, vec3 P, vec3 dPdx, vec3 dPdy)
  50. float textureGrad(sampler1DShadow sampler, vec3 P, float dPdx, float dPdy)
  51. gvec4 textureGrad(gsampler1DArray sampler, vec2 P, float dPdx, float dPdy)
  52. gvec4 textureGrad(gsampler2DArray sampler, vec3 P, vec2 dPdx, vec2 dPdy)
  53. float textureGrad(sampler1DArrayShadow sampler, vec3 P, float dPdx, float dPdy)
  54. float textureGrad(sampler2DShadow sampler, vec3 P, vec2 dPdx, vec2 dPdy)
  55. float textureGrad(samplerCubeShadow sampler, vec4 P, vec3 dPdx, vec3 dPdy)
  56. float textureGrad(sampler2DArrayShadow sampler, vec4 P, vec2 dPdx, vec2 dPdy)
  57. gvec4 textureGrad(gsamplerCubeArray sampler, vec4 P, vec3 dPdx, vec3 dPdy)
  58. gvec4 textureProjGrad(gsampler1D sampler, vec2 P, float dPdx, float dPdy)
  59. gvec4 textureProjGrad(gsampler1D sampler, vec4 P, float dPdx, float dPdy)
  60. gvec4 textureProjGrad(gsampler2D sampler, vec3 P, vec2 dPdx, vec2 dPdy)
  61. gvec4 textureProjGrad(gsampler2D sampler, vec4 P, vec2 dPdx, vec2 dPdy)
  62. gvec4 textureProjGrad(gsampler3D sampler, vec4 P, vec3 dPdx, vec3 dPdy)
  63. float textureProjGrad(sampler1DShadow sampler, vec4 P, float dPdx, float dPdy)
  64. float textureProjGrad(sampler2DShadow sampler, vec4 P, vec2 dPdx, vec2 dPdy)
  65. """
  66. class Type(enum.Enum):
  67. NONE = 0
  68. BASIC = 1
  69. VEC = 2
  70. COMBINED_IMAGE_SAMPLER = 3
  71. SAMPLER = 4
  72. TEXTURE = 5
  73. class TypeFlag(enum.IntEnum):
  74. NONE = 0
  75. FLOAT = 1 << 0
  76. INT = 1 << 1
  77. UINT = 1 << 2
  78. GENERIC = 1 << 3
  79. ARRAY = 1 << 4
  80. SHADOW = 1 << 5
  81. OPTIONAL_ARG = 1 << 6
  82. class TypeInfo:
  83. def __init__(self):
  84. self.type = Type.NONE
  85. self.type_flags = TypeFlag.NONE
  86. self.dim = 0
  87. def __str__(self):
  88. return str(self.__class__) + ": " + str(self.__dict__)
  89. class Arg:
  90. def __init__(self):
  91. self.type = TypeInfo()
  92. self.name = None
  93. class Function:
  94. def __init__(self):
  95. self.return_type = TypeInfo()
  96. self.func_name = None
  97. self.args = []
  98. self.is_generic = False
  99. self.has_optional_arg = False
  100. self.all_shader_stages = False
  101. def __str__(self):
  102. return str(self.__class__) + ": " + str(self.__dict__)
  103. def tokenize(line):
  104. out = []
  105. line = line.replace("(", " ")
  106. line = line.replace(")", " ")
  107. line = line.replace(",", " ")
  108. line = line.replace("[", " ")
  109. line = line.replace("]", " ")
  110. tokens = line.split(" ")
  111. for token in tokens:
  112. token = token.strip()
  113. if len(token) == 0:
  114. continue
  115. out.append(token)
  116. return out
  117. def parse_type(s):
  118. type = TypeInfo()
  119. if s.find("sampler") >= 0:
  120. type.type = Type.COMBINED_IMAGE_SAMPLER
  121. if s[0] == "g":
  122. type.type_flags |= TypeFlag.GENERIC
  123. elif s[0] == "s":
  124. type.type_flags |= TypeFlag.FLOAT
  125. elif s[0] == "u":
  126. type.type_flags |= TypeFlag.UINT
  127. elif s[0] == "i":
  128. type.type_flags |= TypeFlag.INT
  129. else:
  130. assert (False)
  131. if s.find("1D") >= 0:
  132. type.dim = 1
  133. elif s.find("2D") >= 0:
  134. type.dim = 2
  135. elif s.find("3D") >= 0:
  136. type.dim = 3
  137. elif s.find("Cube") >= 0:
  138. type.dim = 6
  139. if s.find("Array") >= 0:
  140. type.type_flags |= TypeFlag.ARRAY
  141. if s.find("Shadow") >= 0:
  142. type.type_flags |= TypeFlag.SHADOW
  143. elif s.find("vec") >= 0:
  144. type.type = Type.VEC
  145. if s[0] == "g":
  146. type.type_flags |= TypeFlag.GENERIC
  147. elif s[0] == "u":
  148. type.type_flags |= TypeFlag.UINT
  149. elif s[0] == "i":
  150. type.type_flags |= TypeFlag.INT
  151. elif s[0] == "v":
  152. type.type_flags |= TypeFlag.FLOAT
  153. else:
  154. assert (False)
  155. if s[-1] == "4":
  156. type.dim = 4
  157. elif s[-1] == "3":
  158. type.dim = 3
  159. elif s[-1] == "2":
  160. type.dim = 2
  161. else:
  162. assert (False)
  163. elif s == "float":
  164. type.dim = 1
  165. type.type_flags |= TypeFlag.FLOAT
  166. type.type = Type.BASIC
  167. elif s == "int":
  168. type.dim = 1
  169. type.type_flags |= TypeFlag.INT
  170. type.type = Type.BASIC
  171. else:
  172. assert (False)
  173. return type
  174. def parse_func(tokens):
  175. func = Function()
  176. func.return_type = parse_type(tokens[0])
  177. func.is_generic = func.is_generic or (
  178. func.return_type.type_flags & TypeFlag.GENERIC)
  179. func.func_name = tokens[1]
  180. if func.func_name.find("Lod") >= 0:
  181. func.all_shader_stages = True
  182. else:
  183. func.all_shader_stages = False
  184. size = len(tokens)
  185. for i in range(2, size, 2):
  186. arg = Arg()
  187. arg.type = parse_type(tokens[i])
  188. arg.name = tokens[i + 1]
  189. if arg.name == "bias":
  190. arg.type.type_flags |= TypeFlag.OPTIONAL_ARG
  191. func.has_optional_arg = True
  192. func.is_generic = func.is_generic or (
  193. arg.type.type_flags & TypeFlag.GENERIC)
  194. func.args.append(arg)
  195. return func
  196. def write_type(type):
  197. out = ""
  198. if type.type == Type.BASIC and type.type_flags & TypeFlag.FLOAT:
  199. out += "float"
  200. elif type.type == Type.BASIC and type.type_flags & TypeFlag.UINT:
  201. out += "uint"
  202. elif type.type == Type.BASIC and type.type_flags & TypeFlag.INT:
  203. out += "int"
  204. elif type.type == Type.VEC and type.type_flags & TypeFlag.FLOAT:
  205. out += "vec" + str(type.dim)
  206. elif type.type == Type.VEC and type.type_flags & TypeFlag.UINT:
  207. out += "uvec" + str(type.dim)
  208. elif type.type == Type.VEC and type.type_flags & TypeFlag.INT:
  209. out += "ivec" + str(type.dim)
  210. elif type.type == Type.COMBINED_IMAGE_SAMPLER:
  211. if type.type_flags & TypeFlag.UINT:
  212. out += "u"
  213. elif type.type_flags & TypeFlag.INT:
  214. out += "i"
  215. out += "sampler"
  216. if type.dim == 1:
  217. out += "1D"
  218. elif type.dim == 2:
  219. out += "2D"
  220. elif type.dim == 3:
  221. out += "3D"
  222. elif type.dim == 6:
  223. out += "Cube"
  224. if type.type_flags & TypeFlag.ARRAY:
  225. out += "Array"
  226. if type.type_flags & TypeFlag.SHADOW:
  227. out += "Shadow"
  228. elif type.type == Type.TEXTURE:
  229. if type.type_flags & TypeFlag.UINT:
  230. out += "u"
  231. elif type.type_flags & TypeFlag.INT:
  232. out += "i"
  233. out += "texture"
  234. if type.dim == 1:
  235. out += "1D"
  236. elif type.dim == 2:
  237. out += "2D"
  238. elif type.dim == 3:
  239. out += "3D"
  240. elif type.dim == 6:
  241. out += "Cube"
  242. if type.type_flags & TypeFlag.ARRAY:
  243. out += "Array"
  244. elif type.type == Type.SAMPLER:
  245. out += "sampler"
  246. if type.type_flags & TypeFlag.SHADOW:
  247. out += "Shadow"
  248. else:
  249. assert False
  250. return out
  251. def gen_split_sampler_tex_func(func):
  252. out = ""
  253. # Generate new function signatures
  254. func_instances = []
  255. if func.is_generic:
  256. for generic_type in [TypeFlag.FLOAT, TypeFlag.UINT, TypeFlag.INT]:
  257. new_func = copy.deepcopy(func)
  258. # Return
  259. if new_func.return_type.type_flags & TypeFlag.GENERIC:
  260. new_func.return_type.type_flags &= ~TypeFlag.GENERIC
  261. new_func.return_type.type_flags |= generic_type
  262. # Args
  263. for arg in new_func.args:
  264. if arg.type.type_flags & TypeFlag.GENERIC:
  265. arg.type.type_flags &= ~TypeFlag.GENERIC
  266. arg.type.type_flags |= generic_type
  267. func_instances.append(new_func)
  268. else:
  269. func_instances.append(copy.deepcopy(func))
  270. # Populate optional arg version
  271. if func.has_optional_arg:
  272. extra_func_instances = []
  273. for func in func_instances:
  274. new_func = copy.deepcopy(func)
  275. assert new_func.args[-1].type.type_flags & TypeFlag.OPTIONAL_ARG
  276. new_func.args.pop()
  277. extra_func_instances.append(new_func)
  278. func_instances.extend(extra_func_instances)
  279. for func in func_instances:
  280. # Shader guard
  281. if not func.all_shader_stages:
  282. out += "#if defined(ANKI_FRAGMENT_SHADER)\n"
  283. # Return type
  284. out += write_type(func.return_type) + " "
  285. # Func name
  286. out += func.func_name
  287. out += "("
  288. # Args
  289. for i in range(len(func.args)):
  290. arg = func.args[i]
  291. if arg.type.type == Type.COMBINED_IMAGE_SAMPLER:
  292. # Write texture
  293. tex_type = copy.deepcopy(arg.type)
  294. tex_type.type = Type.TEXTURE
  295. out += write_type(tex_type)
  296. out += " tex, "
  297. # Write sampler
  298. sampler_type = copy.deepcopy(arg.type)
  299. sampler_type.type = Type.SAMPLER
  300. out += write_type(sampler_type)
  301. out += " sampl"
  302. else:
  303. out += write_type(arg.type)
  304. out += " " + arg.name
  305. if i < len(func.args) - 1:
  306. out += ", "
  307. out += ")\n"
  308. # Body
  309. out += "{\n"
  310. out += "\treturn " + func.func_name + "("
  311. for i in range(len(func.args)):
  312. arg = func.args[i]
  313. if arg.type.type == Type.COMBINED_IMAGE_SAMPLER:
  314. out += write_type(arg.type) + "(tex, sampl)"
  315. else:
  316. out += arg.name
  317. if i < len(func.args) - 1:
  318. out += ", "
  319. else:
  320. out += ");\n"
  321. out += "}\n"
  322. # Shader guard
  323. if not func.all_shader_stages:
  324. out += "#endif\n"
  325. out += "\n"
  326. return out
  327. def main():
  328. print(
  329. """// Copyright (C) 2009-2020, Panagiotis Christopoulos Charitos and contributors.
  330. // All rights reserved.
  331. // Code licensed under the BSD License.
  332. // http://www.anki3d.org/LICENSE
  333. // WARNING: THIS FILE IS AUTO-GENERATED. DON'T CHANGE IT BY HAND.
  334. // This file contains some convenience texture functions.
  335. #pragma once
  336. """)
  337. lines = signatures.splitlines()
  338. for line in lines:
  339. line = line.strip()
  340. # Skip empty
  341. if len(line) == 0:
  342. continue
  343. # Parse the func signature
  344. func = parse_func(tokenize(line))
  345. # Write the alternative func
  346. func_code = gen_split_sampler_tex_func(func)
  347. print(func_code)
  348. # print("""layout(location = 0) out vec4 out_color;
  349. #void main()
  350. #{
  351. # out_color = vec4(0);
  352. #}""")
  353. if __name__ == "__main__":
  354. main()