export const description = `createTexture validation tests.`;

import { AllFeaturesMaxLimitsGPUTest } from '../.././gpu_test.js';
import { makeTestGroup } from '../../../common/framework/test_group.js';
import { assert, makeValueTestVariant } from '../../../common/util/util.js';
import {
  kTextureDimensions,
  kTextureUsages,
  isValidTextureUsageCombination,
  kValidCombinationsOfOneOrTwoTextureUsages,
} from '../../capability_info.js';
import { GPUConst } from '../../constants.js';
import {
  kAllTextureFormats,
  kCompressedTextureFormats,
  kUncompressedTextureFormats,
  kRegularTextureFormats,
  kFeaturesForFormats,
  filterFormatsByFeature,
  textureFormatAndDimensionPossiblyCompatible,
  getBlockInfoForTextureFormat,
  isTextureFormatMultisampled,
  isTextureFormatColorRenderable,
  isTextureFormatPossiblyUsableAsColorRenderAttachment,
  isTextureFormatPossiblyStorageReadable,
  isColorTextureFormat,
  textureFormatsAreViewCompatible,
  textureDimensionAndFormatCompatibleForDevice,
  getMaxValidTextureSizeForFormatAndDimension,
  isTextureFormatUsableWithStorageAccessMode,
} from '../../format_info.js';
import { maxMipLevelCount } from '../../util/texture/base.js';

export const g = makeTestGroup(AllFeaturesMaxLimitsGPUTest);

g.test('zero_size_and_usage')
  .desc(
    `Test texture creation with zero or nonzero size of
    width, height, depthOrArrayLayers and mipLevelCount, usage for every dimension, and
    representative formats.
  `
  )
  .params(u =>
    u
      .combine('dimension', [undefined, ...kTextureDimensions])
      .combine('format', [
        'rgba8unorm',
        'rgb10a2unorm',
        'bc1-rgba-unorm',
        'depth24plus-stencil8',
      ] as const)
      .beginSubcases()
      .combine('zeroArgument', [
        'none',
        'width',
        'height',
        'depthOrArrayLayers',
        'mipLevelCount',
        'usage',
      ] as const)
      // Filter out incompatible dimension type and format combinations.
      .filter(({ dimension, format }) =>
        textureFormatAndDimensionPossiblyCompatible(dimension, format)
      )
  )
  .fn(t => {
    const { dimension, zeroArgument, format } = t.params;
    t.skipIfTextureFormatNotSupported(format);
    t.skipIfTextureFormatAndDimensionNotCompatible(format, dimension);

    const info = getBlockInfoForTextureFormat(format);

    const size = [info.blockWidth, info.blockHeight, 1];
    let mipLevelCount = 1;
    let usage = GPUTextureUsage.TEXTURE_BINDING;

    switch (zeroArgument) {
      case 'width':
        size[0] = 0;
        break;
      case 'height':
        size[1] = 0;
        break;
      case 'depthOrArrayLayers':
        size[2] = 0;
        break;
      case 'mipLevelCount':
        mipLevelCount = 0;
        break;
      case 'usage':
        usage = 0;
        break;
      default:
        break;
    }

    const descriptor = {
      size,
      mipLevelCount,
      dimension,
      format,
      usage,
    };

    const success = zeroArgument === 'none';

    t.expectValidationError(() => {
      t.createTextureTracked(descriptor);
    }, !success);
  });

g.test('dimension_type_and_format_compatibility')
  .desc(
    `Test every dimension type on every format. Note that compressed formats and depth/stencil formats are not valid
    for 1D dimension types while it depends on the format for 3D types.`
  )
  .params(u =>
    u //
      .combine('dimension', [undefined, ...kTextureDimensions])
      .combine('format', kAllTextureFormats)
  )
  .fn(t => {
    const { dimension, format } = t.params;
    t.skipIfTextureFormatNotSupported(format);
    const info = getBlockInfoForTextureFormat(format);

    const descriptor: GPUTextureDescriptor = {
      size: [info.blockWidth, info.blockHeight, 1],
      dimension,
      format,
      usage: GPUTextureUsage.TEXTURE_BINDING,
    };

    t.expectValidationError(
      () => {
        t.createTextureTracked(descriptor);
      },
      !textureDimensionAndFormatCompatibleForDevice(t.device.features, dimension, format)
    );
  });

g.test('mipLevelCount,format')
  .desc(
    `Test texture creation with no mipmap chain, partial mipmap chain, full mipmap chain, out-of-bounds mipmap chain
    for every format with different texture dimension types.`
  )
  .params(u =>
    u
      .combine('dimension', [undefined, ...kTextureDimensions])
      .combine('format', kAllTextureFormats)
      .beginSubcases()
      .combine('mipLevelCount', [1, 2, 3, 6, 7])
      // Filter out incompatible dimension type and format combinations.
      .filter(({ dimension, format }) =>
        textureFormatAndDimensionPossiblyCompatible(dimension, format)
      )
      .combine('largestDimension', [0, 1, 2])
      .unless(({ dimension, largestDimension }) => dimension === '1d' && largestDimension > 0)
  )
  .fn(t => {
    const { dimension, format, mipLevelCount, largestDimension } = t.params;
    t.skipIfTextureFormatNotSupported(format);
    t.skipIfTextureFormatAndDimensionNotCompatible(format, dimension);
    const info = getBlockInfoForTextureFormat(format);

    // Compute dimensions such that the dimensions are in range [17, 32] and aligned with the
    // format block size so that there will be exactly 6 mip levels.
    const kTargetMipLevelCount = 5;
    const kTargetLargeSize = (1 << kTargetMipLevelCount) - 1;
    const largeSize = [
      Math.floor(kTargetLargeSize / info.blockWidth) * info.blockWidth,
      Math.floor(kTargetLargeSize / info.blockHeight) * info.blockHeight,
      kTargetLargeSize,
    ];
    assert(17 <= largeSize[0] && largeSize[0] <= 32);
    assert(17 <= largeSize[1] && largeSize[1] <= 32);

    // Note that compressed formats are not valid for 1D. They have already been filtered out for 1D
    // in this test. So there is no dilemma about size.width equals 1 vs
    // size.width % info.blockHeight equals 0 for 1D compressed formats.
    const size = [info.blockWidth, info.blockHeight, 1];
    size[largestDimension] = largeSize[largestDimension];

    const descriptor = {
      size,
      mipLevelCount,
      dimension,
      format,
      usage: GPUTextureUsage.TEXTURE_BINDING,
    };

    const success = mipLevelCount <= maxMipLevelCount(descriptor);

    t.expectValidationError(() => {
      t.createTextureTracked(descriptor);
    }, !success);
  });

g.test('mipLevelCount,bound_check')
  .desc(
    `Test mip level count bound check upon different texture size and different texture dimension types.
    The cases below test: 1) there must be no mip levels after a 1 level (1D texture), or 1x1 level (2D texture), or 1x1x1 level (3D texture), 2) array layers are not mip-mapped, 3) power-of-two, non-power-of-two, and non-square sizes.`
  )
  .params(u =>
    u //
      .combine('format', ['rgba8unorm', 'bc1-rgba-unorm'] as const)
      .beginSubcases()
      .combineWithParams([
        { size: [32, 32] }, // Mip level sizes: 32x32, 16x16, 8x8, 4x4, 2x2, 1x1
        { size: [31, 32] }, // Mip level sizes: 31x32, 15x16, 7x8, 3x4, 1x2, 1x1
        { size: [28, 32] }, // Mip level sizes: 28x32, 14x16, 7x8, 3x4, 1x2, 1x1
        { size: [32, 31] }, // Mip level sizes: 32x31, 16x15, 8x7, 4x3, 2x1, 1x1
        { size: [32, 28] }, // Mip level sizes: 32x28, 16x14, 8x7, 4x3, 2x1, 1x1
        { size: [31, 31] }, // Mip level sizes: 31x31, 15x15, 7x7, 3x3, 1x1
        { size: [32], dimension: '1d' as const }, // Mip level sizes: 32, 16, 8, 4, 2, 1
        { size: [31], dimension: '1d' as const }, // Mip level sizes: 31, 15, 7, 3, 1
        { size: [32, 32, 32], dimension: '3d' as const }, // Mip level sizes: 32x32x32, 16x16x16, 8x8x8, 4x4x4, 2x2x2, 1x1x1
        { size: [32, 31, 31], dimension: '3d' as const }, // Mip level sizes: 32x31x31, 16x15x15, 8x7x7, 4x3x3, 2x1x1, 1x1x1
        { size: [31, 32, 31], dimension: '3d' as const }, // Mip level sizes: 31x32x31, 15x16x15, 7x8x7, 3x4x3, 1x2x1, 1x1x1
        { size: [31, 31, 32], dimension: '3d' as const }, // Mip level sizes: 31x31x32, 15x15x16, 7x7x8, 3x3x4, 1x1x2, 1x1x1
        { size: [31, 31, 31], dimension: '3d' as const }, // Mip level sizes: 31x31x31, 15x15x15, 7x7x7, 3x3x3, 1x1x1
        { size: [32, 8] }, // Mip levels: 32x8, 16x4, 8x2, 4x1, 2x1, 1x1
        { size: [32, 32, 64] }, // Mip levels: 32x32x64, 16x16x64, 8x8x64, 4x4x64, 2x2x64, 1x1x64
        { size: [32, 32, 64], dimension: '3d' as const }, // Mip levels: 32x32x64, 16x16x32, 8x8x16, 4x4x8, 2x2x4, 1x1x2, 1x1x1
      ])
      .unless(
        ({ format, size, dimension }) =>
          format === 'bc1-rgba-unorm' &&
          (dimension === '1d' ||
            dimension === '3d' ||
            size[0] % getBlockInfoForTextureFormat(format).blockWidth !== 0 ||
            size[1] % getBlockInfoForTextureFormat(format).blockHeight !== 0)
      )
  )
  .fn(t => {
    const { format, size, dimension } = t.params;
    t.skipIfTextureFormatNotSupported(format);

    const descriptor = {
      size,
      mipLevelCount: 0,
      dimension,
      format,
      usage: GPUTextureUsage.TEXTURE_BINDING,
    };

    const mipLevelCount = maxMipLevelCount(descriptor);
    descriptor.mipLevelCount = mipLevelCount;
    t.createTextureTracked(descriptor);

    descriptor.mipLevelCount = mipLevelCount + 1;
    t.expectValidationError(() => {
      t.createTextureTracked(descriptor);
    });
  });

g.test('mipLevelCount,bound_check,bigger_than_integer_bit_width')
  .desc(`Test mip level count bound check when mipLevelCount is bigger than integer bit width`)
  .fn(t => {
    const descriptor = {
      size: [32, 32],
      mipLevelCount: 100,
      format: 'rgba8unorm' as const,
      usage: GPUTextureUsage.TEXTURE_BINDING,
    };

    t.expectValidationError(() => {
      t.createTextureTracked(descriptor);
    });
  });

g.test('sampleCount,various_sampleCount_with_all_formats')
  .desc(
    `Test texture creation with various (valid or invalid) sample count and all formats. Note that 1D and 3D textures can't support multisample.`
  )
  .params(u =>
    u
      .combine('dimension', [undefined, '2d'] as const)
      .combine('format', kAllTextureFormats)
      .beginSubcases()
      .combine('sampleCount', [0, 1, 2, 4, 8, 16, 32, 256])
  )
  .fn(t => {
    const { dimension, sampleCount, format } = t.params;
    t.skipIfTextureFormatNotSupported(format);
    const info = getBlockInfoForTextureFormat(format);

    const usage =
      sampleCount > 1
        ? GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT
        : GPUTextureUsage.TEXTURE_BINDING;
    const descriptor = {
      size: [32 * info.blockWidth, 32 * info.blockHeight, 1],
      sampleCount,
      dimension,
      format,
      usage,
    };

    const success =
      sampleCount === 1 ||
      (sampleCount === 4 && isTextureFormatMultisampled(t.device.features, format));

    t.expectValidationError(() => {
      t.createTextureTracked(descriptor);
    }, !success);
  });

g.test('sampleCount,valid_sampleCount_with_other_parameter_varies')
  .desc(
    `Test texture creation with valid sample count when dimensions, arrayLayerCount, mipLevelCount,
     format, and usage varies. Texture can be single sample (sampleCount is 1) or multi-sample
     (sampleCount is 4). Multisample texture requires that
     1) its dimension is 2d or undefined,
     2) its format supports multisample,
     3) its mipLevelCount and arrayLayerCount are 1,
     4) its usage doesn't include STORAGE_BINDING,
     5) its usage includes RENDER_ATTACHMENT.`
  )
  .params(u =>
    u
      .combine('dimension', [undefined, ...kTextureDimensions])
      .combine('format', kAllTextureFormats)
      .beginSubcases()
      .combine('sampleCount', [1, 4])
      .combine('arrayLayerCount', [1, 2])
      .unless(
        ({ dimension, arrayLayerCount }) =>
          arrayLayerCount === 2 && dimension !== '2d' && dimension !== undefined
      )
      .combine('mipLevelCount', [1, 2])
      .combine('usage', kValidCombinationsOfOneOrTwoTextureUsages)
      // Filter out incompatible dimension type and format combinations.
      .filter(({ dimension, format }) =>
        textureFormatAndDimensionPossiblyCompatible(dimension, format)
      )
      .unless(({ usage, format, arrayLayerCount, mipLevelCount, dimension }) => {
        return (
          ((usage & GPUConst.TextureUsage.RENDER_ATTACHMENT) !== 0 &&
            (!isTextureFormatPossiblyUsableAsColorRenderAttachment(format) ||
              dimension !== '2d')) ||
          ((usage & GPUConst.TextureUsage.STORAGE_BINDING) !== 0 &&
            !isTextureFormatPossiblyStorageReadable(format)) ||
          (mipLevelCount !== 1 && dimension === '1d') ||
          ((usage & GPUConst.TextureUsage.TRANSIENT_ATTACHMENT) !== 0 &&
            (usage !==
              (GPUConst.TextureUsage.RENDER_ATTACHMENT |
                GPUConst.TextureUsage.TRANSIENT_ATTACHMENT) ||
              mipLevelCount !== 1 ||
              arrayLayerCount !== 1))
        );
      })
  )
  .fn(t => {
    const { dimension, sampleCount, format, mipLevelCount, arrayLayerCount, usage } = t.params;
    t.skipIfTextureFormatNotSupported(format);
    t.skipIfTextureFormatAndDimensionNotCompatible(format, dimension);
    if ((usage & GPUConst.TextureUsage.RENDER_ATTACHMENT) !== 0) {
      t.skipIfTextureFormatNotUsableAsRenderAttachment(format);
    }
    // MAINTENANCE_TODO(#4509): Remove this when TRANSIENT_ATTACHMENT is added to the WebGPU spec.
    if ((usage & GPUConst.TextureUsage.TRANSIENT_ATTACHMENT) !== 0) {
      t.skipIfTransientAttachmentNotSupported();
    }
    const { blockWidth, blockHeight } = getBlockInfoForTextureFormat(format);

    const size =
      dimension === '1d'
        ? [32 * blockWidth, 1 * blockHeight, 1]
        : dimension === '2d' || dimension === undefined
        ? [32 * blockWidth, 32 * blockHeight, arrayLayerCount]
        : [32 * blockWidth, 32 * blockHeight, 32];
    const descriptor = {
      size,
      mipLevelCount,
      sampleCount,
      dimension,
      format,
      usage,
    };

    const satisfyWithStorageUsageRequirement =
      (usage & GPUConst.TextureUsage.STORAGE_BINDING) === 0 ||
      isTextureFormatUsableWithStorageAccessMode(t.device.features, format, 'write-only');

    const success =
      (sampleCount === 1 && satisfyWithStorageUsageRequirement) ||
      (sampleCount === 4 &&
        isTextureFormatMultisampled(t.device.features, format) &&
        (dimension === '2d' || dimension === undefined) &&
        mipLevelCount === 1 &&
        arrayLayerCount === 1 &&
        (usage & GPUConst.TextureUsage.RENDER_ATTACHMENT) !== 0 &&
        (usage & GPUConst.TextureUsage.STORAGE_BINDING) === 0);

    t.expectValidationError(() => {
      t.createTextureTracked(descriptor);
    }, !success);
  });

g.test('sample_count,1d_2d_array_3d')
  .desc(`Test that you can not create 1d, 2d_array, and 3d multisampled textures`)
  .params(u =>
    u.combineWithParams([
      { dimension: '2d', size: [4, 4, 1], shouldError: false },
      { dimension: '1d', size: [4, 1, 1], shouldError: true },
      { dimension: '2d', size: [4, 4, 4], shouldError: true },
      { dimension: '2d', size: [4, 4, 6], shouldError: true },
      { dimension: '3d', size: [4, 4, 4], shouldError: true },
    ] as const)
  )
  .fn(t => {
    const { dimension, size, shouldError } = t.params;

    t.expectValidationError(() => {
      t.createTextureTracked({
        size,
        dimension,
        sampleCount: 4,
        format: 'rgba8unorm',
        usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT,
      });
    }, shouldError);
  });

g.test('texture_size,default_value_and_smallest_size,uncompressed_format')
  .desc(
    `Test default values for height and depthOrArrayLayers for every dimension type and every uncompressed format.
    It also tests smallest size (lower bound) for every dimension type and every uncompressed format, while other texture_size tests are testing the upper bound.`
  )
  .params(u =>
    u
      .combine('dimension', [undefined, ...kTextureDimensions])
      .combine('format', kUncompressedTextureFormats)
      .beginSubcases()
      .combine('size', [[1], [1, 1], [1, 1, 1]])
      // Filter out incompatible dimension type and format combinations.
      .filter(({ dimension, format }) =>
        textureFormatAndDimensionPossiblyCompatible(dimension, format)
      )
  )
  .fn(t => {
    const { dimension, format, size } = t.params;
    t.skipIfTextureFormatNotSupported(format);
    t.skipIfTextureFormatAndDimensionNotCompatible(format, dimension);

    const descriptor: GPUTextureDescriptor = {
      size,
      dimension,
      format,
      usage: GPUTextureUsage.TEXTURE_BINDING,
    };

    t.createTextureTracked(descriptor);
  });

g.test('texture_size,default_value_and_smallest_size,compressed_format')
  .desc(
    `Test default values for height and depthOrArrayLayers for every dimension type and every compressed format.
    It also tests smallest size (lower bound) for every dimension type and every compressed format, while other texture_size tests are testing the upper bound.`
  )
  .params(u =>
    u
      // Compressed formats are invalid for 1D.
      .combine('dimension', [undefined, '2d', '3d'] as const)
      .combine('format', kCompressedTextureFormats)
      .filter(({ dimension, format }) =>
        textureFormatAndDimensionPossiblyCompatible(dimension, format)
      )
      .beginSubcases()
      .expandWithParams(p => {
        const { blockWidth, blockHeight } = getBlockInfoForTextureFormat(p.format);
        return [
          { size: [1], _success: false },
          { size: [blockWidth], _success: false },
          { size: [1, 1], _success: false },
          { size: [blockWidth, blockHeight], _success: true },
          { size: [1, 1, 1], _success: false },
          { size: [blockWidth, blockHeight, 1], _success: true },
        ];
      })
  )
  .fn(t => {
    const { dimension, format, size, _success } = t.params;
    t.skipIfTextureFormatNotSupported(format);
    t.skipIfTextureFormatAndDimensionNotCompatible(format, dimension);

    const descriptor: GPUTextureDescriptor = {
      size,
      dimension,
      format,
      usage: GPUTextureUsage.TEXTURE_BINDING,
    };

    t.expectValidationError(() => {
      t.createTextureTracked(descriptor);
    }, !_success);
  });

g.test('texture_size,1d_texture')
  .desc(`Test texture size requirement for 1D texture`)
  .params(u =>
    u //
      // Compressed and depth-stencil textures are invalid for 1D.
      .combine('format', kRegularTextureFormats)
      .beginSubcases()
      .combine('widthVariant', [
        { mult: 1, add: -1 },
        { mult: 1, add: 0 },
        { mult: 1, add: 1 },
      ])
      .combine('height', [1, 2])
      .combine('depthOrArrayLayers', [1, 2])
  )
  .fn(t => {
    const { format, widthVariant, height, depthOrArrayLayers } = t.params;
    t.skipIfTextureFormatNotSupported(format);
    const width = t.makeLimitVariant('maxTextureDimension1D', widthVariant);

    const descriptor: GPUTextureDescriptor = {
      size: [width, height, depthOrArrayLayers],
      dimension: '1d' as const,
      format,
      usage: GPUTextureUsage.TEXTURE_BINDING,
    };

    const success =
      width <= t.device.limits.maxTextureDimension1D && height === 1 && depthOrArrayLayers === 1;

    t.expectValidationError(() => {
      t.createTextureTracked(descriptor);
    }, !success);
  });

g.test('texture_size,2d_texture,uncompressed_format')
  .desc(`Test texture size requirement for 2D texture with uncompressed format.`)
  .params(u =>
    u
      .combine('dimension', [undefined, '2d'] as const)
      .combine('format', kUncompressedTextureFormats)
      .combine(
        'sizeVariant',
        /* prettier-ignore */ [
          // Test the bound of width
          [{ mult: 1, add: -1 }, { mult: 0, add:  1 }, { mult: 0, add:  1 }],
          [{ mult: 1, add:  0 }, { mult: 0, add:  1 }, { mult: 0, add:  1 }],
          [{ mult: 1, add:  1 }, { mult: 0, add:  1 }, { mult: 0, add:  1 }],
          // Test the bound of height
          [{ mult: 0, add:  1 }, { mult: 1, add: -1 }, { mult: 0, add:  1 }],
          [{ mult: 0, add:  1 }, { mult: 1, add:  0 }, { mult: 0, add:  1 }],
          [{ mult: 0, add:  1 }, { mult: 1, add:  1 }, { mult: 0, add:  1 }],
          // Test the bound of array layers
          [{ mult: 0, add:  1 }, { mult: 0, add:  1 }, { mult: 1, add: -1 }],
          [{ mult: 0, add:  1 }, { mult: 0, add:  1 }, { mult: 1, add:  0 }],
          [{ mult: 0, add:  1 }, { mult: 0, add:  1 }, { mult: 1, add:  1 }],
        ]
      )
  )
  .fn(t => {
    const { dimension, format, sizeVariant } = t.params;
    t.skipIfTextureFormatNotSupported(format);
    const size = [
      t.device.limits.maxTextureDimension2D,
      t.device.limits.maxTextureDimension2D,
      t.device.limits.maxTextureArrayLayers,
    ].map((limit, ndx) => makeValueTestVariant(limit, sizeVariant[ndx]));

    const descriptor: GPUTextureDescriptor = {
      size,
      dimension,
      format,
      usage: GPUTextureUsage.TEXTURE_BINDING,
    };

    const success =
      size[0] <= t.device.limits.maxTextureDimension2D &&
      size[1] <= t.device.limits.maxTextureDimension2D &&
      size[2] <= t.device.limits.maxTextureArrayLayers;

    t.expectValidationError(() => {
      t.createTextureTracked(descriptor);
    }, !success);
  });

g.test('texture_size,2d_texture,compressed_format')
  .desc(`Test texture size requirement for 2D texture with compressed format.`)
  .params(u =>
    u
      .combine('dimension', [undefined, '2d'] as const)
      .combine('format', kCompressedTextureFormats)
      .beginSubcases()
      .expand('sizeVariant', p => {
        const { blockWidth, blockHeight } = getBlockInfoForTextureFormat(p.format);
        return [
          // Test the bound of width
          [
            { mult: 1, add: -1 },
            { mult: 0, add: 1 },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 1, add: -blockWidth },
            { mult: 0, add: 1 },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 1, add: -blockWidth },
            { mult: 0, add: blockHeight },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 1, add: 0 },
            { mult: 0, add: 1 },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 1, add: 0 },
            { mult: 0, add: blockHeight },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 1, add: 1 },
            { mult: 0, add: 1 },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 1, add: blockWidth },
            { mult: 0, add: 1 },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 1, add: blockWidth },
            { mult: 0, add: blockHeight },
            { mult: 0, add: 1 },
          ],
          // Test the bound of height
          [
            { mult: 0, add: 1 },
            { mult: 1, add: -1 },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 0, add: 1 },
            { mult: 1, add: -blockHeight },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 0, add: blockWidth },
            { mult: 1, add: -blockHeight },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 0, add: 1 },
            { mult: 1, add: 0 },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 0, add: blockWidth },
            { mult: 1, add: 0 },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 0, add: 1 },
            { mult: 1, add: +1 },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 0, add: 1 },
            { mult: 1, add: +blockWidth },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 0, add: blockWidth },
            { mult: 1, add: +blockHeight },
            { mult: 0, add: 1 },
          ],
          // Test the bound of array layers
          [
            { mult: 0, add: 1 },
            { mult: 0, add: 1 },
            { mult: 1, add: -1 },
          ],
          [
            { mult: 0, add: blockWidth },
            { mult: 0, add: 1 },
            { mult: 1, add: -1 },
          ],
          [
            { mult: 0, add: 1 },
            { mult: 0, add: blockHeight },
            { mult: 1, add: -1 },
          ],
          [
            { mult: 0, add: blockWidth },
            { mult: 0, add: blockHeight },
            { mult: 1, add: -1 },
          ],
          [
            { mult: 0, add: 1 },
            { mult: 0, add: 1 },
            { mult: 1, add: 0 },
          ],
          [
            { mult: 0, add: blockWidth },
            { mult: 0, add: 1 },
            { mult: 1, add: 0 },
          ],
          [
            { mult: 0, add: 1 },
            { mult: 0, add: blockHeight },
            { mult: 1, add: 0 },
          ],
          [
            { mult: 0, add: blockWidth },
            { mult: 0, add: blockHeight },
            { mult: 1, add: 0 },
          ],
          [
            { mult: 0, add: 1 },
            { mult: 0, add: 1 },
            { mult: 1, add: +1 },
          ],
          [
            { mult: 0, add: blockWidth },
            { mult: 0, add: 1 },
            { mult: 1, add: +1 },
          ],
          [
            { mult: 0, add: 1 },
            { mult: 0, add: blockHeight },
            { mult: 1, add: +1 },
          ],
          [
            { mult: 0, add: blockWidth },
            { mult: 0, add: blockHeight },
            { mult: 1, add: +1 },
          ],
        ];
      })
  )
  .fn(t => {
    const { dimension, format, sizeVariant } = t.params;
    t.skipIfTextureFormatNotSupported(format);
    const info = getBlockInfoForTextureFormat(format);
    const size = getMaxValidTextureSizeForFormatAndDimension(t.device, format, '2d').map(
      (limit, ndx) => makeValueTestVariant(limit, sizeVariant[ndx])
    );

    const descriptor: GPUTextureDescriptor = {
      size,
      dimension,
      format,
      usage: GPUTextureUsage.TEXTURE_BINDING,
    };

    const success =
      size[0] % info.blockWidth === 0 &&
      size[1] % info.blockHeight === 0 &&
      size[0] <= t.device.limits.maxTextureDimension2D &&
      size[1] <= t.device.limits.maxTextureDimension2D &&
      size[2] <= t.device.limits.maxTextureArrayLayers;

    t.expectValidationError(() => {
      t.createTextureTracked(descriptor);
    }, !success);
  });

g.test('texture_size,3d_texture,uncompressed_format')
  .desc(
    `Test texture size requirement for 3D texture with uncompressed format. Note that depth/stencil formats are invalid for 3D textures, so we only test regular formats.`
  )
  .params(u =>
    u //
      .combine('format', kRegularTextureFormats)
      .beginSubcases()
      .combine(
        'sizeVariant',
        /* prettier-ignore */ [
          // Test the bound of width
          [{ mult: 1, add: -1 }, { mult: 0, add:  1 }, { mult: 0, add:  1 }],
          [{ mult: 1, add:  0 }, { mult: 0, add:  1 }, { mult: 0, add:  1 }],
          [{ mult: 1, add: +1 }, { mult: 0, add:  1 }, { mult: 0, add:  1 }],
          // Test the bound of height
          [{ mult: 0, add:  1 }, { mult: 1, add: -1 }, { mult: 0, add:  1 }],
          [{ mult: 0, add:  1 }, { mult: 1, add:  0 }, { mult: 0, add:  1 }],
          [{ mult: 0, add:  1 }, { mult: 1, add: +1 }, { mult: 0, add:  1 }],
          // Test the bound of depth
          [{ mult: 0, add:  1 }, { mult: 0, add:  1 }, { mult: 1, add: -1 }],
          [{ mult: 0, add:  1 }, { mult: 0, add:  1 }, { mult: 1, add:  0 }],
          [{ mult: 0, add:  1 }, { mult: 0, add:  1 }, { mult: 1, add: +1 }],
        ]
      )
  )
  .fn(t => {
    const { format, sizeVariant } = t.params;
    t.skipIfTextureFormatNotSupported(format);
    t.skipIfTextureFormatAndDimensionNotCompatible(format, '3d');
    const maxTextureDimension3D = t.device.limits.maxTextureDimension3D;
    const size = sizeVariant.map(variant => t.makeLimitVariant('maxTextureDimension3D', variant));

    const descriptor: GPUTextureDescriptor = {
      size,
      dimension: '3d' as const,
      format,
      usage: GPUTextureUsage.TEXTURE_BINDING,
    };

    const success =
      size[0] <= maxTextureDimension3D &&
      size[1] <= maxTextureDimension3D &&
      size[2] <= maxTextureDimension3D;

    t.expectValidationError(() => {
      t.createTextureTracked(descriptor);
    }, !success);
  });

g.test('texture_size,3d_texture,compressed_format')
  .desc(`Test texture size requirement for 3D texture with compressed format.`)
  .params(u =>
    u //
      .combine('format', kCompressedTextureFormats)
      .beginSubcases()
      .expand('sizeVariant', p => {
        const { blockWidth, blockHeight } = getBlockInfoForTextureFormat(p.format);
        return [
          // Test the bound of width
          [
            { mult: 1, add: -1 },
            { mult: 0, add: 1 },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 1, add: -blockWidth },
            { mult: 0, add: 1 },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 1, add: -blockWidth },
            { mult: 0, add: blockHeight },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 1, add: 0 },
            { mult: 0, add: 1 },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 1, add: 0 },
            { mult: 0, add: blockHeight },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 1, add: +1 },
            { mult: 0, add: 1 },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 1, add: +blockWidth },
            { mult: 0, add: 1 },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 1, add: +blockWidth },
            { mult: 0, add: blockHeight },
            { mult: 0, add: 1 },
          ],
          // Test the bound of height
          [
            { mult: 0, add: 1 },
            { mult: 1, add: -1 },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 0, add: 1 },
            { mult: 1, add: -blockHeight },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 0, add: blockWidth },
            { mult: 1, add: -blockHeight },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 0, add: 1 },
            { mult: 1, add: 0 },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 0, add: blockWidth },
            { mult: 1, add: 0 },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 0, add: 1 },
            { mult: 1, add: +1 },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 0, add: 1 },
            { mult: 1, add: +blockWidth },
            { mult: 0, add: 1 },
          ],
          [
            { mult: 0, add: blockWidth },
            { mult: 1, add: +blockHeight },
            { mult: 0, add: 1 },
          ],
          // Test the bound of depth
          [
            { mult: 0, add: 1 },
            { mult: 0, add: 1 },
            { mult: 1, add: -1 },
          ],
          [
            { mult: 0, add: blockWidth },
            { mult: 0, add: 1 },
            { mult: 1, add: -1 },
          ],
          [
            { mult: 0, add: 1 },
            { mult: 0, add: blockHeight },
            { mult: 1, add: -1 },
          ],
          [
            { mult: 0, add: blockWidth },
            { mult: 0, add: blockHeight },
            { mult: 1, add: -1 },
          ],
          [
            { mult: 0, add: 1 },
            { mult: 0, add: 1 },
            { mult: 1, add: 0 },
          ],
          [
            { mult: 0, add: blockWidth },
            { mult: 0, add: 1 },
            { mult: 1, add: 0 },
          ],
          [
            { mult: 0, add: 1 },
            { mult: 0, add: blockHeight },
            { mult: 1, add: 0 },
          ],
          [
            { mult: 0, add: blockWidth },
            { mult: 0, add: blockHeight },
            { mult: 1, add: 0 },
          ],
          [
            { mult: 0, add: 1 },
            { mult: 0, add: 1 },
            { mult: 1, add: +1 },
          ],
          [
            { mult: 0, add: blockWidth },
            { mult: 0, add: 1 },
            { mult: 1, add: +1 },
          ],
          [
            { mult: 0, add: 1 },
            { mult: 0, add: blockHeight },
            { mult: 1, add: +1 },
          ],
          [
            { mult: 0, add: blockWidth },
            { mult: 0, add: blockHeight },
            { mult: 1, add: +1 },
          ],
        ];
      })
  )
  .fn(t => {
    const { format, sizeVariant } = t.params;
    t.skipIfTextureFormatNotSupported(format);
    t.skipIfTextureFormatAndDimensionNotCompatible(format, '3d');
    const maxTextureDimension3D = t.device.limits.maxTextureDimension3D;
    const info = getBlockInfoForTextureFormat(format);
    const size = getMaxValidTextureSizeForFormatAndDimension(t.device, format, '3d').map(
      (limit, ndx) => makeValueTestVariant(limit, sizeVariant[ndx])
    );

    const descriptor: GPUTextureDescriptor = {
      size,
      dimension: '3d' as const,
      format,
      usage: GPUTextureUsage.TEXTURE_BINDING,
    };

    const success =
      size[0] % info.blockWidth === 0 &&
      size[1] % info.blockHeight === 0 &&
      size[0] <= maxTextureDimension3D &&
      size[1] <= maxTextureDimension3D &&
      size[2] <= maxTextureDimension3D &&
      textureDimensionAndFormatCompatibleForDevice(t.device.features, '3d', format);

    t.expectValidationError(() => {
      t.createTextureTracked(descriptor);
    }, !success);
  });

g.test('texture_usage')
  .desc(
    `Test texture usage (single usage or combined usages) for every texture format and every dimension type`
  )
  .params(u =>
    u
      .combine('dimension', [undefined, ...kTextureDimensions])
      .combine('format', kAllTextureFormats)
      .beginSubcases()
      // If usage0 and usage1 are the same, then the usage being test is a single usage. Otherwise, it is a combined usage.
      .combine('usage0', kTextureUsages)
      .combine('usage1', kTextureUsages)
      // Filter out incompatible dimension type and format combinations.
      .filter(({ dimension, format }) =>
        textureFormatAndDimensionPossiblyCompatible(dimension, format)
      )
      .unless(({ usage0, usage1 }) => {
        return !isValidTextureUsageCombination(usage0 | usage1);
      })
  )
  .fn(t => {
    const { dimension, format, usage0, usage1 } = t.params;
    t.skipIfTextureFormatNotSupported(format);
    t.skipIfTextureFormatAndDimensionNotCompatible(format, dimension);
    const info = getBlockInfoForTextureFormat(format);

    const size = [info.blockWidth, info.blockHeight, 1];
    const usage = usage0 | usage1;
    const descriptor = {
      size,
      dimension,
      format,
      usage,
    };

    // MAINTENANCE_TODO(#4509): Remove this when TRANSIENT_ATTACHMENT is added to the WebGPU spec.
    if ((usage & GPUConst.TextureUsage.TRANSIENT_ATTACHMENT) !== 0) {
      t.skipIfTransientAttachmentNotSupported();
    }

    let success = true;
    const appliedDimension = dimension ?? '2d';
    // Note that we unconditionally test copy usages for all formats and
    // expect failure if copying from or to is not supported.
    if (usage & GPUTextureUsage.STORAGE_BINDING) {
      if (!isTextureFormatUsableWithStorageAccessMode(t.device.features, format, 'write-only'))
        success = false;
    }
    if (usage & GPUTextureUsage.RENDER_ATTACHMENT) {
      if (appliedDimension === '1d') success = false;
      if (
        isColorTextureFormat(format) &&
        !isTextureFormatColorRenderable(t.device.features, format)
      )
        success = false;
    }
    if (usage & GPUTextureUsage.TRANSIENT_ATTACHMENT) {
      if (appliedDimension !== '2d') success = false;
    }

    t.expectValidationError(() => {
      t.createTextureTracked(descriptor);
    }, !success);
  });

g.test('depthOrArrayLayers_and_mipLevelCount_for_transient_attachments')
  .desc(`Test depthOrArrayLayers and mipLevelCount must be 1 for transient attachments`)
  .params(u =>
    u
      .combine('format', ['rgba8unorm', 'depth24plus'] as const)
      .beginSubcases()
      .combine('depthOrArrayLayers', [1, 2])
      .combine('mipLevelCount', [1, 2])
  )
  .fn(t => {
    // MAINTENANCE_TODO(#4509): Remove this when TRANSIENT_ATTACHMENT is added to the WebGPU spec.
    t.skipIfTransientAttachmentNotSupported();

    const { format, depthOrArrayLayers, mipLevelCount } = t.params;

    const info = getBlockInfoForTextureFormat(format);
    const size = [info.blockWidth, info.blockHeight, depthOrArrayLayers];
    const descriptor = {
      size,
      mipLevelCount,
      format,
      usage: GPUConst.TextureUsage.RENDER_ATTACHMENT | GPUConst.TextureUsage.TRANSIENT_ATTACHMENT,
    };

    let success = true;
    if (depthOrArrayLayers !== 1) success = false;
    if (mipLevelCount !== 1) success = false;

    t.expectValidationError(() => {
      t.createTextureTracked(descriptor);
    }, !success);
  });

g.test('viewFormats')
  .desc(
    `Test creating a texture with viewFormats list for all {texture format}x{view format}. Only compatible view formats should be valid.`
  )
  .params(u =>
    u
      .combine('formatFeature', kFeaturesForFormats)
      .combine('viewFormatFeature', kFeaturesForFormats)
      .beginSubcases()
      .expand('format', ({ formatFeature }) =>
        filterFormatsByFeature(formatFeature, kAllTextureFormats)
      )
      .expand('viewFormat', ({ viewFormatFeature }) =>
        filterFormatsByFeature(viewFormatFeature, kAllTextureFormats)
      )
  )
  .fn(t => {
    const { format, viewFormat } = t.params;
    t.skipIfTextureFormatNotSupported(format, viewFormat);

    const { blockWidth, blockHeight } = getBlockInfoForTextureFormat(format);
    const compatible = textureFormatsAreViewCompatible(t.device.features, format, viewFormat);

    // Test the viewFormat in the list.
    t.expectValidationError(() => {
      t.createTextureTracked({
        format,
        size: [blockWidth, blockHeight],
        usage: GPUTextureUsage.TEXTURE_BINDING,
        viewFormats: [viewFormat],
      });
    }, !compatible);

    // Test the viewFormat and the texture format in the list.
    t.expectValidationError(() => {
      t.createTextureTracked({
        format,
        size: [blockWidth, blockHeight],
        usage: GPUTextureUsage.TEXTURE_BINDING,
        viewFormats: [viewFormat, format],
      });
    }, !compatible);

    // Test the viewFormat multiple times in the list.
    t.expectValidationError(() => {
      t.createTextureTracked({
        format,
        size: [blockWidth, blockHeight],
        usage: GPUTextureUsage.TEXTURE_BINDING,
        viewFormats: [viewFormat, viewFormat],
      });
    }, !compatible);
  });
