1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96

content / test / data / gpu / webgpu-domain-unblocking.html [blame]

<script type="text/javascript">

function reportProgress(msg) {
  if (window.domAutomationController) {
    window.domAutomationController.send(msg);
  }
  console.log(msg);
}

// These must be "var" rather than "let" for the Telemetry harness to
// see them.
var gotDevice;
var deviceLost;
var proceed;

const later = (delay) =>
  new Promise(resolve => setTimeout(resolve, delay));

async function init() {
  reportProgress('LOADED');

  // This bakes in knowledge that GpuDataManagerImplPrivate blocks
  // WebGPU from fetching an adapter after two device losses on the
  // same domain.

  for (idx = 0; idx < 2; ++idx) {
    proceed = false;
    const adapter = await navigator.gpu.requestAdapter();
    if (!adapter) {
      reportProgress('FAILED');
      console.log('TEST FAILED - Could not get a GPUAdapter on iteration ' + idx);
      return null;
    }

    console.log('Iteration ' + idx + ': got adapter');

    let device;
    try {
      device = await adapter.requestDevice();
      gotDevice = true;
      deviceLost = false;
    } catch {
      reportProgress('FAILED');
      console.log('TEST FAILED - Could not get a GPUDevice on iteration ' + idx);
      return null;
    }

    console.log('Iteration ' + idx + ': got device');

    // The test runner forces the GPU process to crash. The second time,
    // this should result in the domain being blocked.
    console.log('Iteration ' + idx + ': Waiting for GPU crash to cause device loss');
    const lost = await device.lost;
    if (lost.reason !== 'unknown') {
      console.log('TEST FAILED - Expected device lost reason "unknown"');
      reportProgress('FAILED');
      return;
    }
    gotDevice = false;
    deviceLost = true;

    console.log('Iteration ' + idx + ': lost device');

    try {
      // First check that the previously acquired adapter can't get another device.
      // This should throw an exception.
      await adapter.requestDevice();
      reportProgress('FAILED');
      console.log('TEST FAILED - WebGPU device request should have failed on ' +
                  'stale GPUAdapter');
    } catch {
      console.log('Iteration ' + idx + ': Device request failed as expected');
    }

    // The second time, also check that we can't get another adapter.
    if (idx == 1) {
      const newAdapter = await navigator.gpu.requestAdapter();
      if (newAdapter !== null) {
        reportProgress('FAILED');
        console.log(
          'TEST FAILED - WebGPU adapter request should have been blocked');
      } else {
        console.log('Adapter request failed as expected');
        reportProgress('SUCCESS');
      }
    }

    // The harness will tell us when to proceed to the second iteration.
    while (!proceed) {
      await later(100);
    }
  }
}

init();
</script>