Skip to content

Validation rules and issues of createTexture #1522

@Richard-Yunchao

Description

@Richard-Yunchao

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 2d texture 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).

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.

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.

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.

Some validation rules and issues might be missing...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions