• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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