ensureContext()

in src/webgpu/api/operation/memory_sync/operation_context_helper.ts [183:277]


  ensureContext(context: OperationContext) {
    // Find the common ancestor. So we can transition from currentContext -> context.
    const ancestorContext =
      kOperationContexts[
        Math.min(
          kOperationContexts.indexOf(context),
          kOperationContexts.indexOf(this.currentContext)
        )
      ];

    // Pop the context until we're at the common ancestor.
    while (this.currentContext !== ancestorContext) {
      // About to pop the render pass encoder. Execute any outstanding render bundles.
      if (this.currentContext === 'render-pass-encoder') {
        this.flushRenderBundles();
      }

      const result = this.popContext();
      if (result) {
        if (result instanceof GPURenderBundle) {
          this.renderBundles.push(result);
        } else {
          this.commandBuffers.push(result);
        }
      }
    }

    if (this.currentContext === context) {
      return;
    }

    switch (context) {
      case 'queue':
        unreachable();
        break;
      case 'command-encoder':
        assert(this.currentContext === 'queue');
        this.commandEncoder = this.device.createCommandEncoder();
        break;
      case 'compute-pass-encoder':
        switch (this.currentContext) {
          case 'queue':
            this.commandEncoder = this.device.createCommandEncoder();
          // fallthrough
          case 'command-encoder':
            assert(this.commandEncoder !== undefined);
            this.computePassEncoder = this.commandEncoder.beginComputePass();
            break;
          case 'compute-pass-encoder':
          case 'render-bundle-encoder':
          case 'render-pass-encoder':
            unreachable();
        }
        break;
      case 'render-pass-encoder':
        switch (this.currentContext) {
          case 'queue':
            this.commandEncoder = this.device.createCommandEncoder();
          // fallthrough
          case 'command-encoder':
            assert(this.commandEncoder !== undefined);
            this.renderPassEncoder = this.commandEncoder.beginRenderPass({
              colorAttachments: [this.makeDummyAttachment()],
            });
            break;
          case 'render-pass-encoder':
          case 'render-bundle-encoder':
          case 'compute-pass-encoder':
            unreachable();
        }
        break;
      case 'render-bundle-encoder':
        switch (this.currentContext) {
          case 'queue':
            this.commandEncoder = this.device.createCommandEncoder();
          // fallthrough
          case 'command-encoder':
            assert(this.commandEncoder !== undefined);
            this.renderPassEncoder = this.commandEncoder.beginRenderPass({
              colorAttachments: [this.makeDummyAttachment()],
            });
          // fallthrough
          case 'render-pass-encoder':
            this.renderBundleEncoder = this.device.createRenderBundleEncoder({
              colorFormats: [this.kTextureFormat],
            });
            break;
          case 'render-bundle-encoder':
          case 'compute-pass-encoder':
            unreachable();
        }
        break;
    }
    this.currentContext = context;
  }