* @brief Factory function to create a GPU context, which aggregates WebGPU API * handles to interact with the GPU including the instance, adapter, device, and * queue. * * The function takes gpu index to support for multi GPUs. * To activate this function, it needs not only webgpu's headers but also DAWN's headers. * * If dawn is used, it also sets up an error callback for device loss. *
| 886 | * @endcode |
| 887 | */ |
| 888 | inline Context createContextByGpuIdx(int gpuIdx, |
| 889 | const WGPUInstanceDescriptor &desc = {}, |
| 890 | const WGPUDeviceDescriptor &devDescriptor = {}) { |
| 891 | Context context; |
| 892 | { |
| 893 | #ifdef __EMSCRIPTEN__ |
| 894 | // Emscripten does not support the instance descriptor |
| 895 | // and throws an assertion error if it is not nullptr. |
| 896 | context.instance = wgpuCreateInstance(nullptr); |
| 897 | #else |
| 898 | context.instance = wgpuCreateInstance(&desc); |
| 899 | #endif |
| 900 | // check status |
| 901 | check(context.instance, "Initialize WebGPU", __FILE__, __LINE__); |
| 902 | } |
| 903 | |
| 904 | LOG(kDefLog, kInfo, "Requesting adapter"); |
| 905 | { |
| 906 | std::vector<dawn::native::Adapter> adapters = |
| 907 | dawn::native::Instance(reinterpret_cast<dawn::native::InstanceBase*>(context.instance)) |
| 908 | .EnumerateAdapters(); |
| 909 | LOG(kDefLog, kInfo, "The number of GPUs=%d\n", adapters.size()); |
| 910 | // Note: Second gpu is not available on Macos, but the number of GPUs is 2 on Macos. |
| 911 | // Calling wgpuAdapterGetInfo function for the second gpu becomes segfault. |
| 912 | // When you check all GPUs on linux, uncomment out following codes. |
| 913 | // |
| 914 | // for (size_t i = 0; i < adapters.size(); i++) { |
| 915 | // WGPUAdapterInfo info {}; |
| 916 | // auto ptr = adapters[i].Get(); |
| 917 | // if (ptr && adapters[i]) { |
| 918 | // wgpuAdapterGetInfo(ptr, &info); |
| 919 | // LOG(kDefLog, kInfo, "GPU(Adapter)[%d] = %s\n", i, info.description); |
| 920 | // wgpuAdapterInfoFreeMembers(info); |
| 921 | // } |
| 922 | // } |
| 923 | |
| 924 | { |
| 925 | LOG(kDefLog, kInfo, "Use GPU(Adapter)[%d]\n", gpuIdx); |
| 926 | auto ptr = adapters[gpuIdx].Get(); |
| 927 | if (ptr) { |
| 928 | WGPUAdapterInfo info {}; |
| 929 | wgpuAdapterGetInfo(ptr, &info); |
| 930 | LOG(kDefLog, kInfo, "GPU(Adapter)[%d] = %s\n", gpuIdx, info.description); |
| 931 | wgpuAdapterInfoFreeMembers(info); |
| 932 | } |
| 933 | context.adapter = adapters[gpuIdx].Get(); |
| 934 | dawn::native::GetProcs().adapterAddRef(context.adapter); |
| 935 | } |
| 936 | } |
| 937 | |
| 938 | LOG(kDefLog, kInfo, "Requesting device"); |
| 939 | { |
| 940 | struct DeviceData { |
| 941 | WGPUDevice device = nullptr; |
| 942 | bool requestEnded = false; |
| 943 | }; |
| 944 | DeviceData devData; |
| 945 | auto onDeviceRequestEnded = [](WGPURequestDeviceStatus status, |
nothing calls this directly
no test coverage detected