Document the full HLSL target and its source transformations
design.md states the generated swizzle and mixed-constructor surface, writable matrix rows, HLSL intrinsic types and NaN behavior, the deferred matrix items (float4x4, transpose, determinant, _11 names), the exact HLSL-to-C# transformations the compatibility test applies, and the dxc check. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
88eb365c05
commit
7a1bd1ebb1
2 changed files with 53 additions and 8 deletions
|
|
@ -16,7 +16,9 @@ shader semantics.
|
|||
- `float2`, `float3`, `float4`
|
||||
- component-wise arithmetic
|
||||
- scalar-to-vector splats
|
||||
- swizzles for common lanes
|
||||
- every HLSL swizzle (`xyzw` and `rgba`, repeats readable, non-repeating
|
||||
masks writable) and every HLSL mixed constructor, generated by
|
||||
`tools/generate-swizzles.ps1`
|
||||
- conversions to and from `System.Numerics`
|
||||
- `Random`, a compact deterministic XORShift stream with scalar and vector draws
|
||||
- `BatchMath` SoA kernels over `Span<float>` / `ReadOnlySpan<float>` using
|
||||
|
|
|
|||
|
|
@ -12,20 +12,63 @@ rest of the spelling should survive the move.
|
|||
|
||||
That makes these HLSL rules, not options:
|
||||
|
||||
- Components and swizzles are writable. `v.xz = f2;` and `v[1] = s;` work.
|
||||
Swizzle setters exist only for non-repeating masks, because HLSL rejects
|
||||
`v.xx = ...`.
|
||||
- Every swizzle exists. `float2/3/4`, `int2/3/4`, and `bool2/3/4` expose every
|
||||
read swizzle of length 2 to 4, repeats included (`v.wwxy`), in both `xyzw` and
|
||||
`rgba` naming (never mixed), plus single-component `r/g/b/a`. `double2/3` get
|
||||
lengths 2 and 3 only, because there is no `double4`. Components and swizzles are
|
||||
writable: `v.xz = f2;`, `c.rgb *= 0.5f;`, and `v[1] = s;` work. Setters exist
|
||||
only for non-repeating masks, because HLSL rejects `v.xx = ...`.
|
||||
- Every HLSL mixed constructor exists, as a struct constructor and as a `math`
|
||||
function: `float4(float2, float2)`, `float4(float, float2, float)`,
|
||||
`float3(float, float2)`, the copy form `float3(float3)`, and the rest, for the
|
||||
float, int, and bool families (double gets constructors only; a `math.double3`
|
||||
function would hide the `double3` type name).
|
||||
- Swizzles and mixed constructors are generated. `tools/generate-swizzles.ps1`
|
||||
writes the checked-in `src/CultMath/Swizzles.g.cs` (partial structs plus a
|
||||
partial `math`). Edit the generator, rerun it, and commit both; never edit the
|
||||
output by hand.
|
||||
- Comparison operators (`<`, `>`, `<=`, `>=`, `==`, `!=`) are component-wise and
|
||||
return `bool2`/`bool3`/`bool4`. Reduce them with `any` and `all`.
|
||||
`Equals`/`GetHashCode` stay value-based so vectors still work as dictionary
|
||||
keys.
|
||||
- `select(condition, whenTrue, whenFalse)` uses HLSL's argument order.
|
||||
- Matrices are row-major: constructors take rows, `m[i]` is row i, `_mRC` is
|
||||
row R column C, and products go through `mul` (`mul(m, v)` treats `v` as a
|
||||
column, `mul(v, m)` as a row). `*` on matrices would be component-wise in HLSL,
|
||||
so CultMath does not define it.
|
||||
- Matrices are row-major: constructors take rows, `m[i]` returns a reference to
|
||||
row i (so `m[1][2] = s;` writes one element), `_mRC` is row R column C, and
|
||||
products go through `mul` (`mul(m, v)` treats `v` as a column, `mul(v, m)` as a
|
||||
row). `*` on matrices would be component-wise in HLSL, so CultMath does not
|
||||
define it.
|
||||
- Scalar/vector arithmetic and comparisons have explicit overloads on both
|
||||
sides rather than leaning on implicit scalar splat.
|
||||
- Intrinsics return HLSL's types and edge cases: `sign` returns `int`/`intN`
|
||||
(NaN gives 0); `step(y, x)` is `x >= y ? 1 : 0` (NaN gives 0), in C# and in the
|
||||
HLSL mirror; `any`/`all` accept numeric vectors (a component is true when it is
|
||||
not 0); `min`, `max`, and `abs` on int vectors return int vectors.
|
||||
|
||||
Deferred until a consumer needs them: `float4x4`, `transpose`, `determinant`,
|
||||
and HLSL's one-based `_11`..`_33` element names.
|
||||
|
||||
### HLSL Target: Source Transformations
|
||||
|
||||
`HlslSourceCompatibilityTests` compiles the real `shaders/CultMath.hlsl` with
|
||||
Roslyn against CultMath. These transformations are the complete list; if a body
|
||||
needs anything else, the test fails:
|
||||
|
||||
1. Include guards (`#ifndef`/`#define`/`#endif`) are dropped.
|
||||
2. Functions taking `Texture2D`/`SamplerState` are dropped; GPU resources have
|
||||
no CultMath analog.
|
||||
3. File-scope `static const` becomes `const`.
|
||||
4. Floating literals gain `f` (`0.5` becomes `0.5f`).
|
||||
5. The file body is wrapped in a class, since C# has no free functions; HLSL
|
||||
functions become private instance methods.
|
||||
|
||||
HLSL constructs that stay outside the target and must not appear in the mirror:
|
||||
`const` locals of vector type (C# `const` is primitives only; write a plain
|
||||
local) and writes through a swizzle component (`v.xy.x = s`, which C# rejects as
|
||||
modifying a temporary).
|
||||
|
||||
The HLSL side is checked too: `tools/get-dxc.ps1` fetches Microsoft's
|
||||
DirectXShaderCompiler, and
|
||||
`dxc -T lib_6_3 -HV 2021 shaders/CultMath.hlsl` must compile cleanly.
|
||||
|
||||
Where HLSL is silent, CultMath keeps its own decisions and does not defer to
|
||||
Unity.Mathematics: `normalize` is safe (divides by `max(length, 1e-20)`),
|
||||
|
|
|
|||
Loading…
Reference in a new issue