Skip to content

feat: EDDS volume textures, RG16F and RGBA16 - #53

Merged
TheWillard merged 1 commit into
mainfrom
feat/edds-volume-float
Nov 12, 2026
Merged

TheWillard merged 1 commit into
mainfrom
feat/edds-volume-float

Conversation

@TheWillard

Copy link
Copy Markdown
Contributor

Every .edds in the game paks now reads and decodes (29,139 files, 0 failures). The last two failures were:

  • system/textures/CurlNoise_F16.edds: FourCC field holds 112, the numeric D3DFMT_G16R16F.
  • system/textures/PP/base16_32x32_LUT.edds: a 32x32x32 volume texture (DDSCAPS2_VOLUME), FourCC field 36 (D3DFMT_A16B16G16R16). It's an identity color grading LUT: x is red, y green, the slice blue.

Changes

  • FourCCEnum: numeric D3DFMT_* codes 36 and 110 to 116, so these headers read.
  • EddsFormat::Rg16Float and EddsFormat::Rgba16, from the FourCC codes or the DX10 header (R16G16_FLOAT, R16G16B16A16_UNORM). For the 8 bit output RG16F is clamped to 0..=1 like BC6H (negative values become 0, RawEdds keeps the stored values), RGBA16 is rounded.
  • Volume textures: new Mipmap::depth (1 for 2D textures) that halves with the mipmaps. Slices are decoded one by one and stored one after another, so a decoded volume mipmap reads as a width x height * depth image.

Mipmap gets a public field, so code that builds a Mipmap by hand needs to set depth.

The game's only volume texture has a single mip, so the depth halving across mip levels follows the DDS convention and is covered by synthetic tests only.

Tests

  • Synthetic: both formats from FourCC and DX10 headers, a volume mip chain, a too short volume, a block compressed volume with cropped blocks.
  • Game files: both textures added to e-test-data-part-1.7z, checked by sample texels and checksums.

Some textures store a numeric D3DFORMAT in the FourCC field instead of a
four character code. FourCCEnum now has the D3DFMT_* codes 36 and 110 to
116, and two of them are decoded:

- Rg16Float (D3DFMT_G16R16F, DXGI_FORMAT_R16G16_FLOAT), clamped to 0..=1
  for the 8 bit output like BC6H.
- Rgba16 (D3DFMT_A16B16G16R16, DXGI_FORMAT_R16G16B16A16_UNORM), rounded
  to 8 bits.

Volume textures (DDSCAPS2_VOLUME) are read with every slice: Mipmap has a
depth that halves with the mipmaps, slices are decoded one by one and
stored one after another.

This covers the last two game textures that failed:
system/textures/CurlNoise_F16.edds and the 32x32x32 color grading LUT
system/textures/PP/base16_32x32_LUT.edds, both added to the test data.
@codecov

codecov Bot commented Nov 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.00000% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
arma-file-formats/src/enfusion/edds/format.rs 92.59% 2 Missing ⚠️
Files with missing lines Coverage Δ
...file-formats/src/enfusion/edds/dds_header_enums.rs 0.00% <ø> (ø)
arma-file-formats/src/enfusion/edds/edds.rs 97.03% <100.00%> (+0.34%) ⬆️
arma-file-formats/src/enfusion/edds/format.rs 78.36% <92.59%> (+5.40%) ⬆️

... and 46 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@TheWillard
TheWillard merged commit ea96a07 into main Nov 12, 2026
2 checks passed
@TheWillard
TheWillard deleted the feat/edds-volume-float branch November 12, 2026 21:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant