Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: gpu/command_buffer/tests/fuzzer_main.cc

Issue 2150803003: Introduce gpu_fuzzer to fuzz the GPU command buffers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@fuzzer_land_base
Patch Set: Fix check, zero-out padding Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « gpu/command_buffer/service/common_decoder.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 #include <stddef.h>
5 #include <stdint.h>
6
7 #include <memory>
8 #include <vector>
9
10 #include "base/at_exit.h"
11 #include "base/bind.h"
12 #include "base/command_line.h"
13 #include "base/logging.h"
14 #include "base/memory/ref_counted.h"
15 #include "build/build_config.h"
16 #include "gpu/command_buffer/common/constants.h"
17 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
18 #include "gpu/command_buffer/common/sync_token.h"
19 #include "gpu/command_buffer/service/buffer_manager.h"
20 #include "gpu/command_buffer/service/command_buffer_service.h"
21 #include "gpu/command_buffer/service/command_executor.h"
22 #include "gpu/command_buffer/service/context_group.h"
23 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
24 #include "gpu/command_buffer/service/logger.h"
25 #include "gpu/command_buffer/service/mailbox_manager_impl.h"
26 #include "gpu/command_buffer/service/sync_point_manager.h"
27 #include "gpu/command_buffer/service/transfer_buffer_manager.h"
28 #include "ui/gfx/geometry/size.h"
29 #include "ui/gl/gl_context.h"
30 #include "ui/gl/gl_context_stub_with_extensions.h"
31 #include "ui/gl/gl_image_ref_counted_memory.h"
32 #include "ui/gl/gl_share_group.h"
33 #include "ui/gl/gl_stub_api.h"
34 #include "ui/gl/gl_surface.h"
35 #include "ui/gl/gl_surface_stub.h"
36 #include "ui/gl/init/gl_factory.h"
37 #include "ui/gl/test/gl_surface_test_support.h"
38
39 namespace gpu {
40 namespace {
41
42 const size_t kCommandBufferSize = 16384;
43 const size_t kTransferBufferSize = 16384;
44 const size_t kSmallTransferBufferSize = 16;
45 const size_t kTinyTransferBufferSize = 3;
46
47 class CommandBufferSetup {
48 public:
49 CommandBufferSetup()
50 : atexit_manager_(),
51 sync_point_manager_(new SyncPointManager(false)),
52 sync_point_order_data_(SyncPointOrderData::Create()),
53 mailbox_manager_(new gles2::MailboxManagerImpl),
54 share_group_(new gl::GLShareGroup),
55 surface_(new gl::GLSurfaceStub),
56 context_(new gl::GLContextStub(share_group_.get())),
57 command_buffer_id_(CommandBufferId::FromUnsafeValue(1)) {
58 logging::SetMinLogLevel(logging::LOG_FATAL);
59 base::CommandLine::Init(0, NULL);
60 base::CommandLine::ForCurrentProcess()->AppendSwitch(
61 switches::kEnableUnsafeES3APIs);
62 gpu_preferences_.enable_unsafe_es3_apis = true;
63
64 gl::GLSurfaceTestSupport::InitializeOneOffWithMockBindings();
65 gl::SetStubGLApi(&api_);
66
67 sync_point_client_ = sync_point_manager_->CreateSyncPointClient(
68 sync_point_order_data_, CommandBufferNamespace::IN_PROCESS,
69 command_buffer_id_);
70
71 translator_cache_ = new gles2::ShaderTranslatorCache(gpu_preferences_);
72 completeness_cache_ = new gles2::FramebufferCompletenessCache;
73 }
74
75 void InitDecoder() {
76 context_->MakeCurrent(surface_.get());
77 scoped_refptr<gles2::FeatureInfo> feature_info =
78 new gles2::FeatureInfo();
79 scoped_refptr<gles2::ContextGroup> context_group = new gles2::ContextGroup(
80 gpu_preferences_, mailbox_manager_.get(), nullptr, translator_cache_,
81 completeness_cache_, feature_info, true /* bind_generates_resource */,
82 nullptr /* ImageFactory */);
83 command_buffer_.reset(
84 new CommandBufferService(context_group->transfer_buffer_manager()));
85 command_buffer_->SetPutOffsetChangeCallback(
86 base::Bind(&CommandBufferSetup::PumpCommands, base::Unretained(this)));
87 command_buffer_->SetGetBufferChangeCallback(base::Bind(
88 &CommandBufferSetup::GetBufferChanged, base::Unretained(this)));
89 InitializeInitialCommandBuffer();
90
91 decoder_.reset(gles2::GLES2Decoder::Create(context_group.get()));
92 executor_.reset(new CommandExecutor(command_buffer_.get(), decoder_.get(),
93 decoder_.get()));
94 decoder_->set_engine(executor_.get());
95 decoder_->SetFenceSyncReleaseCallback(base::Bind(
96 &CommandBufferSetup::OnFenceSyncRelease, base::Unretained(this)));
97 decoder_->SetWaitFenceSyncCallback(base::Bind(
98 &CommandBufferSetup::OnWaitFenceSync, base::Unretained(this)));
99 decoder_->GetLogger()->set_log_synthesized_gl_errors(false);
100
101 gles2::ContextCreationAttribHelper attrib_helper;
102 attrib_helper.offscreen_framebuffer_size = gfx::Size(16, 16);
103 attrib_helper.red_size = 8;
104 attrib_helper.green_size = 8;
105 attrib_helper.blue_size = 8;
106 attrib_helper.alpha_size = 8;
107 attrib_helper.depth_size = 0;
108 attrib_helper.stencil_size = 0;
109 attrib_helper.context_type = gles2::CONTEXT_TYPE_OPENGLES3;
110
111 bool result =
112 decoder_->Initialize(surface_.get(), context_.get(), true,
113 gles2::DisallowedFeatures(), attrib_helper);
114 CHECK(result);
115 decoder_->set_max_bucket_size(8 << 20);
116 context_group->buffer_manager()->set_max_buffer_size(8 << 20);
117 }
118
119 void ResetDecoder() {
120 decoder_->Destroy(true);
121 decoder_.reset();
122 command_buffer_.reset();
123 }
124
125 ~CommandBufferSetup() {
126 sync_point_client_ = nullptr;
127 if (sync_point_order_data_) {
128 sync_point_order_data_->Destroy();
129 sync_point_order_data_ = nullptr;
130 }
131 }
132
133 void RunCommandBuffer(const uint8_t* data, size_t size) {
134 InitDecoder();
135 // The commands are flushed at a uint32_t granularity. If the data is not
136 // a full command, we zero-pad it.
137 size_t padded_size = (size + 3) & ~3;
138 CHECK_LE(padded_size, buffer_->size());
139 command_buffer_->SetGetBuffer(buffer_id_);
140 auto* memory = static_cast<char*>(buffer_->memory());
141 memcpy(memory, data, size);
142 if (padded_size > size)
143 memset(memory + size, 0, padded_size - size);
144 command_buffer_->Flush(padded_size / 4);
145 ResetDecoder();
146 }
147
148 private:
149 void PumpCommands() {
150 if (!decoder_->MakeCurrent()) {
151 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason());
152 command_buffer_->SetParseError(::gpu::error::kLostContext);
153 return;
154 }
155
156 uint32_t order_num = sync_point_order_data_->GenerateUnprocessedOrderNumber(
157 sync_point_manager_.get());
158 sync_point_order_data_->BeginProcessingOrderNumber(order_num);
159
160 executor_->PutChanged();
161
162 sync_point_order_data_->FinishProcessingOrderNumber(order_num);
163 }
164
165 bool GetBufferChanged(int32_t transfer_buffer_id) {
166 return executor_->SetGetBuffer(transfer_buffer_id);
167 }
168
169 void OnFenceSyncRelease(uint64_t release) {
170 CHECK(sync_point_client_);
171 sync_point_client_->ReleaseFenceSync(release);
172 }
173
174 bool OnWaitFenceSync(CommandBufferNamespace namespace_id,
175 CommandBufferId command_buffer_id,
176 uint64_t release) {
177 CHECK(sync_point_client_);
178 scoped_refptr<gpu::SyncPointClientState> release_state =
179 sync_point_manager_->GetSyncPointClientState(namespace_id,
180 command_buffer_id);
181 if (!release_state)
182 return true;
183
184 if (release_state->IsFenceSyncReleased(release))
185 return true;
186
187 executor_->SetScheduled(false);
188 return false;
189 }
190
191 void InitializeInitialCommandBuffer() {
192 buffer_id_ = 1;
193 buffer_ = command_buffer_->CreateTransferBufferWithId(kCommandBufferSize,
194 buffer_id_);
195 CHECK(buffer_);
196 // Create some transfer buffers. This is somewhat arbitrary, but having a
197 // reasonably sized buffer in slot 4 allows us to prime the corpus with data
198 // extracted from unit tests.
199 command_buffer_->CreateTransferBufferWithId(kTransferBufferSize, 2);
200 command_buffer_->CreateTransferBufferWithId(kSmallTransferBufferSize, 3);
201 command_buffer_->CreateTransferBufferWithId(kTransferBufferSize, 4);
202 command_buffer_->CreateTransferBufferWithId(kTinyTransferBufferSize, 5);
203 }
204
205 base::AtExitManager atexit_manager_;
206
207 gl::GLStubApi api_;
208 GpuPreferences gpu_preferences_;
209
210 std::unique_ptr<SyncPointManager> sync_point_manager_;
211 scoped_refptr<SyncPointOrderData> sync_point_order_data_;
212 std::unique_ptr<SyncPointClient> sync_point_client_;
213 scoped_refptr<gles2::MailboxManager> mailbox_manager_;
214 scoped_refptr<gl::GLShareGroup> share_group_;
215 scoped_refptr<gl::GLSurface> surface_;
216 scoped_refptr<gl::GLContext> context_;
217 const gpu::CommandBufferId command_buffer_id_;
218
219 scoped_refptr<gles2::ShaderTranslatorCache> translator_cache_;
220 scoped_refptr<gles2::FramebufferCompletenessCache> completeness_cache_;
221
222 std::unique_ptr<CommandBufferService> command_buffer_;
223
224 std::unique_ptr<gles2::GLES2Decoder> decoder_;
225 std::unique_ptr<CommandExecutor> executor_;
226
227 scoped_refptr<Buffer> buffer_;
228 int32_t buffer_id_ = 0;
229 };
230
231 } // anonymous namespace
232 } // namespace gpu
233
234
235 static gpu::CommandBufferSetup& GetSetup() {
236 static gpu::CommandBufferSetup setup;
237 return setup;
238 }
239
240 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
241 GetSetup().RunCommandBuffer(data, size);
242 return 0;
243 }
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/common_decoder.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698