Add SPIR-V support for UseTintGenerator toggle

Turns on Tint generation of SPIR-V if UseTintGenerator is on.
This affects SPIR-V generation for Vulkan, and SPIR-V passed
into SPIRV-Cross to produce GLSL.

It enables DrawTests use_tint_generator for Vulkan/GL where it
should have at least basic support.

Bug: dawn:571
Change-Id: I5df1435bee17572259f5aa3605c4bf19c0136cbc
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/32302
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
Austin Eng 2020-12-07 19:05:33 +00:00 committed by Commit Bot service account
parent 0d948f7752
commit 1ae024ce56
4 changed files with 85 additions and 6 deletions

View File

@ -23,6 +23,14 @@
#include <spirv_glsl.hpp>
#ifdef DAWN_ENABLE_WGSL
// 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>
#endif // DAWN_ENABLE_WGSL
#include <sstream>
namespace dawn_native { namespace opengl {
@ -62,7 +70,7 @@ namespace dawn_native { namespace opengl {
const ShaderModuleDescriptor* descriptor,
ShaderModuleParseResult* parseResult) {
Ref<ShaderModule> module = AcquireRef(new ShaderModule(device, descriptor));
DAWN_TRY(module->InitializeBase(parseResult));
DAWN_TRY(module->Initialize(parseResult));
return module.Detach();
}
@ -70,6 +78,34 @@ namespace dawn_native { namespace opengl {
: ShaderModuleBase(device, descriptor) {
}
MaybeError ShaderModule::Initialize(ShaderModuleParseResult* parseResult) {
DAWN_TRY(InitializeBase(parseResult));
if (GetDevice()->IsToggleEnabled(Toggle::UseTintGenerator)) {
#ifdef DAWN_ENABLE_WGSL
tint::ast::Module module = std::move(*parseResult->tintModule.release());
std::ostringstream errorStream;
errorStream << "Tint SPIR-V (for GLSL) writer failure:" << std::endl;
tint::transform::Manager transformManager;
transformManager.append(std::make_unique<tint::transform::BoundArrayAccessors>());
DAWN_TRY_ASSIGN(module, RunTransforms(&transformManager, &module));
tint::writer::spirv::Generator generator(std::move(module));
if (!generator.Generate()) {
errorStream << "Generator: " << generator.error() << std::endl;
return DAWN_VALIDATION_ERROR(errorStream.str().c_str());
}
mSpirv = generator.result();
#else
UNREACHABLE();
#endif
}
return {};
}
std::string ShaderModule::TranslateToGLSL(const char* entryPointName,
SingleShaderStage stage,
CombinedSamplerInfo* combinedSamplers,
@ -94,7 +130,8 @@ namespace dawn_native { namespace opengl {
options.es = version.IsES();
options.version = version.GetMajor() * 100 + version.GetMinor() * 10;
spirv_cross::CompilerGLSL compiler(GetSpirv());
spirv_cross::CompilerGLSL compiler(
GetDevice()->IsToggleEnabled(Toggle::UseTintGenerator) ? mSpirv : GetSpirv());
compiler.set_common_options(options);
compiler.set_entry_point(entryPointName, ShaderStageToExecutionModel(stage));

View File

@ -59,6 +59,9 @@ namespace dawn_native { namespace opengl {
private:
ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor);
~ShaderModule() override = default;
MaybeError Initialize(ShaderModuleParseResult* parseResult);
std::vector<uint32_t> mSpirv;
};
}} // namespace dawn_native::opengl

View File

@ -20,6 +20,14 @@
#include <spirv_cross.hpp>
#ifdef DAWN_ENABLE_WGSL
// Tint include must be after spirv_hlsl.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>
#endif // DAWN_ENABLE_WGSL
namespace dawn_native { namespace vulkan {
// static
@ -40,15 +48,43 @@ namespace dawn_native { namespace vulkan {
MaybeError ShaderModule::Initialize(ShaderModuleParseResult* parseResult) {
DAWN_TRY(InitializeBase(parseResult));
const std::vector<uint32_t>& spirv = GetSpirv();
std::vector<uint32_t> spirv;
const std::vector<uint32_t>* spirvPtr;
if (GetDevice()->IsToggleEnabled(Toggle::UseTintGenerator)) {
#ifdef DAWN_ENABLE_WGSL
tint::ast::Module module = std::move(*std::move(parseResult->tintModule).release());
std::ostringstream errorStream;
errorStream << "Tint SPIR-V writer failure:" << std::endl;
tint::transform::Manager transformManager;
transformManager.append(std::make_unique<tint::transform::BoundArrayAccessors>());
DAWN_TRY_ASSIGN(module, RunTransforms(&transformManager, &module));
tint::writer::spirv::Generator generator(std::move(module));
if (!generator.Generate()) {
errorStream << "Generator: " << generator.error() << std::endl;
return DAWN_VALIDATION_ERROR(errorStream.str().c_str());
}
spirv = generator.result();
spirvPtr = &spirv;
#else
UNREACHABLE();
#endif
} else {
spirvPtr = &GetSpirv();
}
VkShaderModuleCreateInfo createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
createInfo.pNext = nullptr;
createInfo.flags = 0;
std::vector<uint32_t> vulkanSource;
createInfo.codeSize = spirv.size() * sizeof(uint32_t);
createInfo.pCode = spirv.data();
createInfo.codeSize = spirvPtr->size() * sizeof(uint32_t);
createInfo.pCode = spirvPtr->data();
Device* device = ToBackend(GetDevice());
return CheckVkSuccess(

View File

@ -106,5 +106,8 @@ DAWN_INSTANTIATE_TEST(DrawTest,
D3D12Backend(),
MetalBackend(),
OpenGLBackend(),
OpenGLBackend({"use_tint_generator"}),
OpenGLESBackend(),
VulkanBackend());
OpenGLESBackend({"use_tint_generator"}),
VulkanBackend(),
VulkanBackend({"use_tint_generator"}));