export const description = `
Compute dispatch validation tests.
`;

import { AllFeaturesMaxLimitsGPUTest } from '../.././gpu_test.js';
import { makeTestGroup } from '../../../common/framework/test_group.js';

export const g = makeTestGroup(AllFeaturesMaxLimitsGPUTest);

g.test('dispatch,linear_indexing_range')
  .desc('Tests validation of total invocations for linear_indexing built-in values')
  .params(u =>
    u
      .combine('builtin', ['global_invocation_index', 'workgroup_index'] as const)
      .beginSubcases()
      .combine('size', ['max', 'valid'] as const)
  )
  .fn(t => {
    // Other builtins are not tested due to onerous runtimes.
    t.skipIf(!t.hasLanguageFeature('linear_indexing'), 'Missing linear_indexing language feature');

    // Spec limits:
    // - maxComputeWorkgroupsPerDimension = 65535
    const { maxComputeWorkgroupsPerDimension } = t.device.limits;
    const x = t.params.builtin === 'global_invocation_index' ? 2 : 1,
      y = 1,
      z = 1;
    const wgSize = x * y * z;
    const countX = maxComputeWorkgroupsPerDimension;
    const countY = t.params.size === 'max' ? maxComputeWorkgroupsPerDimension : 1;
    const countZ = t.params.builtin === 'workgroup_index' ? 2 : 1;

    const totalInvocations = wgSize * countX * countY * countZ;
    t.skipIf(t.params.size === 'max' && totalInvocations <= 0xffffffff, 'Uninteresting test');

    const code = `
@compute @workgroup_size(${x}, ${y}, ${z})
fn main(@builtin(${t.params.builtin}) input : u32) {
  _ = input;
}`;

    const shaderModule = t.device.createShaderModule({ code });
    const computePipeline = t.device.createComputePipeline({
      layout: 'auto',
      compute: {
        module: shaderModule,
      },
    });
    const commandEncoder = t.device.createCommandEncoder();
    const computePassEncoder = commandEncoder.beginComputePass();
    computePassEncoder.setPipeline(computePipeline);
    computePassEncoder.dispatchWorkgroups(countX, countY, countZ);
    computePassEncoder.end();

    t.expectValidationError(() => {
      commandEncoder.finish();
    }, t.params.size === 'max');
  });

g.test('dispatchIndirect,linear_indexing_range')
  .desc('Tests dispatchIndirect skips when linear_indexing is out of range')
  .params(u =>
    u
      .combine('builtin', ['global_invocation_index', 'workgroup_index'] as const)
      .beginSubcases()
      .combine('size', ['max', 'valid'] as const)
  )
  .fn(t => {
    // Other builtins are not tested due to onerous runtimes.
    t.skipIf(!t.hasLanguageFeature('linear_indexing'), 'Missing linear_indexing language feature');

    // Spec limits:
    // - maxComputeWorkgroupsPerDimension = 65535
    const { maxComputeWorkgroupsPerDimension } = t.device.limits;
    const x = t.params.builtin === 'global_invocation_index' ? 2 : 1,
      y = 1,
      z = 1;
    const wgSize = x * y * z;
    const countX = maxComputeWorkgroupsPerDimension;
    const countY = t.params.size === 'max' ? maxComputeWorkgroupsPerDimension : 1;
    const countZ = t.params.builtin === 'workgroup_index' ? 2 : 1;

    const totalInvocations = wgSize * countX * countY * countZ;
    t.skipIf(t.params.size === 'max' && totalInvocations <= 0xffffffff, 'Uninteresting test');

    const kMagic = 0xdeadbeef;
    const code = `
@group(0) @binding(0)
var<storage, read_write> out : u32;

@compute @workgroup_size(${x}, ${y}, ${z})
fn main(@builtin(${t.params.builtin}) input : u32,
        @builtin(global_invocation_id) gid : vec3u) {
  _ = input;
  if (gid.x == 0 && gid.y == 0 && gid.z == 0) {
    out = ${kMagic};
  }
}`;

    const dispatchIndirectCounts = new Uint32Array(3);
    dispatchIndirectCounts[0] = countX;
    dispatchIndirectCounts[1] = countY;
    dispatchIndirectCounts[2] = countZ;
    const indirectBuffer = t.makeBufferWithContents(
      dispatchIndirectCounts,
      GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST | GPUBufferUsage.INDIRECT
    );
    t.trackForCleanup(indirectBuffer);
    const outputBuffer = t.makeBufferWithContents(
      new Uint32Array([0]),
      GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST | GPUBufferUsage.STORAGE
    );
    t.trackForCleanup(outputBuffer);

    const shaderModule = t.device.createShaderModule({ code });
    const computePipeline = t.device.createComputePipeline({
      layout: 'auto',
      compute: {
        module: shaderModule,
      },
    });
    const bg = t.device.createBindGroup({
      layout: computePipeline.getBindGroupLayout(0),
      entries: [
        {
          binding: 0,
          resource: {
            buffer: outputBuffer,
          },
        },
      ],
    });
    const commandEncoder = t.device.createCommandEncoder();
    const computePassEncoder = commandEncoder.beginComputePass();
    computePassEncoder.setPipeline(computePipeline);
    computePassEncoder.setBindGroup(0, bg);
    computePassEncoder.dispatchWorkgroupsIndirect(indirectBuffer, 0);
    computePassEncoder.end();
    t.queue.submit([commandEncoder.finish()]);

    const expected = t.params.size === 'max' ? 0 : kMagic;
    t.expectGPUBufferValuesEqual(outputBuffer, new Uint32Array([expected]));
  });
