layers: Validate maxComputeWorkGroupSize
Validate maxComputeWorkGroupSize in create compute pipelines.
Change-Id: Ie7e574d2e3263e197ad9cf11ddbf5174af3de370
diff --git a/layers/shader_validation.cpp b/layers/shader_validation.cpp
index 8d5830c..45f743f 100644
--- a/layers/shader_validation.cpp
+++ b/layers/shader_validation.cpp
@@ -2616,7 +2616,9 @@
}
}
}
-
+ if (pStage->stage == VK_SHADER_STAGE_COMPUTE_BIT) {
+ skip |= ValidateComputeWorkGroupSizes(module);
+ }
return skip;
}
@@ -2913,3 +2915,59 @@
: new shader_module());
shaderModuleMap[*pShaderModule] = std::move(new_shader_module);
}
+
+bool CoreChecks::ValidateComputeWorkGroupSizes(const shader_module *shader) {
+ bool skip = false;
+ uint32_t local_size_x = 0;
+ uint32_t local_size_y = 0;
+ uint32_t local_size_z = 0;
+ if (FindLocalSize(shader, local_size_x, local_size_y, local_size_z)) {
+ if (local_size_x > phys_dev_props.limits.maxComputeWorkGroupSize[0]) {
+ skip |=
+ log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT,
+ HandleToUint64(shader->vk_shader_module), "UNASSIGNED-features-limits-maxComputeWorkGroupSize",
+ "ShaderMdoule %s local_size_x (%" PRIu32 ") exceeds device limit maxComputeWorkGroupSize[0] (%" PRIu32 ").",
+ report_data->FormatHandle(shader->vk_shader_module).c_str(), local_size_x,
+ phys_dev_props.limits.maxComputeWorkGroupSize[0]);
+ }
+ if (local_size_y > phys_dev_props.limits.maxComputeWorkGroupSize[1]) {
+ skip |=
+ log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT,
+ HandleToUint64(shader->vk_shader_module), "UNASSIGNED-features-limits-maxComputeWorkGroupSize",
+ "ShaderMdoule %s local_size_y (%" PRIu32 ") exceeds device limit maxComputeWorkGroupSize[1] (%" PRIu32 ").",
+ report_data->FormatHandle(shader->vk_shader_module).c_str(), local_size_x,
+ phys_dev_props.limits.maxComputeWorkGroupSize[1]);
+ }
+ if (local_size_z > phys_dev_props.limits.maxComputeWorkGroupSize[2]) {
+ skip |=
+ log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT,
+ HandleToUint64(shader->vk_shader_module), "UNASSIGNED-features-limits-maxComputeWorkGroupSize",
+ "ShaderMdoule %s local_size_z (%" PRIu32 ") exceeds device limit maxComputeWorkGroupSize[2] (%" PRIu32 ").",
+ report_data->FormatHandle(shader->vk_shader_module).c_str(), local_size_x,
+ phys_dev_props.limits.maxComputeWorkGroupSize[2]);
+ }
+
+ uint32_t limit = phys_dev_props.limits.maxComputeWorkGroupInvocations;
+ uint64_t invocations = local_size_x * local_size_y;
+ // Prevent overflow.
+ bool fail = false;
+ if (invocations > UINT32_MAX || invocations > limit) {
+ fail = true;
+ }
+ if (!fail) {
+ invocations *= local_size_z;
+ if (invocations > UINT32_MAX || invocations > limit) {
+ fail = true;
+ }
+ }
+ if (fail) {
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT,
+ HandleToUint64(shader->vk_shader_module), "UNASSIGNED-features-limits-maxComputeWorkGroupInvocations",
+ "ShaderMdoule %s local_size (%" PRIu32 ", %" PRIu32 ", %" PRIu32
+ ") exceeds device limit maxComputeWorkGroupInvocations (%" PRIu32 ").",
+ report_data->FormatHandle(shader->vk_shader_module).c_str(), local_size_x, local_size_y, local_size_z,
+ limit);
+ }
+ }
+ return skip;
+}