Nuke SPIRV-Cross.

Change-Id: I1fc58d50ba3999e3a9b6f4e30a0799be301893de
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/79481
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Stephen White <senorblanco@chromium.org>
This commit is contained in:
Stephen White
2022-02-11 00:45:51 +00:00
committed by Dawn LUCI CQ
parent 0778a4285a
commit a52abab38c
16 changed files with 5 additions and 587 deletions

View File

@@ -165,9 +165,6 @@ source_set("sources") {
"${dawn_spirv_tools_dir}:spvtools_val",
"${dawn_tint_dir}/src:libtint",
]
if (dawn_use_spirv_cross) {
deps += [ "${dawn_root}/third_party/gn/spirv_cross:spirv_cross" ]
}
defines = []
libs = []
data_deps = []
@@ -561,8 +558,6 @@ source_set("sources") {
"opengl/SamplerGL.h",
"opengl/ShaderModuleGL.cpp",
"opengl/ShaderModuleGL.h",
"opengl/SpirvUtils.cpp",
"opengl/SpirvUtils.h",
"opengl/SwapChainGL.cpp",
"opengl/SwapChainGL.h",
"opengl/TextureGL.cpp",

View File

@@ -192,13 +192,6 @@ target_link_libraries(dawn_native
absl_str_format_internal
)
if (DAWN_REQUIRES_SPIRV_CROSS)
target_link_libraries(dawn_native PRIVATE spirv-cross-core)
if (DAWN_ENABLE_OPENGL)
target_link_libraries(dawn_native PRIVATE spirv-cross-glsl)
endif()
endif()
target_include_directories(dawn_native PRIVATE ${DAWN_ABSEIL_DIR})
if (DAWN_USE_X11)
@@ -434,8 +427,6 @@ if (DAWN_ENABLE_OPENGL)
"opengl/SamplerGL.h"
"opengl/ShaderModuleGL.cpp"
"opengl/ShaderModuleGL.h"
"opengl/SpirvUtils.cpp"
"opengl/SpirvUtils.h"
"opengl/SwapChainGL.cpp"
"opengl/SwapChainGL.h"
"opengl/TextureGL.cpp"

View File

@@ -81,7 +81,7 @@ namespace dawn::native::d3d12 {
}
case wgpu::BufferBindingType::Storage:
case kInternalStorageBufferBinding: {
// Since SPIRV-Cross outputs HLSL shaders with RWByteAddressBuffer,
// Since Tint outputs HLSL shaders with RWByteAddressBuffer,
// we must use D3D12_BUFFER_UAV_FLAG_RAW when making the
// UNORDERED_ACCESS_VIEW_DESC. Using D3D12_BUFFER_UAV_FLAG_RAW requires
// that we use DXGI_FORMAT_R32_TYPELESS as the format of the view.
@@ -104,7 +104,7 @@ namespace dawn::native::d3d12 {
break;
}
case wgpu::BufferBindingType::ReadOnlyStorage: {
// Like StorageBuffer, SPIRV-Cross outputs HLSL shaders for readonly
// Like StorageBuffer, Tint outputs HLSL shaders for readonly
// storage buffer with ByteAddressBuffer. So we must use
// D3D12_BUFFER_SRV_FLAG_RAW when making the SRV descriptor. And it has
// similar requirement for format, element size, etc.

View File

@@ -295,7 +295,7 @@ namespace dawn::native::metal {
// Metal uses a physical addressing mode which means buffers in the shading language are
// just pointers to the virtual address of their start. This means there is no way to know
// the length of a buffer to compute the length() of unsized arrays at the end of storage
// buffers. SPIRV-Cross implements the length() of unsized arrays by requiring an extra
// buffers. Tint implements the length() of unsized arrays by requiring an extra
// buffer that contains the length of other buffers. This structure that keeps track of the
// length of storage buffers and can apply them to the reserved "buffer length buffer" when
// needed for a draw or a dispatch.
@@ -303,7 +303,7 @@ namespace dawn::native::metal {
wgpu::ShaderStage dirtyStages = wgpu::ShaderStage::None;
// The lengths of buffers are stored as 32bit integers because that is the width the
// MSL code generated by SPIRV-Cross expects.
// MSL code generated by Tint expects.
// UBOs require we align the max buffer count to 4 elements (16 bytes).
static constexpr size_t MaxBufferCount = ((kGenericMetalBufferSlots + 3) / 4) * 4;
PerStage<std::array<uint32_t, MaxBufferCount>> data;

View File

@@ -14,25 +14,14 @@
#include "dawn/native/opengl/ShaderModuleGL.h"
#include "dawn/common/Assert.h"
#include "dawn/common/Platform.h"
#include "dawn/native/BindGroupLayout.h"
#include "dawn/native/SpirvValidation.h"
#include "dawn/native/TintUtils.h"
#include "dawn/native/opengl/DeviceGL.h"
#include "dawn/native/opengl/PipelineLayoutGL.h"
#include "dawn/native/opengl/SpirvUtils.h"
#include "dawn/platform/DawnPlatform.h"
#include "dawn/platform/tracing/TraceEvent.h"
#include <spirv_glsl.hpp>
// Tint include must be after spirv_glsl.hpp, because spirv-cross has its own
// version of spirv_headers. We also need to undef SPV_REVISION because SPIRV-Cross
// is at 3 while spirv-headers is at 4.
#undef SPV_REVISION
#include <tint/tint.h>
#include <spirv-tools/libspirv.hpp>
#include <sstream>
@@ -68,151 +57,6 @@ namespace dawn::native::opengl {
return o.str();
}
ResultOrError<std::unique_ptr<BindingInfoArray>> ExtractSpirvInfo(
const DeviceBase* device,
const spirv_cross::Compiler& compiler,
const std::string& entryPointName,
SingleShaderStage stage) {
const auto& resources = compiler.get_shader_resources();
// Fill in bindingInfo with the SPIRV bindings
auto ExtractResourcesBinding =
[](const DeviceBase* device,
const spirv_cross::SmallVector<spirv_cross::Resource>& resources,
const spirv_cross::Compiler& compiler, BindingInfoType bindingType,
BindingInfoArray* bindings, bool isStorageBuffer = false) -> MaybeError {
for (const auto& resource : resources) {
DAWN_INVALID_IF(
!compiler.get_decoration_bitset(resource.id).get(spv::DecorationBinding),
"No Binding decoration set for resource");
DAWN_INVALID_IF(
!compiler.get_decoration_bitset(resource.id).get(spv::DecorationDescriptorSet),
"No Descriptor Decoration set for resource");
BindingNumber bindingNumber(
compiler.get_decoration(resource.id, spv::DecorationBinding));
BindGroupIndex bindGroupIndex(
compiler.get_decoration(resource.id, spv::DecorationDescriptorSet));
DAWN_INVALID_IF(bindGroupIndex >= kMaxBindGroupsTyped,
"Bind group index over limits in the SPIRV");
const auto& [entry, inserted] =
(*bindings)[bindGroupIndex].emplace(bindingNumber, ShaderBindingInfo{});
DAWN_INVALID_IF(!inserted, "Shader has duplicate bindings");
ShaderBindingInfo* info = &entry->second;
info->id = resource.id;
info->base_type_id = resource.base_type_id;
info->bindingType = bindingType;
switch (bindingType) {
case BindingInfoType::Texture: {
spirv_cross::SPIRType::ImageType imageType =
compiler.get_type(info->base_type_id).image;
spirv_cross::SPIRType::BaseType textureComponentType =
compiler.get_type(imageType.type).basetype;
info->texture.viewDimension =
SpirvDimToTextureViewDimension(imageType.dim, imageType.arrayed);
info->texture.multisampled = imageType.ms;
info->texture.compatibleSampleTypes =
SpirvBaseTypeToSampleTypeBit(textureComponentType);
if (imageType.depth) {
DAWN_INVALID_IF(
(info->texture.compatibleSampleTypes & SampleTypeBit::Float) == 0,
"Depth textures must have a float type");
info->texture.compatibleSampleTypes = SampleTypeBit::Depth;
}
DAWN_INVALID_IF(imageType.ms && imageType.arrayed,
"Multisampled array textures aren't supported");
break;
}
case BindingInfoType::Buffer: {
// Determine buffer size, with a minimum of 1 element in the runtime
// array
spirv_cross::SPIRType type = compiler.get_type(info->base_type_id);
info->buffer.minBindingSize =
compiler.get_declared_struct_size_runtime_array(type, 1);
// Differentiate between readonly storage bindings and writable ones
// based on the NonWritable decoration.
// TODO(dawn:527): Could isStorageBuffer be determined by calling
// compiler.get_storage_class(resource.id)?
if (isStorageBuffer) {
spirv_cross::Bitset flags =
compiler.get_buffer_block_flags(resource.id);
if (flags.get(spv::DecorationNonWritable)) {
info->buffer.type = wgpu::BufferBindingType::ReadOnlyStorage;
} else {
info->buffer.type = wgpu::BufferBindingType::Storage;
}
} else {
info->buffer.type = wgpu::BufferBindingType::Uniform;
}
break;
}
case BindingInfoType::StorageTexture: {
spirv_cross::Bitset flags = compiler.get_decoration_bitset(resource.id);
DAWN_INVALID_IF(!flags.get(spv::DecorationNonReadable),
"Read-write storage textures are not supported.");
info->storageTexture.access = wgpu::StorageTextureAccess::WriteOnly;
spirv_cross::SPIRType::ImageType imageType =
compiler.get_type(info->base_type_id).image;
wgpu::TextureFormat storageTextureFormat =
SpirvImageFormatToTextureFormat(imageType.format);
DAWN_INVALID_IF(storageTextureFormat == wgpu::TextureFormat::Undefined,
"Invalid image format declaration on storage image.");
const Format& format = device->GetValidInternalFormat(storageTextureFormat);
DAWN_INVALID_IF(!format.supportsStorageUsage,
"The storage texture format (%s) is not supported.",
storageTextureFormat);
DAWN_INVALID_IF(imageType.ms,
"Multisampled storage textures aren't supported.");
DAWN_INVALID_IF(imageType.depth,
"Depth storage textures aren't supported.");
info->storageTexture.format = storageTextureFormat;
info->storageTexture.viewDimension =
SpirvDimToTextureViewDimension(imageType.dim, imageType.arrayed);
break;
}
case BindingInfoType::Sampler: {
info->sampler.isComparison = false;
break;
}
case BindingInfoType::ExternalTexture: {
return DAWN_FORMAT_VALIDATION_ERROR("External textures are not supported.");
}
}
}
return {};
};
std::unique_ptr<BindingInfoArray> resultBindings = std::make_unique<BindingInfoArray>();
BindingInfoArray* bindings = resultBindings.get();
DAWN_TRY(ExtractResourcesBinding(device, resources.uniform_buffers, compiler,
BindingInfoType::Buffer, bindings));
DAWN_TRY(ExtractResourcesBinding(device, resources.separate_images, compiler,
BindingInfoType::Texture, bindings));
DAWN_TRY(ExtractResourcesBinding(device, resources.separate_samplers, compiler,
BindingInfoType::Sampler, bindings));
DAWN_TRY(ExtractResourcesBinding(device, resources.storage_buffers, compiler,
BindingInfoType::Buffer, bindings, true));
// ReadonlyStorageTexture is used as a tag to do general storage texture handling.
DAWN_TRY(ExtractResourcesBinding(device, resources.storage_images, compiler,
BindingInfoType::StorageTexture, resultBindings.get()));
return {std::move(resultBindings)};
}
// static
ResultOrError<Ref<ShaderModule>> ShaderModule::Create(Device* device,
const ShaderModuleDescriptor* descriptor,
@@ -226,38 +70,10 @@ namespace dawn::native::opengl {
: ShaderModuleBase(device, descriptor) {
}
// static
ResultOrError<BindingInfoArrayTable> ShaderModule::ReflectShaderUsingSPIRVCross(
DeviceBase* device,
const std::vector<uint32_t>& spirv) {
BindingInfoArrayTable result;
spirv_cross::Compiler compiler(spirv);
for (const spirv_cross::EntryPoint& entryPoint : compiler.get_entry_points_and_stages()) {
ASSERT(result.count(entryPoint.name) == 0);
SingleShaderStage stage = ExecutionModelToShaderStage(entryPoint.execution_model);
compiler.set_entry_point(entryPoint.name, entryPoint.execution_model);
std::unique_ptr<BindingInfoArray> bindings;
DAWN_TRY_ASSIGN(bindings, ExtractSpirvInfo(device, compiler, entryPoint.name, stage));
result[entryPoint.name] = std::move(bindings);
}
return std::move(result);
}
MaybeError ShaderModule::Initialize(ShaderModuleParseResult* parseResult) {
ScopedTintICEHandler scopedICEHandler(GetDevice());
DAWN_TRY(InitializeBase(parseResult));
// Tint currently does not support emitting GLSL, so when provided a Tint program need to
// generate SPIRV and SPIRV-Cross reflection data to be used in this backend.
tint::writer::spirv::Options options;
options.disable_workgroup_init = GetDevice()->IsToggleEnabled(Toggle::DisableWorkgroupInit);
auto result = tint::writer::spirv::Generate(GetTintProgram(), options);
DAWN_INVALID_IF(!result.success, "An error occured while generating SPIR-V: %s.",
result.error);
DAWN_TRY_ASSIGN(mGLBindings, ReflectShaderUsingSPIRVCross(GetDevice(), result.spirv));
return {};
}

View File

@@ -63,11 +63,6 @@ namespace dawn::native::opengl {
ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor);
~ShaderModule() override = default;
MaybeError Initialize(ShaderModuleParseResult* parseResult);
static ResultOrError<BindingInfoArrayTable> ReflectShaderUsingSPIRVCross(
DeviceBase* device,
const std::vector<uint32_t>& spirv);
BindingInfoArrayTable mGLBindings;
};
} // namespace dawn::native::opengl

View File

@@ -1,179 +0,0 @@
// 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.
#include "dawn/native/opengl/SpirvUtils.h"
namespace dawn::native {
spv::ExecutionModel ShaderStageToExecutionModel(SingleShaderStage stage) {
switch (stage) {
case SingleShaderStage::Vertex:
return spv::ExecutionModelVertex;
case SingleShaderStage::Fragment:
return spv::ExecutionModelFragment;
case SingleShaderStage::Compute:
return spv::ExecutionModelGLCompute;
}
UNREACHABLE();
}
SingleShaderStage ExecutionModelToShaderStage(spv::ExecutionModel model) {
switch (model) {
case spv::ExecutionModelVertex:
return SingleShaderStage::Vertex;
case spv::ExecutionModelFragment:
return SingleShaderStage::Fragment;
case spv::ExecutionModelGLCompute:
return SingleShaderStage::Compute;
default:
UNREACHABLE();
}
}
wgpu::TextureViewDimension SpirvDimToTextureViewDimension(spv::Dim dim, bool arrayed) {
switch (dim) {
case spv::Dim::Dim1D:
return wgpu::TextureViewDimension::e1D;
case spv::Dim::Dim2D:
if (arrayed) {
return wgpu::TextureViewDimension::e2DArray;
} else {
return wgpu::TextureViewDimension::e2D;
}
case spv::Dim::Dim3D:
return wgpu::TextureViewDimension::e3D;
case spv::Dim::DimCube:
if (arrayed) {
return wgpu::TextureViewDimension::CubeArray;
} else {
return wgpu::TextureViewDimension::Cube;
}
default:
UNREACHABLE();
}
}
wgpu::TextureFormat SpirvImageFormatToTextureFormat(spv::ImageFormat format) {
switch (format) {
case spv::ImageFormatR8:
return wgpu::TextureFormat::R8Unorm;
case spv::ImageFormatR8Snorm:
return wgpu::TextureFormat::R8Snorm;
case spv::ImageFormatR8ui:
return wgpu::TextureFormat::R8Uint;
case spv::ImageFormatR8i:
return wgpu::TextureFormat::R8Sint;
case spv::ImageFormatR16ui:
return wgpu::TextureFormat::R16Uint;
case spv::ImageFormatR16i:
return wgpu::TextureFormat::R16Sint;
case spv::ImageFormatR16f:
return wgpu::TextureFormat::R16Float;
case spv::ImageFormatRg8:
return wgpu::TextureFormat::RG8Unorm;
case spv::ImageFormatRg8Snorm:
return wgpu::TextureFormat::RG8Snorm;
case spv::ImageFormatRg8ui:
return wgpu::TextureFormat::RG8Uint;
case spv::ImageFormatRg8i:
return wgpu::TextureFormat::RG8Sint;
case spv::ImageFormatR32f:
return wgpu::TextureFormat::R32Float;
case spv::ImageFormatR32ui:
return wgpu::TextureFormat::R32Uint;
case spv::ImageFormatR32i:
return wgpu::TextureFormat::R32Sint;
case spv::ImageFormatRg16ui:
return wgpu::TextureFormat::RG16Uint;
case spv::ImageFormatRg16i:
return wgpu::TextureFormat::RG16Sint;
case spv::ImageFormatRg16f:
return wgpu::TextureFormat::RG16Float;
case spv::ImageFormatRgba8:
return wgpu::TextureFormat::RGBA8Unorm;
case spv::ImageFormatRgba8Snorm:
return wgpu::TextureFormat::RGBA8Snorm;
case spv::ImageFormatRgba8ui:
return wgpu::TextureFormat::RGBA8Uint;
case spv::ImageFormatRgba8i:
return wgpu::TextureFormat::RGBA8Sint;
case spv::ImageFormatRgb10A2:
return wgpu::TextureFormat::RGB10A2Unorm;
case spv::ImageFormatR11fG11fB10f:
return wgpu::TextureFormat::RG11B10Ufloat;
case spv::ImageFormatRg32f:
return wgpu::TextureFormat::RG32Float;
case spv::ImageFormatRg32ui:
return wgpu::TextureFormat::RG32Uint;
case spv::ImageFormatRg32i:
return wgpu::TextureFormat::RG32Sint;
case spv::ImageFormatRgba16ui:
return wgpu::TextureFormat::RGBA16Uint;
case spv::ImageFormatRgba16i:
return wgpu::TextureFormat::RGBA16Sint;
case spv::ImageFormatRgba16f:
return wgpu::TextureFormat::RGBA16Float;
case spv::ImageFormatRgba32f:
return wgpu::TextureFormat::RGBA32Float;
case spv::ImageFormatRgba32ui:
return wgpu::TextureFormat::RGBA32Uint;
case spv::ImageFormatRgba32i:
return wgpu::TextureFormat::RGBA32Sint;
default:
return wgpu::TextureFormat::Undefined;
}
}
wgpu::TextureComponentType SpirvBaseTypeToTextureComponentType(
spirv_cross::SPIRType::BaseType spirvBaseType) {
switch (spirvBaseType) {
case spirv_cross::SPIRType::Float:
return wgpu::TextureComponentType::Float;
case spirv_cross::SPIRType::Int:
return wgpu::TextureComponentType::Sint;
case spirv_cross::SPIRType::UInt:
return wgpu::TextureComponentType::Uint;
default:
UNREACHABLE();
}
}
SampleTypeBit SpirvBaseTypeToSampleTypeBit(spirv_cross::SPIRType::BaseType spirvBaseType) {
switch (spirvBaseType) {
case spirv_cross::SPIRType::Float:
return SampleTypeBit::Float | SampleTypeBit::UnfilterableFloat;
case spirv_cross::SPIRType::Int:
return SampleTypeBit::Sint;
case spirv_cross::SPIRType::UInt:
return SampleTypeBit::Uint;
default:
UNREACHABLE();
}
}
VertexFormatBaseType SpirvBaseTypeToVertexFormatBaseType(
spirv_cross::SPIRType::BaseType spirvBaseType) {
switch (spirvBaseType) {
case spirv_cross::SPIRType::Float:
return VertexFormatBaseType::Float;
case spirv_cross::SPIRType::Int:
return VertexFormatBaseType::Sint;
case spirv_cross::SPIRType::UInt:
return VertexFormatBaseType::Uint;
default:
UNREACHABLE();
}
}
} // namespace dawn::native

View File

@@ -1,51 +0,0 @@
// 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.
// This file contains utilities to convert from-to spirv.hpp datatypes without polluting other
// headers with spirv.hpp
#ifndef DAWNNATIVE_OPENGL_SPIRV_UTILS_H_
#define DAWNNATIVE_OPENGL_SPIRV_UTILS_H_
#include "dawn/native/Format.h"
#include "dawn/native/PerStage.h"
#include "dawn/native/VertexFormat.h"
#include "dawn/native/dawn_platform.h"
#include <spirv_cross.hpp>
namespace dawn::native {
// Returns the spirv_cross equivalent for this shader stage and vice-versa.
spv::ExecutionModel ShaderStageToExecutionModel(SingleShaderStage stage);
SingleShaderStage ExecutionModelToShaderStage(spv::ExecutionModel model);
// Returns the texture view dimension for corresponding to (dim, arrayed).
wgpu::TextureViewDimension SpirvDimToTextureViewDimension(spv::Dim dim, bool arrayed);
// Returns the texture format corresponding to format.
wgpu::TextureFormat SpirvImageFormatToTextureFormat(spv::ImageFormat format);
// Returns the format "component type" corresponding to the SPIRV base type.
wgpu::TextureComponentType SpirvBaseTypeToTextureComponentType(
spirv_cross::SPIRType::BaseType spirvBaseType);
SampleTypeBit SpirvBaseTypeToSampleTypeBit(spirv_cross::SPIRType::BaseType spirvBaseType);
// Returns the VertexFormatBaseType corresponding to the SPIRV base type.
VertexFormatBaseType SpirvBaseTypeToVertexFormatBaseType(
spirv_cross::SPIRType::BaseType spirvBaseType);
} // namespace dawn::native
#endif // DAWNNATIVE_OPENGL_SPIRV_UTILS_H_