Move tint::transform::Robustness to a santizier transform

There's no good reason for this to be public.
Move it into the writers, and expose a 'disable_robustness' option to
turn it off. This can be expanded to hold more fine-grain control in the
future.

Change-Id: I6ea6e54a27b2ae0fbcba5fdf45539063045cc15a
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/122203
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Ben Clayton <bclayton@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Auto-Submit: Ben Clayton <bclayton@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Ben Clayton
2023-03-02 20:48:48 +00:00
committed by Dawn LUCI CQ
parent 902c9e5726
commit 03de0e83ae
201 changed files with 2208 additions and 2204 deletions

View File

@@ -331,10 +331,6 @@ ResultOrError<std::string> TranslateToHLSL(
std::move(r.substituteOverrideConfig).value());
}
if (r.isRobustnessEnabled) {
transformManager.Add<tint::transform::Robustness>();
}
transformManager.Add<tint::transform::BindingRemapper>();
// D3D12 registers like `t3` and `c3` have the same bindingOffset number in
@@ -383,6 +379,7 @@ ResultOrError<std::string> TranslateToHLSL(
}
tint::writer::hlsl::Options options;
options.disable_robustness = !r.isRobustnessEnabled;
options.disable_workgroup_init = r.disableWorkgroupInit;
if (r.usesNumWorkgroups) {
options.root_constant_binding_point =

View File

@@ -222,9 +222,6 @@ ResultOrError<CacheResult<MslCompilation>> TranslateToMSL(
std::move(r.substituteOverrideConfig).value());
}
if (r.isRobustnessEnabled) {
transformManager.Add<tint::transform::Robustness>();
}
transformManager.Add<BindingRemapper>();
transformInputs.Add<BindingRemapper::Remappings>(std::move(r.bindingPoints),
BindingRemapper::AccessControls{},
@@ -262,6 +259,7 @@ ResultOrError<CacheResult<MslCompilation>> TranslateToMSL(
}
tint::writer::msl::Options options;
options.disable_robustness = !r.isRobustnessEnabled;
options.buffer_size_ubo_index = kBufferLengthBufferSlot;
options.fixed_sample_mask = r.sampleMask;
options.disable_workgroup_init = r.disableWorkgroupInit;

View File

@@ -391,8 +391,6 @@ MaybeError ComputePipeline::Initialize() {
tint::transform::Manager transformManager;
tint::transform::DataMap transformInputs;
transformManager.Add<tint::transform::Robustness>();
if (!computeStage.metadata->overrides.empty()) {
transformManager.Add<tint::transform::SingleEntryPoint>();
transformInputs.Add<tint::transform::SingleEntryPoint::Config>(

View File

@@ -228,6 +228,9 @@ ResultOrError<GLuint> ShaderModule::CompileShader(const OpenGLFunctions& gl,
tintOptions.version = tint::writer::glsl::Version(ToTintGLStandard(r.glVersionStandard),
r.glVersionMajor, r.glVersionMinor);
// TODO(crbug.com/dawn/1686): Robustness causes shader compilation failures.
tintOptions.disable_robustness = true;
// When textures are accessed without a sampler (e.g., textureLoad()),
// GetSamplerTextureUses() will return this sentinel value.
BindingPoint placeholderBindingPoint{static_cast<uint32_t>(kMaxBindGroupsTyped), 0};

View File

@@ -293,10 +293,6 @@ ResultOrError<ShaderModule::ModuleAndSpirv> ShaderModule::GetHandleAndSpirv(
std::move(r.substituteOverrideConfig).value());
}
if (r.isRobustnessEnabled) {
transformManager.append(std::make_unique<tint::transform::Robustness>());
}
// Run the binding remapper after SingleEntryPoint to avoid collisions with
// unused entryPoints.
transformManager.append(std::make_unique<tint::transform::BindingRemapper>());
@@ -344,6 +340,7 @@ ResultOrError<ShaderModule::ModuleAndSpirv> ShaderModule::GetHandleAndSpirv(
}
tint::writer::spirv::Options options;
options.disable_robustness = !r.isRobustnessEnabled;
options.emit_vertex_point_size = true;
options.disable_workgroup_init = r.disableWorkgroupInit;
options.use_zero_initialize_workgroup_memory_extension =

View File

@@ -79,6 +79,7 @@ struct Options {
bool print_hash = false;
bool demangle = false;
bool dump_inspector_bindings = false;
bool enable_robustness = false;
std::unordered_set<uint32_t> skip_hash;
@@ -533,6 +534,7 @@ bool GenerateSpirv(const tint::Program* program, const Options& options) {
#if TINT_BUILD_SPV_WRITER
// TODO(jrprice): Provide a way for the user to set non-default options.
tint::writer::spirv::Options gen_options;
gen_options.disable_robustness = !options.enable_robustness;
gen_options.disable_workgroup_init = options.disable_workgroup_init;
gen_options.generate_external_texture_bindings = true;
auto result = tint::writer::spirv::Generate(program, gen_options);
@@ -639,6 +641,7 @@ bool GenerateMsl(const tint::Program* program, const Options& options) {
// TODO(jrprice): Provide a way for the user to set non-default options.
tint::writer::msl::Options gen_options;
gen_options.disable_robustness = !options.enable_robustness;
gen_options.disable_workgroup_init = options.disable_workgroup_init;
gen_options.generate_external_texture_bindings = true;
auto result = tint::writer::msl::Generate(input_program, gen_options);
@@ -699,6 +702,7 @@ bool GenerateHlsl(const tint::Program* program, const Options& options) {
#if TINT_BUILD_HLSL_WRITER
// TODO(jrprice): Provide a way for the user to set non-default options.
tint::writer::hlsl::Options gen_options;
gen_options.disable_robustness = !options.enable_robustness;
gen_options.disable_workgroup_init = options.disable_workgroup_init;
gen_options.generate_external_texture_bindings = true;
gen_options.root_constant_binding_point = options.hlsl_root_constant_binding_point;
@@ -838,6 +842,7 @@ bool GenerateGlsl(const tint::Program* program, const Options& options) {
auto generate = [&](const tint::Program* prg, const std::string entry_point_name) -> bool {
tint::writer::glsl::Options gen_options;
gen_options.disable_robustness = !options.enable_robustness;
gen_options.generate_external_texture_bindings = true;
auto result = tint::writer::glsl::Generate(prg, gen_options, entry_point_name);
if (!result.success) {
@@ -946,8 +951,9 @@ int main(int argc, const char** argv) {
return true;
}},
{"robustness",
[](tint::inspector::Inspector&, tint::transform::Manager& m, tint::transform::DataMap&) {
m.Add<tint::transform::Robustness>();
[&](tint::inspector::Inspector&, tint::transform::Manager&,
tint::transform::DataMap&) { // enabled via writer option
options.enable_robustness = true;
return true;
}},
{"substitute_override",

View File

@@ -43,16 +43,14 @@ class ReaderWriterFuzzer : public CommonFuzzer {
CommonFuzzer::SetTransformManager(tm, inputs);
}
/// Pass through to the CommonFuzzer implementation, but will setup a
/// robustness transform, if no other transforms have been set.
/// @param data buffer of data that will interpreted as a byte array or string
/// depending on the shader input format.
/// Pass through to the CommonFuzzer implementation.
/// @param data buffer of data that will interpreted as a byte array or string depending on the
/// shader input format.
/// @param size number of elements in buffer
/// @returns 0, this is what libFuzzer expects
int Run(const uint8_t* data, size_t size) {
if (!tm_set_) {
tb_ = std::make_unique<TransformBuilder>(data, size);
tb_->AddTransform<tint::transform::Robustness>();
SetTransformManager(tb_->manager(), tb_->data_map());
}

View File

@@ -15,6 +15,7 @@
#include "src/tint/fuzzers/fuzzer_init.h"
#include "src/tint/fuzzers/tint_common_fuzzer.h"
#include "src/tint/fuzzers/transform_builder.h"
#include "src/tint/transform/robustness.h"
namespace tint::fuzzers {

View File

@@ -22,6 +22,7 @@
#include "src/tint/fuzzers/data_builder.h"
#include "src/tint/fuzzers/shuffle_transform.h"
#include "src/tint/transform/robustness.h"
namespace tint::fuzzers {
@@ -61,7 +62,6 @@ class TransformBuilder {
/// Helper that invokes Add*Transform for all of the platform independent
/// passes.
void AddPlatformIndependentPasses() {
AddTransform<transform::Robustness>();
AddTransform<transform::FirstIndexOffset>();
AddTransform<transform::BindingRemapper>();
AddTransform<transform::Renamer>();

View File

@@ -22,6 +22,8 @@ namespace tint::transform {
/// This transform turns all explicit alignment and sizing into padding
/// members of structs. This is required for GLSL ES, since it not support
/// the offset= decoration.
///
/// @note This transform requires the CanonicalizeEntryPointIO transform to have been run first.
class PadStructs final : public Castable<PadStructs, Transform> {
public:
/// Constructor

View File

@@ -31,6 +31,7 @@ namespace tint::transform {
/// the bounds of the array. Any access before the start of the array will clamp
/// to zero and any access past the end of the array will clamp to
/// (array length - 1).
/// @note This transform must come before the BuiltinPolyfill transform
class Robustness final : public Castable<Robustness, Transform> {
public:
/// Address space to be skipped in the transform

View File

@@ -63,6 +63,9 @@ struct Options {
/// transform
std::unordered_map<sem::BindingPoint, builtin::Access> access_controls;
/// Set to `true` to disable software robustness that prevents out-of-bounds accesses.
bool disable_robustness = false;
/// If true, then validation will be disabled for binding point collisions
/// generated by the BindingRemapper transform
bool allow_collisions = false;
@@ -75,6 +78,13 @@ struct Options {
/// The GLSL version to emit
Version version;
/// Reflect the fields of this class so that it can be used by tint::ForeachField()
TINT_REFLECT(disable_robustness,
allow_collisions,
disable_workgroup_init,
generate_external_texture_bindings,
version);
};
/// The result produced when generating GLSL.

View File

@@ -57,6 +57,7 @@
#include "src/tint/transform/promote_side_effects_to_decl.h"
#include "src/tint/transform/remove_phonies.h"
#include "src/tint/transform/renamer.h"
#include "src/tint/transform/robustness.h"
#include "src/tint/transform/simplify_pointers.h"
#include "src/tint/transform/single_entry_point.h"
#include "src/tint/transform/std140.h"
@@ -149,6 +150,33 @@ SanitizedResult Sanitize(const Program* in,
// ExpandCompoundAssignment must come before BuiltinPolyfill
manager.Add<transform::ExpandCompoundAssignment>();
if (!entry_point.empty()) {
manager.Add<transform::SingleEntryPoint>();
data.Add<transform::SingleEntryPoint::Config>(entry_point);
}
manager.Add<transform::Renamer>();
data.Add<transform::Renamer::Config>(transform::Renamer::Target::kGlslKeywords,
/* preserve_unicode */ false);
manager.Add<transform::PreservePadding>(); // Must come before DirectVariableAccess
manager.Add<transform::Unshadow>(); // Must come before DirectVariableAccess
manager.Add<transform::DirectVariableAccess>();
manager.Add<transform::PromoteSideEffectsToDecl>();
if (!options.disable_robustness) {
// Robustness must come before BuiltinPolyfill
manager.Add<transform::Robustness>();
}
if (options.generate_external_texture_bindings) {
// Note: it is more efficient for MultiplanarExternalTexture to come after Robustness
auto new_bindings_map = writer::GenerateExternalTextureBindings(in);
data.Add<transform::MultiplanarExternalTexture::NewBindingPoints>(new_bindings_map);
manager.Add<transform::MultiplanarExternalTexture>();
}
{ // Builtin polyfills
transform::BuiltinPolyfill::Builtins polyfills;
polyfills.acosh = transform::BuiltinPolyfill::Level::kRangeCheck;
@@ -169,26 +197,16 @@ SanitizedResult Sanitize(const Program* in,
manager.Add<transform::BuiltinPolyfill>();
}
if (!entry_point.empty()) {
manager.Add<transform::SingleEntryPoint>();
data.Add<transform::SingleEntryPoint::Config>(entry_point);
}
manager.Add<transform::Renamer>();
data.Add<transform::Renamer::Config>(transform::Renamer::Target::kGlslKeywords,
/* preserve_unicode */ false);
manager.Add<transform::PreservePadding>(); // Must come before DirectVariableAccess
manager.Add<transform::Unshadow>(); // Must come before DirectVariableAccess
manager.Add<transform::DirectVariableAccess>();
if (!options.disable_workgroup_init) {
// ZeroInitWorkgroupMemory must come before CanonicalizeEntryPointIO as
// ZeroInitWorkgroupMemory may inject new builtin parameters.
manager.Add<transform::ZeroInitWorkgroupMemory>();
}
// CanonicalizeEntryPointIO must come after Robustness
manager.Add<transform::CanonicalizeEntryPointIO>();
manager.Add<transform::PromoteSideEffectsToDecl>();
// PadStructs must come after CanonicalizeEntryPointIO
manager.Add<transform::PadStructs>();
// DemoteToHelper must come after PromoteSideEffectsToDecl and ExpandCompoundAssignment.
@@ -196,12 +214,6 @@ SanitizedResult Sanitize(const Program* in,
manager.Add<transform::RemovePhonies>();
if (options.generate_external_texture_bindings) {
auto new_bindings_map = writer::GenerateExternalTextureBindings(in);
data.Add<transform::MultiplanarExternalTexture::NewBindingPoints>(new_bindings_map);
}
manager.Add<transform::MultiplanarExternalTexture>();
data.Add<transform::CombineSamplers::BindingInfo>(options.binding_map,
options.placeholder_binding_point);
manager.Add<transform::CombineSamplers>();

View File

@@ -32,6 +32,14 @@ class TestHelperBase : public BODY, public ProgramBuilder {
TestHelperBase() = default;
~TestHelperBase() override = default;
/// @returns the default generator options for SanitizeAndBuild(), if no explicit options are
/// provided.
static Options DefaultOptions() {
Options opts;
opts.disable_robustness = true;
return opts;
}
/// Builds the program and returns a GeneratorImpl from the program.
/// @note The generator is only built once. Multiple calls to Build() will
/// return the same GeneratorImpl without rebuilding.
@@ -60,7 +68,8 @@ class TestHelperBase : public BODY, public ProgramBuilder {
/// @param version the GLSL version
/// @param options the GLSL backend options
/// @return the built generator
GeneratorImpl& SanitizeAndBuild(Version version = Version(), const Options& options = {}) {
GeneratorImpl& SanitizeAndBuild(Version version = Version(),
const Options& options = DefaultOptions()) {
if (gen_) {
return *gen_;
}

View File

@@ -49,23 +49,32 @@ struct Options {
/// @returns this Options
Options& operator=(const Options&);
/// Set to `true` to disable software robustness that prevents out-of-bounds accesses.
bool disable_robustness = false;
/// The binding point to use for information passed via root constants.
std::optional<sem::BindingPoint> root_constant_binding_point;
/// Set to `true` to disable workgroup memory zero initialization
bool disable_workgroup_init = false;
/// Set to 'true' to generates binding mappings for external textures
bool generate_external_texture_bindings = false;
/// 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;
/// Set to `true` to generate polyfill for `reflect` builtin for vec2<f32>
bool polyfill_reflect_vec2_f32 = false;
/// Reflect the fields of this class so that it can be used by tint::ForeachField()
TINT_REFLECT(root_constant_binding_point,
TINT_REFLECT(disable_robustness,
root_constant_binding_point,
disable_workgroup_init,
generate_external_texture_bindings,
array_length_from_uniform);

View File

@@ -57,6 +57,7 @@
#include "src/tint/transform/promote_side_effects_to_decl.h"
#include "src/tint/transform/remove_continue_in_switch.h"
#include "src/tint/transform/remove_phonies.h"
#include "src/tint/transform/robustness.h"
#include "src/tint/transform/simplify_pointers.h"
#include "src/tint/transform/truncate_interstage_variables.h"
#include "src/tint/transform/unshadow.h"
@@ -165,6 +166,33 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
// ExpandCompoundAssignment must come before BuiltinPolyfill
manager.Add<transform::ExpandCompoundAssignment>();
manager.Add<transform::Unshadow>(); // Must come before DirectVariableAccess
manager.Add<transform::DirectVariableAccess>();
// LocalizeStructArrayAssignment must come after:
// * SimplifyPointers, because it assumes assignment to arrays in structs are
// done directly, not indirectly.
// TODO(crbug.com/tint/1340): See if we can get rid of the duplicate
// SimplifyPointers transform. Can't do it right now because
// LocalizeStructArrayAssignment introduces pointers.
manager.Add<transform::SimplifyPointers>();
manager.Add<transform::LocalizeStructArrayAssignment>();
manager.Add<transform::PromoteSideEffectsToDecl>();
if (!options.disable_robustness) {
// Robustness must come before BuiltinPolyfill
manager.Add<transform::Robustness>();
}
if (options.generate_external_texture_bindings) {
// Note: it is more efficient for MultiplanarExternalTexture to come after Robustness
auto new_bindings_map = GenerateExternalTextureBindings(in);
data.Add<transform::MultiplanarExternalTexture::NewBindingPoints>(new_bindings_map);
manager.Add<transform::MultiplanarExternalTexture>();
}
{ // Builtin polyfills
transform::BuiltinPolyfill::Builtins polyfills;
polyfills.acosh = transform::BuiltinPolyfill::Level::kFull;
@@ -189,37 +217,13 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
manager.Add<transform::BuiltinPolyfill>();
}
// Build the config for the internal ArrayLengthFromUniform transform.
auto& array_length_from_uniform = options.array_length_from_uniform;
transform::ArrayLengthFromUniform::Config array_length_from_uniform_cfg(
array_length_from_uniform.ubo_binding);
array_length_from_uniform_cfg.bindpoint_to_size_index =
array_length_from_uniform.bindpoint_to_size_index;
if (options.generate_external_texture_bindings) {
auto new_bindings_map = GenerateExternalTextureBindings(in);
data.Add<transform::MultiplanarExternalTexture::NewBindingPoints>(new_bindings_map);
}
manager.Add<transform::MultiplanarExternalTexture>();
manager.Add<transform::Unshadow>(); // Must come before DirectVariableAccess
manager.Add<transform::DirectVariableAccess>();
// LocalizeStructArrayAssignment must come after:
// * SimplifyPointers, because it assumes assignment to arrays in structs are
// done directly, not indirectly.
// TODO(crbug.com/tint/1340): See if we can get rid of the duplicate
// SimplifyPointers transform. Can't do it right now because
// LocalizeStructArrayAssignment introduces pointers.
manager.Add<transform::SimplifyPointers>();
manager.Add<transform::LocalizeStructArrayAssignment>();
if (!options.disable_workgroup_init) {
// ZeroInitWorkgroupMemory must come before CanonicalizeEntryPointIO as
// ZeroInitWorkgroupMemory may inject new builtin parameters.
manager.Add<transform::ZeroInitWorkgroupMemory>();
}
// CanonicalizeEntryPointIO must come after Robustness
manager.Add<transform::CanonicalizeEntryPointIO>();
if (options.interstage_locations.any()) {
@@ -246,11 +250,17 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
// assumes that num_workgroups builtins only appear as struct members and are
// only accessed directly via member accessors.
manager.Add<transform::NumWorkgroupsFromUniform>();
manager.Add<transform::PromoteSideEffectsToDecl>();
manager.Add<transform::VectorizeScalarMatrixInitializers>();
manager.Add<transform::SimplifyPointers>();
manager.Add<transform::RemovePhonies>();
// Build the config for the internal ArrayLengthFromUniform transform.
auto& array_length_from_uniform = options.array_length_from_uniform;
transform::ArrayLengthFromUniform::Config array_length_from_uniform_cfg(
array_length_from_uniform.ubo_binding);
array_length_from_uniform_cfg.bindpoint_to_size_index =
array_length_from_uniform.bindpoint_to_size_index;
// DemoteToHelper must come after CanonicalizeEntryPointIO, PromoteSideEffectsToDecl, and
// ExpandCompoundAssignment.
// TODO(crbug.com/tint/1752): This is only necessary when FXC is being used.

View File

@@ -34,6 +34,14 @@ class TestHelperBase : public BODY, public ProgramBuilder {
TestHelperBase() = default;
~TestHelperBase() override = default;
/// @returns the default generator options for SanitizeAndBuild(), if no explicit options are
/// provided.
static Options DefaultOptions() {
Options opts;
opts.disable_robustness = true;
return opts;
}
/// Builds the program and returns a GeneratorImpl from the program.
/// @note The generator is only built once. Multiple calls to Build() will
/// return the same GeneratorImpl without rebuilding.
@@ -60,7 +68,7 @@ class TestHelperBase : public BODY, public ProgramBuilder {
/// @note The generator is only built once. Multiple calls to Build() will
/// return the same GeneratorImpl without rebuilding.
/// @return the built generator
GeneratorImpl& SanitizeAndBuild(const Options& options = {}) {
GeneratorImpl& SanitizeAndBuild(const Options& options = DefaultOptions()) {
if (gen_) {
return *gen_;
}

View File

@@ -44,6 +44,9 @@ struct Options {
/// @returns this Options
Options& operator=(const Options&);
/// Set to `true` to disable software robustness that prevents out-of-bounds accesses.
bool disable_robustness = false;
/// The index to use when generating a UBO to receive storage buffer sizes.
/// Defaults to 30, which is the last valid buffer slot.
uint32_t buffer_size_ubo_index = 30;
@@ -67,7 +70,8 @@ struct Options {
ArrayLengthFromUniformOptions array_length_from_uniform = {};
/// Reflect the fields of this class so that it can be used by tint::ForeachField()
TINT_REFLECT(buffer_size_ubo_index,
TINT_REFLECT(disable_robustness,
buffer_size_ubo_index,
fixed_sample_mask,
emit_vertex_point_size,
disable_workgroup_init,

View File

@@ -53,6 +53,7 @@
#include "src/tint/transform/promote_initializers_to_let.h"
#include "src/tint/transform/promote_side_effects_to_decl.h"
#include "src/tint/transform/remove_phonies.h"
#include "src/tint/transform/robustness.h"
#include "src/tint/transform/simplify_pointers.h"
#include "src/tint/transform/unshadow.h"
#include "src/tint/transform/vectorize_scalar_matrix_initializers.h"
@@ -171,24 +172,6 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
// ExpandCompoundAssignment must come before BuiltinPolyfill
manager.Add<transform::ExpandCompoundAssignment>();
{ // Builtin polyfills
transform::BuiltinPolyfill::Builtins polyfills;
polyfills.acosh = transform::BuiltinPolyfill::Level::kRangeCheck;
polyfills.atanh = transform::BuiltinPolyfill::Level::kRangeCheck;
polyfills.bitshift_modulo = true; // crbug.com/tint/1543
polyfills.clamp_int = true;
polyfills.extract_bits = transform::BuiltinPolyfill::Level::kClampParameters;
polyfills.first_leading_bit = true;
polyfills.first_trailing_bit = true;
polyfills.insert_bits = transform::BuiltinPolyfill::Level::kClampParameters;
polyfills.int_div_mod = true;
polyfills.sign_int = true;
polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true;
polyfills.workgroup_uniform_load = true;
data.Add<transform::BuiltinPolyfill::Config>(polyfills);
manager.Add<transform::BuiltinPolyfill>();
}
// Build the config for the internal ArrayLengthFromUniform transform.
auto& array_length_from_uniform = options.array_length_from_uniform;
transform::ArrayLengthFromUniform::Config array_length_from_uniform_cfg(
@@ -217,23 +200,51 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
transform::CanonicalizeEntryPointIO::ShaderStyle::kMsl, options.fixed_sample_mask,
options.emit_vertex_point_size);
if (options.generate_external_texture_bindings) {
auto new_bindings_map = GenerateExternalTextureBindings(in);
data.Add<transform::MultiplanarExternalTexture::NewBindingPoints>(new_bindings_map);
}
manager.Add<transform::MultiplanarExternalTexture>();
manager.Add<transform::PreservePadding>();
manager.Add<transform::Unshadow>();
manager.Add<transform::PromoteSideEffectsToDecl>();
if (!options.disable_robustness) {
// Robustness must come before BuiltinPolyfill
manager.Add<transform::Robustness>();
}
{ // Builtin polyfills
transform::BuiltinPolyfill::Builtins polyfills;
polyfills.acosh = transform::BuiltinPolyfill::Level::kRangeCheck;
polyfills.atanh = transform::BuiltinPolyfill::Level::kRangeCheck;
polyfills.bitshift_modulo = true; // crbug.com/tint/1543
polyfills.clamp_int = true;
polyfills.extract_bits = transform::BuiltinPolyfill::Level::kClampParameters;
polyfills.first_leading_bit = true;
polyfills.first_trailing_bit = true;
polyfills.insert_bits = transform::BuiltinPolyfill::Level::kClampParameters;
polyfills.int_div_mod = true;
polyfills.sign_int = true;
polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true;
polyfills.workgroup_uniform_load = true;
data.Add<transform::BuiltinPolyfill::Config>(polyfills);
manager.Add<transform::BuiltinPolyfill>();
}
if (options.generate_external_texture_bindings) {
// Note: it is more efficient for MultiplanarExternalTexture to come after Robustness
auto new_bindings_map = GenerateExternalTextureBindings(in);
data.Add<transform::MultiplanarExternalTexture::NewBindingPoints>(new_bindings_map);
manager.Add<transform::MultiplanarExternalTexture>();
}
if (!options.disable_workgroup_init) {
// ZeroInitWorkgroupMemory must come before CanonicalizeEntryPointIO as
// ZeroInitWorkgroupMemory may inject new builtin parameters.
manager.Add<transform::ZeroInitWorkgroupMemory>();
}
// CanonicalizeEntryPointIO must come after Robustness
manager.Add<transform::CanonicalizeEntryPointIO>();
manager.Add<transform::PromoteSideEffectsToDecl>();
manager.Add<transform::PromoteInitializersToLet>();
// DemoteToHelper must come after PromoteSideEffectsToDecl and ExpandCompoundAssignment.

View File

@@ -33,6 +33,14 @@ class TestHelperBase : public BASE, public ProgramBuilder {
TestHelperBase() = default;
~TestHelperBase() override = default;
/// @returns the default generator options for SanitizeAndBuild(), if no explicit options are
/// provided.
static Options DefaultOptions() {
Options opts;
opts.disable_robustness = true;
return opts;
}
/// Builds and returns a GeneratorImpl from the program.
/// @note The generator is only built once. Multiple calls to Build() will
/// return the same GeneratorImpl without rebuilding.
@@ -59,7 +67,7 @@ class TestHelperBase : public BASE, public ProgramBuilder {
/// @note The generator is only built once. Multiple calls to Build() will
/// return the same GeneratorImpl without rebuilding.
/// @return the built generator
GeneratorImpl& SanitizeAndBuild(const Options& options = {}) {
GeneratorImpl& SanitizeAndBuild(const Options& options = DefaultOptions()) {
if (gen_) {
return *gen_;
}

View File

@@ -2107,7 +2107,7 @@ OpEntryPoint Fragment %24 "a_func"
OpExecutionMode %24 OriginUpperLeft
OpName %5 "v"
OpName %8 "tint_quantizeToF16"
OpName %9 "v_1"
OpName %9 "v"
OpName %24 "a_func"
%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3

View File

@@ -35,6 +35,9 @@ namespace tint::writer::spirv {
/// Configuration options used for generating SPIR-V.
struct Options {
/// Set to `true` to disable software robustness that prevents out-of-bounds accesses.
bool disable_robustness = false;
/// Set to `true` to generate a PointSize builtin and have it set to 1.0
/// from all vertex shaders in the module.
bool emit_vertex_point_size = true;
@@ -50,7 +53,8 @@ struct Options {
bool use_zero_initialize_workgroup_memory_extension = false;
/// Reflect the fields of this class so that it can be used by tint::ForeachField()
TINT_REFLECT(emit_vertex_point_size,
TINT_REFLECT(disable_robustness,
emit_vertex_point_size,
disable_workgroup_init,
generate_external_texture_bindings,
use_zero_initialize_workgroup_memory_extension);

View File

@@ -32,6 +32,7 @@
#include "src/tint/transform/promote_side_effects_to_decl.h"
#include "src/tint/transform/remove_phonies.h"
#include "src/tint/transform/remove_unreachable_statements.h"
#include "src/tint/transform/robustness.h"
#include "src/tint/transform/simplify_pointers.h"
#include "src/tint/transform/std140.h"
#include "src/tint/transform/unshadow.h"
@@ -53,7 +54,34 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
// ExpandCompoundAssignment must come before BuiltinPolyfill
manager.Add<transform::ExpandCompoundAssignment>();
manager.Add<transform::PreservePadding>(); // Must come before DirectVariableAccess
manager.Add<transform::Unshadow>(); // Must come before DirectVariableAccess
manager.Add<transform::RemoveUnreachableStatements>();
manager.Add<transform::PromoteSideEffectsToDecl>();
manager.Add<transform::SimplifyPointers>(); // Required for arrayLength()
manager.Add<transform::RemovePhonies>();
manager.Add<transform::VectorizeScalarMatrixInitializers>();
manager.Add<transform::VectorizeMatrixConversions>();
manager.Add<transform::WhileToLoop>(); // ZeroInitWorkgroupMemory
manager.Add<transform::MergeReturn>();
if (!options.disable_robustness) {
// Robustness must come before BuiltinPolyfill
manager.Add<transform::Robustness>();
}
if (options.generate_external_texture_bindings) {
// Note: it is more efficient for MultiplanarExternalTexture to come after Robustness
auto new_bindings_map = GenerateExternalTextureBindings(in);
data.Add<transform::MultiplanarExternalTexture::NewBindingPoints>(new_bindings_map);
manager.Add<transform::MultiplanarExternalTexture>();
}
{ // Builtin polyfills
// BuiltinPolyfill must come before DirectVariableAccess, due to the use of pointer
// parameter for workgroupUniformLoad()
transform::BuiltinPolyfill::Builtins polyfills;
polyfills.acosh = transform::BuiltinPolyfill::Level::kRangeCheck;
polyfills.atanh = transform::BuiltinPolyfill::Level::kRangeCheck;
@@ -75,18 +103,11 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
manager.Add<transform::BuiltinPolyfill>();
}
if (options.generate_external_texture_bindings) {
auto new_bindings_map = GenerateExternalTextureBindings(in);
data.Add<transform::MultiplanarExternalTexture::NewBindingPoints>(new_bindings_map);
}
manager.Add<transform::MultiplanarExternalTexture>();
manager.Add<transform::PreservePadding>(); // Must come before DirectVariableAccess
manager.Add<transform::Unshadow>(); // Must come before DirectVariableAccess
bool disable_workgroup_init_in_sanitizer =
options.disable_workgroup_init || options.use_zero_initialize_workgroup_memory_extension;
if (!disable_workgroup_init_in_sanitizer) {
// ZeroInitWorkgroupMemory must come before CanonicalizeEntryPointIO as
// ZeroInitWorkgroupMemory may inject new builtin parameters.
manager.Add<transform::ZeroInitWorkgroupMemory>();
}
@@ -98,16 +119,11 @@ SanitizedResult Sanitize(const Program* in, const Options& options) {
manager.Add<transform::DirectVariableAccess>();
}
manager.Add<transform::RemoveUnreachableStatements>();
manager.Add<transform::PromoteSideEffectsToDecl>();
manager.Add<transform::SimplifyPointers>(); // Required for arrayLength()
manager.Add<transform::RemovePhonies>();
manager.Add<transform::VectorizeScalarMatrixInitializers>();
manager.Add<transform::VectorizeMatrixConversions>();
manager.Add<transform::WhileToLoop>(); // ZeroInitWorkgroupMemory
manager.Add<transform::MergeReturn>();
// CanonicalizeEntryPointIO must come after Robustness
manager.Add<transform::CanonicalizeEntryPointIO>();
manager.Add<transform::AddEmptyEntryPoint>();
// AddBlockAttribute must come after MultiplanarExternalTexture
manager.Add<transform::AddBlockAttribute>();
// DemoteToHelper must come after CanonicalizeEntryPointIO, PromoteSideEffectsToDecl, and

View File

@@ -33,6 +33,14 @@ class TestHelperBase : public ProgramBuilder, public BASE {
TestHelperBase() = default;
~TestHelperBase() override = default;
/// @returns the default generator options for SanitizeAndBuild(), if no explicit options are
/// provided.
static Options DefaultOptions() {
Options opts;
opts.disable_robustness = true;
return opts;
}
/// Builds and returns a spirv::Builder from the program.
/// @note The spirv::Builder is only built once. Multiple calls to Build()
/// will return the same spirv::Builder without rebuilding.
@@ -59,7 +67,7 @@ class TestHelperBase : public ProgramBuilder, public BASE {
/// @note The spirv::Builder is only built once. Multiple calls to Build()
/// will return the same spirv::Builder without rebuilding.
/// @return the built spirv::Builder
spirv::Builder& SanitizeAndBuild(const Options& options = {}) {
spirv::Builder& SanitizeAndBuild(const Options& options = DefaultOptions()) {
if (spirv_builder) {
return *spirv_builder;
}