| 74 | } |
| 75 | |
| 76 | int main() { |
| 77 | |
| 78 | static constexpr size_t N = 3072; |
| 79 | |
| 80 | // Host data - input and output arrays on the CPU |
| 81 | std::array<float, N> inputArr; |
| 82 | std::array<float, N> outputArr; |
| 83 | for (size_t i = 0; i < N; i++) { |
| 84 | // Populate input array with a range of dummy values |
| 85 | inputArr[i] = static_cast<float>(i); |
| 86 | } |
| 87 | |
| 88 | // API representations for interfacing with the GPU |
| 89 | WGPUInstance instance; // The instance is the top-level context object for |
| 90 | // WebGPU. It is used to create adapters. |
| 91 | WGPUAdapter adapter; // The adapter is the physical device that WebGPU uses |
| 92 | // to interface with the GPU. |
| 93 | WGPUDevice device; // The device is the logical device that WebGPU uses to |
| 94 | // interface with the adapter. |
| 95 | WGPUQueue queue; // The queue is used to submit work to the GPU. |
| 96 | |
| 97 | // Buffers - buffers are used to store data on the GPU. |
| 98 | WGPUBuffer inputBuffer; // The input buffer is used to store the input data. |
| 99 | WGPUBuffer outputBuffer; // The output buffer is used to store the output data. |
| 100 | WGPUBuffer readbackBuffer; // The readback buffer is used to copy the output |
| 101 | // data from the GPU back to the CPU. |
| 102 | WGPUCommandBuffer commandBuffer; // The command buffer is used to store the |
| 103 | // sequence of operations to be executed on |
| 104 | // the GPU. |
| 105 | |
| 106 | // Async management - polling the GPU is asynchronous, so we need to manage |
| 107 | // the async work. |
| 108 | std::promise<void> promise; // used to signal when the work is done. |
| 109 | std::future<void> future; // used to wait for the work to be done. |
| 110 | |
| 111 | // Here we initialize the instance, adapter, device, and queue. |
| 112 | spdlog::info("Setting up GPU Context"); |
| 113 | { |
| 114 | const WGPUInstanceDescriptor desc = {}; |
| 115 | WGPURequestAdapterOptions adapterOpts = {}; |
| 116 | WGPUDeviceDescriptor devDescriptor = {}; |
| 117 | spdlog::info("Creating instance"); |
| 118 | { |
| 119 | instance = wgpuCreateInstance(&desc); |
| 120 | check(instance, "Initialize WebGPU", __FILE__, __LINE__); |
| 121 | } |
| 122 | spdlog::info("Requesting adapter"); |
| 123 | { |
| 124 | struct AdapterData { |
| 125 | WGPUAdapter adapter = nullptr; |
| 126 | bool requestEnded = false; |
| 127 | }; |
| 128 | AdapterData adapterData; |
| 129 | auto onAdapterRequestEnded = [](WGPURequestAdapterStatus status, |
| 130 | WGPUAdapter adapter, char const *message, |
| 131 | void *pUserData) { |
| 132 | AdapterData &adapterData = *reinterpret_cast<AdapterData *>(pUserData); |
| 133 | check(status == WGPURequestAdapterStatus_Success, |