Remove usages of SPVC

Remove all usages of SPVC from the code and update the fuzzers. Some
of the include paths and deps came transitively from spvc, so needed
to update build rules.

This patch does NOT remove the flags related to spvc usage, they are
just no-ops as the moment. After this patch lands I will remove the
usage of those flags from the bots, then remove the flags.

BUG=dawn:521

Change-Id: I0d7c3e28f79354c78f00c48b6a383b823094a069
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/27900
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
This commit is contained in:
Ryan Harrison 2020-09-02 22:09:08 +00:00 committed by Commit Bot service account
parent a1758eef07
commit c35e2ba379
23 changed files with 241 additions and 1000 deletions

View File

@ -33,7 +33,7 @@ This repository contains the implementation of Dawn, which is itself composed of
The largest library in Dawn is `dawn_native` which implements the WebGPU API by translating to native graphics APIs such as D3D12, Metal or Vulkan. It is composed of a frontend that does all the state-tracking and validation, and backends that do the actual translation to the native graphics APIs. The largest library in Dawn is `dawn_native` which implements the WebGPU API by translating to native graphics APIs such as D3D12, Metal or Vulkan. It is composed of a frontend that does all the state-tracking and validation, and backends that do the actual translation to the native graphics APIs.
`dawn_native` hosts the [SPVC](https://github.com/google/shaderc/tree/master/spvc) shader translator that validates SPIR-V for WebGPU and converts it to an equivalent shader for use in the native graphics API (HLSL for D3D12, MSL for Metal or Vulkan SPIR-V for Vulkan). `dawn_native` hosts the [spirv-val](https://github.com/KhronosGroup/SPIRV-Tools) for validation of SPIR-V shaders and uses [SPIRV-Cross](https://github.com/KhronosGroup/SPIRV-Cross) shader translator to convert SPIR-V shaders to an equivalent shader for use in the native graphics API (HLSL for D3D12, MSL for Metal or Vulkan SPIR-V for Vulkan).
## Dawn Wire (`dawn_wire`) ## Dawn Wire (`dawn_wire`)

View File

@ -129,7 +129,7 @@ source_set("dawn_native_sources") {
":dawn_native_headers", ":dawn_native_headers",
":dawn_native_utils_gen", ":dawn_native_utils_gen",
"${dawn_root}/src/common", "${dawn_root}/src/common",
"${dawn_shaderc_dir}:spirv_cross", "${dawn_root}/third_party/gn/spirv_cross:spirv_cross",
"${dawn_spirv_tools_dir}:spvtools_val", "${dawn_spirv_tools_dir}:spvtools_val",
] ]
defines = [] defines = []
@ -141,10 +141,7 @@ source_set("dawn_native_sources") {
# Dependencies that are needed to compile dawn_native entry points in # Dependencies that are needed to compile dawn_native entry points in
# FooBackend.cpp need to be public deps so they are propagated to the # FooBackend.cpp need to be public deps so they are propagated to the
# dawn_native target # dawn_native target
public_deps = [ public_deps = [ "${dawn_root}/src/dawn_platform" ]
"${dawn_root}/src/dawn_platform",
"${dawn_shaderc_dir}:libshaderc_spvc",
]
sources = get_target_outputs(":dawn_native_utils_gen") sources = get_target_outputs(":dawn_native_utils_gen")
sources += [ sources += [

View File

@ -149,7 +149,6 @@ target_link_libraries(dawn_native
PRIVATE dawn_common PRIVATE dawn_common
dawn_platform dawn_platform
dawn_internal_config dawn_internal_config
shaderc_spvc
spirv-cross-core spirv-cross-core
) )

View File

@ -74,79 +74,6 @@ namespace dawn_native {
} }
} }
wgpu::TextureViewDimension ToWGPUTextureViewDimension(
shaderc_spvc_texture_view_dimension dim) {
switch (dim) {
case shaderc_spvc_texture_view_dimension_undefined:
return wgpu::TextureViewDimension::Undefined;
case shaderc_spvc_texture_view_dimension_e1D:
return wgpu::TextureViewDimension::e1D;
case shaderc_spvc_texture_view_dimension_e2D:
return wgpu::TextureViewDimension::e2D;
case shaderc_spvc_texture_view_dimension_e2D_array:
return wgpu::TextureViewDimension::e2DArray;
case shaderc_spvc_texture_view_dimension_cube:
return wgpu::TextureViewDimension::Cube;
case shaderc_spvc_texture_view_dimension_cube_array:
return wgpu::TextureViewDimension::CubeArray;
case shaderc_spvc_texture_view_dimension_e3D:
return wgpu::TextureViewDimension::e3D;
}
UNREACHABLE();
}
Format::Type ToDawnFormatType(shaderc_spvc_texture_format_type type) {
switch (type) {
case shaderc_spvc_texture_format_type_float:
return Format::Type::Float;
case shaderc_spvc_texture_format_type_sint:
return Format::Type::Sint;
case shaderc_spvc_texture_format_type_uint:
return Format::Type::Uint;
case shaderc_spvc_texture_format_type_other:
return Format::Type::Other;
}
UNREACHABLE();
}
wgpu::BindingType ToWGPUBindingType(shaderc_spvc_binding_type type) {
switch (type) {
case shaderc_spvc_binding_type_uniform_buffer:
return wgpu::BindingType::UniformBuffer;
case shaderc_spvc_binding_type_storage_buffer:
return wgpu::BindingType::StorageBuffer;
case shaderc_spvc_binding_type_readonly_storage_buffer:
return wgpu::BindingType::ReadonlyStorageBuffer;
case shaderc_spvc_binding_type_sampler:
return wgpu::BindingType::Sampler;
case shaderc_spvc_binding_type_comparison_sampler:
return wgpu::BindingType::ComparisonSampler;
case shaderc_spvc_binding_type_sampled_texture:
return wgpu::BindingType::SampledTexture;
case shaderc_spvc_binding_type_readonly_storage_texture:
return wgpu::BindingType::ReadonlyStorageTexture;
case shaderc_spvc_binding_type_writeonly_storage_texture:
return wgpu::BindingType::WriteonlyStorageTexture;
case shaderc_spvc_binding_type_storage_texture:
return wgpu::BindingType::StorageTexture;
default:
UNREACHABLE();
}
}
SingleShaderStage ToSingleShaderStage(shaderc_spvc_execution_model execution_model) {
switch (execution_model) {
case shaderc_spvc_execution_model_vertex:
return SingleShaderStage::Vertex;
case shaderc_spvc_execution_model_fragment:
return SingleShaderStage::Fragment;
case shaderc_spvc_execution_model_glcompute:
return SingleShaderStage::Compute;
default:
UNREACHABLE();
}
}
wgpu::TextureFormat ToWGPUTextureFormat(spv::ImageFormat format) { wgpu::TextureFormat ToWGPUTextureFormat(spv::ImageFormat format) {
switch (format) { switch (format) {
case spv::ImageFormatR8: case spv::ImageFormatR8:
@ -218,77 +145,6 @@ namespace dawn_native {
} }
} }
wgpu::TextureFormat ToWGPUTextureFormat(shaderc_spvc_storage_texture_format format) {
switch (format) {
case shaderc_spvc_storage_texture_format_r8unorm:
return wgpu::TextureFormat::R8Unorm;
case shaderc_spvc_storage_texture_format_r8snorm:
return wgpu::TextureFormat::R8Snorm;
case shaderc_spvc_storage_texture_format_r8uint:
return wgpu::TextureFormat::R8Uint;
case shaderc_spvc_storage_texture_format_r8sint:
return wgpu::TextureFormat::R8Sint;
case shaderc_spvc_storage_texture_format_r16uint:
return wgpu::TextureFormat::R16Uint;
case shaderc_spvc_storage_texture_format_r16sint:
return wgpu::TextureFormat::R16Sint;
case shaderc_spvc_storage_texture_format_r16float:
return wgpu::TextureFormat::R16Float;
case shaderc_spvc_storage_texture_format_rg8unorm:
return wgpu::TextureFormat::RG8Unorm;
case shaderc_spvc_storage_texture_format_rg8snorm:
return wgpu::TextureFormat::RG8Snorm;
case shaderc_spvc_storage_texture_format_rg8uint:
return wgpu::TextureFormat::RG8Uint;
case shaderc_spvc_storage_texture_format_rg8sint:
return wgpu::TextureFormat::RG8Sint;
case shaderc_spvc_storage_texture_format_r32float:
return wgpu::TextureFormat::R32Float;
case shaderc_spvc_storage_texture_format_r32uint:
return wgpu::TextureFormat::R32Uint;
case shaderc_spvc_storage_texture_format_r32sint:
return wgpu::TextureFormat::R32Sint;
case shaderc_spvc_storage_texture_format_rg16uint:
return wgpu::TextureFormat::RG16Uint;
case shaderc_spvc_storage_texture_format_rg16sint:
return wgpu::TextureFormat::RG16Sint;
case shaderc_spvc_storage_texture_format_rg16float:
return wgpu::TextureFormat::RG16Float;
case shaderc_spvc_storage_texture_format_rgba8unorm:
return wgpu::TextureFormat::RGBA8Unorm;
case shaderc_spvc_storage_texture_format_rgba8snorm:
return wgpu::TextureFormat::RGBA8Snorm;
case shaderc_spvc_storage_texture_format_rgba8uint:
return wgpu::TextureFormat::RGBA8Uint;
case shaderc_spvc_storage_texture_format_rgba8sint:
return wgpu::TextureFormat::RGBA8Sint;
case shaderc_spvc_storage_texture_format_rgb10a2unorm:
return wgpu::TextureFormat::RGB10A2Unorm;
case shaderc_spvc_storage_texture_format_rg11b10float:
return wgpu::TextureFormat::RG11B10Ufloat;
case shaderc_spvc_storage_texture_format_rg32float:
return wgpu::TextureFormat::RG32Float;
case shaderc_spvc_storage_texture_format_rg32uint:
return wgpu::TextureFormat::RG32Uint;
case shaderc_spvc_storage_texture_format_rg32sint:
return wgpu::TextureFormat::RG32Sint;
case shaderc_spvc_storage_texture_format_rgba16uint:
return wgpu::TextureFormat::RGBA16Uint;
case shaderc_spvc_storage_texture_format_rgba16sint:
return wgpu::TextureFormat::RGBA16Sint;
case shaderc_spvc_storage_texture_format_rgba16float:
return wgpu::TextureFormat::RGBA16Float;
case shaderc_spvc_storage_texture_format_rgba32float:
return wgpu::TextureFormat::RGBA32Float;
case shaderc_spvc_storage_texture_format_rgba32uint:
return wgpu::TextureFormat::RGBA32Uint;
case shaderc_spvc_storage_texture_format_rgba32sint:
return wgpu::TextureFormat::RGBA32Sint;
default:
return wgpu::TextureFormat::Undefined;
}
}
std::string GetShaderDeclarationString(BindGroupIndex group, BindingNumber binding) { std::string GetShaderDeclarationString(BindGroupIndex group, BindingNumber binding) {
std::ostringstream ostream; std::ostringstream ostream;
ostream << "the shader module declaration at set " << static_cast<uint32_t>(group) ostream << "the shader module declaration at set " << static_cast<uint32_t>(group)
@ -790,10 +646,6 @@ namespace dawn_native {
default: default:
UNREACHABLE(); UNREACHABLE();
} }
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvcParser)) {
mSpvcContext.SetUseSpvcParser(true);
}
} }
ShaderModuleBase::ShaderModuleBase(DeviceBase* device, ObjectBase::ErrorTag tag) ShaderModuleBase::ShaderModuleBase(DeviceBase* device, ObjectBase::ErrorTag tag)
@ -827,186 +679,12 @@ namespace dawn_native {
MaybeError ShaderModuleBase::ExtractSpirvInfo(const spirv_cross::Compiler& compiler) { MaybeError ShaderModuleBase::ExtractSpirvInfo(const spirv_cross::Compiler& compiler) {
ASSERT(!IsError()); ASSERT(!IsError());
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) { DAWN_TRY_ASSIGN(mMainEntryPoint, ExtractSpirvInfoImpl(compiler));
DAWN_TRY_ASSIGN(mMainEntryPoint, ExtractSpirvInfoWithSpvc());
} else {
DAWN_TRY_ASSIGN(mMainEntryPoint, ExtractSpirvInfoWithSpirvCross(compiler));
}
return {}; return {};
} }
ResultOrError<std::unique_ptr<EntryPointMetadata>> ResultOrError<std::unique_ptr<EntryPointMetadata>> ShaderModuleBase::ExtractSpirvInfoImpl(
ShaderModuleBase::ExtractSpirvInfoWithSpvc() { const spirv_cross::Compiler& compiler) {
DeviceBase* device = GetDevice();
std::unique_ptr<EntryPointMetadata> metadata = std::make_unique<EntryPointMetadata>();
shaderc_spvc_execution_model execution_model;
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.GetExecutionModel(&execution_model),
"Unable to get execution model for shader."));
metadata->stage = ToSingleShaderStage(execution_model);
size_t push_constant_buffers_count;
DAWN_TRY(
CheckSpvcSuccess(mSpvcContext.GetPushConstantBufferCount(&push_constant_buffers_count),
"Unable to get push constant buffer count for shader."));
// TODO(rharrison): This should be handled by spirv-val pass in spvc,
// but need to confirm.
if (push_constant_buffers_count > 0) {
return DAWN_VALIDATION_ERROR("Push constants aren't supported.");
}
// Fill in bindingInfo with the SPIRV bindings
auto ExtractResourcesBinding =
[](const DeviceBase* device, const std::vector<shaderc_spvc_binding_info>& spvcBindings,
EntryPointMetadata::BindingInfo* metadataBindings) -> MaybeError {
for (const shaderc_spvc_binding_info& binding : spvcBindings) {
BindGroupIndex bindGroupIndex(binding.set);
if (bindGroupIndex >= kMaxBindGroupsTyped) {
return DAWN_VALIDATION_ERROR("Bind group index over limits in the SPIRV");
}
const auto& it = (*metadataBindings)[bindGroupIndex].emplace(
BindingNumber(binding.binding), EntryPointMetadata::ShaderBindingInfo{});
if (!it.second) {
return DAWN_VALIDATION_ERROR("Shader has duplicate bindings");
}
EntryPointMetadata::ShaderBindingInfo* info = &it.first->second;
info->id = binding.id;
info->base_type_id = binding.base_type_id;
info->type = ToWGPUBindingType(binding.binding_type);
switch (info->type) {
case wgpu::BindingType::SampledTexture: {
info->multisampled = binding.multisampled;
info->viewDimension = ToWGPUTextureViewDimension(binding.texture_dimension);
info->textureComponentType =
ToDawnFormatType(binding.texture_component_type);
break;
}
case wgpu::BindingType::StorageTexture:
case wgpu::BindingType::ReadonlyStorageTexture:
case wgpu::BindingType::WriteonlyStorageTexture: {
wgpu::TextureFormat storageTextureFormat =
ToWGPUTextureFormat(binding.storage_texture_format);
if (storageTextureFormat == wgpu::TextureFormat::Undefined) {
return DAWN_VALIDATION_ERROR(
"Invalid image format declaration on storage image");
}
const Format& format = device->GetValidInternalFormat(storageTextureFormat);
if (!format.supportsStorageUsage) {
return DAWN_VALIDATION_ERROR(
"The storage texture format is not supported");
}
info->multisampled = binding.multisampled;
info->storageTextureFormat = storageTextureFormat;
info->viewDimension = ToWGPUTextureViewDimension(binding.texture_dimension);
break;
}
case wgpu::BindingType::UniformBuffer:
case wgpu::BindingType::StorageBuffer:
case wgpu::BindingType::ReadonlyStorageBuffer:
info->minBufferBindingSize = binding.minimum_buffer_size;
break;
default:
break;
}
}
return {};
};
std::vector<shaderc_spvc_binding_info> resource_bindings;
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.GetBindingInfo(
shaderc_spvc_shader_resource_uniform_buffers,
shaderc_spvc_binding_type_uniform_buffer, &resource_bindings),
"Unable to get binding info for uniform buffers from shader"));
DAWN_TRY(ExtractResourcesBinding(device, resource_bindings, &metadata->bindings));
DAWN_TRY(CheckSpvcSuccess(
mSpvcContext.GetBindingInfo(shaderc_spvc_shader_resource_separate_images,
shaderc_spvc_binding_type_sampled_texture,
&resource_bindings),
"Unable to get binding info for sampled textures from shader"));
DAWN_TRY(ExtractResourcesBinding(device, resource_bindings, &metadata->bindings));
DAWN_TRY(CheckSpvcSuccess(
mSpvcContext.GetBindingInfo(shaderc_spvc_shader_resource_separate_samplers,
shaderc_spvc_binding_type_sampler, &resource_bindings),
"Unable to get binding info for samples from shader"));
DAWN_TRY(ExtractResourcesBinding(device, resource_bindings, &metadata->bindings));
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.GetBindingInfo(
shaderc_spvc_shader_resource_storage_buffers,
shaderc_spvc_binding_type_storage_buffer, &resource_bindings),
"Unable to get binding info for storage buffers from shader"));
DAWN_TRY(ExtractResourcesBinding(device, resource_bindings, &metadata->bindings));
DAWN_TRY(CheckSpvcSuccess(
mSpvcContext.GetBindingInfo(shaderc_spvc_shader_resource_storage_images,
shaderc_spvc_binding_type_storage_texture,
&resource_bindings),
"Unable to get binding info for storage textures from shader"));
DAWN_TRY(ExtractResourcesBinding(device, resource_bindings, &metadata->bindings));
std::vector<shaderc_spvc_resource_location_info> input_stage_locations;
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.GetInputStageLocationInfo(&input_stage_locations),
"Unable to get input stage location information from shader"));
for (const auto& input : input_stage_locations) {
if (metadata->stage == SingleShaderStage::Vertex) {
if (input.location >= kMaxVertexAttributes) {
return DAWN_VALIDATION_ERROR("Attribute location over limits in the SPIRV");
}
metadata->usedVertexAttributes.set(input.location);
} else if (metadata->stage == SingleShaderStage::Fragment) {
// Without a location qualifier on vertex inputs, spirv_cross::CompilerMSL gives
// them all the location 0, causing a compile error.
if (!input.has_location) {
return DAWN_VALIDATION_ERROR("Need location qualifier on fragment input");
}
}
}
std::vector<shaderc_spvc_resource_location_info> output_stage_locations;
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.GetOutputStageLocationInfo(&output_stage_locations),
"Unable to get output stage location information from shader"));
for (const auto& output : output_stage_locations) {
if (metadata->stage == SingleShaderStage::Vertex) {
// Without a location qualifier on vertex outputs, spirv_cross::CompilerMSL
// gives them all the location 0, causing a compile error.
if (!output.has_location) {
return DAWN_VALIDATION_ERROR("Need location qualifier on vertex output");
}
} else if (metadata->stage == SingleShaderStage::Fragment) {
if (output.location >= kMaxColorAttachments) {
return DAWN_VALIDATION_ERROR(
"Fragment output location over limits in the SPIRV");
}
}
}
if (metadata->stage == SingleShaderStage::Fragment) {
std::vector<shaderc_spvc_resource_type_info> output_types;
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.GetOutputStageTypeInfo(&output_types),
"Unable to get output stage type information from shader"));
for (const auto& output : output_types) {
if (output.type == shaderc_spvc_texture_format_type_other) {
return DAWN_VALIDATION_ERROR("Unexpected Fragment output type");
}
metadata->fragmentOutputFormatBaseTypes[output.location] =
ToDawnFormatType(output.type);
}
}
return {std::move(metadata)};
}
ResultOrError<std::unique_ptr<EntryPointMetadata>>
ShaderModuleBase::ExtractSpirvInfoWithSpirvCross(const spirv_cross::Compiler& compiler) {
DeviceBase* device = GetDevice(); DeviceBase* device = GetDevice();
std::unique_ptr<EntryPointMetadata> metadata = std::make_unique<EntryPointMetadata>(); std::unique_ptr<EntryPointMetadata> metadata = std::make_unique<EntryPointMetadata>();
@ -1230,18 +908,6 @@ namespace dawn_native {
return a->mSpirv == b->mSpirv; return a->mSpirv == b->mSpirv;
} }
MaybeError ShaderModuleBase::CheckSpvcSuccess(shaderc_spvc_status status,
const char* error_msg) {
if (status != shaderc_spvc_status_success) {
return DAWN_VALIDATION_ERROR(error_msg);
}
return {};
}
shaderc_spvc::Context* ShaderModuleBase::GetContext() {
return &mSpvcContext;
}
const std::vector<uint32_t>& ShaderModuleBase::GetSpirv() const { const std::vector<uint32_t>& ShaderModuleBase::GetSpirv() const {
return mSpirv; return mSpirv;
} }
@ -1256,15 +922,6 @@ namespace dawn_native {
} }
#endif #endif
shaderc_spvc::CompileOptions ShaderModuleBase::GetCompileOptions() const {
shaderc_spvc::CompileOptions options;
options.SetValidate(GetDevice()->IsValidationEnabled());
options.SetRobustBufferAccessPass(GetDevice()->IsRobustnessEnabled());
options.SetSourceEnvironment(shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_1);
options.SetTargetEnvironment(shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_1);
return options;
}
MaybeError ShaderModuleBase::InitializeBase() { MaybeError ShaderModuleBase::InitializeBase() {
if (mType == Type::Wgsl) { if (mType == Type::Wgsl) {
#ifdef DAWN_ENABLE_WGSL #ifdef DAWN_ENABLE_WGSL

View File

@ -26,8 +26,6 @@
#include "dawn_native/dawn_platform.h" #include "dawn_native/dawn_platform.h"
#include "spvc/spvc.hpp"
#include <bitset> #include <bitset>
#include <map> #include <map>
#include <vector> #include <vector>
@ -113,7 +111,6 @@ namespace dawn_native {
bool operator()(const ShaderModuleBase* a, const ShaderModuleBase* b) const; bool operator()(const ShaderModuleBase* a, const ShaderModuleBase* b) const;
}; };
shaderc_spvc::Context* GetContext();
const std::vector<uint32_t>& GetSpirv() const; const std::vector<uint32_t>& GetSpirv() const;
#ifdef DAWN_ENABLE_WGSL #ifdef DAWN_ENABLE_WGSL
@ -124,12 +121,8 @@ namespace dawn_native {
#endif #endif
protected: protected:
static MaybeError CheckSpvcSuccess(shaderc_spvc_status status, const char* error_msg);
shaderc_spvc::CompileOptions GetCompileOptions() const;
MaybeError InitializeBase(); MaybeError InitializeBase();
shaderc_spvc::Context mSpvcContext;
// Allows backends to get the stage for the "main" entrypoint while they are transitioned to // Allows backends to get the stage for the "main" entrypoint while they are transitioned to
// support multiple entrypoints. // support multiple entrypoints.
// TODO(dawn:216): Remove this once the transition is complete. // TODO(dawn:216): Remove this once the transition is complete.
@ -138,10 +131,7 @@ namespace dawn_native {
private: private:
ShaderModuleBase(DeviceBase* device, ObjectBase::ErrorTag tag); ShaderModuleBase(DeviceBase* device, ObjectBase::ErrorTag tag);
// Different implementations reflection into the shader depending on ResultOrError<std::unique_ptr<EntryPointMetadata>> ExtractSpirvInfoImpl(
// whether using spvc, or directly accessing spirv-cross.
ResultOrError<std::unique_ptr<EntryPointMetadata>> ExtractSpirvInfoWithSpvc();
ResultOrError<std::unique_ptr<EntryPointMetadata>> ExtractSpirvInfoWithSpirvCross(
const spirv_cross::Compiler& compiler); const spirv_cross::Compiler& compiler);
enum class Type { Undefined, Spirv, Wgsl }; enum class Type { Undefined, Spirv, Wgsl };

View File

@ -100,37 +100,9 @@ namespace dawn_native { namespace d3d12 {
DAWN_TRY(InitializeBase()); DAWN_TRY(InitializeBase());
const std::vector<uint32_t>& spirv = GetSpirv(); const std::vector<uint32_t>& spirv = GetSpirv();
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) { spirv_cross::CompilerHLSL compiler(spirv);
shaderc_spvc::CompileOptions options = GetCompileOptions(); DAWN_TRY(ExtractSpirvInfo(compiler));
options.SetForceZeroInitializedVariables(true);
if (GetDevice()->IsExtensionEnabled(Extension::ShaderFloat16)) {
options.SetHLSLShaderModel(ToBackend(GetDevice())->GetDeviceInfo().shaderModel);
options.SetHLSLEnable16BitTypes(true);
} else {
options.SetHLSLShaderModel(51);
}
// PointCoord and PointSize are not supported in HLSL
// TODO (hao.x.li@intel.com): The point_coord_compat and point_size_compat are
// required temporarily for https://bugs.chromium.org/p/dawn/issues/detail?id=146,
// but should be removed once WebGPU requires there is no gl_PointSize builtin.
// See https://github.com/gpuweb/gpuweb/issues/332
options.SetHLSLPointCoordCompat(true);
options.SetHLSLPointSizeCompat(true);
options.SetHLSLNonWritableUAVTextureAsSRV(true);
DAWN_TRY(CheckSpvcSuccess(
mSpvcContext.InitializeForHlsl(spirv.data(), spirv.size(), options),
"Unable to initialize instance of spvc"));
spirv_cross::Compiler* compiler;
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.GetCompiler(reinterpret_cast<void**>(&compiler)),
"Unable to get cross compiler"));
DAWN_TRY(ExtractSpirvInfo(*compiler));
} else {
spirv_cross::CompilerHLSL compiler(spirv);
DAWN_TRY(ExtractSpirvInfo(compiler));
}
return {}; return {};
} }
@ -138,37 +110,32 @@ namespace dawn_native { namespace d3d12 {
ASSERT(!IsError()); ASSERT(!IsError());
const std::vector<uint32_t>& spirv = GetSpirv(); const std::vector<uint32_t>& spirv = GetSpirv();
std::unique_ptr<spirv_cross::CompilerHLSL> compilerImpl; // If these options are changed, the values in DawnSPIRVCrossHLSLFastFuzzer.cpp need to
spirv_cross::CompilerHLSL* compiler = nullptr; // be updated.
if (!GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) { spirv_cross::CompilerGLSL::Options options_glsl;
// If these options are changed, the values in DawnSPIRVCrossHLSLFastFuzzer.cpp need to // Force all uninitialized variables to be 0, otherwise they will fail to compile
// be updated. // by FXC.
spirv_cross::CompilerGLSL::Options options_glsl; options_glsl.force_zero_initialized_variables = true;
// Force all uninitialized variables to be 0, otherwise they will fail to compile
// by FXC.
options_glsl.force_zero_initialized_variables = true;
spirv_cross::CompilerHLSL::Options options_hlsl; spirv_cross::CompilerHLSL::Options options_hlsl;
if (GetDevice()->IsExtensionEnabled(Extension::ShaderFloat16)) { if (GetDevice()->IsExtensionEnabled(Extension::ShaderFloat16)) {
options_hlsl.shader_model = ToBackend(GetDevice())->GetDeviceInfo().shaderModel; options_hlsl.shader_model = ToBackend(GetDevice())->GetDeviceInfo().shaderModel;
options_hlsl.enable_16bit_types = true; options_hlsl.enable_16bit_types = true;
} else { } else {
options_hlsl.shader_model = 51; options_hlsl.shader_model = 51;
}
// PointCoord and PointSize are not supported in HLSL
// TODO (hao.x.li@intel.com): The point_coord_compat and point_size_compat are
// required temporarily for https://bugs.chromium.org/p/dawn/issues/detail?id=146,
// but should be removed once WebGPU requires there is no gl_PointSize builtin.
// See https://github.com/gpuweb/gpuweb/issues/332
options_hlsl.point_coord_compat = true;
options_hlsl.point_size_compat = true;
options_hlsl.nonwritable_uav_texture_as_srv = true;
compilerImpl = std::make_unique<spirv_cross::CompilerHLSL>(spirv);
compiler = compilerImpl.get();
compiler->set_common_options(options_glsl);
compiler->set_hlsl_options(options_hlsl);
} }
// PointCoord and PointSize are not supported in HLSL
// TODO (hao.x.li@intel.com): The point_coord_compat and point_size_compat are
// required temporarily for https://bugs.chromium.org/p/dawn/issues/detail?id=146,
// but should be removed once WebGPU requires there is no gl_PointSize builtin.
// See https://github.com/gpuweb/gpuweb/issues/332
options_hlsl.point_coord_compat = true;
options_hlsl.point_size_compat = true;
options_hlsl.nonwritable_uav_texture_as_srv = true;
spirv_cross::CompilerHLSL compiler(spirv);
compiler.set_common_options(options_glsl);
compiler.set_hlsl_options(options_hlsl);
const EntryPointMetadata::BindingInfo& moduleBindingInfo = const EntryPointMetadata::BindingInfo& moduleBindingInfo =
GetEntryPoint("main", GetMainEntryPointStageForTransition()).bindings; GetEntryPoint("main", GetMainEntryPointStageForTransition()).bindings;
@ -190,38 +157,14 @@ namespace dawn_native { namespace d3d12 {
bgl->GetBindingInfo(bindingIndex).type == wgpu::BindingType::StorageBuffer); bgl->GetBindingInfo(bindingIndex).type == wgpu::BindingType::StorageBuffer);
uint32_t bindingOffset = bindingOffsets[bindingIndex]; uint32_t bindingOffset = bindingOffsets[bindingIndex];
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) { compiler.set_decoration(bindingInfo.id, spv::DecorationBinding, bindingOffset);
DAWN_TRY(CheckSpvcSuccess( if (forceStorageBufferAsUAV) {
mSpvcContext.SetDecoration(bindingInfo.id, SHADERC_SPVC_DECORATION_BINDING, compiler.set_hlsl_force_storage_buffer_as_uav(
bindingOffset), static_cast<uint32_t>(group), static_cast<uint32_t>(bindingNumber));
"Unable to set decorating binding before generating HLSL shader w/ "
"spvc"));
if (forceStorageBufferAsUAV) {
DAWN_TRY(CheckSpvcSuccess(
mSpvcContext.SetHLSLForceStorageBufferAsUAV(
static_cast<uint32_t>(group), static_cast<uint32_t>(bindingNumber)),
"Unable to force read-only storage buffer as UAV w/ spvc"));
}
} else {
compiler->set_decoration(bindingInfo.id, spv::DecorationBinding, bindingOffset);
if (forceStorageBufferAsUAV) {
compiler->set_hlsl_force_storage_buffer_as_uav(
static_cast<uint32_t>(group), static_cast<uint32_t>(bindingNumber));
}
} }
} }
} }
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) { return compiler.compile();
shaderc_spvc::CompilationResult result;
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.CompileShader(&result),
"Unable to generate HLSL shader w/ spvc"));
std::string result_string;
DAWN_TRY(CheckSpvcSuccess(result.GetStringOutput(&result_string),
"Unable to get HLSL shader text"));
return std::move(result_string);
} else {
return compiler->compile();
}
} }
ResultOrError<ComPtr<IDxcBlob>> ShaderModule::CompileShaderDXC(SingleShaderStage stage, ResultOrError<ComPtr<IDxcBlob>> ShaderModule::CompileShaderDXC(SingleShaderStage stage,

View File

@ -63,7 +63,7 @@ namespace dawn_native { namespace metal {
MaybeError Device::Initialize() { MaybeError Device::Initialize() {
InitTogglesFromDriver(); InitTogglesFromDriver();
if (!IsRobustnessEnabled() || !IsToggleEnabled(Toggle::UseSpvc)) { if (!IsRobustnessEnabled()) {
ForceSetToggle(Toggle::MetalEnableVertexPulling, false); ForceSetToggle(Toggle::MetalEnableVertexPulling, false);
} }

View File

@ -55,8 +55,6 @@ namespace dawn_native { namespace metal {
ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor); ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor);
~ShaderModule() override = default; ~ShaderModule() override = default;
MaybeError Initialize(); MaybeError Initialize();
shaderc_spvc::CompileOptions GetMSLCompileOptions(uint32_t sampleMask = 0xFFFFFFFF);
}; };
}} // namespace dawn_native::metal }} // namespace dawn_native::metal

View File

@ -39,20 +39,6 @@ namespace dawn_native { namespace metal {
UNREACHABLE(); UNREACHABLE();
} }
} }
shaderc_spvc_execution_model ToSpvcExecutionModel(SingleShaderStage stage) {
switch (stage) {
case SingleShaderStage::Vertex:
return shaderc_spvc_execution_model_vertex;
case SingleShaderStage::Fragment:
return shaderc_spvc_execution_model_fragment;
case SingleShaderStage::Compute:
return shaderc_spvc_execution_model_glcompute;
default:
UNREACHABLE();
return shaderc_spvc_execution_model_invalid;
}
}
} // namespace } // namespace
// static // static
@ -71,21 +57,9 @@ namespace dawn_native { namespace metal {
DAWN_TRY(InitializeBase()); DAWN_TRY(InitializeBase());
const std::vector<uint32_t>& spirv = GetSpirv(); const std::vector<uint32_t>& spirv = GetSpirv();
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) { spirv_cross::CompilerMSL compiler(spirv);
shaderc_spvc::CompileOptions options = GetMSLCompileOptions(); DAWN_TRY(ExtractSpirvInfo(compiler));
DAWN_TRY(
CheckSpvcSuccess(mSpvcContext.InitializeForMsl(spirv.data(), spirv.size(), options),
"Unable to initialize instance of spvc"));
spirv_cross::CompilerMSL* compiler;
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.GetCompiler(reinterpret_cast<void**>(&compiler)),
"Unable to get cross compiler"));
DAWN_TRY(ExtractSpirvInfo(*compiler));
} else {
spirv_cross::CompilerMSL compiler(spirv);
DAWN_TRY(ExtractSpirvInfo(compiler));
}
return {}; return {};
} }
@ -112,39 +86,25 @@ namespace dawn_native { namespace metal {
} }
#endif #endif
std::unique_ptr<spirv_cross::CompilerMSL> compilerImpl; // If these options are changed, the values in DawnSPIRVCrossMSLFastFuzzer.cpp need to
spirv_cross::CompilerMSL* compiler; // be updated.
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) { spirv_cross::CompilerMSL::Options options_msl;
// Initializing the compiler is needed every call, because this method uses reflection
// to mutate the compiler's IR.
DAWN_TRY(
CheckSpvcSuccess(mSpvcContext.InitializeForMsl(spirv->data(), spirv->size(),
GetMSLCompileOptions(sampleMask)),
"Unable to initialize instance of spvc"));
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.GetCompiler(reinterpret_cast<void**>(&compiler)),
"Unable to get cross compiler"));
} else {
// If these options are changed, the values in DawnSPIRVCrossMSLFastFuzzer.cpp need to
// be updated.
spirv_cross::CompilerMSL::Options options_msl;
// Disable PointSize builtin for https://bugs.chromium.org/p/dawn/issues/detail?id=146 // Disable PointSize builtin for https://bugs.chromium.org/p/dawn/issues/detail?id=146
// Because Metal will reject PointSize builtin if the shader is compiled into a render // Because Metal will reject PointSize builtin if the shader is compiled into a render
// pipeline that uses a non-point topology. // pipeline that uses a non-point topology.
// TODO (hao.x.li@intel.com): Remove this once WebGPU requires there is no // TODO (hao.x.li@intel.com): Remove this once WebGPU requires there is no
// gl_PointSize builtin (https://github.com/gpuweb/gpuweb/issues/332). // gl_PointSize builtin (https://github.com/gpuweb/gpuweb/issues/332).
options_msl.enable_point_size_builtin = false; options_msl.enable_point_size_builtin = false;
// Always use vertex buffer 30 (the last one in the vertex buffer table) to contain // Always use vertex buffer 30 (the last one in the vertex buffer table) to contain
// the shader storage buffer lengths. // the shader storage buffer lengths.
options_msl.buffer_size_buffer_index = kBufferLengthBufferSlot; options_msl.buffer_size_buffer_index = kBufferLengthBufferSlot;
options_msl.additional_fixed_sample_mask = sampleMask; options_msl.additional_fixed_sample_mask = sampleMask;
compilerImpl = std::make_unique<spirv_cross::CompilerMSL>(*spirv); spirv_cross::CompilerMSL compiler(*spirv);
compiler = compilerImpl.get(); compiler.set_msl_options(options_msl);
compiler->set_msl_options(options_msl);
}
// By default SPIRV-Cross will give MSL resources indices in increasing order. // By default SPIRV-Cross will give MSL resources indices in increasing order.
// To make the MSL indices match the indices chosen in the PipelineLayout, we build // To make the MSL indices match the indices chosen in the PipelineLayout, we build
@ -164,25 +124,14 @@ namespace dawn_native { namespace metal {
for (auto stage : IterateStages(bindingInfo.visibility)) { for (auto stage : IterateStages(bindingInfo.visibility)) {
uint32_t shaderIndex = layout->GetBindingIndexInfo(stage)[group][bindingIndex]; uint32_t shaderIndex = layout->GetBindingIndexInfo(stage)[group][bindingIndex];
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) { spirv_cross::MSLResourceBinding mslBinding;
shaderc_spvc_msl_resource_binding mslBinding; mslBinding.stage = SpirvExecutionModelForStage(stage);
mslBinding.stage = ToSpvcExecutionModel(stage); mslBinding.desc_set = static_cast<uint32_t>(group);
mslBinding.desc_set = static_cast<uint32_t>(group); mslBinding.binding = static_cast<uint32_t>(bindingNumber);
mslBinding.binding = static_cast<uint32_t>(bindingNumber); mslBinding.msl_buffer = mslBinding.msl_texture = mslBinding.msl_sampler =
mslBinding.msl_buffer = mslBinding.msl_texture = mslBinding.msl_sampler = shaderIndex;
shaderIndex;
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.AddMSLResourceBinding(mslBinding),
"Unable to add MSL Resource Binding"));
} else {
spirv_cross::MSLResourceBinding mslBinding;
mslBinding.stage = SpirvExecutionModelForStage(stage);
mslBinding.desc_set = static_cast<uint32_t>(group);
mslBinding.binding = static_cast<uint32_t>(bindingNumber);
mslBinding.msl_buffer = mslBinding.msl_texture = mslBinding.msl_sampler =
shaderIndex;
compiler->add_msl_resource_binding(mslBinding); compiler.add_msl_resource_binding(mslBinding);
}
} }
} }
} }
@ -193,45 +142,27 @@ namespace dawn_native { namespace metal {
for (uint32_t dawnIndex : IterateBitSet(renderPipeline->GetVertexBufferSlotsUsed())) { for (uint32_t dawnIndex : IterateBitSet(renderPipeline->GetVertexBufferSlotsUsed())) {
uint32_t metalIndex = renderPipeline->GetMtlVertexBufferIndex(dawnIndex); uint32_t metalIndex = renderPipeline->GetMtlVertexBufferIndex(dawnIndex);
shaderc_spvc_msl_resource_binding mslBinding; spirv_cross::MSLResourceBinding mslBinding;
mslBinding.stage = ToSpvcExecutionModel(SingleShaderStage::Vertex);
mslBinding.stage = SpirvExecutionModelForStage(SingleShaderStage::Vertex);
mslBinding.desc_set = kPullingBufferBindingSet; mslBinding.desc_set = kPullingBufferBindingSet;
mslBinding.binding = dawnIndex; mslBinding.binding = dawnIndex;
mslBinding.msl_buffer = metalIndex; mslBinding.msl_buffer = metalIndex;
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.AddMSLResourceBinding(mslBinding), compiler.add_msl_resource_binding(mslBinding);
"Unable to add MSL Resource Binding"));
} }
} }
{ {
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) { spv::ExecutionModel executionModel = SpirvExecutionModelForStage(functionStage);
shaderc_spvc_execution_model executionModel = ToSpvcExecutionModel(functionStage); auto size = compiler.get_entry_point(functionName, executionModel).workgroup_size;
shaderc_spvc_workgroup_size size; out->localWorkgroupSize = MTLSizeMake(size.x, size.y, size.z);
DAWN_TRY(CheckSpvcSuccess(
mSpvcContext.GetWorkgroupSize(functionName, executionModel, &size),
"Unable to get workgroup size for shader"));
out->localWorkgroupSize = MTLSizeMake(size.x, size.y, size.z);
} else {
spv::ExecutionModel executionModel = SpirvExecutionModelForStage(functionStage);
auto size = compiler->get_entry_point(functionName, executionModel).workgroup_size;
out->localWorkgroupSize = MTLSizeMake(size.x, size.y, size.z);
}
} }
{ {
// SPIRV-Cross also supports re-ordering attributes but it seems to do the correct thing // SPIRV-Cross also supports re-ordering attributes but it seems to do the correct thing
// by default. // by default.
NSString* mslSource; NSString* mslSource;
std::string msl; std::string msl = compiler.compile();
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) {
shaderc_spvc::CompilationResult result;
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.CompileShader(&result),
"Unable to compile MSL shader"));
DAWN_TRY(CheckSpvcSuccess(result.GetStringOutput(&msl),
"Unable to get MSL shader text"));
} else {
msl = compiler->compile();
}
// Metal uses Clang to compile the shader as C++14. Disable everything in the -Wall // Metal uses Clang to compile the shader as C++14. Disable everything in the -Wall
// category. -Wunused-variable in particular comes up a lot in generated code, and some // category. -Wunused-variable in particular comes up a lot in generated code, and some
// (old?) Metal drivers accidentally treat it as a MTLLibraryErrorCompileError instead // (old?) Metal drivers accidentally treat it as a MTLLibraryErrorCompileError instead
@ -272,13 +203,7 @@ namespace dawn_native { namespace metal {
[library release]; [library release];
} }
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) { out->needsStorageBufferLength = compiler.needs_buffer_size_buffer();
DAWN_TRY(
CheckSpvcSuccess(mSpvcContext.NeedsBufferSizeBuffer(&out->needsStorageBufferLength),
"Unable to determine if shader needs buffer size buffer"));
} else {
out->needsStorageBufferLength = compiler->needs_buffer_size_buffer();
}
if (GetDevice()->IsToggleEnabled(Toggle::MetalEnableVertexPulling) && if (GetDevice()->IsToggleEnabled(Toggle::MetalEnableVertexPulling) &&
GetEntryPoint(functionName, functionStage).usedVertexAttributes.any()) { GetEntryPoint(functionName, functionStage).usedVertexAttributes.any()) {
@ -287,26 +212,4 @@ namespace dawn_native { namespace metal {
return {}; return {};
} }
shaderc_spvc::CompileOptions ShaderModule::GetMSLCompileOptions(uint32_t sampleMask) {
// If these options are changed, the values in DawnSPIRVCrossGLSLFastFuzzer.cpp need to
// be updated.
shaderc_spvc::CompileOptions options = GetCompileOptions();
// Disable PointSize builtin for https://bugs.chromium.org/p/dawn/issues/detail?id=146
// Because Metal will reject PointSize builtin if the shader is compiled into a render
// pipeline that uses a non-point topology.
// TODO (hao.x.li@intel.com): Remove this once WebGPU requires there is no
// gl_PointSize builtin (https://github.com/gpuweb/gpuweb/issues/332).
options.SetMSLEnablePointSizeBuiltIn(false);
// Always use vertex buffer 30 (the last one in the vertex buffer table) to contain
// the shader storage buffer lengths.
options.SetMSLBufferSizeBufferIndex(kBufferLengthBufferSlot);
options.SetMSLAdditionalFixedSampleMask(sampleMask);
return options;
}
}} // namespace dawn_native::metal }} // namespace dawn_native::metal

View File

@ -129,27 +129,8 @@ namespace dawn_native { namespace null {
ResultOrError<ShaderModuleBase*> Device::CreateShaderModuleImpl( ResultOrError<ShaderModuleBase*> Device::CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) { const ShaderModuleDescriptor* descriptor) {
Ref<ShaderModule> module = AcquireRef(new ShaderModule(this, descriptor)); Ref<ShaderModule> module = AcquireRef(new ShaderModule(this, descriptor));
spirv_cross::Compiler compiler(module->GetSpirv());
if (IsToggleEnabled(Toggle::UseSpvc)) { DAWN_TRY(module->ExtractSpirvInfo(compiler));
shaderc_spvc::CompileOptions options;
options.SetValidate(IsValidationEnabled());
shaderc_spvc::Context* context = module->GetContext();
shaderc_spvc_status status = context->InitializeForGlsl(
module->GetSpirv().data(), module->GetSpirv().size(), options);
if (status != shaderc_spvc_status_success) {
return DAWN_VALIDATION_ERROR("Unable to initialize instance of spvc");
}
spirv_cross::Compiler* compiler;
status = context->GetCompiler(reinterpret_cast<void**>(&compiler));
if (status != shaderc_spvc_status_success) {
return DAWN_VALIDATION_ERROR("Unable to get cross compiler");
}
DAWN_TRY(module->ExtractSpirvInfo(*compiler));
} else {
spirv_cross::Compiler compiler(module->GetSpirv());
DAWN_TRY(module->ExtractSpirvInfo(compiler));
}
return module.Detach(); return module.Detach();
} }
ResultOrError<SwapChainBase*> Device::CreateSwapChainImpl( ResultOrError<SwapChainBase*> Device::CreateSwapChainImpl(

View File

@ -74,110 +74,47 @@ namespace dawn_native { namespace opengl {
DAWN_TRY(InitializeBase()); DAWN_TRY(InitializeBase());
const std::vector<uint32_t>& spirv = GetSpirv(); const std::vector<uint32_t>& spirv = GetSpirv();
std::unique_ptr<spirv_cross::CompilerGLSL> compilerImpl; // If these options are changed, the values in DawnSPIRVCrossGLSLFastFuzzer.cpp need to
spirv_cross::CompilerGLSL* compiler; // be updated.
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) { spirv_cross::CompilerGLSL::Options options;
// If these options are changed, the values in DawnSPIRVCrossGLSLFastFuzzer.cpp need to
// be updated.
shaderc_spvc::CompileOptions options = GetCompileOptions();
// The range of Z-coordinate in the clipping volume of OpenGL is [-w, w], while it is // The range of Z-coordinate in the clipping volume of OpenGL is [-w, w], while it is
// [0, w] in D3D12, Metal and Vulkan, so we should normalize it in shaders in all // [0, w] in D3D12, Metal and Vulkan, so we should normalize it in shaders in all
// backends. See the documentation of // backends. See the documentation of
// spirv_cross::CompilerGLSL::Options::vertex::fixup_clipspace for more details. // spirv_cross::CompilerGLSL::Options::vertex::fixup_clipspace for more details.
options.SetFlipVertY(true); options.vertex.flip_vert_y = true;
options.SetFixupClipspace(true); options.vertex.fixup_clipspace = true;
// TODO(cwallez@chromium.org): discover the backing context version and use that. // TODO(cwallez@chromium.org): discover the backing context version and use that.
#if defined(DAWN_PLATFORM_APPLE) #if defined(DAWN_PLATFORM_APPLE)
options.SetGLSLLanguageVersion(410); options.version = 410;
#else #else
options.SetGLSLLanguageVersion(440); options.version = 440;
#endif
DAWN_TRY(CheckSpvcSuccess(
mSpvcContext.InitializeForGlsl(spirv.data(), spirv.size(), options),
"Unable to initialize instance of spvc"));
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.GetCompiler(reinterpret_cast<void**>(&compiler)),
"Unable to get cross compiler"));
} else {
// If these options are changed, the values in DawnSPIRVCrossGLSLFastFuzzer.cpp need to
// be updated.
spirv_cross::CompilerGLSL::Options options;
// The range of Z-coordinate in the clipping volume of OpenGL is [-w, w], while it is
// [0, w] in D3D12, Metal and Vulkan, so we should normalize it in shaders in all
// backends. See the documentation of
// spirv_cross::CompilerGLSL::Options::vertex::fixup_clipspace for more details.
options.vertex.flip_vert_y = true;
options.vertex.fixup_clipspace = true;
// TODO(cwallez@chromium.org): discover the backing context version and use that.
#if defined(DAWN_PLATFORM_APPLE)
options.version = 410;
#else
options.version = 440;
#endif #endif
compilerImpl = std::make_unique<spirv_cross::CompilerGLSL>(spirv); spirv_cross::CompilerGLSL compiler(spirv);
compiler = compilerImpl.get(); compiler.set_common_options(options);
compiler->set_common_options(options);
}
DAWN_TRY(ExtractSpirvInfo(*compiler)); DAWN_TRY(ExtractSpirvInfo(compiler));
// Extract bindings names so that it can be used to get its location in program. // Extract bindings names so that it can be used to get its location in program.
// Now translate the separate sampler / textures into combined ones and store their info. // Now translate the separate sampler / textures into combined ones and store their info.
// We need to do this before removing the set and binding decorations. // We need to do this before removing the set and binding decorations.
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) { compiler.build_combined_image_samplers();
mSpvcContext.BuildCombinedImageSamplers();
} else {
compiler->build_combined_image_samplers();
}
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) { for (const auto& combined : compiler.get_combined_image_samplers()) {
std::vector<shaderc_spvc_combined_image_sampler> samplers; mCombinedInfo.emplace_back();
mSpvcContext.GetCombinedImageSamplers(&samplers);
for (auto sampler : samplers) {
mCombinedInfo.emplace_back();
auto& info = mCombinedInfo.back();
uint32_t samplerGroup; auto& info = mCombinedInfo.back();
mSpvcContext.GetDecoration(sampler.sampler_id, info.samplerLocation.group = BindGroupIndex(
shaderc_spvc_decoration_descriptorset, &samplerGroup); compiler.get_decoration(combined.sampler_id, spv::DecorationDescriptorSet));
info.samplerLocation.group = BindGroupIndex(samplerGroup); info.samplerLocation.binding =
BindingNumber(compiler.get_decoration(combined.sampler_id, spv::DecorationBinding));
uint32_t samplerBinding; info.textureLocation.group = BindGroupIndex(
mSpvcContext.GetDecoration(sampler.sampler_id, shaderc_spvc_decoration_binding, compiler.get_decoration(combined.image_id, spv::DecorationDescriptorSet));
&samplerBinding); info.textureLocation.binding =
info.samplerLocation.binding = BindingNumber(samplerBinding); BindingNumber(compiler.get_decoration(combined.image_id, spv::DecorationBinding));
compiler.set_name(combined.combined_id, info.GetName());
uint32_t textureGroup;
mSpvcContext.GetDecoration(sampler.image_id, shaderc_spvc_decoration_descriptorset,
&textureGroup);
info.textureLocation.group = BindGroupIndex(textureGroup);
uint32_t textureBinding;
mSpvcContext.GetDecoration(sampler.image_id, shaderc_spvc_decoration_binding,
&textureBinding);
info.textureLocation.binding = BindingNumber(textureBinding);
mSpvcContext.SetName(sampler.combined_id, info.GetName());
}
} else {
for (const auto& combined : compiler->get_combined_image_samplers()) {
mCombinedInfo.emplace_back();
auto& info = mCombinedInfo.back();
info.samplerLocation.group = BindGroupIndex(
compiler->get_decoration(combined.sampler_id, spv::DecorationDescriptorSet));
info.samplerLocation.binding = BindingNumber(
compiler->get_decoration(combined.sampler_id, spv::DecorationBinding));
info.textureLocation.group = BindGroupIndex(
compiler->get_decoration(combined.image_id, spv::DecorationDescriptorSet));
info.textureLocation.binding = BindingNumber(
compiler->get_decoration(combined.image_id, spv::DecorationBinding));
compiler->set_name(combined.combined_id, info.GetName());
}
} }
const EntryPointMetadata::BindingInfo& bindingInfo = const EntryPointMetadata::BindingInfo& bindingInfo =
@ -205,27 +142,14 @@ namespace dawn_native { namespace opengl {
break; break;
} }
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) { compiler.set_name(resourceId, GetBindingName(group, bindingNumber));
mSpvcContext.SetName(resourceId, GetBindingName(group, bindingNumber)); compiler.unset_decoration(info.id, spv::DecorationBinding);
mSpvcContext.UnsetDecoration(info.id, shaderc_spvc_decoration_binding); compiler.unset_decoration(info.id, spv::DecorationDescriptorSet);
mSpvcContext.UnsetDecoration(info.id, shaderc_spvc_decoration_descriptorset);
} else {
compiler->set_name(resourceId, GetBindingName(group, bindingNumber));
compiler->unset_decoration(info.id, spv::DecorationBinding);
compiler->unset_decoration(info.id, spv::DecorationDescriptorSet);
}
} }
} }
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) { mGlslSource = compiler.compile();
shaderc_spvc::CompilationResult result;
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.CompileShader(&result),
"Unable to compile GLSL shader using spvc"));
DAWN_TRY(CheckSpvcSuccess(result.GetStringOutput(&mGlslSource),
"Unable to get GLSL shader text"));
} else {
mGlslSource = compiler->compile();
}
return {}; return {};
} }

View File

@ -42,39 +42,16 @@ namespace dawn_native { namespace vulkan {
// Use SPIRV-Cross to extract info from the SPIRV even if Vulkan consumes SPIRV. We want to // Use SPIRV-Cross to extract info from the SPIRV even if Vulkan consumes SPIRV. We want to
// have a translation step eventually anyway. // have a translation step eventually anyway.
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) { spirv_cross::Compiler compiler(spirv);
shaderc_spvc::CompileOptions options = GetCompileOptions(); DAWN_TRY(ExtractSpirvInfo(compiler));
DAWN_TRY(CheckSpvcSuccess(
mSpvcContext.InitializeForVulkan(spirv.data(), spirv.size(), options),
"Unable to initialize instance of spvc"));
spirv_cross::Compiler* compiler;
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.GetCompiler(reinterpret_cast<void**>(&compiler)),
"Unable to get cross compiler"));
DAWN_TRY(ExtractSpirvInfo(*compiler));
} else {
spirv_cross::Compiler compiler(spirv);
DAWN_TRY(ExtractSpirvInfo(compiler));
}
VkShaderModuleCreateInfo createInfo; VkShaderModuleCreateInfo createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
createInfo.pNext = nullptr; createInfo.pNext = nullptr;
createInfo.flags = 0; createInfo.flags = 0;
std::vector<uint32_t> vulkanSource; std::vector<uint32_t> vulkanSource;
if (GetDevice()->IsToggleEnabled(Toggle::UseSpvc)) { createInfo.codeSize = spirv.size() * sizeof(uint32_t);
shaderc_spvc::CompilationResult result; createInfo.pCode = spirv.data();
DAWN_TRY(CheckSpvcSuccess(mSpvcContext.CompileShader(&result),
"Unable to generate Vulkan shader"));
DAWN_TRY(CheckSpvcSuccess(result.GetBinaryOutput(&vulkanSource),
"Unable to get binary output of Vulkan shader"));
createInfo.codeSize = vulkanSource.size() * sizeof(uint32_t);
createInfo.pCode = vulkanSource.data();
} else {
createInfo.codeSize = spirv.size() * sizeof(uint32_t);
createInfo.pCode = spirv.data();
}
Device* device = ToBackend(GetDevice()); Device* device = ToBackend(GetDevice());
return CheckVkSuccess( return CheckVkSuccess(

View File

@ -74,7 +74,10 @@ static_library("dawn_spirv_cross_fuzzer_common") {
"DawnSPIRVCrossFuzzer.cpp", "DawnSPIRVCrossFuzzer.cpp",
"DawnSPIRVCrossFuzzer.h", "DawnSPIRVCrossFuzzer.h",
] ]
public_deps = [ "${dawn_shaderc_dir}:libshaderc_spvc" ] public_deps = [
"${dawn_root}/third_party/gn/spirv_cross:spirv_cross",
"${dawn_spirv_tools_dir}:spvtools_val",
]
} }
static_library("dawn_wire_server_fuzzer_common") { static_library("dawn_wire_server_fuzzer_common") {
@ -119,21 +122,6 @@ dawn_fuzzer_test("dawn_spirv_cross_msl_fast_fuzzer") {
asan_options = [ "allow_user_segv_handler=1" ] asan_options = [ "allow_user_segv_handler=1" ]
} }
dawn_fuzzer_test("dawn_spvc_glsl_fast_fuzzer") {
sources = [ "DawnSPVCglslFastFuzzer.cpp" ]
deps = [ "${dawn_shaderc_dir}:libshaderc_spvc" ]
}
dawn_fuzzer_test("dawn_spvc_hlsl_fast_fuzzer") {
sources = [ "DawnSPVChlslFastFuzzer.cpp" ]
deps = [ "${dawn_shaderc_dir}:libshaderc_spvc" ]
}
dawn_fuzzer_test("dawn_spvc_msl_fast_fuzzer") {
sources = [ "DawnSPVCmslFastFuzzer.cpp" ]
deps = [ "${dawn_shaderc_dir}:libshaderc_spvc" ]
}
dawn_fuzzer_test("dawn_wire_server_and_frontend_fuzzer") { dawn_fuzzer_test("dawn_wire_server_and_frontend_fuzzer") {
sources = [ "DawnWireServerAndFrontendFuzzer.cpp" ] sources = [ "DawnWireServerAndFrontendFuzzer.cpp" ]
@ -167,9 +155,6 @@ group("dawn_fuzzers") {
":dawn_spirv_cross_glsl_fast_fuzzer", ":dawn_spirv_cross_glsl_fast_fuzzer",
":dawn_spirv_cross_hlsl_fast_fuzzer", ":dawn_spirv_cross_hlsl_fast_fuzzer",
":dawn_spirv_cross_msl_fast_fuzzer", ":dawn_spirv_cross_msl_fast_fuzzer",
":dawn_spvc_glsl_fast_fuzzer",
":dawn_spvc_hlsl_fast_fuzzer",
":dawn_spvc_msl_fast_fuzzer",
":dawn_wire_server_and_frontend_fuzzer", ":dawn_wire_server_and_frontend_fuzzer",
":dawn_wire_server_and_vulkan_backend_fuzzer", ":dawn_wire_server_and_vulkan_backend_fuzzer",
] ]

View File

@ -15,9 +15,12 @@
#include <csetjmp> #include <csetjmp>
#include <csignal> #include <csignal>
#include <cstdint> #include <cstdint>
#include <sstream>
#include <string> #include <string>
#include <vector> #include <vector>
#include <spirv-tools/libspirv.hpp>
#include "DawnSPIRVCrossFuzzer.h" #include "DawnSPIRVCrossFuzzer.h"
namespace { namespace {
@ -26,12 +29,8 @@ namespace {
void (*old_signal_handler)(int); void (*old_signal_handler)(int);
// Handler to trap signals, so that it doesn't crash the fuzzer when running // Handler to trap signals, so that it doesn't crash the fuzzer when running
// the code under test. Currently the // the code under test. The code being fuzzed uses abort() to report errors
// code being fuzzed uses abort() to report errors like bad input instead of // like bad input instead of returning an error code.
// returning an error code. This will be changing in the future.
//
// TODO(rharrison): Remove all of this signal trapping once SPIRV-Cross has
// been changed to not use abort() for reporting errors.
[[noreturn]] static void sigabrt_trap(int sig) { [[noreturn]] static void sigabrt_trap(int sig) {
std::longjmp(jump_buffer, 1); std::longjmp(jump_buffer, 1);
} }
@ -69,6 +68,16 @@ namespace DawnSPIRVCrossFuzzer {
const uint32_t* u32Data = reinterpret_cast<const uint32_t*>(data); const uint32_t* u32Data = reinterpret_cast<const uint32_t*>(data);
std::vector<uint32_t> input(u32Data, u32Data + sizeInU32); std::vector<uint32_t> input(u32Data, u32Data + sizeInU32);
spvtools::SpirvTools spirvTools(SPV_ENV_VULKAN_1_1);
spirvTools.SetMessageConsumer(
[](spv_message_level_t, const char*, const spv_position_t&, const char*) {});
// Dawn is responsible to validating input before it goes into
// SPIRV-Cross.
if (!spirvTools.Validate(input.data(), input.size())) {
return 0;
}
if (input.size() != 0) { if (input.size() != 0) {
task(input); task(input);
} }

View File

@ -16,13 +16,9 @@
#include <functional> #include <functional>
#include <vector> #include <vector>
#include "spvc/spvc.hpp"
namespace DawnSPIRVCrossFuzzer { namespace DawnSPIRVCrossFuzzer {
using Task = std::function<int(const std::vector<uint32_t>&)>; using Task = std::function<int(const std::vector<uint32_t>&)>;
using TaskWithOptions =
std::function<int(const std::vector<uint32_t>&, shaderc_spvc::CompileOptions)>;
// Used to wrap code that may fire a SIGABRT. Do not allocate anything local within |exec|, as // Used to wrap code that may fire a SIGABRT. Do not allocate anything local within |exec|, as
// it is not guaranteed to return. // it is not guaranteed to return.

View File

@ -16,29 +16,25 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <spirv_glsl.hpp>
#include "DawnSPIRVCrossFuzzer.h" #include "DawnSPIRVCrossFuzzer.h"
namespace { namespace {
int GLSLFastFuzzTask(const std::vector<uint32_t>& input) { int GLSLFastFuzzTask(const std::vector<uint32_t>& input) {
shaderc_spvc::Context context; // Values come from ShaderModuleGL.cpp
if (!context.IsValid()) { spirv_cross::CompilerGLSL::Options options;
return 0; options.vertex.flip_vert_y = true;
} options.vertex.fixup_clipspace = true;
#if defined(DAWN_PLATFORM_APPLE)
options.version = 410;
#else
options.version = 440;
#endif
DawnSPIRVCrossFuzzer::ExecuteWithSignalTrap([&context, &input]() { spirv_cross::CompilerGLSL compiler(input);
shaderc_spvc::CompilationResult result; compiler.set_common_options(options);
shaderc_spvc::CompileOptions options; compiler.compile();
options.SetSourceEnvironment(shaderc_target_env_webgpu, shaderc_env_version_webgpu);
options.SetTargetEnvironment(shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_1);
// Using the options that are used by Dawn, they appear in ShaderModuleGL.cpp
options.SetGLSLLanguageVersion(440);
options.SetFixupClipspace(true);
if (context.InitializeForGlsl(input.data(), input.size(), options) ==
shaderc_spvc_status_success) {
context.CompileShader(&result);
}
});
return 0; return 0;
} }

View File

@ -16,40 +16,32 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <spirv_hlsl.hpp>
#include "DawnSPIRVCrossFuzzer.h" #include "DawnSPIRVCrossFuzzer.h"
namespace { namespace {
int FuzzTask(const std::vector<uint32_t>& input) { int FuzzTask(const std::vector<uint32_t>& input) {
shaderc_spvc::Context context; // Values come from ShaderModuleD3D12.cpp
if (!context.IsValid()) { spirv_cross::CompilerGLSL::Options options_glsl;
return 0; // Force all uninitialized variables to be 0, otherwise they will fail to compile
} // by FXC.
options_glsl.force_zero_initialized_variables = true;
DawnSPIRVCrossFuzzer::ExecuteWithSignalTrap([&context, &input]() { spirv_cross::CompilerHLSL::Options options_hlsl;
shaderc_spvc::CompilationResult result; options_hlsl.shader_model = 51;
shaderc_spvc::CompileOptions options; options_hlsl.point_coord_compat = true;
options.SetSourceEnvironment(shaderc_target_env_webgpu, shaderc_env_version_webgpu); options_hlsl.point_size_compat = true;
options.SetTargetEnvironment(shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_1); options_hlsl.nonwritable_uav_texture_as_srv = true;
// Using the options that are used by Dawn, they appear in ShaderModuleD3D12.cpp spirv_cross::CompilerHLSL compiler(input);
options.SetForceZeroInitializedVariables(true); compiler.set_common_options(options_glsl);
options.SetHLSLShaderModel(51); compiler.set_hlsl_options(options_hlsl);
// TODO (hao.x.li@intel.com): The HLSLPointCoordCompat and HLSLPointSizeCompat are compiler.compile();
// required temporarily for https://bugs.chromium.org/p/dawn/issues/detail?id=146,
// but should be removed once WebGPU requires there is no gl_PointSize builtin.
// See https://github.com/gpuweb/gpuweb/issues/332
options.SetHLSLPointCoordCompat(true);
options.SetHLSLPointSizeCompat(true);
if (context.InitializeForHlsl(input.data(), input.size(), options) ==
shaderc_spvc_status_success) {
context.CompileShader(&result);
}
});
return 0; return 0;
} }
} // namespace } // namespace
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) { extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {

View File

@ -16,28 +16,21 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <spirv_msl.hpp>
#include "DawnSPIRVCrossFuzzer.h" #include "DawnSPIRVCrossFuzzer.h"
namespace { namespace {
int FuzzTask(const std::vector<uint32_t>& input) { int FuzzTask(const std::vector<uint32_t>& input) {
shaderc_spvc::Context context; // Values come from ShaderModuleMTL.mm
if (!context.IsValid()) { spirv_cross::CompilerMSL::Options options_msl;
return 0; options_msl.enable_point_size_builtin = false;
} options_msl.buffer_size_buffer_index = 30;
DawnSPIRVCrossFuzzer::ExecuteWithSignalTrap([&context, &input]() { spirv_cross::CompilerMSL compiler(input);
shaderc_spvc::CompilationResult result; compiler.set_msl_options(options_msl);
shaderc_spvc::CompileOptions options; compiler.compile();
options.SetSourceEnvironment(shaderc_target_env_webgpu, shaderc_env_version_webgpu);
options.SetTargetEnvironment(shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_1);
// Using the options that are used by Dawn, they appear in ShaderModuleMTL.mm
if (context.InitializeForMsl(input.data(), input.size(), options) ==
shaderc_spvc_status_success) {
context.CompileShader(&result);
}
});
return 0; return 0;
} }

View File

@ -1,57 +0,0 @@
// Copyright 2019 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 <cstdint>
#include <string>
#include <vector>
#include "spvc/spvc.hpp"
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
return 0;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
shaderc_spvc::Context context;
if (!context.IsValid()) {
return 0;
}
shaderc_spvc::CompilationResult result;
shaderc_spvc::CompileOptions options;
options.SetSourceEnvironment(shaderc_target_env_webgpu, shaderc_env_version_webgpu);
options.SetTargetEnvironment(shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_1);
// Using the options that are used by Dawn, they appear in ShaderModuleGL.cpp
// TODO(sarahM0): double check these option after completion of spvc integration
options.SetFlipVertY(true);
options.SetFixupClipspace(true);
#if defined(DAWN_PLATFORM_APPLE)
options.SetGLSLLanguageVersion(410);
#else
options.SetGLSLLanguageVersion(440);
#endif
size_t sizeInU32 = size / sizeof(uint32_t);
const uint32_t* u32Data = reinterpret_cast<const uint32_t*>(data);
std::vector<uint32_t> input(u32Data, u32Data + sizeInU32);
if (input.size() != 0) {
if (context.InitializeForGlsl(input.data(), input.size(), options) ==
shaderc_spvc_status_success) {
context.SetUseSpvcParser(true);
context.CompileShader(&result);
}
}
return 0;
}

View File

@ -1,57 +0,0 @@
// Copyright 2019 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 <cstdint>
#include <string>
#include <vector>
#include "spvc/spvc.hpp"
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
return 0;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
shaderc_spvc::Context context;
if (!context.IsValid()) {
return 0;
}
shaderc_spvc::CompilationResult result;
shaderc_spvc::CompileOptions options;
options.SetSourceEnvironment(shaderc_target_env_webgpu, shaderc_env_version_webgpu);
options.SetTargetEnvironment(shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_1);
// Using the options that are used by Dawn, they appear in ShaderModuleD3D12.cpp
// TODO(sarahM0): double check these option after completion of spvc integration
options.SetHLSLShaderModel(51);
// TODO (hao.x.li@intel.com): The HLSLPointCoordCompat and HLSLPointSizeCompat are
// required temporarily for https://bugs.chromium.org/p/dawn/issues/detail?id=146,
// but should be removed once WebGPU requires there is no gl_PointSize builtin.
// See https://github.com/gpuweb/gpuweb/issues/332
options.SetHLSLPointCoordCompat(true);
options.SetHLSLPointSizeCompat(true);
size_t sizeInU32 = size / sizeof(uint32_t);
const uint32_t* u32Data = reinterpret_cast<const uint32_t*>(data);
std::vector<uint32_t> input(u32Data, u32Data + sizeInU32);
if (input.size() != 0) {
if (context.InitializeForHlsl(input.data(), input.size(), options) ==
shaderc_spvc_status_success) {
context.CompileShader(&result);
}
}
return 0;
}

View File

@ -1,49 +0,0 @@
// Copyright 2019 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 <cstdint>
#include <string>
#include <vector>
#include "spvc/spvc.hpp"
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
return 0;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
shaderc_spvc::Context context;
if (!context.IsValid()) {
return 0;
}
shaderc_spvc::CompilationResult result;
shaderc_spvc::CompileOptions options;
options.SetSourceEnvironment(shaderc_target_env_webgpu, shaderc_env_version_webgpu);
options.SetTargetEnvironment(shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_1);
// Using the options that are used by Dawn, they appear in ShaderModuleMTL.mm
// TODO(sarahM0): double check these option after completion of spvc integration
size_t sizeInU32 = size / sizeof(uint32_t);
const uint32_t* u32Data = reinterpret_cast<const uint32_t*>(data);
std::vector<uint32_t> input(u32Data, u32Data + sizeInU32);
if (input.size() != 0) {
if (context.InitializeForMsl(input.data(), input.size(), options) ==
shaderc_spvc_status_success) {
context.CompileShader(&result);
}
}
return 0;
}

View File

@ -39,11 +39,7 @@ if (NOT TARGET glslang)
add_subdirectory(${DAWN_GLSLANG_DIR}) add_subdirectory(${DAWN_GLSLANG_DIR})
endif() endif()
if (TARGET shaderc) if (NOT TARGET shaderc)
if (NOT TARGET shaderc_spvc)
message(FATAL_ERROR "Dawn: If shaderc is configured before Dawn, it must include SPVC")
endif()
else()
set(SHADERC_SKIP_TESTS ON CACHE BOOL "" FORCE) set(SHADERC_SKIP_TESTS ON CACHE BOOL "" FORCE)
set(SHADERC_SKIP_INSTALL ON CACHE BOOL "" FORCE) set(SHADERC_SKIP_INSTALL ON CACHE BOOL "" FORCE)
set(SHADERC_ENABLE_SPVC ON CACHE BOOL "" FORCE) set(SHADERC_ENABLE_SPVC ON CACHE BOOL "" FORCE)
@ -56,10 +52,8 @@ else()
# Let SPVC's CMakeLists.txt deal with configuring SPIRV-Cross # Let SPVC's CMakeLists.txt deal with configuring SPIRV-Cross
set(SPIRV_CROSS_ENABLE_TESTS OFF CACHE BOOL "" FORCE) set(SPIRV_CROSS_ENABLE_TESTS OFF CACHE BOOL "" FORCE)
set(SHADERC_SPIRV_CROSS_DIR "${DAWN_SPIRV_CROSS_DIR}" CACHE BOOL "" FORCE)
message(STATUS "Dawn: using shaderc[_spvc] at ${DAWN_SHADERC_DIR}") message(STATUS "Dawn: using shaderc at ${DAWN_SHADERC_DIR}")
message(STATUS "Dawn: - with SPIRV-Cross at ${DAWN_SPIRV_CROSS_DIR}")
add_subdirectory(${DAWN_SHADERC_DIR}) add_subdirectory(${DAWN_SHADERC_DIR})
endif() endif()

70
third_party/gn/spirv_cross/BUILD.gn vendored Normal file
View File

@ -0,0 +1,70 @@
# Copyright 2020 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.
import("../../../scripts/dawn_overrides_with_defaults.gni")
import("//build_overrides/build.gni")
# SPIRV_Cross does not have BUILD.gn rules, so implement our own.
is_msvc = is_win && !is_clang
config("spirv_cross_public") {
include_dirs = [
"${dawn_spirv_cross_dir}",
"${dawn_spirv_cross_dir}/..",
]
defines = [ "SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS" ]
}
config("spirv_cross_internal") {
if (!is_msvc) {
cflags_cc = [
"-Wno-implicit-fallthrough",
"-Wno-return-type",
"-Wno-sign-compare",
]
} else {
# Disable "not all control paths return a value" warning.
cflags_cc = [ "/wd4715" ]
}
}
source_set("spirv_cross") {
public_configs = [ ":spirv_cross_public" ]
configs += [ ":spirv_cross_internal" ]
sources = [
"${dawn_spirv_cross_dir}/GLSL.std.450.h",
"${dawn_spirv_cross_dir}/spirv.hpp",
"${dawn_spirv_cross_dir}/spirv_cfg.cpp",
"${dawn_spirv_cross_dir}/spirv_cfg.hpp",
"${dawn_spirv_cross_dir}/spirv_common.hpp",
"${dawn_spirv_cross_dir}/spirv_cross.cpp",
"${dawn_spirv_cross_dir}/spirv_cross.hpp",
"${dawn_spirv_cross_dir}/spirv_cross_containers.hpp",
"${dawn_spirv_cross_dir}/spirv_cross_error_handling.hpp",
"${dawn_spirv_cross_dir}/spirv_cross_parsed_ir.cpp",
"${dawn_spirv_cross_dir}/spirv_cross_parsed_ir.hpp",
"${dawn_spirv_cross_dir}/spirv_glsl.cpp",
"${dawn_spirv_cross_dir}/spirv_glsl.hpp",
"${dawn_spirv_cross_dir}/spirv_hlsl.cpp",
"${dawn_spirv_cross_dir}/spirv_hlsl.hpp",
"${dawn_spirv_cross_dir}/spirv_msl.cpp",
"${dawn_spirv_cross_dir}/spirv_msl.hpp",
"${dawn_spirv_cross_dir}/spirv_parser.cpp",
"${dawn_spirv_cross_dir}/spirv_parser.hpp",
"${dawn_spirv_cross_dir}/spirv_reflect.cpp",
"${dawn_spirv_cross_dir}/spirv_reflect.hpp",
]
}