|
2 | 2 |
|
3 | 3 | #include <algorithm> |
4 | 4 | #include <cstdio> |
| 5 | +#include <cstring> |
5 | 6 | #include <memory> |
6 | 7 | #include <string> |
7 | 8 | #include <unordered_set> |
8 | 9 | #include <utility> |
9 | 10 | #include <vector> |
10 | 11 |
|
| 12 | +#ifdef __APPLE__ |
| 13 | +#include <TargetConditionals.h> |
| 14 | +#endif |
| 15 | + |
11 | 16 | #include "Convertors.h" |
12 | 17 |
|
13 | 18 | #include "GPUFeatures.h" |
@@ -150,16 +155,39 @@ async::AsyncTaskHandle GPUAdapter::requestDevice( |
150 | 155 | for (const auto &t : dawnToggles->enabledToggles.value()) { |
151 | 156 | enabledToggles.push_back(t.c_str()); |
152 | 157 | } |
153 | | - toggles.enabledToggleCount = enabledToggles.size(); |
154 | | - toggles.enabledToggles = enabledToggles.data(); |
155 | 158 | } |
156 | 159 | if (dawnToggles->disabledToggles) { |
157 | 160 | for (const auto &t : dawnToggles->disabledToggles.value()) { |
158 | 161 | disabledToggles.push_back(t.c_str()); |
159 | 162 | } |
160 | | - toggles.disabledToggleCount = disabledToggles.size(); |
161 | | - toggles.disabledToggles = disabledToggles.data(); |
162 | 163 | } |
| 164 | + } |
| 165 | +#if defined(TARGET_OS_SIMULATOR) && TARGET_OS_SIMULATOR |
| 166 | + // The iOS Simulator only advertises MTLFeatureSet_iOS_GPUFamily2, so |
| 167 | + // Dawn defaults disable_base_instance/disable_base_vertex on and then |
| 168 | + // rejects every draw with a non-zero firstInstance or baseVertex, |
| 169 | + // both core WebGPU. The simulator forwards Metal calls to the host |
| 170 | + // GPU, which does support base vertex/instance drawing, so force the |
| 171 | + // toggles off. Device builds are unaffected: WebGPU-capable iPhones |
| 172 | + // and iPads are all GPUFamily3+. These are device-stage toggles, so |
| 173 | + // they must be chained here rather than on the instance descriptor |
| 174 | + // (instance-stage toggle parsing silently drops them). |
| 175 | + static const char *const kSimulatorDisabledToggles[] = { |
| 176 | + "disable_base_instance", "disable_base_vertex"}; |
| 177 | + for (const char *name : kSimulatorDisabledToggles) { |
| 178 | + const bool explicitlyEnabled = std::any_of( |
| 179 | + enabledToggles.begin(), enabledToggles.end(), |
| 180 | + [name](const char *t) { return std::strcmp(t, name) == 0; }); |
| 181 | + if (!explicitlyEnabled) { |
| 182 | + disabledToggles.push_back(name); |
| 183 | + } |
| 184 | + } |
| 185 | +#endif |
| 186 | + if (!enabledToggles.empty() || !disabledToggles.empty()) { |
| 187 | + toggles.enabledToggleCount = enabledToggles.size(); |
| 188 | + toggles.enabledToggles = enabledToggles.data(); |
| 189 | + toggles.disabledToggleCount = disabledToggles.size(); |
| 190 | + toggles.disabledToggles = disabledToggles.data(); |
163 | 191 | deviceDesc.nextInChain = &toggles; |
164 | 192 | } |
165 | 193 | _instance.RequestDevice( |
|
0 commit comments