GenVecSwizzles.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #!/usr/bin/env python3
  2. """
  3. Generate all valid HLSL swizzles for float2, float3 and float4.
  4. Rules used:
  5. - float2: components = x, y
  6. - float3: components = x, y, z
  7. - float4: components = x, y, z, w
  8. - Swizzle lengths: 1..4 (HLSL allows swizzles up to length 4)
  9. - Repetition and any ordering allowed, but only components that exist for the given vector type
  10. Outputs the swizzles to stdout and writes them to files:
  11. - swizzles_float2.txt
  12. - swizzles_float3.txt
  13. - swizzles_float4.txt
  14. Quick usage: python3 hlsl_swizzles.py
  15. """
  16. from itertools import product
  17. VECTOR_COMPONENTS = {
  18. 'float2': 'xy',
  19. 'float3': 'xyz',
  20. 'float4': 'xyzw',
  21. }
  22. MAX_SWIZZLE_LEN = 4
  23. def comp_to_index(c):
  24. if c == "x": return "0"
  25. elif c == "y": return "1"
  26. elif c == "z": return "2"
  27. else: return "3"
  28. def swizzle_to_indices(p):
  29. txt = ""
  30. for i in range(len(p)):
  31. txt += comp_to_index(p[i]) + (", " if i < len(p) - 1 else "")
  32. return txt
  33. def generate_swizzles(components: str, max_len: int = 4):
  34. """Yield swizzle strings using only the provided components, lengths 1..max_len."""
  35. comp_count = len(components)
  36. for L in range(1, max_len + 1):
  37. for p in product(components, repeat=L):
  38. if len(p) > 1:
  39. yield "TVecSwizzledData<T, {}, {}> {};".format(comp_count, swizzle_to_indices(p), ''.join(p))
  40. if __name__ == '__main__':
  41. totals = {}
  42. for vt, comps in VECTOR_COMPONENTS.items():
  43. swizzles = list(generate_swizzles(comps, MAX_SWIZZLE_LEN))
  44. totals[vt] = len(swizzles)
  45. # Print short summary
  46. print(f"{vt}: {len(swizzles)} swizzles (components: {', '.join(comps)})")
  47. # Optionally group by length — small readable output
  48. by_len = {}
  49. for s in swizzles:
  50. by_len.setdefault(len(s), []).append(s)
  51. for L in sorted(by_len):
  52. print(f" len={L}: {len(by_len[L])} -> example: {', '.join(by_len[L][:8])}{'...' if len(by_len[L])>8 else ''}")
  53. # write full list to file
  54. fname = f"swizzles_{vt}.txt"
  55. with open(fname, 'w') as f:
  56. for s in swizzles:
  57. f.write(s + '\n')
  58. print(f" full list written to: {fname}\n")
  59. total_all = sum(totals.values())
  60. print(f"Total swizzles generated: {total_all}")