这是indexloc提供的服务,不要输入任何密码
Skip to content

Investigation: Generate mipmaps #386

@litherum

Description

@litherum

Generating mipmaps is something that most 3D applications want to do. As textures are often the largest asset 3D apps need to download, generating the smaller miplevels can save significant downloading time, causing the app to be able to launch earlier. We've heard that download times are a significant concern to Web game developers; there's a strong inverse correlation between how long a games takes to load and how many users actually end up playing the game.

WebGPU currently provides no facilities to generate mipmaps. It is true that a 3rd party library could do this, but taking an additional dependency and sending a library across the wire for something that most 3D authors will want to do seems like bad design. Indeed; the purpose of doing this in the browser is to decrease download sizes, and adding an additional framework dependency is contrary to that goal.

WebGL solved this by including WebGLRenderingContext.generateMipmap(). Developers clearly desire using this; a quick search of GitHub shows that it's used more than 46,000 times. Indeed, at least one developer is using this WebGL API to generate mipmaps and then passing the results into WebGPU.

WebGPU should provide built-in facilities for generating mipmaps. Of course, we shouldn't force developers to use the built-in facilities. It is true that different developers desire mipmap filtering algorithms, and they should be free to write their own mipmap generation code. However, for most authors, the presence of built-in mipmap generation facilities will be the difference between mipmaps existing in their app at all, and mipmaps not existing in their app.

Metal

It's a method on MTLBlitCommandEncoder. It is executed on the GPU, so the command needs to be submitted to the queue and is therefore ordered with relation to other GPU operations. Also, because this is inside a command encoder, all compute/graphics command encoders need to be closed before this can be issued.

The docs have a note:

The filtering used to generate the mipmaps is implementation-dependent and may vary by Metal feature set.

Direct3D 12

The core API doesn't have any support for generating mipmaps. However, the Microsoft-authored DirectX Tool Kit 12 includes support for it. Unfortunately, this Kit isn't included in the Windows SDK; Windows browsers would take a dependency on it. The docs say that it's implemented on top of a compute shader.

The GenerateMips function uses a DirectCompute shader to perform the mip-generation using bi-linear interpolation

Direct3D 12 doesn't have passes, so there are no concerns there. However, the API isn't a one-shot generation; instead, it's a ResourceUploadBatch object that has to be opened and closed.

Vulkan

Vulkan doesn't have any built-in facilities for generating mipmaps (because of course it doesn't). It looks like you can do it with (a ton of code around)vkCmdBlitImage, which means that any render passes need to be closed.

Compute shader

Even if Windows browsers didn't want to take a dependency on DirectX Tool Kit 12, we could still implement it using a compute shader. This would require that all render passes are closed.

Recommendation

In keeping with the current design of putting blit-style commands directly on the GPUCommandEncoder, we can add a generateMipmaps(texture) call there. This will allow for us to require that any render or compute passes are closed before it's called. Such a design should be compatible with each of the above approaches.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions