1 // Copyright 2023 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "testing/libfuzzer/fuzzers/command_buffer_lpm_fuzzer/webgpu_support.h"
6 #include "gpu/webgpu/callback.h"
7 #include "testing/libfuzzer/fuzzers/command_buffer_lpm_fuzzer/cmd_buf_lpm_fuzz.h"
8
9 namespace gpu::cmdbuf::fuzzing {
10
11 DawnWireSerializerFuzzer::DawnWireSerializerFuzzer() = default;
12 DawnWireSerializerFuzzer::~DawnWireSerializerFuzzer() = default;
13
GetMaximumAllocationSize() const14 size_t DawnWireSerializerFuzzer::GetMaximumAllocationSize() const {
15 // Some fuzzer bots have a 2GB allocation limit. Pick a value reasonably
16 // below that.
17 return 1024 * 1024 * 1024;
18 }
19
GetCmdSpace(size_t size)20 void* DawnWireSerializerFuzzer::GetCmdSpace(size_t size) {
21 if (size > buf.size()) {
22 buf.resize(size);
23 }
24 return buf.data();
25 }
26
Flush()27 bool DawnWireSerializerFuzzer::Flush() {
28 return true;
29 }
30
WebGPURequestAdapter()31 void CmdBufFuzz::WebGPURequestAdapter() {
32 DVLOG(3) << "Requesting WebGPU adapter...";
33 wgpu::RequestAdapterOptions ra_options = {};
34 ra_options.forceFallbackAdapter = false;
35 bool done = false;
36 auto* adapter_callback = webgpu::BindWGPUOnceCallback(
37 [](CmdBufFuzz* test, bool* done, WGPURequestAdapterStatus status,
38 WGPUAdapter adapter, const char* message) {
39 CHECK_EQ(status, WGPURequestAdapterStatus_Success);
40 CHECK_NE(adapter, nullptr);
41 test->webgpu_adapter_ = std::make_unique<wgpu::Adapter>(adapter);
42 DVLOG(3) << "Adapter acquired";
43 *done = true;
44 },
45 this, &done);
46 webgpu_instance_->RequestAdapter(&ra_options,
47 adapter_callback->UnboundCallback(),
48 adapter_callback->AsUserdata());
49 webgpu_impl_->FlushCommands();
50 while (!done) {
51 RunPendingTasks();
52 base::PlatformThread::Sleep(kTinyTimeout);
53 }
54 }
55
WebGPURequestDevice()56 void CmdBufFuzz::WebGPURequestDevice() {
57 DVLOG(3) << "Requesting WebGPU device...";
58 bool done = false;
59 // webgpu_device_ = std::make_unique<wgpu::Device>().get();
60 wgpu::DeviceDescriptor device_desc = {};
61 auto* device_callback = webgpu::BindWGPUOnceCallback(
62 [](wgpu::Device* device_out, bool* done, WGPURequestDeviceStatus status,
63 WGPUDevice device, const char* message) {
64 DVLOG(3) << "Attempting to acquire device";
65 *device_out = wgpu::Device::Acquire(device);
66 DVLOG(3) << "Device acquired";
67 *done = true;
68 },
69 &webgpu_device_, &done);
70
71 DCHECK(webgpu_adapter_);
72 webgpu_adapter_->RequestDevice(&device_desc,
73 device_callback->UnboundCallback(),
74 device_callback->AsUserdata());
75 webgpu()->FlushCommands();
76 while (!done) {
77 RunPendingTasks();
78 base::PlatformThread::Sleep(kTinyTimeout);
79 }
80
81 webgpu_device_.SetDeviceLostCallback(
82 [](WGPUDeviceLostReason reason, const char* message, void*) {
83 if (message) {
84 DVLOG(3) << "***** Device lost: " << message << " *****";
85 }
86 if (reason == WGPUDeviceLostReason_Destroyed) {
87 return;
88 }
89 LOG(FATAL) << "Unexpected device lost (" << reason << "): " << message;
90 },
91 nullptr);
92 }
93
WebGPUDestroyDevice()94 void CmdBufFuzz::WebGPUDestroyDevice() {
95 DVLOG(3) << "Destroying device";
96 webgpu_device_.Destroy();
97 webgpu()->FlushCommands();
98 WaitForCompletion(webgpu_device_);
99 DVLOG(3) << "Device destroyed? (see DeviceLostCallback log)";
100 }
101
WebGPUCreateBuffer()102 void CmdBufFuzz::WebGPUCreateBuffer() {
103 DVLOG(3) << "Creating WebGPU buffer";
104 wgpu::BufferDescriptor buffer_desc;
105 buffer_desc.size = 4;
106 buffer_desc.usage = wgpu::BufferUsage::MapRead | wgpu::BufferUsage::CopyDst;
107 wgpu::Buffer buff = webgpu_device_.CreateBuffer(&buffer_desc);
108 webgpu()->FlushCommands();
109 WaitForCompletion(webgpu_device_);
110 wgpu_buffers_.push_back(std::move(buff));
111 DVLOG(3) << "Created WebGPU buffer";
112 }
113
WebGPUDestroyBuffer()114 void CmdBufFuzz::WebGPUDestroyBuffer() {
115 DVLOG(3) << "Destroying WebGPU buffer";
116 for (wgpu::Buffer buff : wgpu_buffers_) {
117 buff.Destroy();
118 buff.Release();
119 }
120 wgpu_buffers_.clear();
121 DVLOG(3) << "Destroyed WebGPU buffer";
122 return;
123 }
124
WebGPUReset()125 void CmdBufFuzz::WebGPUReset() {
126 // Let in-flight work finish.
127 PollUntilIdle();
128 // TODO: release & destroy buffer(s), device(s) & adapter(s).
129 }
130
131 } // namespace gpu::cmdbuf::fuzzing
132