Skip to content

Commit eac5acc

Browse files
authored
KTX2Loader: Fix ETC1S/UASTC prioritization (#31871)
Due to a historical accident, the list of formats for ETC1S was sorted using UASTC priority. This change fixes that. However, this exposes a problem that already exists for UASTC to ETC1S as well: on Linux, Mesa drivers for various Intel and AMD GPUs expose support for ETC2 and ASTC extensions even if the hardware does not support them, as part of GLES compatibility. When a texture with an emulated format is uploaded, the driver runs a very expensive CPU side decompression; this runs on the main thread and causes performance and memory issues. When using Chrome based browsers, ANGLE filters out ASTC and ETC extensions for us; we now detect Gecko based browsers like Firefox that don't use ANGLE and do this filtering ourselves. In principle, it is possible for GPUs to support all formats - notably, Safari exposes all formats on macOS when using Apple Silicon hardware, as it genuinely supports all possible formats. In this case we still should prefer native (ASTC/ETC2) format targets as they are faster to transcode to. A corner case is a combination of Firefox / Asahi Linux on Apple Silicon hardware; in the future it might be possible to detect the unmasked vendor to disambiguate, but even that combination will simply use BC7 for UASTC or dual-slice ETC1S which is probably reasonable.
1 parent f25b5a6 commit eac5acc

File tree

1 file changed

+17
-6
lines changed

1 file changed

+17
-6
lines changed

examples/jsm/loaders/KTX2Loader.js

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ class KTX2Loader extends Loader {
194194
* Async version of {@link KTX2Loader#detectSupport}.
195195
*
196196
* @async
197-
* @param {WebGPURenderer|WebGLRenderer} renderer - The renderer.
197+
* @param {WebGPURenderer} renderer - The renderer.
198198
* @return {Promise} A Promise that resolves when the support has been detected.
199199
*/
200200
async detectSupportAsync( renderer ) {
@@ -247,6 +247,21 @@ class KTX2Loader extends Loader {
247247
pvrtcSupported: renderer.extensions.has( 'WEBGL_compressed_texture_pvrtc' )
248248
|| renderer.extensions.has( 'WEBKIT_WEBGL_compressed_texture_pvrtc' )
249249
};
250+
251+
if ( typeof navigator !== 'undefined' &&
252+
navigator.platform.indexOf( 'Linux' ) >= 0 && navigator.userAgent.indexOf( 'Firefox' ) >= 0 &&
253+
this.workerConfig.astcSupported && this.workerConfig.etc2Supported &&
254+
this.workerConfig.bptcSupported && this.workerConfig.dxtSupported ) {
255+
256+
// On Linux, Mesa drivers for AMD and Intel GPUs expose ETC2 and ASTC even though the hardware doesn't support these.
257+
// Using these extensions will result in expensive software decompression on the main thread inside the driver, causing performance issues.
258+
// When using ANGLE (e.g. via Chrome), these extensions are not exposed except for some specific Intel GPU models - however, Firefox doesn't perform this filtering.
259+
// Since a granular filter is a little too fragile and we can transcode into other GPU formats, disable formats that are likely to be emulated.
260+
261+
this.workerConfig.astcSupported = false;
262+
this.workerConfig.etc2Supported = false;
263+
264+
}
250265

251266
}
252267

@@ -846,13 +861,9 @@ KTX2Loader.BasisWorker = function () {
846861
];
847862

848863
const OPTIONS = {
849-
// TODO: For ETC1S we intentionally sort by _UASTC_ priority, preserving
850-
// a historical accident shown to avoid performance pitfalls for Linux with
851-
// Firefox & AMD GPU (RadeonSI). Further work needed.
852-
// See https://github.com/mrdoob/three.js/pull/29730.
853864
[ BasisFormat.ETC1S ]: FORMAT_OPTIONS
854865
.filter( ( opt ) => opt.basisFormat.includes( BasisFormat.ETC1S ) )
855-
.sort( ( a, b ) => a.priorityUASTC - b.priorityUASTC ),
866+
.sort( ( a, b ) => a.priorityETC1S - b.priorityETC1S ),
856867

857868
[ BasisFormat.UASTC ]: FORMAT_OPTIONS
858869
.filter( ( opt ) => opt.basisFormat.includes( BasisFormat.UASTC ) )

0 commit comments

Comments
 (0)