Add Dawn Wire Server LPM Fuzzer [5/N]

Add custom C++ serializer for methods that need to be handwritten

Bug: chromium:1374747
Change-Id: I438db05b6fd6d1a1542d847c4b40f22b9143b0d5
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/114721
Commit-Queue: Brendon Tiszka <tiszka@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Brendon Tiszka 2023-05-16 03:45:03 +00:00 committed by Dawn LUCI CQ
parent 64df2e6235
commit f9f9f829e3
6 changed files with 140 additions and 3 deletions

View File

@ -16,6 +16,7 @@
#include "dawn/fuzzers/lpmfuzz/DawnLPMFuzzer.h" #include "dawn/fuzzers/lpmfuzz/DawnLPMFuzzer.h"
#include "dawn/fuzzers/lpmfuzz/DawnLPMObjectStore.h" #include "dawn/fuzzers/lpmfuzz/DawnLPMObjectStore.h"
#include "dawn/fuzzers/lpmfuzz/DawnLPMSerializer_autogen.h" #include "dawn/fuzzers/lpmfuzz/DawnLPMSerializer_autogen.h"
#include "dawn/fuzzers/lpmfuzz/DawnLPMSerializerCustom.h"
#include "dawn/webgpu.h" #include "dawn/webgpu.h"
#include "dawn/wire/BufferConsumer_impl.h" #include "dawn/wire/BufferConsumer_impl.h"
#include "dawn/wire/ObjectHandle.h" #include "dawn/wire/ObjectHandle.h"
@ -231,7 +232,7 @@ namespace dawn::wire {
WireResult SerializedData(const fuzzing::Program& program, dawn::wire::ChunkedCommandSerializer serializer) { WireResult SerializedData(const fuzzing::Program& program, dawn::wire::ChunkedCommandSerializer serializer) {
DawnLPMObjectIdProvider provider; DawnLPMObjectIdProvider provider;
PerObjectType<DawnLPMObjectStore> objectStores, &objectStoresRef = objectStores; PerObjectType<DawnLPMObjectStore> objectStores;
// Allocate a scoped buffer allocation // Allocate a scoped buffer allocation
const size_t kMaxSerializeBufferSize = 65536; const size_t kMaxSerializeBufferSize = 65536;
@ -249,13 +250,14 @@ WireResult SerializedData(const fuzzing::Program& program, dawn::wire::ChunkedCo
{{ name }}Cmd *cmd = nullptr; {{ name }}Cmd *cmd = nullptr;
WIRE_TRY(serializeBuffer.Next(&cmd)); WIRE_TRY(serializeBuffer.Next(&cmd));
WIRE_TRY({{name}}ProtoConvert(command.{{ command.name.concatcase() }}(), cmd, &serializeBuffer, objectStoresRef)); WIRE_TRY({{name}}ProtoConvert(command.{{ command.name.concatcase() }}(), cmd, &serializeBuffer, objectStores));
serializer.SerializeCommand(*cmd, provider); serializer.SerializeCommand(*cmd, provider);
break; break;
} }
{% endfor %} {% endfor %}
default: { default: {
GetCustomSerializedData(command, serializer, objectStores, provider);
break; break;
} }
} }

View File

@ -19,6 +19,8 @@
namespace dawn::wire { namespace dawn::wire {
constexpr uint32_t kObjectTypes = {{len(by_category["object"])}};
enum class ObjectType : uint32_t { enum class ObjectType : uint32_t {
{% for type in by_category["object"] %} {% for type in by_category["object"] %}
{{type.name.CamelCase()}}, {{type.name.CamelCase()}},

View File

@ -177,6 +177,8 @@ if (is_dawn_lpm_fuzzer && build_with_chromium && dawn_use_swiftshader) {
"lpmfuzz/DawnLPMFuzzerAndVulkanBackend.cpp", "lpmfuzz/DawnLPMFuzzerAndVulkanBackend.cpp",
"lpmfuzz/DawnLPMObjectStore.cpp", "lpmfuzz/DawnLPMObjectStore.cpp",
"lpmfuzz/DawnLPMObjectStore.h", "lpmfuzz/DawnLPMObjectStore.h",
"lpmfuzz/DawnLPMSerializerCustom.cpp",
"lpmfuzz/DawnLPMSerializerCustom.h",
] ]
deps = [ deps = [

View File

@ -0,0 +1,99 @@
// Copyright 2023 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <algorithm>
#include "dawn/fuzzers/lpmfuzz/DawnLPMConstants_autogen.h"
#include "dawn/fuzzers/lpmfuzz/DawnLPMObjectStore.h"
#include "dawn/fuzzers/lpmfuzz/DawnLPMSerializerCustom.h"
#include "dawn/fuzzers/lpmfuzz/DawnLPMSerializer_autogen.h"
#include "dawn/webgpu.h"
#include "dawn/wire/ChunkedCommandSerializer.h"
#include "dawn/wire/ObjectType_autogen.h"
namespace dawn::wire {
void GetCustomSerializedData(const fuzzing::Command& command,
dawn::wire::ChunkedCommandSerializer serializer,
PerObjectType<DawnLPMObjectStore>& objectStores,
DawnLPMObjectIdProvider& provider) {
switch (command.command_case()) {
case fuzzing::Command::kDeviceCreateShaderModule: {
DeviceCreateShaderModuleCmd cmd;
memset(&cmd, 0, sizeof(DeviceCreateShaderModuleCmd));
ObjectId cmd_self_id =
objectStores[ObjectType::Device].Lookup(command.devicecreateshadermodule().self());
if (cmd_self_id == static_cast<ObjectId>(DawnLPMFuzzer::kInvalidObjectId)) {
break;
}
cmd.self = reinterpret_cast<WGPUDevice>(cmd_self_id);
WGPUShaderModuleDescriptor cmd_descriptor;
memset(&cmd_descriptor, 0, sizeof(struct WGPUShaderModuleDescriptor));
WGPUShaderModuleWGSLDescriptor wgsl_desc = {};
wgsl_desc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor;
// Hardcoded shader for now, eventually we should write an LPM grammar for WGSL
wgsl_desc.source =
"@group(0) @binding(0)\n"
"var<storage, read_write> output: array<f32>;\n"
"@compute @workgroup_size(64)\n"
"fn main( \n"
" @builtin(global_invocation_id) global_id : vec3<u32>,\n"
" @builtin(local_invocation_id) local_id : vec3<u32>,\n"
") { \n"
"output[global_id.x] = \n"
" f32(global_id.x) * 1000. + f32(local_id.x);\n"
"}";
cmd_descriptor.nextInChain = reinterpret_cast<WGPUChainedStruct*>(&wgsl_desc);
cmd.descriptor = &cmd_descriptor;
if (objectStores[ObjectType::ShaderModule].Size() >=
DawnLPMFuzzer::kShaderModuleLimit) {
break;
}
cmd.result = objectStores[ObjectType::ShaderModule].ReserveHandle();
serializer.SerializeCommand(cmd, provider);
break;
}
case fuzzing::Command::kDestroyObject: {
DestroyObjectCmd cmd;
memset(&cmd, 0, sizeof(DestroyObjectCmd));
cmd.objectType =
static_cast<ObjectType>(command.destroyobject().objecttype() % kObjectTypes);
cmd.objectId = objectStores[static_cast<ObjectType>(cmd.objectType)].Lookup(
command.destroyobject().objectid());
if (cmd.objectId == static_cast<ObjectId>(DawnLPMFuzzer::kInvalidObjectId)) {
break;
}
objectStores[cmd.objectType].Free(cmd.objectId);
serializer.SerializeCommand(cmd, provider);
break;
}
default: {
break;
}
}
}
} // namespace dawn::wire

View File

@ -0,0 +1,31 @@
// Copyright 2023 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_DAWN_FUZZERS_DAWNLPMCUSTOMSERIALIZER_H_
#define SRC_DAWN_FUZZERS_DAWNLPMCUSTOMSERIALIZER_H_
#include "dawn/fuzzers/lpmfuzz/DawnLPMObjectStore.h"
#include "dawn/fuzzers/lpmfuzz/DawnLPMSerializer_autogen.h"
#include "dawn/wire/ChunkedCommandSerializer.h"
#include "dawn/wire/ObjectType_autogen.h"
namespace dawn::wire {
void GetCustomSerializedData(
const fuzzing::Command& command,
dawn::wire::ChunkedCommandSerializer serializer,
ityp::array<dawn::wire::ObjectType, dawn::wire::DawnLPMObjectStore, 24>& gObjectStores,
DawnLPMObjectIdProvider& provider);
}
#endif // SRC_DAWN_FUZZERS_DAWNLPMCUSTOMSERIALIZER_H_

View File

@ -17,6 +17,7 @@ package fuzzing;
import "third_party/dawn/src/dawn/fuzzers/lpmfuzz/dawn_object_types_lpm_autogen.proto"; import "third_party/dawn/src/dawn/fuzzers/lpmfuzz/dawn_object_types_lpm_autogen.proto";
// Custom commands
message DeviceCreateShaderModule { message DeviceCreateShaderModule {
required uint32 self = 1; required uint32 self = 1;
} }
@ -24,4 +25,4 @@ message DeviceCreateShaderModule {
message DestroyObject { message DestroyObject {
required ObjectType objectType = 1; required ObjectType objectType = 1;
required uint32 objectId = 2; required uint32 objectId = 2;
} }