-
Notifications
You must be signed in to change notification settings - Fork 353
Description
Texture creation is one of the most basic and most important function in WebGPU. But we don't have validation rules for createTexture, we have a couple trials though. For example #799 and #1237.
Recently I rewrote validation tests for createTexture. I'd like to summarize the
- validation rules (which are clear and determined per my understanding, but I may misunderstood something and made mistakes), and
- issues (which are not very clear to me).
I will continue my investigation and try to figure out the issues left, but your comments/insights are very welcome.
I put my answers (and reasons) to the issues but the answers may not be reliable because I haven't done thorough investigation.
I will update the status of issues and mark them as clarified if we get consensus via discussion.
TextureDescriptor
Texture creation depends on TextureDescriptor. Its definition is listed as follows:
dictionary GPUTextureDescriptor : GPUObjectDescriptorBase {
required GPUExtent3D size;
GPUIntegerCoordinate mipLevelCount = 1;
GPUSize32 sampleCount = 1;
GPUTextureDimension dimension = "2d";
required GPUTextureFormat format;
required GPUTextureUsageFlags usage;
};
I will go through each parameter in the next section. Note that texture formats impact every other parameter. So I discuss formats in the parameter where they impact. I don't put these validation rules and issues under the category of format.
Validation rules and issues
Dimensions (size) and dimension types (1D/2D/3D):
These two parameters impact each other. So I put them together.
validation rules
- Dimensions (width, height, depthOrArrayLayers) should not be 0 (should be equal or greater than 1).
- If Dimension is
1d, size.height should be 1. - If Dimension is
1d, size.depthOrArrayLayers should be 1.
There is no 1D-array texture view, do we support 1D-array texture (if not, depthOrArrayLayers > 1 is invalid for 1D texture)?
I think we should not support 1D-array texture. So size.depthOrArrayLayers should be 1. - Don’t exceed the dimension limit on every dimension (maxDimensionTexture{1D, 2D, 3D}, maxDimensionArrayLayers, etc. Note that cubemap limit equals to maxDimensionArrayLayers?)
- Make sure that texture width/height are aligned with blockWidth/ blockHeight for compressed texture formats
- All formats can be supported for
2dtexture if the validation rules for other parameters are fulfilled.
issues - clarified
- Are compressed formats allowed for 1D/3D textures?
Compressed formats for 1D/3D textures are complicated (for copy, etc). In addition, compressed 1D/3D textures are not as useful as 2D compressed texture. So I tend to say we don't support compressed texture for 1D/3D in WebGPU MVP/v1. We can add it if needed in later version.- Conclusion: we will not support 1D/3D compressed textures unless somebody comes up with a strong case.
- Any total size limit (width * height * depthOrArrayLayers)? Note that if we create a 2D array texture with size = [maxDimensionTexture2D, maxDimensionTexture2D, maxDimensionArrayLayers], it will lead to out-of-memory failure.
- Conclusion: Just let it be. OOM is a fine reaction. We got the conclusion for buffer size limit. Let's follow the same rule.
- Some formats are not valid for 1D/3D textures.
- Conclusion: in addition to compressed formats invalid for 1D/3D textures, depth/stencil formats are invalid for 1D/3D textures.
- Depth/stencil formats are invalid for 3D on D3D12. This link lists all formats' capability (including 1D/2D/3D texture support) on FeatureLevel_11_0 for D3D. Note that D3D12 can be supported from FeatureLevel_11_0.
- CTS testing on Metal indicates that Metal has this requirement: depth/stencil formats are valid only for 2D (including 2D array textures, 2D cube textures).
- Conclusion: in addition to compressed formats invalid for 1D/3D textures, depth/stencil formats are invalid for 1D/3D textures.
Mipmap (mipLevelCount)
validation rules
- mipLevelCount should not be 0
- mipLevelCount should not be larger than the max values allowed (can be calculated according to its dimensions and dimension types)
- mipLevelCount should be less than integer bit width
- mipLevelCount can be any value between 1 and max allowed values, even for compressed formats.
issues - clarrified
- Are there any formats that can't support mipmap? compressed texture formats are valid for mipmaps (at least for 2D texture), what about depth/stencil formats?
- According to my investigation about texture formats in D3D12 (and GLES 3.2), I didn't find any limitation about mipmap support for any formats. Let's assume there are no additional limits for now.
- Some formats cannot support mipmap in D3D12, but WebGPU didn't support those formats. For example, YUV, NV12, etc.
- In GLES, there are some limits about how to sample mipmap: some depth/stencil formats can only support mipmap_nearest, while the majority of texture formats can support both mipmap_nearest and mipmap_linear. This indicates that depth/stencil formats (and other formats) can support mipmap.
- According to my investigation about texture formats in D3D12 (and GLES 3.2), I didn't find any limitation about mipmap support for any formats. Let's assume there are no additional limits for now.
Multisample (sampleCount)
validation rules
- Valid sample count are 1 (single-sample) and 4 (multi-sample). All other values are invalid.
- If we support multisample (sampleCount is 4), then
- Its dimension type should be 2D only. 1D and 3D multisample texture are not supported in Metal. Note that there are no 1DMultisample or 3DMultisample texture types.
- This also means that sampleCount for 1D/3D textures should be 1.
- mipLevelCount should be 1
- Its usage should not include TextureUsage.STORAGE.
- Compressed formats are invalid.
- Its dimension type should be 2D only. 1D and 3D multisample texture are not supported in Metal. Note that there are no 1DMultisample or 3DMultisample texture types.
issues - clarified
- Except for compressed formats, are there any other formats that are invalid for multisample?
- Conclusion: formats which can be used as RENDER_ATTACHMENT or Depth/Stencil can support multisample. Other formats can't.
- Can we support 2D array multisample texture (if not, arrayLayerCount should be 1 for 2D texture) ?
Currently we disallow this in CTS, but it looks like 2D array multisample textures can be supported in D3D12/Metal/Vulkan.- Conclusion: we can't support 2D array multisample. Metal can support 2D array multisample only on MacOS 10.14+ and iOS 14.0+, see this link
Texture Usage:
validation rules
- All formats can be used as TextureUsage.SAMPLED
- Some formats are not renderable (say compressed formats, rgb9e5, rgb19a2, etc). Those formats should not include TextureUsage.RENDER_ATTACHMENT
TODO: list these formats - Some formats can not be used as storage (say compressed formats, depth/stencil formats, etc). Those formats should not include TextureUsage.STORAGE
TODO: list these formats. - What about format validation upon TextureUsage.COPY_SRC and TextureUsage.Copy_DST?
I think all formats are valid for TextureUsage.COPY_SRC and TextureUsage.Copy_DST. But we need to consider depth/stencil formats used as Copy_SRC/COPY_DST, and the complexity to copy operation.
issues - clarified
- Any usage combination conflict?
Looks like the answer is no.- Conclusion: no conflict.
- Is there any usage that is not allowed for 1D/3D textures?
Looks like the answer is no.- Conclusion: no. All usages are allowed for 1D/3D textures.
Format
validation rules
- Some formats need extension support (compressed formats, etc.). Otherwise texture creation will fail.
- TextureFormat in WebGPU spec has already listed the required extension for each format if it needs an extension.
Some validation rules and issues might be missing...