gpuweb / gpuweb

Where the GPU for the Web work happens!
https://webgpu.io
Other
4.79k stars 318 forks source link

Investigation: Compressed Texture Formats #144

Closed Jiawei-Shao closed 2 years ago

Jiawei-Shao commented 5 years ago

Introduction

Compressed texture formats are useful when we want to save memory bandwidth for access to textures. There are mainly 4 families of compressed texture formats: BC, PVRTC, ETC and ASTC. In this report we will investigate the support of these compressed texture formats on D3D12, Metal and Vulkan

Compressed Texture Formats

BC

There are totally 7 BC algorithms (BC1, BC2, BC3, BC4, BC5, BC6H, BC7). BC1, BC2 and BC3 are also known as S3TC or DXTC. BC1 refers to DXT1, BC2 refers to DXT2 and DXT3, and BC3 refers to DXT4 and DXT5.

For D3D12, all BC formats are supported on the devices that support feature level 11_0 and above.

For Metal, BC formats are supported on all macOS devices, but they are not supported on iOS devices.

For Vulkan, the support of BC formats can be queried from vkGetPhysicalDeviceFeatures(), and if textureCompressionBC == true, then we know this Vulkan driver supports BC formats. 88% of Vulkan Hardware Database entries support BC formats.

PVRTC

PVRTC formats are only supported on iOS devices. No macOS, D3D12 or Vulkan devices support PVRTC formats despite OpenGL ES support on PowerVR Android devices.

ETC

ETC format family includes ETC1, ETC2 and EAC texture formats.

For D3D12, no ETC formats are supported.

For Metal, ETC formats are supported on all iOS devices, but they are not supported on macOS devices.

For Vulkan, the support of ETC formats can be queried from vkGetPhysicalDeviceFeatures(), and if textureCompressionETC2 == true, then we know this Vulkan driver supports ETC formats. 22% of Vulkan Hardware Database entries support ETC formats.

ASTC

For D3D12, no ASTC formats are supported.

For Metal, ASTC formats are supported on newer iOS devices (A8 and later), but they are not supported on macOS devices.

For Vulkan, the support of ASTC formats can be queried from vkGetPhysicalDeviceFeatures(), and if textureCompressionASTC_LDR == true, then we know this Vulkan driver supports ASTC formats. 19% of Vulkan Hardware Database entries support ASTC formats.

Proposal

The supports of compressed texture formats on D3D12, Metal and Vulkan can be summarized in the following table. From this table we can see that no compressed texture formats can be supported on D3D12, Metal or Vulkan simultaneously.

D3D12 Metal Vulkan
BC FL11_0 and above macOS textureCompressionBC == true (88%)
PVRTC No Support iOS No Support
ETC No Support iOS textureCompressionETC2 == true (22%)
ASTC No Support Newer iOS (A8 and above) textureCompressionASTC_LDR == true (19%)

As it could cause huge performance loss to emulate any compressed texture format by software, one feasible way is treating each of them as separate WebGPU extensions, which is actually how compressed texture formats are supported in WebGL.

kdashg commented 5 years ago

I'm really surprised there are desktop Vulkan environments without BC. For WebGL I encourage BC (BPTC) and ETC2 (or ASTC). We tried emulating compressed textures in WebGL (ETC2 emulation in ANGLE), but pulled it out in response to dev feedback. We need to surface whether the underlying driver actually supports whatever formats we do expose. We can either: A) Only allow these formats where drivers support them. B) Always allow these formats, but surface whether the support is emulated.

One potential issue with B is that we'd need to ship decompression algorithms, which might not be Free of licensing issues. IIRC only ETC(2) and ASTC are open formats.

grorg commented 5 years ago

This was discussed in the 10 Dec 2018 meeting

litherum commented 5 years ago

Transcoding between two compressed texture formats is lossy, so doing it under the hood would be unfortunate.

devshgraphicsprogramming commented 5 years ago

It would be very unfortunate if I as a developer were not notified that the compression is not supported in hardware and emulated in software (by decompressing and using decompressed version), because at least then I could ship/use uncompressed textures which are higher quality at the same cost.

kainino0x commented 5 years ago

In the meeting we resolved to not require any compressed texture formats, and expose (at least) BC, ETC2, and ASTC each as an extension (only on hardware which supports it).

(This is the same thing that WebGL does.)

litherum commented 5 years ago

Considering something like

typedef (ImageBitmap or
         ImageData or
         HTMLImageElement or
         HTMLCanvasElement or
         HTMLVideoElement or
         OffscreenCanvas) TexImageSource;

partial interface WebGPUDevice {
    WebGPUTexture createCompressedTexture(TexImageSource texImageSource);
}

I don’t this kind of approach got a fair discussion in the meeting. The discussion centered around the need to support encoders for the compressed image formats; however we already have at least two independent instances of precident for the Web Platform using image encoders.

This type of API moves the logic of picking the right compressed texture format from the web app to the browser, so the browser can pick the best format for the image/hardware combination. If the native API supports a new, better type of compressed texture format, web apps don’t need to be updated to use it. The platforms already often have APIs to encode these compressed texture formats. And, it makes fingerprinting users more difficult.

kvark commented 5 years ago

@litherum I don't think that we should be encoding anything at all. Compressed formats are lossy, and we don't have the permission from the user to degrade image quality. For this reasons, a normal application does the encoding off-line (while having some measure of quality loss and taking responsibility for it), while the texture upload is the near-instant (all the data is ready, no processing is needed, and the footprint is smaller than the uncompressed would have).

kainino0x commented 5 years ago

If we wanted a compression API, I think it should be an entirely separate API, not attached to WebGPU at all, which takes in an image and returns the bytes for the compressed texture.

magcius commented 5 years ago

Which platforms have APIs to encode compressed texture formats at runtime, on device? I'm not aware of any.

kvark commented 5 years ago

@magcius OpenGL :D

devshgraphicsprogramming commented 5 years ago

Not many people use that API or expect it to work with OpenGL, mostly because the quality and speed (no idea if encoder is GPU or CPU) of the compression varies between implementations.

litherum commented 5 years ago

Compressed formats are lossy, and we don't have the permission from the user to degrade image quality.

The other image encoding facilities in the web platform are also lossy.

it should be an entirely separate API, not attached to WebGPU at all

The Web application doesn’t know the best kind of compressed texture to use for your hardware. Joining this API to WebGPU allows the browser to pick the best compressed texture format for the underlying platform.

Which platforms have APIs to encode compressed texture formats at runtime, on device?

macOS and iOS do it with the standard system facilities. I believe Windows has a way to do it too but I can’t remember how. And @kvark is right that OpenGL has a way to do it, too.

magcius commented 5 years ago

Saying "ASTC" isn't enough, the quality of the compressor matters a huge degree. ASTC is infamous for its large search space and large time to compress offline. I'd expect that any runtime encoder would not really give acceptable results.

Game developers spend a lot of time adjusting and tweaking this stuff (it was a full-time job the studio I worked at to adjust texture resolution and compression formats across all platforms to ensure that things looked OK), and not all compression techniques apply to all textures. These artifacts are incredibly real, and people notice.

Leaving the visual fidelity of a project to the whim of browser developers will not go over well.

litherum commented 5 years ago

the quality of the compressor matters a huge degree.

A quality control seems like a natural part of the API i'm proposing.

It would be unfortunate if it was required to have different codepaths on mobile and desktop in order to use compressed textures. Authors shouldn't have to write platform-specific code to use facilities that every platform supports.

Perhaps we could compromise and get the best of both worlds: we can have separate extensions for the game dev shops that need control over every individual byte of their compressed textures, but we can also have a larger "use less memory and bandwidth please" API with a quality parameter. That way, simple things are easy and complicated things are possible.

grovesNL commented 5 years ago

It would be unfortunate if it was required to have different codepaths on mobile and desktop in order to use compressed textures.

I don't think we can simply abstract over all of these details. A lot of these compressors aren't supposed to execute at run-time because they take a simply take a long time to run. I don't think it's reasonable to emulate too much GPU functionality like this, and it would serve developers much better to give them a list of which formats are available so they can decide what to do (i.e. perhaps fallback to another compressed format that is available).

kainino0x commented 5 years ago

The "simple, easy" path is to just not compress textures.

litherum commented 5 years ago

It seems unlikely to expect every web developer to provide pre-compressed textures for every platform on the Web. Given that, I'm worried about the case where a WebGPU app works great on Android because they use the Android compressed texture format, but works terribly on iOS because they never thought about testing there (or vice-versa).

kainino0x commented 5 years ago

I don't think this is that different from any other extension. If an application uses an extension (e.g. ETC), it has to also make sure it works without it (uncompressed textures). And there are only a few formats, so if a developer is aware of and using one compressed format, they are presumably aware of and capable of using other compressed formats, and understand the necessity of targeting multiple platforms.

I still think that a separate compression API would be better than a built-in one. Even if apps are doing on-the-fly compression, they need control over what format ends up being used (because some data cannot be properly compressed using some algorithms). It could be essentially as simple as: device.compressedFormats => ['bc', 'etc'] texturecompressor.compress(device.compressedFormats, rawdata) => ['bc', compresseddata]

And if the compression API is separate, why shouldn't it just be a JS library?


Emulated compressed texture support (by decompressing) as a dev tool would be useful, to allow developers to test their e.g. PVRTC codepath without having a PVRTC device.

litherum commented 5 years ago

The difference is that all platforms have facilities for compressed textures.

magcius commented 5 years ago

Vulkan and D3D12 have no built-in APIs to compress textures. OpenGL shipped such an API but it is basically unsupported in the modern era, and GLES does not have it. Microsoft does ship a DirectXTex library but it is intended for tool developers, not to be used at runtime. It is not part of Direct3D proper.

Maksims commented 5 years ago

This topic closely relates to same topic that happened with WebGL and potential encoding or decoding of textures automatically. It was clearly stated there array of issues with doing such "magic" behind the scenes.

First of all encoding something - is extremely expensive, and is almost always done offline by developer. This is approach that most engines take. Encoding for certain things have to be done in a very specific manner as there are various issues with different compression formats, as some formats suffer from channels leaking to each other - which makes them not suitable for textures where in each channel is stored different grayscale texture. There are compression formats that allow better normal map encoding, but others would just ruin normal map completely. There is no holygrail one approach to compression topic. So developer have to make conscious choice to use additional compressed variant for texture or not. But as JPEG and PNG is universally supported, developers use it as base fallback.

Decoding compressed texture into non-compressed behind the scenes - is harmful too, because it looses completely the point of compressed textures, and developer almost always will have non compressed base variant available (PNG / JPEG).

Simply provide flags of what is hardware supported and what is not, and let developer to decide to download one or the other texture variant. This gives control to developer, does not make more or less work than in other scenarios, and makes it simple to understand. As well as avoids awful issues such as: high CPU load by encode/decode; high VRAM usage with compressed textures (because they are not supported apparently); forcing developers maintaining own whitelist to know where it is really supported; etc.

grorg commented 5 years ago

This was discussed at the 14 Jan 2019 Teleconference

devshgraphicsprogramming commented 5 years ago

My two cents as a developer, I don't mind the API decompressing losslessly a BC, ASCT or ECT texture to some other appropriate format if the base input format is not supported.

P.S. The way we solve the problem of DXT being huge on the disk compared to PNG/JPEG is we compress the block-compressed .dds textures with LZMA or ZLIB.

Maksims commented 5 years ago

This was discussed at the 14 Jan 2019 Teleconference

Those who support idea of compressing behind the scenes, ever developed any WebGL apps that supported variety of different compressed textures for different mobile and desktop applications? It seems to me, that many who vote on this, actually have not worked with it ever in real projects.

Texture compression, is dramatically slow. It has a lot of limitations too, for example some texture formats minimum size is something like 16x16, some compressed formats can deal only with square images. Most of them deal only with PoT textures. Almost all of the have channel color leaking, but differs between which ones, important aspect when compressing combined textures (gloss, metalness, ao, etc in one texture). There are loads of rules and limitations per each individual texture format, that developer have to be aware of while developing their content. There is no holy-grail solution for this here, not even on a paper.

Then there is CPU Time, it takes enormous amount of CPU Time to compress textures. Nobody does it on the fly in gaming or interactive GPU content. Period. We run clusters of servers in PlayCanvas on a cloud, just to handle compression pipeline jobs. Some textures might take up to minutes to compress. With such weird browser behaviours, users on the phone will go away from page by the time his CPU is loaded 100% trying to compress 256x256 JPEG into PVR for example for minutes.

Then there is no lossless compressed textures formats. They don't exist. JPEG is almost always smaller download size than compressed texture. PNG is lossless. Each individual format have cons and pros, and there are subformats with support of different color spaces, leaking behaviours, color bitrate and so on. This is case by case have to be chosen by the developer, there is no compression format without sacrifices.

Before whoever making calls on this, research before, talk to real developers in industry who uses compressed textures in real projects.

Compressed formats still today, is not used almost by anyone in industry, Only very high-end projects in WebGL will have pipeline and devs capability to do compressed textures, as it is not just "plug-n-play" thing. Most engines don't have nice abstraction over compressed textures as variants of original, and ability to download supported variant when requested.

Here is an example of the way PNG is handled by some iOS devices differently than by everyone else. As there is some assumption on pixel RGB content when Alpha is 0 of that pixel. This is some assumptions someone made, without understanding implications of such, leading to issues down the line for developers to find workarounds. Compression textures in this analogy will be 10x more complex assumption.

It is not MVP, but it is highly nice to have in today's Web 3D environment. It has been discussed before in mailing lists and already been highlighted why it is an awful idea.

And all decent modern mobile platforms - support own formats, just expose querying of support, and let developer decide. No magic, no weird workarounds of underlying undocumented behaviours by different vendors, no hassle. Do not brake existing, accepted in industry mechanics.

Better focus on CPU<>GPU thread locking: avoiding uploading textures to GPU locks of thread, compilation shaders lock of threads (worst thing today), and any GC related to API - those are current issues with WebGL that have been holding progress in making amazing content. Not lack of compressed textures support.

RafaelCintron commented 5 years ago

I agree with @Maksims points.

Back in my game development days, I remember artists spending considerable time tweaking their content so the transition from Photoshop through DX1-5 compression went well. They even wanted control over every mipmap. GenerateMips wouldn't cut it.

To me, the degree to which we auto-compress content depends on the delta in visual fidelity (and speed) between what the web developer sees at creation time and what users see at runtime. If the difference is substantial, I do not believe auto-compression will be viable.

gyagp commented 5 years ago

compilation shaders lock of threads (worst thing today) We have been working on WebGL parallel shader compilation for a while. D3D support is ready now in Chrome, while OpenGL backend is still WIP. More details can be found below: Spechttps://www.khronos.org/registry/webgl/extensions/KHR_parallel_shader_compile/ Benchmarkhttps://github.com/KhronosGroup/WebGL/tree/master/sdk/tests/performance/parallel_shader_compile Chrome issuehttps://bugs.chromium.org/p/chromium/issues/detail?id=849576 Performance datahttps://docs.google.com/presentation/d/1NlEf7iewlc_i771GO086jBVL_t_tLZvB6zVK7JA2-30/edit#slide=id.g384c91526c_0_5

Comments are welcome!

Maksims commented 5 years ago

@gyagp this is a great extension! It will open path of making complex WebGL demos without annoying shader compilation freezes of main JS thread.

Really appreciated!

gyagp commented 5 years ago

@Maksims, the patch to support WebGL parallel shader compilation with OpenGL backend just merged. One note is that most of features are implemented inside ANGLE. On one hand, as most of mainstream browsers are using ANGLE now, it should be relatively easy for them to integrate this feature. On the other hand, ANGLE is not by default used in Chrome on OSes other than Windows, which means OpenGL support can not be used right away, though you may already give a try with some Chrome options (like --use-gl=angle). I'm not sure about concrete plan for Chrome to use ANGLE everywhere.

kdashg commented 5 years ago

Resolved: We're going to require implementations support at least one of [BC, ETC], and may include additional formats. Also, include text that outlines these block-based formats, including how the transfers are restricted. (Saves us from having to redefine these common parts between extensions)

alecazam commented 3 years ago

There is BC1 rgb and BC1 rgba. These are different types in Vulkan, but not in Metal.

Also ASTC HDR (only iPhone 11+ and newer Android and M1), and ASTC with/without 3d block support (not iOS, maybe Mali). And the GL types for ASTC don't distinguish LDR from HDR, but Vulkan/Metal do. Metal doesn't have 3d block support, so all pixels in a 3d texture are 2d planes.

Also don't forget Basis which can transcode. Support for KTX2 with supercompression should be a part of the spec, and that can hold BC/ASTC/ETC/Basis content with compressed mips. There should also be fast array multiple level upload like glTexImage3D, and not Metal's current array single level upload. This applies to cube, cubearray, and 2d array textures.

Also 1D and 1D array textures can't be compressed, so drop these in favor of 2D and 2D array textures.

Drop PVRTC if possible, the encoders are slow and the format is non-existant these days. It has pow2 restrictions, and also needs to know wrap vs. clamp at encode time. This doesn't bode well for sparse texture support either due to all the limitations.

Unlike WebGL, please include the srgb versions of the block formats in the spec and not in some unsupported extension. These are important.

kainino0x commented 3 years ago

@alecazam Please look at the format list in the spec and let us know if you have specific concerns about what's already there: https://gpuweb.github.io/gpuweb/#enumdef-gputextureformat https://gpuweb.github.io/gpuweb/#texture-compression-bc So far we have only added BC formats, and have compression only for 2d (2d-array) textures. The rest is TBD.

The next priority format family is ETC, which we will definitely have before V1 (so we can get compression on mobile devices). ASTC is next after that.

Also don't forget Basis which can transcode. Support for KTX2 with supercompression should be a part of the spec, and that can hold BC/ASTC/ETC/Basis content with compressed mips.

This can be done with the hardware formats (BC/ASTC/ETC) plus userspace tools. Therefore KTX2/Basis support in the API itself is not necessary, it would just be a convenience/enhancement (potentially to be considered in the future - and don't worry, we won't forget, we love Basis too). WebGL made the same decision.

Also 1D and 1D array textures can't be compressed, so drop these in favor of 2D and 2D array textures.

Are you suggesting dropping 1D textures entirely? Or just compressed 1D textures? (which we already don't have) AFAIK, 1D textures are still useful for hardware-interpolated lookup tables (ramps).

Drop PVRTC if possible,

This has already been agreed upon :)

Unlike WebGL, please include the srgb versions of the block formats in the spec and not in some unsupported extension. These are important.

Let us know if you have any issue with the BC format list as specced.

The separate WebGL extension was a necessity due to what extensions had been published in the past, and restrictions on underlying GL implementations. There is no such division in WebGPU as you can already see in the spec. If you have any issue with the availability of those extensions, please file bugs with the affected browsers.

alecazam commented 3 years ago

I often feel like WebGL made mobile too much of a priority, when most of the WebGL usage was on desktop. I worked on a few apps using WebGL. Prioritizing desktop BC, then mobile ASTC, then ETC is best. ETC is sliding off the old hardware slope, since it doesn't support partitioning and more modern encode features. I do still like EACr/rg11 though.

Are you suggesting dropping 1D textures entirely? Or just compressed 1D textures? (which we already don't have) AFAIK, 1D textures are still useful for hardware-interpolated lookup tables (ramps).

A 1d and 1d array texture are not any different than a 16x1 or 16x1@20 layer 2d array texture. The main difference is the 1D and 1d array case doesn't support compressed blocks. I'd heard some people were using buffers for 1d textures, since those are linear and not twiddled but those aren't encoded. There are a lot of encoding tools that don't support 1d or 1d array textures as well, and it makes specifying containers more complex than needed (f.e. h = 0 in KTX). And encoders then need to block use of encoded formats on these.

Thanks for the spec links. I'll take a look.

I don't see a bc1-rgb-unorm/-srgb format in the spec. If I encode and don't use the 3 color + black mode, and I use the 4 color rgb only mode. I thought that's why Vulkan had the seperate types. But Metal doesn't have those. Rich Geldreich also mentioned the 3 color + black, but force alpha to 1 using a swizzle technique (stored in bc1-rgba I guess). Just saying that those are 3 variants that either do or don't have an unique alpha.

magcius commented 3 years ago

I admittedly haven't worked much on mobile, but I thought ASTC was sort of considered a failure by now? Too complicated for its own good? And most either used PVRTC2 or ETC2 / EAC.

alecazam commented 3 years ago

ASTC is very much alive. The astcenc encoder is getting a lot of improvements, and I use that. ASTC is on iOS/M1/Android, and is the new universal texture format on mobile, but it's not universal on desktop. The block size support above 6x6 is pretty much worthless, and it's got weird swizzles compared to BC/ETC2. The 3d block encode is barely supported, and it's one of the few formats with HDR for full rgba. BC6H is HDR but rgb only. Also comparitively, ASTC HDR is a rarity, and so there isn't a clear HDR winner yet. I've been told it's way too much silicon for ASTC, but chips use it, and dies get more dense.

So really it's just a competition of 4x4 LDR block sizes for ASTC and BC. With BC on PC/console/M1, but not mobile. But BC is off patent trolls now, so that bodes well. BC is a little long in the tooth, so the hardware's been really optimized and there are many CPU and GPU compressors. I don't know of many ASTC GPU encoders. I think Granite has one.

kdashg commented 3 years ago

I expect that as we get further away from the date of our original investigations from 2018(!) that we will feel more and more like one_of(BC,ASTC) will replace one_of(BC,ETC). I think we do want ASTC, but that we've punted it for now to focus on other things for MVP.

We mostly ended up with ETC instead of ASTC because of iOS support, for pre-A8 (pre-iPhone6) devices. I wonder if those devices are still in-scope for webgpu for Apple? @litherum

alecazam commented 3 years ago

ETC2 is also useful on Android, where it's anyone's guess what ancient hardware you'll need to run upon. The encoders aren't very fast though or maintained. I modified Etc2Comp to run a lot faster in my texture engine called "kram". EAC (part of ETC2) also has 11-bit r and rg compressed formats that unpack to rg16f.

Basis ETC1S and UASTC can transcode to any of the compressed formats, but those variants are a subset of the actual formats. The encode times are slower on UASTC and especially so with RDO added on top.

We encode around 500 textures to ETC2 and BC and ASTC in around 2-3 minutes with 8 cores. Adding zstd for KTX2 is not a big overhead either. BC7enc is the fastest, astc-encoder next, and Etc2Comp (modfied) next fastest. I'll likely add UASTC decode next, and ktx tools can generate KTX2 files with either basis forma. The nice part is zstd decode of blocks can go straight into the staging buffer, and then use repeated blits for each chunk to the GPU-resident texture.

kainino0x commented 3 years ago

I think the need for ETC is more driven by Android than by iOS. In any case, those iOS devices are out of scope: see #1069.

one_of(BC,ASTC) will replace one_of(BC,ETC)

I don't think there's any reason to expect BC to replace ETC - most new mobile devices (Android and iOS) still do not support BC. Did you mean something else?

fintelia commented 3 years ago

At the same time, even some of the most recent desktop GPUs don't support ETC2 or ATSC, so I can't see BC going away any time either.

alecazam commented 3 years ago

I don't have one, but I the new M1 chip in my Air support ETC/ASTC/BC now. And that chip is in the iPad. BC is off patent troll now. So that brings mobile in-line with desktop/console which has traditionally skipped the mobile formats.

BC6 is ASTC4x4 HDR without alpha, and BC7 is close to ASTC4x4 LDR. The blocks above 6x6 in ASTC are of limited utility though and not easy to trascode back to 4x4 block formats if used. BC4/5 and EAC_R/RG11 are nice 1/2 channel formats, where ASTC requires swizzles of RRR1 and RRRG/GGGR to use 2 channels and it stays in 8-bit. Mobile ETC is safest bet, and desktop/console BC. Or transcode as needed.

limingchina commented 3 years ago

22% of Vulkan Hardware Database entries support ETC formats.

The above link in the original post is broken. The ETC2 support on android for vulkan is quite good as expected: (textureCompressionETC2 99.4%) from this page: https://vulkan.gpuinfo.org/listfeaturescore10.php?platform=android For linux and windows, they are 17.7% and 9.9% as of end of May, 2021, respectively.

alecazam commented 3 years ago

I know of no etc2 support at the DirectX level, so those numbers seem far off from reality on the Win side. Maybe Win on ARM, but that has seen little adoption so far. Even those Linux numbers may be Android devices.

fintelia commented 3 years ago

A bunch of integrated GPUs have support for ETC2, so that's probably how Windows ended up with a non-trivial fraction. But none of this changes the prior point that BC is still needed for the significant faction of desktop platforms that don't support the other formats, and ETC2 (or ASTC?) is needed for mobile.

kainino0x commented 3 years ago

We certainly can't replace BC with ETC2 or ETC2 with BC.

I think the real open question is which of the following do we pick:

I do not know what the market penetration looks like for ASTC so I have no idea if either of the last two options is viable.

kainino0x commented 3 years ago
  • BC, ASTC (~= drop support for mobile devices without ASTC)

A quick investigation on GPUinfo makes this looks viable. GPUinfo has a fairly small dataset for android devices, but it appears that there are essentially zero Vulkan Android devices without ASTC.

kainino0x commented 3 years ago

Oh, and per #1069, I don't think we need to support any iOS hardware that doesn't have ASTC.

Adding to agenda to consider replacing ETC2 with ASTC, or just plan to have all three for MVP. (Unfortunately this is a bit of work as ASTC is rather complicated.)

kainino0x commented 3 years ago

~@RafaelCintron are there D3D12 devices that don't support BC (or which emulate it), and, since D3D12 doesn't support ASTC, would require ETC2 in order to use compressed textures?~ Sorry, I posted too soon. D3D12 doesn't support ETC2 at all either so even Windows ARM devices can't be using it.

magcius commented 3 years ago

BC is common on desktop devices. Intel, AMD, NVIDIA all support modern BC compression.

ASTC and ETC are common on mobile devices. ETC2 is supported by Adreno and Mali, though there are some asterisks on the exact format subsets that are supported. Apple supports some ASTC, but not ETC (I don't believe).

PVRTC is supported by PowerVR and Apple, and nobody else.

Basis Universal uses a clever subset of ETC2 that is easily transcoded at runtime to BC and PVRTC, though it does this tradeoff for a quality loss.

kainino0x commented 3 years ago

Metal should have full ETC2 support on all Apple GPUs, and ASTC LDR on everything A8+.

My understanding is Basis Universal can target ASTC 4x4 as well (I think even if the format is ETC1S?), so I'm pretty sure there's no strict requirement that we have ETC2 to support Basis Universal.

ETC2 was of course core in OpenGL ES 3.0, so every ES 3.0 device supported it. I believe ASTC became core in ES 3.2, so it is likely to be ubiquitous among the Android Vulkan devices we target.

fintelia commented 3 years ago

Are there any devices which support ASTC but don't support ETC2? If not, a different option would be to require implementations to either support BC or else to support ETC2 and ASTC.

kainino0x commented 3 years ago

That's a solid option if we decide we would want to have all three (e.g. if we were fine with BC+ASTC but want ETC2 to support apps that need it), thanks for suggesting it.