Skip to content

Commit 13aae68

Browse files
committed
compressed1 helper macro cleanup
1 parent 1aa8c4a commit 13aae68

1 file changed

Lines changed: 69 additions & 37 deletions

File tree

d3d/Raytracing2.md

Lines changed: 69 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# DirectX Raytracing (DXR) Functional Spec, Part 2 <!-- omit in toc -->
22

3-
v0.19 3/17/2026
3+
v0.20 3/18/2026
44

55
---
66

@@ -1654,95 +1654,126 @@ typedef int INT;
16541654
###### D3D12_VERTEX_FORMAT_COMPRESSED1_HEADER macros
16551655

16561656
```C++
1657-
// 24-bit sign extension (portable, no arithmetic-shift dependency)
1658-
#define D3D12_COMPRESSED1_SIGN_EXTEND_24(val) \
1659-
((INT)(((val) ^ 0x800000) - 0x800000))
1660-
1661-
// ENCODER MACRO: Store exponent field (read-modify-write). Caller must pass biased exponent (actual + 127).
1662-
#define ENCODE_D3D12_COMPRESSED1_EXPONENT(header, exponent) ((header).field0 = ((header).field0 & 0xFFFFFF00) | ((UINT)(exponent) & 0xFF))
1657+
// ENCODER MACRO: Store exponent field (read-modify-write).
1658+
// Caller must pass biased exponent (actual + 127).
1659+
#define ENCODE_D3D12_COMPRESSED1_EXPONENT(header, exponent) \
1660+
((header).field0 = ((header).field0 & ~0xFF) | (UINT(exponent) & 0xFF))
16631661

16641662
// ENCODER MACRO: Store x_anchor field (read-modify-write).
1665-
#define ENCODE_D3D12_COMPRESSED1_X_ANCHOR(header, x_anchor) ((header).field0 = ((header).field0 & 0xFF) | (((UINT)(x_anchor) << 8) & 0xFFFFFF00))
1663+
#define ENCODE_D3D12_COMPRESSED1_X_ANCHOR(header, x_anchor) \
1664+
((header).field0 = ((header).field0 & 0xFF) | ((UINT(x_anchor) << 8)))
16661665

16671666
// ENCODER MACRO: Store x_bits field (read-modify-write). Caller must pass (bit_count - 1).
1668-
#define ENCODE_D3D12_COMPRESSED1_X_BITS(header, x_bits) ((header).field1 = ((header).field1 & ~0xF) | ((UINT)(x_bits) & 0xF))
1667+
#define ENCODE_D3D12_COMPRESSED1_X_BITS(header, x_bits) \
1668+
((header).field1 = ((header).field1 & ~0xF) | ((UINT(x_bits) & 0xF)))
16691669

16701670
// ENCODER MACRO: Store y_bits field (read-modify-write). Caller must pass (bit_count - 1).
1671-
#define ENCODE_D3D12_COMPRESSED1_Y_BITS(header, y_bits) ((header).field1 = ((header).field1 & ~0xF0) | (((UINT)(y_bits) & 0xF) << 4))
1671+
#define ENCODE_D3D12_COMPRESSED1_Y_BITS(header, y_bits) \
1672+
((header).field1 = ((header).field1 & ~0xF0) | ((UINT(y_bits) & 0xF) << 4))
16721673

16731674
// ENCODER MACRO: Store y_anchor field (read-modify-write).
1674-
#define ENCODE_D3D12_COMPRESSED1_Y_ANCHOR(header, y_anchor) ((header).field1 = ((header).field1 & 0xFF) | (((UINT)(y_anchor) << 8) & 0xFFFFFF00))
1675+
#define ENCODE_D3D12_COMPRESSED1_Y_ANCHOR(header, y_anchor) \
1676+
((header).field1 = ((header).field1 & 0xFF) | ((UINT(y_anchor) << 8)))
16751677

16761678
// ENCODER MACRO: Store z_bits field (read-modify-write). Caller must pass (bit_count - 1).
1677-
#define ENCODE_D3D12_COMPRESSED1_Z_BITS(header, z_bits) ((header).field2 = ((header).field2 & ~0xF) | ((UINT)(z_bits) & 0xF))
1679+
#define ENCODE_D3D12_COMPRESSED1_Z_BITS(header, z_bits) \
1680+
((header).field2 = ((header).field2 & ~0xF) | ((UINT(z_bits) & 0xF)))
16781681

16791682
// ENCODER MACRO: Store z_anchor field (read-modify-write).
1680-
#define ENCODE_D3D12_COMPRESSED1_Z_ANCHOR(header, z_anchor) ((header).field2 = ((header).field2 & 0xFF) | (((UINT)(z_anchor) << 8) & 0xFFFFFF00))
1683+
#define ENCODE_D3D12_COMPRESSED1_Z_ANCHOR(header, z_anchor) \
1684+
((header).field2 = ((header).field2 & 0xFF) | ((UINT(z_anchor) << 8)))
16811685

1682-
// ENCODER MACRO Store all field0 members: exponent and x_anchor. Caller must pass biased exponent (actual + 127).
1686+
// ENCODER MACRO Store all field0 members: exponent and x_anchor.
1687+
// Caller must pass biased exponent (actual + 127).
16831688
#define ENCODE_D3D12_COMPRESSED1_EXPONENT_X_ANCHOR(header, exponent, x_anchor) \
1684-
((header).field0 = (((UINT)(exponent) & 0xFF) | (((UINT)(x_anchor) << 8) & 0xFFFFFF00)))
1689+
((header).field0 = ((UINT(exponent) & 0xFF) | (UINT(x_anchor) << 8)))
16851690

1686-
// ENCODER MACRO Store all field1 members: x_bits, y_bits, and y_anchor. Caller must pass (bit_count - 1) for x_bits and y_bits.
1691+
// ENCODER MACRO Store all field1 members: x_bits, y_bits, and y_anchor.
1692+
// Caller must pass (bit_count - 1) for x_bits and y_bits.
16871693
#define ENCODE_D3D12_COMPRESSED1_XY_BITS_Y_ANCHOR(header, x_bits, y_bits, y_anchor) \
1688-
((header).field1 = (((UINT)(x_bits) & 0xF) | (((UINT)(y_bits) & 0xF) << 4) | (((UINT)(y_anchor) << 8) & 0xFFFFFF00)))
1694+
((header).field1 = ((UINT(x_bits) & 0xF) | ((UINT(y_bits) & 0xF) << 4) | (UINT(y_anchor) << 8)))
16891695

1690-
// ENCODER MACRO Store all field2 members: z_bits and z_anchor. Caller must pass (bit_count - 1) for z_bits. Bits [07:04] are set to zero (unused).
1696+
// ENCODER MACRO Store all field2 members: z_bits and z_anchor.
1697+
// Caller must pass (bit_count - 1) for z_bits. Bits [07:04] are set to zero (unused).
16911698
#define ENCODE_D3D12_COMPRESSED1_Z_BITS_Z_ANCHOR(header, z_bits, z_anchor) \
1692-
((header).field2 = (((UINT)(z_bits) & 0xF) | (((UINT)(z_anchor) << 8) & 0xFFFFFF00)))
1693-
1694-
// DECODER MACRO: Extract the 8-bit biased exponent. Caller must subtract 127 from result to get the actual exponent.
1699+
((header).field2 = ((UINT(z_bits) & 0xF) | (UINT(z_anchor) << 8)))
1700+
1701+
// ENCODER MACRO: Store all fields. Caller must pass biased exponent
1702+
// (actual + 127) and (bit_count - 1) for x_bits, y_bits, and z_bits.
1703+
// Bits [07:04] in field2 are set to zero (unused).
1704+
#define ENCODE_D3D12_COMPRESSED1(header, exponent, x_anchor, y_anchor, z_anchor, x_bits, y_bits, z_bits ) \
1705+
((header).field0 = ((UINT(exponent) & 0xFF) | (UINT(x_anchor) << 8)), \
1706+
(header).field1 = ((UINT(x_bits) & 0xF) | ((UINT(y_bits) & 0xF) << 4) | (UINT(y_anchor) << 8)), \
1707+
(header).field2 = ((UINT(z_bits) & 0xF) | (UINT(z_anchor) << 8)))
1708+
1709+
// DECODER MACRO: Extract the 8-bit biased exponent.
1710+
// Caller must subtract 127 from result to get the actual exponent.
16951711
#define DECODE_D3D12_COMPRESSED1_EXPONENT(header) (((header).field0) & 0xFF)
16961712

16971713
// DECODER MACRO: Extract the 24-bit x_anchor as a signed integer.
1698-
#define DECODE_D3D12_COMPRESSED1_X_ANCHOR(header) D3D12_COMPRESSED1_SIGN_EXTEND_24((((header).field0) >> 8) & 0xFFFFFF)
1714+
#define DECODE_D3D12_COMPRESSED1_X_ANCHOR(header) (INT((header).field0) >> 8)
16991715

1700-
// DECODER MACRO: Extract the 4-bit x_bits value. Caller must add 1 to result to get the actual bit count.
1716+
// DECODER MACRO: Extract the 4-bit x_bits value.
1717+
// Caller must add 1 to result to get the actual bit count.
17011718
#define DECODE_D3D12_COMPRESSED1_X_BITS(header) (((header).field1) & 0xF)
17021719

1703-
// DECODER MACRO: Extract the 4-bit y_bits value. Caller must add 1 to result to get the actual bit count.
1720+
// DECODER MACRO: Extract the 4-bit y_bits value.
1721+
// Caller must add 1 to result to get the actual bit count.
17041722
#define DECODE_D3D12_COMPRESSED1_Y_BITS(header) ((((header).field1) >> 4) & 0xF)
17051723

17061724
// DECODER MACRO: Extract the 24-bit y_anchor as a signed integer.
1707-
#define DECODE_D3D12_COMPRESSED1_Y_ANCHOR(header) D3D12_COMPRESSED1_SIGN_EXTEND_24((((header).field1) >> 8) & 0xFFFFFF)
1725+
#define DECODE_D3D12_COMPRESSED1_Y_ANCHOR(header) (INT((header).field1) >> 8)
17081726

1709-
// DECODER MACRO: Extract the 4-bit z_bits value. Caller must add 1 to result to get the actual bit count.
1727+
// DECODER MACRO: Extract the 4-bit z_bits value.
1728+
// Caller must add 1 to result to get the actual bit count.
17101729
#define DECODE_D3D12_COMPRESSED1_Z_BITS(header) (((header).field2) & 0xF)
17111730

17121731
// DECODER MACRO: Extract the 24-bit z_anchor as a signed integer.
1713-
#define DECODE_D3D12_COMPRESSED1_Z_ANCHOR(header) D3D12_COMPRESSED1_SIGN_EXTEND_24((((header).field2) >> 8) & 0xFFFFFF)
1732+
#define DECODE_D3D12_COMPRESSED1_Z_ANCHOR(header) (INT((header).field2) >> 8)
1733+
17141734
```
17151735

17161736
###### D3D12_VERTEX_FORMAT_COMPRESSED1_TEMPLATE_HEADER macros
17171737

17181738
```C++
17191739
// ENCODER MACRO: Store exponent field (read-modify-write). Caller must pass biased exponent (actual + 127).
1720-
#define ENCODE_D3D12_COMPRESSED1_TEMPLATE_EXPONENT(header, exponent) ((header).field0 = ((header).field0 & ~0xFF) | ((UINT)(exponent) & 0xFF))
1740+
#define ENCODE_D3D12_COMPRESSED1_TEMPLATE_EXPONENT(header, exponent) \
1741+
((header).field0 = ((header).field0 & ~0xFF) | (UINT(exponent) & 0xFF))
17211742

17221743
// ENCODER MACRO: Store x_bits field (read-modify-write). Caller must pass (bit_count - 1).
1723-
#define ENCODE_D3D12_COMPRESSED1_TEMPLATE_X_BITS(header, x_bits) ((header).field0 = ((header).field0 & ~0xF00) | (((UINT)(x_bits) & 0xF) << 8))
1744+
#define ENCODE_D3D12_COMPRESSED1_TEMPLATE_X_BITS(header, x_bits) \
1745+
((header).field0 = ((header).field0 & ~0xF00) | ((UINT(x_bits) & 0xF) << 8))
17241746

17251747
// ENCODER MACRO: Store y_bits field (read-modify-write). Caller must pass (bit_count - 1).
1726-
#define ENCODE_D3D12_COMPRESSED1_TEMPLATE_Y_BITS(header, y_bits) ((header).field0 = ((header).field0 & ~0xF000) | (((UINT)(y_bits) & 0xF) << 12))
1748+
#define ENCODE_D3D12_COMPRESSED1_TEMPLATE_Y_BITS(header, y_bits) \
1749+
((header).field0 = ((header).field0 & ~0xF000) | ((UINT(y_bits) & 0xF) << 12))
17271750

17281751
// ENCODER MACRO: Store z_bits field (read-modify-write). Caller must pass (bit_count - 1).
1729-
#define ENCODE_D3D12_COMPRESSED1_TEMPLATE_Z_BITS(header, z_bits) ((header).field0 = ((header).field0 & ~0xF0000) | (((UINT)(z_bits) & 0xF) << 16))
1752+
#define ENCODE_D3D12_COMPRESSED1_TEMPLATE_Z_BITS(header, z_bits) \
1753+
((header).field0 = ((header).field0 & ~0xF0000) | ((UINT(z_bits) & 0xF) << 16))
17301754

1731-
// ENCODER MACRO: Store all members: exponent, x_bits, y_bits, and z_bits. Caller must pass biased exponent (actual + 127) and (bit_count - 1) for each bits field. Bits [31:20] are set to zero (unused).
1755+
// ENCODER MACRO: Store all members: exponent, x_bits, y_bits, and z_bits.
1756+
// Caller must pass biased exponent (actual + 127) and (bit_count - 1) for each bits field.
1757+
// Bits [31:20] are set to zero (unused).
17321758
#define ENCODE_D3D12_COMPRESSED1_TEMPLATE(header, exponent, x_bits, y_bits, z_bits) \
1733-
((header).field0 = (((UINT)(exponent) & 0xFF) | (((UINT)(x_bits) & 0xF) << 8) | (((UINT)(y_bits) & 0xF) << 12) | (((UINT)(z_bits) & 0xF) << 16)))
1759+
((header).field0 = ((UINT(exponent) & 0xFF) | ((UINT(x_bits) & 0xF) << 8) | ((UINT(y_bits) & 0xF) << 12) | ((UINT(z_bits) & 0xF) << 16)))
17341760

17351761
// DECODER MACRO: Extract the 8-bit biased exponent. Caller must subtract 127 to get the actual exponent.
1736-
#define DECODE_D3D12_COMPRESSED1_TEMPLATE_EXPONENT(header) (((header).field0) & 0xFF)
1762+
#define DECODE_D3D12_COMPRESSED1_TEMPLATE_EXPONENT(header) \
1763+
(((header).field0) & 0xFF)
17371764

17381765
// DECODER MACRO: Extract the 4-bit x_bits value. Caller must add 1 to get the actual bit count.
1739-
#define DECODE_D3D12_COMPRESSED1_TEMPLATE_X_BITS(header) ((((header).field0) >> 8) & 0xF)
1766+
#define DECODE_D3D12_COMPRESSED1_TEMPLATE_X_BITS(header) \
1767+
((((header).field0) >> 8) & 0xF)
17401768

17411769
// DECODER MACRO: Extract the 4-bit y_bits value. Caller must add 1 to get the actual bit count.
1742-
#define DECODE_D3D12_COMPRESSED1_TEMPLATE_Y_BITS(header) ((((header).field0) >> 12) & 0xF)
1770+
#define DECODE_D3D12_COMPRESSED1_TEMPLATE_Y_BITS(header) \
1771+
((((header).field0) >> 12) & 0xF)
17431772

17441773
// DECODER MACRO: Extract the 4-bit z_bits value. Caller must add 1 to get the actual bit count.
1745-
#define DECODE_D3D12_COMPRESSED1_TEMPLATE_Z_BITS(header) ((((header).field0) >> 16) & 0xF)
1774+
#define DECODE_D3D12_COMPRESSED1_TEMPLATE_Z_BITS(header) \
1775+
((((header).field0) >> 16) & 0xF)
1776+
17461777
```
17471778

17481779
---
@@ -2204,3 +2235,4 @@ v0.16|3/11/2026|<li>In [D3D12_RTAS_CLUSTER_TRIANGLES_INPUTS_DESC](#d3d12_rtas_cl
22042235
v0.17|3/12/2026|<li>Added [Why compaction doesn't apply to clustered geometry](#why-compaction-doesnt-apply-to-clustered-geometry) section</li>
22052236
v0.18|3/16/2026|<li>Replaced C++ bitfields with plain `UINT` members (to be manually packed by user) in [D3D12_VERTEX_FORMAT_COMPRESSED1_HEADER](#compressed1-position-encoding) and [D3D12_VERTEX_FORMAT_COMPRESSED1_TEMPLATE_HEADER](#d3d12_vertex_format_compressed1_template_header) for portable layout across C++ compilers, architectures, and HLSL. Added [Compressed1 bitfield helper macros](#compressed1-bitfield-helper-macros) section with encode/decode macros from `d3d12.h` that work in both C++ and HLSL (with `UINT`/`INT` typedefs). For the same reason, in [D3D12_RTAS_OPERATION_BUILD_CLAS_FROM_TRIANGLES_ARGS](#d3d12_rtas_operation_build_clas_from_triangles_args) replaced bitfield members with vanilla typed members.</li><li>In [D3D12_RTAS_OPERATION_BUILD_CLAS_FROM_TRIANGLES_ARGS](#d3d12_rtas_operation_build_clas_from_triangles_args), for `IndexBufferStride` limited the maximum stride value to 4 bytes. The purpose of this stride is just for cases where an application may have index values of a larger size (e.g. 4 bytes) but knows the values would happen to fit in a smaller size like 1 byte, which implementations might process more efficiently. The intent isn't for interleaving arbitrary data between indices (something more reasonable to do with the other stride values in this struct).</li>
22062237
v0.19|3/17/2026|<li>Moved `D3D12_RTAS_CLUSTER_OPERATION_CLAS_FLAG_ALLOW_DATA_ACCESS` from [D3D12_RTAS_CLUSTER_OPERATION_CLAS_FLAGS](#d3d12_rtas_cluster_operation_clas_flags) to [D3D12_RTAS_OPERATION_FLAGS](#d3d12_rtas_operation_flags) as `D3D12_RTAS_OPERATION_FLAG_ALLOW_DATA_ACCESS`. This flag applies to CLAS builds and CLAS template builds; it is ignored for CLAS template instantiation, which inherits the allow/disallow state from the template. It not allowed for cluster BLAS builds; instead, all CLAS referenced by a given cluster BLAS must have consistently chosen to allow data access or not when they were built.</li><li>Added `D3D12_RTAS_CLUSTER_OPERATION_CLAS_FLAG_DISALLOW_DATA_ACCESS` to [D3D12_RTAS_CLUSTER_OPERATION_CLAS_FLAGS](#d3d12_rtas_cluster_operation_clas_flags) to selectively disable data access for individual cluster builds within an operation that has `ALLOW_DATA_ACCESS` globally set.</li>
2238+
v0.20|3/18/2026|<li>In [Compressed1 bitfield helper macros](#compressed1-bitfield-helper-macros), macro cleanup and bugfixes: removed unnecessary mask after left shifting; `UINT(val)` instead of `(UINT)(val)` (less verbose); use sign extend on right shift - support is ubiquitous enough (old macro also incorrectly masked result)</li>

0 commit comments

Comments
 (0)