Move tint writer outputs into the SPIRV request.
This CL moves the options which are passed to the tint writer for the
SPIR-V backend out of the compilation callback and passes them directly
through the `SpirvCompilationRequest`. This should incur less copying of
the data in the request.
Change-Id: I1a91ec348001fc8d463fc424d51db60d4723d939
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/154100
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/dawn/native/StreamImplTint.cpp b/src/dawn/native/StreamImplTint.cpp
index 3cc052c..d1c4f9e 100644
--- a/src/dawn/native/StreamImplTint.cpp
+++ b/src/dawn/native/StreamImplTint.cpp
@@ -60,6 +60,14 @@
#if TINT_BUILD_SPV_WRITER
// static
template <>
+void stream::Stream<tint::spirv::writer::Options>::Write(
+ stream::Sink* sink,
+ const tint::spirv::writer::Options& options) {
+ StreamInTintObject(options, sink);
+}
+
+// static
+template <>
void stream::Stream<tint::spirv::writer::Bindings>::Write(
stream::Sink* sink,
const tint::spirv::writer::Bindings& bindings) {
diff --git a/src/dawn/native/vulkan/ShaderModuleVk.cpp b/src/dawn/native/vulkan/ShaderModuleVk.cpp
index 3698afc..d425e93 100644
--- a/src/dawn/native/vulkan/ShaderModuleVk.cpp
+++ b/src/dawn/native/vulkan/ShaderModuleVk.cpp
@@ -172,20 +172,11 @@
#define SPIRV_COMPILATION_REQUEST_MEMBERS(X) \
X(SingleShaderStage, stage) \
X(const tint::Program*, inputProgram) \
- X(tint::spirv::writer::Bindings, bindings) \
X(std::optional<tint::ast::transform::SubstituteOverride::Config>, substituteOverrideConfig) \
X(LimitsForCompilationRequest, limits) \
X(std::string_view, entryPointName) \
- X(bool, isRobustnessEnabled) \
- X(bool, disableWorkgroupInit) \
X(bool, disableSymbolRenaming) \
- X(bool, useZeroInitializeWorkgroupMemoryExtension) \
- X(bool, clampFragDepth) \
- X(bool, disableImageRobustness) \
- X(bool, disableRuntimeSizedArrayIndexClamping) \
- X(bool, experimentalRequireSubgroupUniformControlFlow) \
- X(bool, passMatrixByPointer) \
- X(bool, useTintIR) \
+ X(tint::spirv::writer::Options, tintOptions) \
X(CacheKey::UnsafeUnkeyedValue<dawn::platform::Platform*>, platform)
DAWN_MAKE_CACHE_REQUEST(SpirvCompilationRequest, SPIRV_COMPILATION_REQUEST_MEMBERS);
@@ -301,31 +292,38 @@
SpirvCompilationRequest req = {};
req.stage = stage;
req.inputProgram = GetTintProgram();
- req.bindings = std::move(bindings);
req.entryPointName = programmableStage.entryPoint;
- req.isRobustnessEnabled = GetDevice()->IsRobustnessEnabled();
- req.disableWorkgroupInit = GetDevice()->IsToggleEnabled(Toggle::DisableWorkgroupInit);
req.disableSymbolRenaming = GetDevice()->IsToggleEnabled(Toggle::DisableSymbolRenaming);
- req.useZeroInitializeWorkgroupMemoryExtension =
- GetDevice()->IsToggleEnabled(Toggle::VulkanUseZeroInitializeWorkgroupMemoryExtension);
- req.clampFragDepth = clampFragDepth;
- req.disableImageRobustness = GetDevice()->IsToggleEnabled(Toggle::VulkanUseImageRobustAccess2);
- // Currently we can disable index clamping on all runtime-sized arrays in Tint robustness
- // transform as unsized arrays can only be declared on storage address space.
- req.disableRuntimeSizedArrayIndexClamping =
- GetDevice()->IsToggleEnabled(Toggle::VulkanUseBufferRobustAccess2);
req.platform = UnsafeUnkeyedValue(GetDevice()->GetPlatform());
req.substituteOverrideConfig = std::move(substituteOverrideConfig);
- req.useTintIR = GetDevice()->IsToggleEnabled(Toggle::UseTintIR);
+
+ req.tintOptions.clamp_frag_depth = clampFragDepth;
+ req.tintOptions.disable_robustness = !GetDevice()->IsRobustnessEnabled();
+ req.tintOptions.emit_vertex_point_size = true;
+ req.tintOptions.disable_workgroup_init =
+ GetDevice()->IsToggleEnabled(Toggle::DisableWorkgroupInit);
+ req.tintOptions.use_zero_initialize_workgroup_memory_extension =
+ GetDevice()->IsToggleEnabled(Toggle::VulkanUseZeroInitializeWorkgroupMemoryExtension);
+ req.tintOptions.bindings = std::move(bindings);
+ req.tintOptions.disable_image_robustness =
+ GetDevice()->IsToggleEnabled(Toggle::VulkanUseImageRobustAccess2);
+ // Currently we can disable index clamping on all runtime-sized arrays in Tint robustness
+ // transform as unsized arrays can only be declared on storage address space.
+ req.tintOptions.disable_runtime_sized_array_index_clamping =
+ GetDevice()->IsToggleEnabled(Toggle::VulkanUseBufferRobustAccess2);
+ req.tintOptions.use_tint_ir = GetDevice()->IsToggleEnabled(Toggle::UseTintIR);
+
// Set subgroup uniform control flow flag for subgroup experiment, if device has
// Chromium-experimental-subgroup-uniform-control-flow feature. (dawn:464)
if (GetDevice()->HasFeature(Feature::ChromiumExperimentalSubgroupUniformControlFlow)) {
- req.experimentalRequireSubgroupUniformControlFlow = true;
+ req.tintOptions.experimental_require_subgroup_uniform_control_flow = true;
+ } else {
+ req.tintOptions.experimental_require_subgroup_uniform_control_flow = false;
}
// Pass matrices to user functions by pointer on Qualcomm devices to workaround a known bug.
// See crbug.com/tint/2045.
if (ToBackend(GetDevice()->GetPhysicalDevice())->IsAndroidQualcomm()) {
- req.passMatrixByPointer = true;
+ req.tintOptions.pass_matrix_by_pointer = true;
}
const CombinedLimits& limits = GetDevice()->GetLimits();
@@ -387,24 +385,8 @@
program, remappedEntryPoint.c_str(), r.limits));
}
- tint::spirv::writer::Options options;
- options.clamp_frag_depth = r.clampFragDepth;
- options.disable_robustness = !r.isRobustnessEnabled;
- options.emit_vertex_point_size = true;
- options.disable_workgroup_init = r.disableWorkgroupInit;
- options.use_zero_initialize_workgroup_memory_extension =
- r.useZeroInitializeWorkgroupMemoryExtension;
- options.bindings = r.bindings;
- options.disable_image_robustness = r.disableImageRobustness;
- options.disable_runtime_sized_array_index_clamping =
- r.disableRuntimeSizedArrayIndexClamping;
- options.experimental_require_subgroup_uniform_control_flow =
- r.experimentalRequireSubgroupUniformControlFlow;
- options.use_tint_ir = r.useTintIR;
- options.pass_matrix_by_pointer = r.passMatrixByPointer;
-
TRACE_EVENT0(r.platform.UnsafeGetValue(), General, "tint::spirv::writer::Generate()");
- auto tintResult = tint::spirv::writer::Generate(program, options);
+ auto tintResult = tint::spirv::writer::Generate(program, r.tintOptions);
DAWN_INVALID_IF(!tintResult, "An error occurred while generating SPIR-V\n%s",
tintResult.Failure().reason.str());
diff --git a/src/tint/lang/spirv/writer/common/option_builder.cc b/src/tint/lang/spirv/writer/common/option_builder.cc
index d68baa6d..66df1e4 100644
--- a/src/tint/lang/spirv/writer/common/option_builder.cc
+++ b/src/tint/lang/spirv/writer/common/option_builder.cc
@@ -25,7 +25,7 @@
auto wgsl_seen = [&diagnostics, &seen_wgsl_bindings](const tint::BindingPoint& info) -> bool {
if (seen_wgsl_bindings.Contains(info)) {
std::stringstream str;
- str << "Found duplicate WGSL binding point: " << info;
+ str << "found duplicate WGSL binding point: " << info;
diagnostics.add_error(diag::System::Writer, str.str());
return true;
@@ -38,7 +38,7 @@
&seen_spirv_bindings](const binding::BindingInfo& info) -> bool {
if (seen_spirv_bindings.Contains(info)) {
std::stringstream str;
- str << "Found duplicate SPIR-V binding point: [group: " << info.group
+ str << "found duplicate SPIR-V binding point: [group: " << info.group
<< ", binding: " << info.binding << "]";
diagnostics.add_error(diag::System::Writer, str.str());
return true;
@@ -64,23 +64,23 @@
};
if (!valid(options.bindings.uniform)) {
- diagnostics.add_note(diag::System::Writer, "When processing uniform", {});
+ diagnostics.add_note(diag::System::Writer, "when processing uniform", {});
return false;
}
if (!valid(options.bindings.storage)) {
- diagnostics.add_note(diag::System::Writer, "When processing storage", {});
+ diagnostics.add_note(diag::System::Writer, "when processing storage", {});
return false;
}
if (!valid(options.bindings.texture)) {
- diagnostics.add_note(diag::System::Writer, "When processing texture", {});
+ diagnostics.add_note(diag::System::Writer, "when processing texture", {});
return false;
}
if (!valid(options.bindings.storage_texture)) {
- diagnostics.add_note(diag::System::Writer, "When processing storage_texture", {});
+ diagnostics.add_note(diag::System::Writer, "when processing storage_texture", {});
return false;
}
if (!valid(options.bindings.sampler)) {
- diagnostics.add_note(diag::System::Writer, "When processing sampler", {});
+ diagnostics.add_note(diag::System::Writer, "when processing sampler", {});
return false;
}
@@ -92,20 +92,20 @@
// Validate with the actual source regardless of what the remapper will do
if (wgsl_seen(src_binding)) {
- diagnostics.add_note(diag::System::Writer, "When processing external_texture", {});
+ diagnostics.add_note(diag::System::Writer, "when processing external_texture", {});
return false;
}
if (spirv_seen(plane0)) {
- diagnostics.add_note(diag::System::Writer, "When processing external_texture", {});
+ diagnostics.add_note(diag::System::Writer, "when processing external_texture", {});
return false;
}
if (spirv_seen(plane1)) {
- diagnostics.add_note(diag::System::Writer, "When processing external_texture", {});
+ diagnostics.add_note(diag::System::Writer, "when processing external_texture", {});
return false;
}
if (spirv_seen(metadata)) {
- diagnostics.add_note(diag::System::Writer, "When processing external_texture", {});
+ diagnostics.add_note(diag::System::Writer, "when processing external_texture", {});
return false;
}
}
diff --git a/src/tint/lang/spirv/writer/helpers/generate_bindings.cc b/src/tint/lang/spirv/writer/helpers/generate_bindings.cc
index 0285b0b..5ed371c 100644
--- a/src/tint/lang/spirv/writer/helpers/generate_bindings.cc
+++ b/src/tint/lang/spirv/writer/helpers/generate_bindings.cc
@@ -25,6 +25,8 @@
#include "src/tint/lang/wgsl/ast/module.h"
#include "src/tint/lang/wgsl/program/program.h"
#include "src/tint/lang/wgsl/sem/variable.h"
+#include "src/tint/utils/containers/hashmap.h"
+#include "src/tint/utils/containers/vector.h"
#include "src/tint/utils/rtti/switch.h"
namespace tint::spirv::writer {
@@ -38,31 +40,34 @@
std::unordered_set<tint::BindingPoint> seen_binding_points;
// Collect next valid binding number per group
- std::unordered_map<uint32_t, uint32_t> group_to_next_binding_number;
- std::vector<tint::BindingPoint> ext_tex_bps;
+ Hashmap<uint32_t, uint32_t, 4> group_to_next_binding_number;
+ Vector<tint::BindingPoint, 4> ext_tex_bps;
for (auto* var : program.AST().GlobalVariables()) {
if (auto* sem_var = program.Sem().Get(var)->As<sem::GlobalVariable>()) {
if (auto bp = sem_var->BindingPoint()) {
// This is a bit of a hack. The binding points must be unique over all the `binding`
// entries. But, this is looking at _all_ entry points where bindings can overlap.
// In the case where both entry points used the same type (uniform, sampler, etc)
- // then it woudl be fine as it just overwrites with itself. But, if one entry point
+ // then it would be fine as it just overwrites with itself. But, if one entry point
// has a uniform and the other a sampler at the same (group,binding) pair then we'll
// get a validation error due to duplicate WGSL bindings.
//
- // For generate bindings we don't really care as we always map to itself, so if it
+ // For generating bindings we don't really care as we always map to itself, so if it
// exists anywhere, we just pretend that's the only one.
if (seen_binding_points.find(*bp) != seen_binding_points.end()) {
continue;
}
seen_binding_points.emplace(*bp);
- auto& n = group_to_next_binding_number[bp->group];
- n = std::max(n, bp->binding + 1);
+ if (auto val = group_to_next_binding_number.Find(bp->group)) {
+ *val = std::max(*val, bp->binding + 1);
+ } else {
+ group_to_next_binding_number.Add(bp->group, bp->binding + 1);
+ }
// Store up the external textures, we'll add them in the next step
if (sem_var->Type()->UnwrapRef()->Is<core::type::ExternalTexture>()) {
- ext_tex_bps.emplace_back(*bp);
+ ext_tex_bps.Push(*bp);
continue;
}
@@ -104,12 +109,14 @@
for (auto bp : ext_tex_bps) {
uint32_t g = bp.group;
- uint32_t& next_num = group_to_next_binding_number[g];
+ uint32_t next_num = *(group_to_next_binding_number.GetOrZero(g));
binding::BindingInfo plane0{bp.group, bp.binding};
binding::BindingInfo plane1{g, next_num++};
binding::BindingInfo metadata{g, next_num++};
+ group_to_next_binding_number.Replace(g, next_num);
+
bindings.external_texture.emplace(bp, binding::ExternalTexture{metadata, plane0, plane1});
}