Add a feature for allowing LocalSizeId (#4492)

Allow LocalSizeId as a way of sizing compute workgroups where the
environment allows it. A command-line switch is also added to force
acceptance even where the environment would not otherwise allow it.
This commit is contained in:
gnl21 2021-08-26 19:33:19 +01:00 коммит произвёл GitHub
Родитель 2a5cc342fb
Коммит ee30773650
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 45 добавлений и 0 удалений

Просмотреть файл

@ -659,6 +659,11 @@ SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetWorkgroupScalarBlockLayout(
SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetSkipBlockLayout(
spv_validator_options options, bool val);
// Records whether or not the validator should allow the LocalSizeId
// decoration where the environment otherwise would not allow it.
SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetAllowLocalSizeId(
spv_validator_options options, bool val);
// Creates an optimizer options object with default options. Returns a valid
// options object. The object remains valid until it is passed into
// |spvOptimizerOptionsDestroy|.

Просмотреть файл

@ -115,6 +115,12 @@ class ValidatorOptions {
spvValidatorOptionsSetSkipBlockLayout(options_, val);
}
// Enables LocalSizeId decorations where the environment would not otherwise
// allow them.
void SetAllowLocalSizeId(bool val) {
spvValidatorOptionsSetAllowLocalSizeId(options_, val);
}
// Records whether or not the validator should relax the rules on pointer
// usage in logical addressing mode.
//

Просмотреть файл

@ -120,3 +120,8 @@ void spvValidatorOptionsSetSkipBlockLayout(spv_validator_options options,
bool val) {
options->skip_block_layout = val;
}
void spvValidatorOptionsSetAllowLocalSizeId(spv_validator_options options,
bool val) {
options->allow_localsizeid = val;
}

Просмотреть файл

@ -47,6 +47,7 @@ struct spv_validator_options_t {
scalar_block_layout(false),
workgroup_scalar_block_layout(false),
skip_block_layout(false),
allow_localsizeid(false),
before_hlsl_legalization(false) {}
validator_universal_limits_t universal_limits_;
@ -57,6 +58,7 @@ struct spv_validator_options_t {
bool scalar_block_layout;
bool workgroup_scalar_block_layout;
bool skip_block_layout;
bool allow_localsizeid;
bool before_hlsl_legalization;
};

Просмотреть файл

@ -225,6 +225,13 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) {
}
}
}
if (i.opcode() == SpvOpExecutionModeId) {
const auto mode = i.GetOperandAs<SpvExecutionMode>(1);
if (mode == SpvExecutionModeLocalSizeId) {
ok = true;
break;
}
}
}
if (!ok) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
@ -429,6 +436,10 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _,
break;
case SpvExecutionModeLocalSize:
case SpvExecutionModeLocalSizeId:
if (mode == SpvExecutionModeLocalSizeId && !_.IsLocalSizeIdAllowed())
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "LocalSizeId mode is not allowed by the current environment.";
if (!std::all_of(models->begin(), models->end(),
[&_](const SpvExecutionModel& model) {
switch (model) {

Просмотреть файл

@ -175,6 +175,9 @@ ValidationState_t::ValidationState_t(const spv_const_context ctx,
}
}
// LocalSizeId is always allowed in non-Vulkan environments.
features_.env_allow_localsizeid = !spvIsVulkanEnv(env);
// Only attempt to count if we have words, otherwise let the other validation
// fail and generate an error.
if (num_words > 0) {

Просмотреть файл

@ -121,6 +121,9 @@ class ValidationState_t {
// SPIR-V 1.4 allows Function and Private variables to be NonWritable
bool nonwritable_var_in_function_or_private = false;
// Whether LocalSizeId execution mode is allowed by the environment.
bool env_allow_localsizeid = false;
};
ValidationState_t(const spv_const_context context,
@ -493,6 +496,12 @@ class ValidationState_t {
return features_.env_relaxed_block_layout || options()->relax_block_layout;
}
// Returns true if allowing localsizeid, either because the environment always
// allows it, or because it is enabled from the command-line.
bool IsLocalSizeIdAllowed() const {
return features_.env_allow_localsizeid || options()->allow_localsizeid;
}
/// Sets the struct nesting depth for a given struct ID
void set_struct_nesting_depth(uint32_t id, uint32_t depth) {
struct_nesting_depth_[id] = depth;

Просмотреть файл

@ -64,6 +64,8 @@ Options:
--relax-struct-store Allow store from one struct type to a
different type with compatible layout and
members.
--allow-localsizeid Allow use of the LocalSizeId decoration where it would otherwise not
be allowed by the target environment.
--before-hlsl-legalization Allows code patterns that are intended to be
fixed by spirv-opt's legalization passes.
--version Display validator version information.
@ -153,6 +155,8 @@ int main(int argc, char** argv) {
options.SetWorkgroupScalarBlockLayout(true);
} else if (0 == strcmp(cur_arg, "--skip-block-layout")) {
options.SetSkipBlockLayout(true);
} else if (0 == strcmp(cur_arg, "--allow-localsizeid")) {
options.SetAllowLocalSizeId(true);
} else if (0 == strcmp(cur_arg, "--relax-struct-store")) {
options.SetRelaxStructStore(true);
} else if (0 == cur_arg[1]) {