Skip to content

Commit bd12775

Browse files
committed
fix: support explicit Lavapipe selection and test GPU completion without application frames
1 parent 6e2dbf8 commit bd12775

3 files changed

Lines changed: 20 additions & 7 deletions

File tree

‎experiments/WebScene.NativeEngine.Probe/native/graphics/native_webgpu_device.h‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ struct native_webgpu_device {
1717
wgpu::Adapter adapter;
1818
wgpu::Device device;
1919
static native_webgpu_device create(wgpu::BackendType backend,
20-
std::vector<wgpu::FeatureName> features = {},
21-
bool force_software_adapter = false) {
20+
std::vector<wgpu::FeatureName> features = {}) {
2221
native_webgpu_device result;
2322
constexpr auto timed_wait = wgpu::InstanceFeatureName::TimedWaitAny;
2423
wgpu::InstanceDescriptor descriptor{};
@@ -34,7 +33,6 @@ struct native_webgpu_device {
3433
};
3534
wgpu::RequestAdapterOptions options{};
3635
options.backendType = backend;
37-
options.forceFallbackAdapter = force_software_adapter;
3836
auto future = result.instance.RequestAdapter(&options, wgpu::CallbackMode::WaitAnyOnly,
3937
[state, message](wgpu::RequestAdapterStatus status, wgpu::Adapter adapter, wgpu::StringView error) {
4038
if (status == wgpu::RequestAdapterStatus::Success) state->adapter = std::move(adapter);

‎experiments/WebScene.NativeEngine.Probe/native/graphics/native_webgpu_offscreen_surface.h‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,13 +150,19 @@ class native_webgpu_offscreen_surface final {
150150
#endif
151151
}
152152
static std::shared_ptr<native_webgpu_device> create_gpu() {
153+
// Dawn's forceFallbackAdapter currently recognizes only SwiftShader,
154+
// not other software Vulkan ICDs such as Mesa Lavapipe. The caller
155+
// selects its ICD; verify the returned adapter rather than mislabeling
156+
// a hardware/default adapter or silently rejecting a software driver.
153157
auto gpu=std::make_shared<native_webgpu_device>(
154-
native_webgpu_device::create(backend(),{},software_requested()));
158+
native_webgpu_device::create(backend()));
155159
wgpu::AdapterInfo info{};
156160
if(gpu->adapter.GetInfo(&info)!=wgpu::Status::Success)
157161
throw std::runtime_error("Cannot inspect offscreen GPU adapter");
158162
const bool hardware=info.adapterType==wgpu::AdapterType::DiscreteGPU ||
159163
info.adapterType==wgpu::AdapterType::IntegratedGPU;
164+
if(software_requested() && info.adapterType!=wgpu::AdapterType::CPU)
165+
throw std::runtime_error("Software GPU requested: select a CPU Vulkan ICD with VK_ICD_FILENAMES");
160166
if(!hardware && !software_requested())
161167
throw std::runtime_error("Software GPU requires WEBSCENE_HEADLESS_FORCE_SOFTWARE_ADAPTER=1");
162168
return gpu;

‎tests/SDKLinux/offscreen_gpu.cpp‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ int main() {
3838
wgpu::AdapterInfo info{};require(surface.adapter().GetInfo(&info)==wgpu::Status::Success,"adapter identity unavailable");
3939
hardware=info.adapterType==wgpu::AdapterType::DiscreteGPU || info.adapterType==wgpu::AdapterType::IntegratedGPU;
4040
require(info.backendType==wgpu::BackendType::Vulkan,"Linux test did not run Vulkan");
41+
// GPU completion must retire an abandoned snapshot while application
42+
// frames are paused. No ProcessEvents or render timer drives this wait.
43+
{
44+
auto abandoned=paint(surface,1,0,0);abandoned.reset();
45+
const auto deadline=std::chrono::steady_clock::now()+std::chrono::seconds(20);
46+
while(surface.busy_images() && std::chrono::steady_clock::now()<deadline)
47+
std::this_thread::sleep_for(std::chrono::milliseconds(1));
48+
require(surface.busy_images()==0,"hidden GPU completion did not retire dropped snapshot");
49+
}
4150
auto red=resolve(surface,paint(surface,1,0,0));
4251
auto green=resolve(surface,paint(surface,0,1,0));
4352
auto blue=resolve(surface,paint(surface,0,0,1));
@@ -52,7 +61,7 @@ int main() {
5261
require(resized->value.describe().allocation_generation>generation,"resize did not advance generation");
5362
require(resized->value.describe().width==65 && resized->value.describe().height==7,"resized metadata mismatch");
5463
pixel(capture_offscreen_image(*resized),0,255,0);
55-
pixel(capture_offscreen_image(*red),255,0,0); // old front image remains immutable across resize
64+
pixel(capture_offscreen_image(*red),255,0,0);
5665
require(surface.resident_bytes()<=64*1024,"resident allocation budget exceeded");
5766
bool wrong_thread=false;
5867
std::thread foreign([&]{try{surface.resize(2,2);}catch(const std::logic_error&){wrong_thread=true;}});foreign.join();
@@ -69,13 +78,13 @@ int main() {
6978
require(budget_rejected,"capture ignored byte budget");
7079
captures=surface.capture_count();allocations=surface.created_images();surviving=std::move(red);
7180
}
72-
pixel(capture_offscreen_image(*surviving),255,0,0); // retained lease owns device and provider
81+
pixel(capture_offscreen_image(*surviving),255,0,0);
7382
surviving.reset();
7483
for(int i=0;i<3;++i) {
7584
native_webgpu_surface surface(10+i,13,5);
7685
auto image=resolve(surface,paint(surface,0,1,0));pixel(capture_offscreen_image(*image),0,255,0);
7786
}
7887
std::cout<<"{\"backend\":\"Vulkan\",\"hardware\":"<<(hardware?"true":"false")
7988
<<",\"readbacksBeforeCapture\":0,\"explicitCaptures\":"<<captures
80-
<<",\"allocations\":"<<allocations<<",\"pixelValidation\":true,\"retainedResize\":true,\"repeatedShutdown\":true}\n";
89+
<<",\"allocations\":"<<allocations<<",\"hiddenCompletion\":true,\"pixelValidation\":true,\"retainedResize\":true,\"repeatedShutdown\":true}\n";
8190
}

0 commit comments

Comments
 (0)