Use tint::transform::Spirv

The new tint::transform::[Spirv,Hlsl,Msl] transforms sanitize the tint::Program for the given backend.

The tint::transform::Spirv transform handles edge cases for sample masks (crbug.com/tint/372). We can now enable these tests.

Rework dawn_native::[opengl,vulkan]::ShaderModule::Initialize() so that transforms are applied *before* calling ShaderModuleBase::InitializeBase(). This is done as InitializeBase() wants to validate the SPIR-V, which requires the pre-processing of tint::transform::Spirv.
InitializeBase() also performs shader reflection which needs to be performed on the post-transformed program for the information to be correct.

Bug: tint:372
Change-Id: I4c96ce89b6ae286972549d8c7efe59e77c469063
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/42223
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton 2021-02-24 12:50:00 +00:00 committed by Commit Bot service account
parent d67544797e
commit bbc235425b
4 changed files with 34 additions and 13 deletions

View File

@ -871,6 +871,7 @@ namespace dawn_native {
tint::transform::Manager transformManager; tint::transform::Manager transformManager;
transformManager.append( transformManager.append(
std::make_unique<tint::transform::EmitVertexPointSize>()); std::make_unique<tint::transform::EmitVertexPointSize>());
transformManager.append(std::make_unique<tint::transform::Spirv>());
DAWN_TRY_ASSIGN(program, RunTransforms(&transformManager, &program)); DAWN_TRY_ASSIGN(program, RunTransforms(&transformManager, &program));
} }
@ -1072,6 +1073,7 @@ namespace dawn_native {
transformManager.append( transformManager.append(
MakeVertexPullingTransform(vertexState, entryPoint, pullingBufferBindingSet)); MakeVertexPullingTransform(vertexState, entryPoint, pullingBufferBindingSet));
transformManager.append(std::make_unique<tint::transform::EmitVertexPointSize>()); transformManager.append(std::make_unique<tint::transform::EmitVertexPointSize>());
transformManager.append(std::make_unique<tint::transform::Spirv>());
if (GetDevice()->IsRobustnessEnabled()) { if (GetDevice()->IsRobustnessEnabled()) {
// TODO(enga): Run the Tint BoundArrayAccessors transform instead of the SPIRV Tools // TODO(enga): Run the Tint BoundArrayAccessors transform instead of the SPIRV Tools
// one, but it appears to crash after running VertexPulling. // one, but it appears to crash after running VertexPulling.

View File

@ -79,19 +79,19 @@ namespace dawn_native { namespace opengl {
} }
MaybeError ShaderModule::Initialize(ShaderModuleParseResult* parseResult) { MaybeError ShaderModule::Initialize(ShaderModuleParseResult* parseResult) {
DAWN_TRY(InitializeBase(parseResult));
if (GetDevice()->IsToggleEnabled(Toggle::UseTintGenerator)) { if (GetDevice()->IsToggleEnabled(Toggle::UseTintGenerator)) {
#ifdef DAWN_ENABLE_WGSL #ifdef DAWN_ENABLE_WGSL
tint::Program program = std::move(*parseResult->tintProgram.release());
std::ostringstream errorStream; std::ostringstream errorStream;
errorStream << "Tint SPIR-V (for GLSL) writer failure:" << std::endl; errorStream << "Tint SPIR-V (for GLSL) writer failure:" << std::endl;
tint::transform::Manager transformManager; tint::transform::Manager transformManager;
transformManager.append(std::make_unique<tint::transform::BoundArrayAccessors>()); transformManager.append(std::make_unique<tint::transform::BoundArrayAccessors>());
transformManager.append(std::make_unique<tint::transform::EmitVertexPointSize>()); transformManager.append(std::make_unique<tint::transform::EmitVertexPointSize>());
transformManager.append(std::make_unique<tint::transform::Spirv>());
DAWN_TRY_ASSIGN(program, RunTransforms(&transformManager, &program)); tint::Program program;
DAWN_TRY_ASSIGN(program,
RunTransforms(&transformManager, parseResult->tintProgram.get()));
tint::writer::spirv::Generator generator(&program); tint::writer::spirv::Generator generator(&program);
if (!generator.Generate()) { if (!generator.Generate()) {
@ -100,9 +100,18 @@ namespace dawn_native { namespace opengl {
} }
mSpirv = generator.result(); mSpirv = generator.result();
ShaderModuleParseResult transformedParseResult;
transformedParseResult.tintProgram =
std::make_unique<tint::Program>(std::move(program));
transformedParseResult.spirv = mSpirv;
DAWN_TRY(InitializeBase(&transformedParseResult));
#else #else
UNREACHABLE(); UNREACHABLE();
#endif #endif
} else {
DAWN_TRY(InitializeBase(parseResult));
} }
return {}; return {};
} }

View File

@ -47,22 +47,22 @@ namespace dawn_native { namespace vulkan {
} }
MaybeError ShaderModule::Initialize(ShaderModuleParseResult* parseResult) { MaybeError ShaderModule::Initialize(ShaderModuleParseResult* parseResult) {
DAWN_TRY(InitializeBase(parseResult));
std::vector<uint32_t> spirv; std::vector<uint32_t> spirv;
const std::vector<uint32_t>* spirvPtr; const std::vector<uint32_t>* spirvPtr;
if (GetDevice()->IsToggleEnabled(Toggle::UseTintGenerator)) { if (GetDevice()->IsToggleEnabled(Toggle::UseTintGenerator)) {
#ifdef DAWN_ENABLE_WGSL #ifdef DAWN_ENABLE_WGSL
tint::Program program = std::move(*std::move(parseResult->tintProgram).release());
std::ostringstream errorStream; std::ostringstream errorStream;
errorStream << "Tint SPIR-V writer failure:" << std::endl; errorStream << "Tint SPIR-V writer failure:" << std::endl;
tint::transform::Manager transformManager; tint::transform::Manager transformManager;
transformManager.append(std::make_unique<tint::transform::BoundArrayAccessors>()); transformManager.append(std::make_unique<tint::transform::BoundArrayAccessors>());
transformManager.append(std::make_unique<tint::transform::EmitVertexPointSize>()); transformManager.append(std::make_unique<tint::transform::EmitVertexPointSize>());
transformManager.append(std::make_unique<tint::transform::Spirv>());
DAWN_TRY_ASSIGN(program, RunTransforms(&transformManager, &program)); tint::Program program;
DAWN_TRY_ASSIGN(program,
RunTransforms(&transformManager, parseResult->tintProgram.get()));
tint::writer::spirv::Generator generator(&program); tint::writer::spirv::Generator generator(&program);
if (!generator.Generate()) { if (!generator.Generate()) {
@ -72,10 +72,18 @@ namespace dawn_native { namespace vulkan {
spirv = generator.result(); spirv = generator.result();
spirvPtr = &spirv; spirvPtr = &spirv;
ShaderModuleParseResult transformedParseResult;
transformedParseResult.tintProgram =
std::make_unique<tint::Program>(std::move(program));
transformedParseResult.spirv = spirv;
DAWN_TRY(InitializeBase(&transformedParseResult));
#else #else
UNREACHABLE(); UNREACHABLE();
#endif #endif
} else { } else {
DAWN_TRY(InitializeBase(parseResult));
spirvPtr = &GetSpirv(); spirvPtr = &GetSpirv();
} }

View File

@ -733,8 +733,9 @@ TEST_P(MultisampledRenderingTest, MultisampledRenderingWithDepthTestAndSampleMas
// Test using one multisampled color attachment with resolve target can render correctly // Test using one multisampled color attachment with resolve target can render correctly
// with non-default sample mask and shader-output mask. // with non-default sample mask and shader-output mask.
TEST_P(MultisampledRenderingTest, ResolveInto2DTextureWithSampleMaskAndShaderOutputMask) { TEST_P(MultisampledRenderingTest, ResolveInto2DTextureWithSampleMaskAndShaderOutputMask) {
// TODO(crbug.com/tint/372): Support sample mask builtin. // TODO(github.com/KhronosGroup/SPIRV-Cross/issues/1626): SPIRV-Cross produces bad GLSL for
DAWN_SKIP_TEST_IF(HasToggleEnabled("use_tint_generator")); // unsigned SampleMask builtins
DAWN_SKIP_TEST_IF(HasToggleEnabled("use_tint_generator") && (IsOpenGL() || IsOpenGLES()));
// TODO(crbug.com/dawn/673): Work around or enforce via validation that sample variables are not // TODO(crbug.com/dawn/673): Work around or enforce via validation that sample variables are not
// supported on some platforms. // supported on some platforms.
@ -783,8 +784,9 @@ TEST_P(MultisampledRenderingTest, ResolveInto2DTextureWithSampleMaskAndShaderOut
// Test doing MSAA resolve into multiple resolve targets works correctly with a non-default // Test doing MSAA resolve into multiple resolve targets works correctly with a non-default
// shader-output mask. // shader-output mask.
TEST_P(MultisampledRenderingTest, ResolveIntoMultipleResolveTargetsWithShaderOutputMask) { TEST_P(MultisampledRenderingTest, ResolveIntoMultipleResolveTargetsWithShaderOutputMask) {
// TODO(crbug.com/tint/372): Support sample mask builtin. // TODO(github.com/KhronosGroup/SPIRV-Cross/issues/1626): SPIRV-Cross produces bad GLSL for
DAWN_SKIP_TEST_IF(HasToggleEnabled("use_tint_generator")); // unsigned SampleMask builtins
DAWN_SKIP_TEST_IF(HasToggleEnabled("use_tint_generator") && (IsOpenGL() || IsOpenGLES()));
// TODO(crbug.com/dawn/673): Work around or enforce via validation that sample variables are not // TODO(crbug.com/dawn/673): Work around or enforce via validation that sample variables are not
// supported on some platforms. // supported on some platforms.