Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ASTC HDR format variants #102777

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

darksylinc
Copy link
Contributor

Given issue #102696 and PR #102461 I figured we needed to properly support ASTC HDR.

I haven't tested it. I didn't touch the Metal backend, it does some weird stuff with lots of texture format setup I didn't have the time to decipher (MTLViewClass + calling addDataFormatDesc + calling addMTLPixelFormatDesc + setMTLPixFmtCapsIf).

@stuartcarnie
Copy link
Contributor

Metal already has mappings for the HDR variants, so you shouldn't have to do anything for the driver to support it:

bool noHDR_ASTC = p_feat.highestFamily < MTLGPUFamilyApple6;
setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_4x4_HDR, None);
setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_5x4_HDR, None);
setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_5x5_HDR, None);
setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_6x5_HDR, None);
setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_6x6_HDR, None);
setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_8x5_HDR, None);
setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_8x6_HDR, None);
setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_8x8_HDR, None);
setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_10x5_HDR, None);
setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_10x6_HDR, None);
setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_10x8_HDR, None);
setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_10x10_HDR, None);
setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_12x10_HDR, None);
setMTLPixFmtCapsIf(noHDR_ASTC, ASTC_12x12_HDR, None);

This logic only disables it if the Apple GPU family is < and Apple6 GPU, which didn't support it.

@stuartcarnie
Copy link
Contributor

stuartcarnie commented Feb 12, 2025

Ahh wait, I see, the mapping to Godot's DataFormat from Metal is missing; I can add that

@stuartcarnie
Copy link
Contributor

@darksylinc here is the patch to add ASTC HDR support for Metal:

Subject: [PATCH] Fixes for #102670
---
Index: drivers/metal/pixel_formats.mm
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/drivers/metal/pixel_formats.mm b/drivers/metal/pixel_formats.mm
--- a/drivers/metal/pixel_formats.mm	(revision 48dd134735a45a645c00c5fa8ff0d57f31f70e08)
+++ b/drivers/metal/pixel_formats.mm	(date 1739387266155)
@@ -493,32 +493,46 @@
 	addDataFormatDesc(EAC_R11G11_SNORM_BLOCK, EAC_RG11Snorm, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
 
 	addDataFormatDesc(ASTC_4x4_UNORM_BLOCK, ASTC_4x4_LDR, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
+	addDataFormatDesc(ASTC_4x4_SFLOAT_BLOCK, ASTC_4x4_HDR, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
 	addDataFormatDesc(ASTC_4x4_SRGB_BLOCK, ASTC_4x4_sRGB, Invalid, Invalid, Invalid, 4, 4, 16, Compressed);
 	addDataFormatDesc(ASTC_5x4_UNORM_BLOCK, ASTC_5x4_LDR, Invalid, Invalid, Invalid, 5, 4, 16, Compressed);
+	addDataFormatDesc(ASTC_5x4_SFLOAT_BLOCK, ASTC_5x4_HDR, Invalid, Invalid, Invalid, 5, 4, 16, Compressed);
 	addDataFormatDesc(ASTC_5x4_SRGB_BLOCK, ASTC_5x4_sRGB, Invalid, Invalid, Invalid, 5, 4, 16, Compressed);
 	addDataFormatDesc(ASTC_5x5_UNORM_BLOCK, ASTC_5x5_LDR, Invalid, Invalid, Invalid, 5, 5, 16, Compressed);
+	addDataFormatDesc(ASTC_5x5_SFLOAT_BLOCK, ASTC_5x5_HDR, Invalid, Invalid, Invalid, 5, 5, 16, Compressed);
 	addDataFormatDesc(ASTC_5x5_SRGB_BLOCK, ASTC_5x5_sRGB, Invalid, Invalid, Invalid, 5, 5, 16, Compressed);
 	addDataFormatDesc(ASTC_6x5_UNORM_BLOCK, ASTC_6x5_LDR, Invalid, Invalid, Invalid, 6, 5, 16, Compressed);
+	addDataFormatDesc(ASTC_6x5_SFLOAT_BLOCK, ASTC_6x5_HDR, Invalid, Invalid, Invalid, 6, 5, 16, Compressed);
 	addDataFormatDesc(ASTC_6x5_SRGB_BLOCK, ASTC_6x5_sRGB, Invalid, Invalid, Invalid, 6, 5, 16, Compressed);
 	addDataFormatDesc(ASTC_6x6_UNORM_BLOCK, ASTC_6x6_LDR, Invalid, Invalid, Invalid, 6, 6, 16, Compressed);
+	addDataFormatDesc(ASTC_6x6_SFLOAT_BLOCK, ASTC_6x6_HDR, Invalid, Invalid, Invalid, 6, 6, 16, Compressed);
 	addDataFormatDesc(ASTC_6x6_SRGB_BLOCK, ASTC_6x6_sRGB, Invalid, Invalid, Invalid, 6, 6, 16, Compressed);
 	addDataFormatDesc(ASTC_8x5_UNORM_BLOCK, ASTC_8x5_LDR, Invalid, Invalid, Invalid, 8, 5, 16, Compressed);
+	addDataFormatDesc(ASTC_8x5_SFLOAT_BLOCK, ASTC_8x5_HDR, Invalid, Invalid, Invalid, 8, 5, 16, Compressed);
 	addDataFormatDesc(ASTC_8x5_SRGB_BLOCK, ASTC_8x5_sRGB, Invalid, Invalid, Invalid, 8, 5, 16, Compressed);
 	addDataFormatDesc(ASTC_8x6_UNORM_BLOCK, ASTC_8x6_LDR, Invalid, Invalid, Invalid, 8, 6, 16, Compressed);
+	addDataFormatDesc(ASTC_8x6_SFLOAT_BLOCK, ASTC_8x6_HDR, Invalid, Invalid, Invalid, 8, 6, 16, Compressed);
 	addDataFormatDesc(ASTC_8x6_SRGB_BLOCK, ASTC_8x6_sRGB, Invalid, Invalid, Invalid, 8, 6, 16, Compressed);
 	addDataFormatDesc(ASTC_8x8_UNORM_BLOCK, ASTC_8x8_LDR, Invalid, Invalid, Invalid, 8, 8, 16, Compressed);
+	addDataFormatDesc(ASTC_8x8_SFLOAT_BLOCK, ASTC_8x8_HDR, Invalid, Invalid, Invalid, 8, 8, 16, Compressed);
 	addDataFormatDesc(ASTC_8x8_SRGB_BLOCK, ASTC_8x8_sRGB, Invalid, Invalid, Invalid, 8, 8, 16, Compressed);
 	addDataFormatDesc(ASTC_10x5_UNORM_BLOCK, ASTC_10x5_LDR, Invalid, Invalid, Invalid, 10, 5, 16, Compressed);
+	addDataFormatDesc(ASTC_10x5_SFLOAT_BLOCK, ASTC_10x5_HDR, Invalid, Invalid, Invalid, 10, 5, 16, Compressed);
 	addDataFormatDesc(ASTC_10x5_SRGB_BLOCK, ASTC_10x5_sRGB, Invalid, Invalid, Invalid, 10, 5, 16, Compressed);
 	addDataFormatDesc(ASTC_10x6_UNORM_BLOCK, ASTC_10x6_LDR, Invalid, Invalid, Invalid, 10, 6, 16, Compressed);
+	addDataFormatDesc(ASTC_10x6_SFLOAT_BLOCK, ASTC_10x6_HDR, Invalid, Invalid, Invalid, 10, 6, 16, Compressed);
 	addDataFormatDesc(ASTC_10x6_SRGB_BLOCK, ASTC_10x6_sRGB, Invalid, Invalid, Invalid, 10, 6, 16, Compressed);
 	addDataFormatDesc(ASTC_10x8_UNORM_BLOCK, ASTC_10x8_LDR, Invalid, Invalid, Invalid, 10, 8, 16, Compressed);
+	addDataFormatDesc(ASTC_10x8_SFLOAT_BLOCK, ASTC_10x8_HDR, Invalid, Invalid, Invalid, 10, 8, 16, Compressed);
 	addDataFormatDesc(ASTC_10x8_SRGB_BLOCK, ASTC_10x8_sRGB, Invalid, Invalid, Invalid, 10, 8, 16, Compressed);
 	addDataFormatDesc(ASTC_10x10_UNORM_BLOCK, ASTC_10x10_LDR, Invalid, Invalid, Invalid, 10, 10, 16, Compressed);
+	addDataFormatDesc(ASTC_10x10_SFLOAT_BLOCK, ASTC_10x10_HDR, Invalid, Invalid, Invalid, 10, 10, 16, Compressed);
 	addDataFormatDesc(ASTC_10x10_SRGB_BLOCK, ASTC_10x10_sRGB, Invalid, Invalid, Invalid, 10, 10, 16, Compressed);
 	addDataFormatDesc(ASTC_12x10_UNORM_BLOCK, ASTC_12x10_LDR, Invalid, Invalid, Invalid, 12, 10, 16, Compressed);
+	addDataFormatDesc(ASTC_12x10_SFLOAT_BLOCK, ASTC_12x10_HDR, Invalid, Invalid, Invalid, 12, 10, 16, Compressed);
 	addDataFormatDesc(ASTC_12x10_SRGB_BLOCK, ASTC_12x10_sRGB, Invalid, Invalid, Invalid, 12, 10, 16, Compressed);
 	addDataFormatDesc(ASTC_12x12_UNORM_BLOCK, ASTC_12x12_LDR, Invalid, Invalid, Invalid, 12, 12, 16, Compressed);
+	addDataFormatDesc(ASTC_12x12_SFLOAT_BLOCK, ASTC_12x12_HDR, Invalid, Invalid, Invalid, 12, 12, 16, Compressed);
 	addDataFormatDesc(ASTC_12x12_SRGB_BLOCK, ASTC_12x12_sRGB, Invalid, Invalid, Invalid, 12, 12, 16, Compressed);
 
 	addDfFormatDescChromaSubsampling(G8B8G8R8_422_UNORM, GBGR422, 1, 8, 2, 1, 4);

@darksylinc
Copy link
Contributor Author

here is the patch to add ASTC HDR support for Metal:

Thanks!!! I just updated the PR with it.

I suspected the necessary changes were among those lines but I was unsure if anything else was needed.

@darksylinc darksylinc marked this pull request as ready for review February 13, 2025 01:49
@darksylinc darksylinc requested review from a team as code owners February 13, 2025 01:49
@BlueCube3310
Copy link
Contributor

BlueCube3310 commented Feb 13, 2025

Tested on Android with ARM Mali-G76 MC4
Results:

4.4 Beta 3 (Mobile) This PR (Mobile) Compatibility
4_4_b3 pr 4_4_compat

The new formats should probably be also added to RenderingDeviceCommons::get_compressed_image_format_block_byte_size and RenderingDeviceCommons::get_compressed_image_format_pixel_rshift (8x8 only), it might fix this

@darksylinc
Copy link
Contributor Author

Oh! A different output! PROGRESS!

@BlueCube3310 is there are a simple tutorial or youtube video I can follow and you can recommend to repro all this? I can look it up online but I'd waste time.

Basically the steps to repro so I can diagnose the problem (I coded this PR blindly).

The new formats should probably be also added to RenderingDeviceCommons::get_compressed_image_format_block_byte_size and RenderingDeviceCommons::get_compressed_image_format_pixel_rshift (8x8 only), it might fix this

Thanks! I don't know how I missed those. I'll update the PR.

@darksylinc
Copy link
Contributor Author

darksylinc commented Feb 13, 2025

The new formats should probably be also added to RenderingDeviceCommons::get_compressed_image_format_block_byte_size and RenderingDeviceCommons::get_compressed_image_format_pixel_rshift (8x8 only), it might fix this

OK I've updated the PR with these.

But this only raises more questions. For example get_compressed_image_format_block_dimensions and get_compressed_image_format_block_byte_size look like a code smell.

Even the code itself says things like:

// Again, not sure about astc.
case DATA_FORMAT_ASTC_5x4_UNORM_BLOCK: // Unsupported

Which tells me this path is very untested. The way it does the math appears to be wrong for ASTC and would need refactoring. Fortunately I'm well versed in this area, but first I need to test ASTC actually works.

@BlueCube3310
Copy link
Contributor

Oh! A different output! PROGRESS!

@BlueCube3310 is there are a simple tutorial or youtube video I can follow and you can recommend to repro all this? I can look it up online but I'd waste time.

Basically the steps to repro so I can diagnose the problem (I coded this PR blindly).

The new formats should probably be also added to RenderingDeviceCommons::get_compressed_image_format_block_byte_size and RenderingDeviceCommons::get_compressed_image_format_pixel_rshift (8x8 only), it might fix this

Thanks! I don't know how I missed those. I'll update the PR.

For testing I downloaded the android editor build artifact and created an empty project. I then imported a random HDRi either .exr or .hdr, then set the compression mode to VRAM Compressed in the import settings. The preview in the inspector will show the results.

@BlueCube3310
Copy link
Contributor

Tested it again, the latest version works correctly

Preview Sky, energy 0.1 Sky, energy 0.5
image 0_1_exp 0_5_exp

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants