summaryrefslogtreecommitdiff
path: root/src/tests/webgpu_test_fixture.cc
blob: 750dea0bb5b74fbfa750f94ebbcf69cae3228c22 (plain)
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// This file is part of the 64k demo project.
// It implements shared WebGPU initialization for GPU tests.
// Provides graceful fallback if GPU unavailable.

#if !defined(STRIP_ALL)  // Test code only - zero size impact on final binary

#include "webgpu_test_fixture.h"
#include <cstdio>
#include <cstdlib>

WebGPUTestFixture::WebGPUTestFixture() {
}

WebGPUTestFixture::~WebGPUTestFixture() {
  shutdown();
}

bool WebGPUTestFixture::init() {
  // Create instance
  const WGPUInstanceDescriptor instance_desc = {};
  instance_ = wgpuCreateInstance(&instance_desc);
  if (!instance_) {
    fprintf(stderr,
            "WebGPU not available (wgpuCreateInstance failed) - skipping GPU "
            "test\n");
    return false;
  }

  // Request adapter (API differs between Win32 and native)
  WGPUAdapter adapter = nullptr;
  const WGPURequestAdapterOptions adapter_opts = {
      .compatibleSurface = nullptr,
      .powerPreference = WGPUPowerPreference_HighPerformance,
  };

#if defined(DEMO_CROSS_COMPILE_WIN32)
  // Win32: Old callback API (function pointer + userdata)
  auto on_adapter = [](WGPURequestAdapterStatus status, WGPUAdapter a,
                       const char* message, void* userdata) {
    if (status == WGPURequestAdapterStatus_Success) {
      *(WGPUAdapter*)userdata = a;
    } else if (message) {
      fprintf(stderr, "Adapter request failed: %s\n", message);
    }
  };
  wgpuInstanceRequestAdapter(instance_, &adapter_opts, on_adapter, &adapter);
#else
  // Native: New callback info API
  auto on_adapter = [](WGPURequestAdapterStatus status, WGPUAdapter a,
                       WGPUStringView message, void* userdata, void* user2) {
    (void)user2;
    (void)message;
    if (status == WGPURequestAdapterStatus_Success) {
      *(WGPUAdapter*)userdata = a;
    }
  };
  WGPURequestAdapterCallbackInfo adapter_cb = {};
  adapter_cb.mode = WGPUCallbackMode_WaitAnyOnly;
  adapter_cb.callback = on_adapter;
  adapter_cb.userdata1 = &adapter;
  wgpuInstanceRequestAdapter(instance_, &adapter_opts, adapter_cb);
#endif

  // Wait for adapter callback
  for (int i = 0; i < 100 && !adapter; ++i) {
    wgpuInstanceProcessEvents(instance_);
  }

  if (!adapter) {
    fprintf(stderr, "No WebGPU adapter available - skipping GPU test\n");
    shutdown();
    return false;
  }

  adapter_ = adapter;

  // Request device (API differs between Win32 and native)
  WGPUDevice device = nullptr;
  const WGPUDeviceDescriptor device_desc = {};

#if defined(DEMO_CROSS_COMPILE_WIN32)
  // Win32: Old callback API
  auto on_device = [](WGPURequestDeviceStatus status, WGPUDevice d,
                      const char* message, void* userdata) {
    if (status == WGPURequestDeviceStatus_Success) {
      *(WGPUDevice*)userdata = d;
    } else if (message) {
      fprintf(stderr, "Device request failed: %s\n", message);
    }
  };
  wgpuAdapterRequestDevice(adapter_, &device_desc, on_device, &device);
#else
  // Native: New callback info API
  auto on_device = [](WGPURequestDeviceStatus status, WGPUDevice d,
                      WGPUStringView message, void* userdata, void* user2) {
    (void)user2;
    (void)message;
    if (status == WGPURequestDeviceStatus_Success) {
      *(WGPUDevice*)userdata = d;
    }
  };
  WGPURequestDeviceCallbackInfo device_cb = {};
  device_cb.mode = WGPUCallbackMode_WaitAnyOnly;
  device_cb.callback = on_device;
  device_cb.userdata1 = &device;
  wgpuAdapterRequestDevice(adapter_, &device_desc, device_cb);
#endif

  // Wait for device callback
  for (int i = 0; i < 100 && !device; ++i) {
    wgpuInstanceProcessEvents(instance_);
  }

  if (!device) {
    fprintf(stderr, "Failed to create WebGPU device - skipping GPU test\n");
    shutdown();
    return false;
  }

  device_ = device;
  queue_ = wgpuDeviceGetQueue(device_);

  return true;
}

void WebGPUTestFixture::shutdown() {
  if (queue_) {
    wgpuQueueRelease(queue_);
    queue_ = nullptr;
  }
  if (device_) {
    wgpuDeviceRelease(device_);
    device_ = nullptr;
  }
  if (adapter_) {
    wgpuAdapterRelease(adapter_);
    adapter_ = nullptr;
  }
  if (instance_) {
    wgpuInstanceRelease(instance_);
    instance_ = nullptr;
  }
}

#endif  /* !defined(STRIP_ALL) */