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:
Родитель
2a5cc342fb
Коммит
ee30773650
|
@ -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]) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче