diff --git a/generator/templates/dawn/fuzzers/lpmfuzz/DawnLPMSerializer.cpp b/generator/templates/dawn/fuzzers/lpmfuzz/DawnLPMSerializer.cpp index f379807ec2..347047fb51 100644 --- a/generator/templates/dawn/fuzzers/lpmfuzz/DawnLPMSerializer.cpp +++ b/generator/templates/dawn/fuzzers/lpmfuzz/DawnLPMSerializer.cpp @@ -16,6 +16,7 @@ #include "dawn/fuzzers/lpmfuzz/DawnLPMFuzzer.h" #include "dawn/fuzzers/lpmfuzz/DawnLPMObjectStore.h" #include "dawn/fuzzers/lpmfuzz/DawnLPMSerializer_autogen.h" +#include "dawn/fuzzers/lpmfuzz/DawnLPMSerializerCustom.h" #include "dawn/webgpu.h" #include "dawn/wire/BufferConsumer_impl.h" #include "dawn/wire/ObjectHandle.h" @@ -231,7 +232,7 @@ namespace dawn::wire { WireResult SerializedData(const fuzzing::Program& program, dawn::wire::ChunkedCommandSerializer serializer) { DawnLPMObjectIdProvider provider; - PerObjectType objectStores, &objectStoresRef = objectStores; + PerObjectType objectStores; // Allocate a scoped buffer allocation const size_t kMaxSerializeBufferSize = 65536; @@ -249,13 +250,14 @@ WireResult SerializedData(const fuzzing::Program& program, dawn::wire::ChunkedCo {{ name }}Cmd *cmd = nullptr; 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); break; } {% endfor %} default: { + GetCustomSerializedData(command, serializer, objectStores, provider); break; } } diff --git a/generator/templates/dawn/wire/ObjectType.h b/generator/templates/dawn/wire/ObjectType.h index 54ae08e697..8ef463fafc 100644 --- a/generator/templates/dawn/wire/ObjectType.h +++ b/generator/templates/dawn/wire/ObjectType.h @@ -19,6 +19,8 @@ namespace dawn::wire { + constexpr uint32_t kObjectTypes = {{len(by_category["object"])}}; + enum class ObjectType : uint32_t { {% for type in by_category["object"] %} {{type.name.CamelCase()}}, diff --git a/src/dawn/fuzzers/BUILD.gn b/src/dawn/fuzzers/BUILD.gn index 5d8ffa1b97..74ef0bfd0b 100644 --- a/src/dawn/fuzzers/BUILD.gn +++ b/src/dawn/fuzzers/BUILD.gn @@ -177,6 +177,8 @@ if (is_dawn_lpm_fuzzer && build_with_chromium && dawn_use_swiftshader) { "lpmfuzz/DawnLPMFuzzerAndVulkanBackend.cpp", "lpmfuzz/DawnLPMObjectStore.cpp", "lpmfuzz/DawnLPMObjectStore.h", + "lpmfuzz/DawnLPMSerializerCustom.cpp", + "lpmfuzz/DawnLPMSerializerCustom.h", ] deps = [ diff --git a/src/dawn/fuzzers/lpmfuzz/DawnLPMSerializerCustom.cpp b/src/dawn/fuzzers/lpmfuzz/DawnLPMSerializerCustom.cpp new file mode 100644 index 0000000000..adcc5fe0a9 --- /dev/null +++ b/src/dawn/fuzzers/lpmfuzz/DawnLPMSerializerCustom.cpp @@ -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 + +#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& 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(DawnLPMFuzzer::kInvalidObjectId)) { + break; + } + + cmd.self = reinterpret_cast(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 output: array;\n" + "@compute @workgroup_size(64)\n" + "fn main( \n" + " @builtin(global_invocation_id) global_id : vec3,\n" + " @builtin(local_invocation_id) local_id : vec3,\n" + ") { \n" + "output[global_id.x] = \n" + " f32(global_id.x) * 1000. + f32(local_id.x);\n" + "}"; + cmd_descriptor.nextInChain = reinterpret_cast(&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(command.destroyobject().objecttype() % kObjectTypes); + + cmd.objectId = objectStores[static_cast(cmd.objectType)].Lookup( + command.destroyobject().objectid()); + + if (cmd.objectId == static_cast(DawnLPMFuzzer::kInvalidObjectId)) { + break; + } + + objectStores[cmd.objectType].Free(cmd.objectId); + serializer.SerializeCommand(cmd, provider); + break; + } + default: { + break; + } + } +} + +} // namespace dawn::wire diff --git a/src/dawn/fuzzers/lpmfuzz/DawnLPMSerializerCustom.h b/src/dawn/fuzzers/lpmfuzz/DawnLPMSerializerCustom.h new file mode 100644 index 0000000000..fd2cc84577 --- /dev/null +++ b/src/dawn/fuzzers/lpmfuzz/DawnLPMSerializerCustom.h @@ -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& gObjectStores, + DawnLPMObjectIdProvider& provider); +} + +#endif // SRC_DAWN_FUZZERS_DAWNLPMCUSTOMSERIALIZER_H_ diff --git a/src/dawn/fuzzers/lpmfuzz/dawn_custom_lpm.proto b/src/dawn/fuzzers/lpmfuzz/dawn_custom_lpm.proto index d0f33b8b38..f9f29461de 100644 --- a/src/dawn/fuzzers/lpmfuzz/dawn_custom_lpm.proto +++ b/src/dawn/fuzzers/lpmfuzz/dawn_custom_lpm.proto @@ -17,6 +17,7 @@ package fuzzing; import "third_party/dawn/src/dawn/fuzzers/lpmfuzz/dawn_object_types_lpm_autogen.proto"; +// Custom commands message DeviceCreateShaderModule { required uint32 self = 1; } @@ -24,4 +25,4 @@ message DeviceCreateShaderModule { message DestroyObject { required ObjectType objectType = 1; required uint32 objectId = 2; -} \ No newline at end of file +}