Skip to content

Commit

Permalink
layers: Improve RequiredSubgroupSizeCreateInfo messages
Browse files Browse the repository at this point in the history
  • Loading branch information
spencer-lunarg committed Aug 21, 2024
1 parent c4dd022 commit 60b8a03
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 40 deletions.
66 changes: 31 additions & 35 deletions layers/core_checks/cc_spirv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2388,11 +2388,7 @@ bool CoreChecks::ValidateShaderStage(const ShaderStageState &stage_state, const
local_size_x, local_size_y, local_size_z, phys_dev_props.limits.maxComputeWorkGroupInvocations);
}

if (const auto *required_subgroup_size_features =
vku::FindStructInPNextChain<VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT>(stage_state.GetPNext())) {
skip |= ValidateRequiredSubgroupSize(module_state, stage_state, *required_subgroup_size_features, invocations,
local_size_x, local_size_y, local_size_z, loc);
}
skip |= ValidateRequiredSubgroupSize(module_state, stage_state, invocations, local_size_x, local_size_y, local_size_z, loc);
skip |= ValidateWorkgroupSharedMemory(module_state, stage, total_workgroup_shared_memory, loc);
}

Expand Down Expand Up @@ -2595,58 +2591,60 @@ bool CoreChecks::PreCallValidateGetShaderModuleCreateInfoIdentifierEXT(VkDevice
}

bool CoreChecks::ValidateRequiredSubgroupSize(const spirv::Module &module_state, const ShaderStageState &stage_state,
const VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT &required_subgroup_size,
uint64_t invocations, uint32_t local_size_x, uint32_t local_size_y,
uint32_t local_size_z, const Location &loc) const {
bool skip = false;

const uint32_t requiredSubgroupSize = required_subgroup_size.requiredSubgroupSize;
const auto *required_subgroup_size_ci =
vku::FindStructInPNextChain<VkPipelineShaderStageRequiredSubgroupSizeCreateInfo>(stage_state.GetPNext());
if (!required_subgroup_size_ci) return skip;

const Location pNext_loc = loc.pNext(Struct::VkPipelineShaderStageRequiredSubgroupSizeCreateInfo);

const uint32_t required_subgroup_size = required_subgroup_size_ci->requiredSubgroupSize;
if (!enabled_features.subgroupSizeControl) {
skip |= LogError("VUID-VkPipelineShaderStageCreateInfo-pNext-02755", module_state.handle(), loc,
"subgroupSizeControl was not enabled");
skip |= LogError("VUID-VkPipelineShaderStageCreateInfo-pNext-02755", module_state.handle(), pNext_loc,
"the subgroupSizeControl feature was not enabled");
}
if ((phys_dev_ext_props.subgroup_size_control_props.requiredSubgroupSizeStages & stage_state.GetStage()) == 0) {
skip |= LogError(
"VUID-VkPipelineShaderStageCreateInfo-pNext-02755", module_state.handle(), loc,
"SPIR-V (%s) is not in requiredSubgroupSizeStages (%s).", string_VkShaderStageFlagBits(stage_state.GetStage()),
string_VkShaderStageFlags(phys_dev_ext_props.subgroup_size_control_props.requiredSubgroupSizeStages).c_str());
skip |=
LogError("VUID-VkPipelineShaderStageCreateInfo-pNext-02755", module_state.handle(), loc,
"SPIR-V (%s) is not in requiredSubgroupSizeStages (%s).", string_VkShaderStageFlagBits(stage_state.GetStage()),
string_VkShaderStageFlags(phys_dev_ext_props.subgroup_size_control_props.requiredSubgroupSizeStages).c_str());
}
if ((invocations > requiredSubgroupSize * phys_dev_ext_props.subgroup_size_control_props.maxComputeWorkgroupSubgroups)) {
if ((invocations > required_subgroup_size * phys_dev_ext_props.subgroup_size_control_props.maxComputeWorkgroupSubgroups)) {
skip |= LogError("VUID-VkPipelineShaderStageCreateInfo-pNext-02756", module_state.handle(), loc,
"SPIR-V Local workgroup size (%" PRIu32 ", %" PRIu32 ", %" PRIu32
") is greater than requiredSubgroupSize (%" PRIu32 ") * maxComputeWorkgroupSubgroups (%" PRIu32 ").",
local_size_x, local_size_y, local_size_z, requiredSubgroupSize,
local_size_x, local_size_y, local_size_z, required_subgroup_size,
phys_dev_ext_props.subgroup_size_control_props.maxComputeWorkgroupSubgroups);
}
if (stage_state.pipeline_create_info &&
(stage_state.pipeline_create_info->flags & VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT) > 0) {
if (SafeModulo(local_size_x, requiredSubgroupSize) != 0) {
if (SafeModulo(local_size_x, required_subgroup_size) != 0) {
skip |= LogError("VUID-VkPipelineShaderStageCreateInfo-pNext-02757", module_state.handle(), loc,
"SPIR-V Local workgroup size x (%" PRIu32
") is not a multiple of "
"requiredSubgroupSize (%" PRIu32 ").",
local_size_x, requiredSubgroupSize);
local_size_x, required_subgroup_size);
}
}
if (!IsPowerOfTwo(requiredSubgroupSize)) {
skip |=
LogError("VUID-VkPipelineShaderStageRequiredSubgroupSizeCreateInfo-requiredSubgroupSize-02760", module_state.handle(),
loc.pNext(Struct::VkPipelineShaderStageRequiredSubgroupSizeCreateInfo, Field::requiredSubgroupSizeStages),
"(%" PRIu32 ") is not a power of 2.", requiredSubgroupSize);
if (!IsPowerOfTwo(required_subgroup_size)) {
skip |= LogError("VUID-VkPipelineShaderStageRequiredSubgroupSizeCreateInfo-requiredSubgroupSize-02760",
module_state.handle(), pNext_loc.dot(Field::requiredSubgroupSizeStages),
"(%" PRIu32 ") is not a power of 2.", required_subgroup_size);
}
if (requiredSubgroupSize < phys_dev_ext_props.subgroup_size_control_props.minSubgroupSize) {
if (required_subgroup_size < phys_dev_ext_props.subgroup_size_control_props.minSubgroupSize) {
skip |=
LogError("VUID-VkPipelineShaderStageRequiredSubgroupSizeCreateInfo-requiredSubgroupSize-02761", module_state.handle(),
loc.pNext(Struct::VkPipelineShaderStageRequiredSubgroupSizeCreateInfo, Field::requiredSubgroupSizeStages),
"(%" PRIu32 ") is less than minSubgroupSize (%" PRIu32 ").", requiredSubgroupSize,
phys_dev_ext_props.subgroup_size_control_props.minSubgroupSize);
pNext_loc.dot(Field::requiredSubgroupSizeStages), "(%" PRIu32 ") is less than minSubgroupSize (%" PRIu32 ").",
required_subgroup_size, phys_dev_ext_props.subgroup_size_control_props.minSubgroupSize);
}
if (requiredSubgroupSize > phys_dev_ext_props.subgroup_size_control_props.maxSubgroupSize) {
skip |=
LogError("VUID-VkPipelineShaderStageRequiredSubgroupSizeCreateInfo-requiredSubgroupSize-02762", module_state.handle(),
loc.pNext(Struct::VkPipelineShaderStageRequiredSubgroupSizeCreateInfo, Field::requiredSubgroupSizeStages),
"(%" PRIu32 ") is greater than maxSubgroupSize (%" PRIu32 ").", requiredSubgroupSize,
phys_dev_ext_props.subgroup_size_control_props.maxSubgroupSize);
if (required_subgroup_size > phys_dev_ext_props.subgroup_size_control_props.maxSubgroupSize) {
skip |= LogError("VUID-VkPipelineShaderStageRequiredSubgroupSizeCreateInfo-requiredSubgroupSize-02762",
module_state.handle(), pNext_loc.dot(Field::requiredSubgroupSizeStages),
"(%" PRIu32 ") is greater than maxSubgroupSize (%" PRIu32 ").", required_subgroup_size,
phys_dev_ext_props.subgroup_size_control_props.maxSubgroupSize);
}

return skip;
Expand Down Expand Up @@ -2692,9 +2690,7 @@ bool CoreChecks::ValidateComputeWorkGroupSizes(const spirv::Module &module_state
} else if ((stage_state.pipeline_create_info->flags & VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT) &&
(stage_state.pipeline_create_info->flags &
VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT) == 0) {
const auto *required_subgroup_size_features =
vku::FindStructInPNextChain<VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT>(stage_state.GetPNext());
if (!required_subgroup_size_features) {
if (!vku::FindStructInPNextChain<VkPipelineShaderStageRequiredSubgroupSizeCreateInfo>(stage_state.GetPNext())) {
if (SafeModulo(local_size_x, phys_dev_props_core11.subgroupSize) != 0) {
skip |=
LogError("VUID-VkPipelineShaderStageCreateInfo-flags-02759", module_state.handle(), loc.dot(Field::flags),
Expand Down
5 changes: 2 additions & 3 deletions layers/core_checks/core_validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -2084,9 +2084,8 @@ class CoreChecks : public ValidationStateTracker {
const ErrorObject& error_obj) const override;
bool PreCallValidateGetSemaphoreCounterValue(VkDevice device, VkSemaphore sempahore, uint64_t* pValue,
const ErrorObject& error_obj) const override;
bool ValidateRequiredSubgroupSize(const spirv::Module& module_state, const ShaderStageState& stage_state,
const VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT& required_subgroup_size,
uint64_t invocations, uint32_t local_size_x, uint32_t local_size_y, uint32_t local_size_z,
bool ValidateRequiredSubgroupSize(const spirv::Module& module_state, const ShaderStageState& stage_state, uint64_t invocations,
uint32_t local_size_x, uint32_t local_size_y, uint32_t local_size_z,
const Location& loc) const;
bool ValidateComputeWorkGroupSizes(const spirv::Module& module_state, const spirv::EntryPoint& entrypoint,
const ShaderStageState& stage_state, uint32_t local_size_x, uint32_t local_size_y,
Expand Down
4 changes: 2 additions & 2 deletions layers/stateless/sl_pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,11 @@ bool StatelessValidation::ValidatePipelineShaderStageCreateInfoCommon(const VkPi
skip |= ValidateString(loc.dot(Field::pName), "VUID-VkPipelineShaderStageCreateInfo-pName-parameter", create_info.pName);
}

if (vku::FindStructInPNextChain<VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT>(create_info.pNext)) {
if (vku::FindStructInPNextChain<VkPipelineShaderStageRequiredSubgroupSizeCreateInfo>(create_info.pNext)) {
if ((create_info.flags & VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT) != 0) {
skip |= LogError("VUID-VkPipelineShaderStageCreateInfo-pNext-02754", device, loc.dot(Field::flags),
"(%s) includes VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT while "
"VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT is included in the pNext chain.",
"VkPipelineShaderStageRequiredSubgroupSizeCreateInfo is included in the pNext chain.",
string_VkPipelineShaderStageCreateFlags(create_info.flags).c_str());
}
}
Expand Down

0 comments on commit 60b8a03

Please sign in to comment.