Update inter stage variable subsetting validation and add tests

Sync up with current WebGPU spec to allow FS input being a
subset of VS output instead of requiring a strict match.
This patch involves changing the validation and adding tests,
together with using the TruncateInterstageVariables for hlsl
generator to workaround the extra limit for D3D12 backend.

Bug: dawn:1493
Change-Id: I2d4ba7f43dbe57f17ecd5c5d659f4ca93bb682a3
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/109460
Commit-Queue: Shrek Shao <shrekshao@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Auto-Submit: Shrek Shao <shrekshao@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
shrekshao
2022-11-22 21:36:27 +00:00
committed by Dawn LUCI CQ
parent 7f760cb25c
commit f9c6633006
9 changed files with 517 additions and 27 deletions

View File

@@ -15,6 +15,7 @@
#ifndef SRC_TINT_WRITER_HLSL_GENERATOR_H_
#define SRC_TINT_WRITER_HLSL_GENERATOR_H_
#include <bitset>
#include <memory>
#include <optional>
#include <string>
@@ -25,6 +26,7 @@
#include "src/tint/ast/pipeline_stage.h"
#include "src/tint/reflection.h"
#include "src/tint/sem/binding_point.h"
#include "src/tint/utils/bitset.h"
#include "src/tint/writer/array_length_from_uniform_options.h"
#include "src/tint/writer/text.h"
@@ -56,6 +58,9 @@ struct Options {
/// Options used to specify a mapping of binding points to indices into a UBO
/// from which to load buffer sizes.
ArrayLengthFromUniformOptions array_length_from_uniform = {};
/// Interstage locations actually used as inputs in the next stage of the pipeline.
/// This is potentially used for truncating unused interstage outputs at current shader stage.
std::bitset<16> interstage_locations;
/// Reflect the fields of this class so that it can be used by tint::ForeachField()
TINT_REFLECT(root_constant_binding_point,

View File

@@ -64,6 +64,7 @@
#include "src/tint/transform/remove_continue_in_switch.h"
#include "src/tint/transform/remove_phonies.h"
#include "src/tint/transform/simplify_pointers.h"
#include "src/tint/transform/truncate_interstage_variables.h"
#include "src/tint/transform/unshadow.h"
#include "src/tint/transform/vectorize_scalar_matrix_initializers.h"
#include "src/tint/transform/zero_init_workgroup_memory.h"
@@ -210,6 +211,27 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
manager.Add<transform::ZeroInitWorkgroupMemory>();
}
manager.Add<transform::CanonicalizeEntryPointIO>();
if (options.interstage_locations.any()) {
// When interstage_locations is empty, it means there's no user-defined interstage variables
// being used in the next stage. This is treated as a special case.
// TruncateInterstageVariables transform is trying to solve the HLSL compiler register
// mismatch issue. So it is not needed if no register is assigned to any interstage
// variables. As a result we only add this transform when there is at least one interstage
// locations being used.
// TruncateInterstageVariables itself will skip when interstage_locations matches exactly
// with the current stage output.
// Build the config for internal TruncateInterstageVariables transform.
transform::TruncateInterstageVariables::Config truncate_interstage_variables_cfg;
truncate_interstage_variables_cfg.interstage_locations =
std::move(options.interstage_locations);
manager.Add<transform::TruncateInterstageVariables>();
data.Add<transform::TruncateInterstageVariables::Config>(
std::move(truncate_interstage_variables_cfg));
}
// NumWorkgroupsFromUniform must come after CanonicalizeEntryPointIO, as it
// assumes that num_workgroups builtins only appear as struct members and are
// only accessed directly via member accessors.