layers: Rewrite ViewportState checks and tests
- deal with #1685
- report correct object type
- improve? msg texts a bit
- add extension structs to pNext check
- use correct printf token where possible
- make tests to match changes + improve coverage (nullptr +
multiViewport)
- remove viewport state (and other stuff) from tests that do not use it
- merge some tests together that are too related
- remove unnecessary dynamic state from PSOLineWidthInvalid)
- correct invalid VkViewport in some places
- correct missing/null pViewport and pScissors in some places
- update and correct the VUID database
diff --git a/layers/parameter_validation_utils.cpp b/layers/parameter_validation_utils.cpp
index 24a6f41..e29d74f 100644
--- a/layers/parameter_validation_utils.cpp
+++ b/layers/parameter_validation_utils.cpp
@@ -1033,118 +1033,132 @@
if ((pCreateInfos[i].pRasterizationState != nullptr) &&
(pCreateInfos[i].pRasterizationState->rasterizerDiscardEnable == VK_FALSE)) {
if (pCreateInfos[i].pViewportState == nullptr) {
- skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
- __LINE__, VALIDATION_ERROR_096005dc, LayerName,
- "vkCreateGraphicsPipelines: if pCreateInfos[%d].pRasterizationState->rasterizerDiscardEnable "
- "is VK_FALSE, pCreateInfos[%d].pViewportState must be a pointer to a valid "
- "VkPipelineViewportStateCreateInfo structure. %s",
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
+ VK_NULL_HANDLE, __LINE__, VALIDATION_ERROR_096005dc, LayerName,
+ "vkCreateGraphicsPipelines: Rasterization is enabled (pCreateInfos[%" PRIu32
+ "].pRasterizationState->rasterizerDiscardEnable is VK_FALSE), but pCreateInfos[%" PRIu32
+ "].pViewportState (=NULL) is not a valid pointer. %s",
i, i, validation_error_map[VALIDATION_ERROR_096005dc]);
} else {
- if (pCreateInfos[i].pViewportState->scissorCount != pCreateInfos[i].pViewportState->viewportCount) {
- skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
- __LINE__, VALIDATION_ERROR_10c00988, LayerName,
- "Graphics Pipeline viewport count (%u) must match scissor count (%u). %s",
- pCreateInfos[i].pViewportState->viewportCount, pCreateInfos[i].pViewportState->scissorCount,
- validation_error_map[VALIDATION_ERROR_10c00988]);
+ const auto &viewport_state = *pCreateInfos[i].pViewportState;
+
+ if (viewport_state.sType != VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO) {
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
+ VK_NULL_HANDLE, __LINE__, VALIDATION_ERROR_10c2b00b, LayerName,
+ "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
+ "].pViewportState->sType is not VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO. %s",
+ i, validation_error_map[VALIDATION_ERROR_10c2b00b]);
}
+ const VkStructureType allowed_structs_VkPipelineViewportStateCreateInfo[] = {
+ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV,
+ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV};
skip |= validate_struct_pnext(
report_data, "vkCreateGraphicsPipelines",
- ParameterName("pCreateInfos[%i].pViewportState->pNext", ParameterName::IndexVector{i}), NULL,
- pCreateInfos[i].pViewportState->pNext, 0, NULL, GeneratedHeaderVersion, VALIDATION_ERROR_10c1c40d);
+ ParameterName("pCreateInfos[%i].pViewportState->pNext", ParameterName::IndexVector{i}),
+ "VkPipelineViewportSwizzleStateCreateInfoNV, VkPipelineViewportWScalingStateCreateInfoNV",
+ viewport_state.pNext, ARRAY_SIZE(allowed_structs_VkPipelineViewportStateCreateInfo),
+ allowed_structs_VkPipelineViewportStateCreateInfo, 65, VALIDATION_ERROR_10c1c40d);
skip |= validate_reserved_flags(
report_data, "vkCreateGraphicsPipelines",
ParameterName("pCreateInfos[%i].pViewportState->flags", ParameterName::IndexVector{i}),
- pCreateInfos[i].pViewportState->flags, VALIDATION_ERROR_10c09005);
+ viewport_state.flags, VALIDATION_ERROR_10c09005);
- if (pCreateInfos[i].pViewportState->sType != VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO) {
- skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
- __LINE__, INVALID_STRUCT_STYPE, LayerName,
- "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pViewportState->sType must be "
- "VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO",
- i);
- }
+ if (!device_data->physical_device_features.multiViewport) {
+ if (viewport_state.viewportCount != 1) {
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
+ VK_NULL_HANDLE, __LINE__, VALIDATION_ERROR_10c00980, LayerName,
+ "vkCreateGraphicsPipelines: The VkPhysicalDeviceFeatures::multiViewport feature is "
+ "disabled, but pCreateInfos[%" PRIu32 "].pViewportState->viewportCount (=%" PRIu32
+ ") is not 1. %s",
+ i, viewport_state.viewportCount, validation_error_map[VALIDATION_ERROR_10c00980]);
+ }
- if (device_data->physical_device_features.multiViewport == false) {
- if (pCreateInfos[i].pViewportState->viewportCount != 1) {
- skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
- __LINE__, VALIDATION_ERROR_10c00980, LayerName,
- "vkCreateGraphicsPipelines: The multiViewport feature is not enabled, so "
- "pCreateInfos[%d].pViewportState->viewportCount must be 1 but is %d. %s",
- i, pCreateInfos[i].pViewportState->viewportCount,
- validation_error_map[VALIDATION_ERROR_10c00980]);
+ if (viewport_state.scissorCount != 1) {
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
+ VK_NULL_HANDLE, __LINE__, VALIDATION_ERROR_10c00982, LayerName,
+ "vkCreateGraphicsPipelines: The VkPhysicalDeviceFeatures::multiViewport feature is "
+ "disabled, but pCreateInfos[%" PRIu32 "].pViewportState->scissorCount (=%" PRIu32
+ ") is not 1. %s",
+ i, viewport_state.scissorCount, validation_error_map[VALIDATION_ERROR_10c00982]);
}
- if (pCreateInfos[i].pViewportState->scissorCount != 1) {
- skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
- __LINE__, VALIDATION_ERROR_10c00982, LayerName,
- "vkCreateGraphicsPipelines: The multiViewport feature is not enabled, so "
- "pCreateInfos[%d].pViewportState->scissorCount must be 1 but is %d. %s",
- i, pCreateInfos[i].pViewportState->scissorCount,
- validation_error_map[VALIDATION_ERROR_10c00982]);
+ } else { // multiViewport enabled
+ if (viewport_state.viewportCount == 0) {
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
+ VK_NULL_HANDLE, __LINE__, VALIDATION_ERROR_10c30a1b, LayerName,
+ "vkCreateGraphicsPipelines: The pCreateInfos[%" PRIu32
+ "].pViewportState->viewportCount is 0. %s",
+ i, validation_error_map[VALIDATION_ERROR_10c30a1b]);
+ } else if (viewport_state.viewportCount > device_data->device_limits.maxViewports) {
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
+ VK_NULL_HANDLE, __LINE__, VALIDATION_ERROR_10c00984, LayerName,
+ "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
+ "].pViewportState->viewportCount (=%" PRIu32
+ ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 "). %s",
+ i, viewport_state.viewportCount, device_data->device_limits.maxViewports,
+ validation_error_map[VALIDATION_ERROR_10c00984]);
}
- } else {
- if ((pCreateInfos[i].pViewportState->viewportCount < 1) ||
- (pCreateInfos[i].pViewportState->viewportCount > device_data->device_limits.maxViewports)) {
- skip |=
- log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
- __LINE__, VALIDATION_ERROR_10c00984, LayerName,
- "vkCreateGraphicsPipelines: multiViewport feature is enabled; "
- "pCreateInfos[%d].pViewportState->viewportCount is %d but must be between 1 and "
- "maxViewports (%d), inclusive. %s",
- i, pCreateInfos[i].pViewportState->viewportCount, device_data->device_limits.maxViewports,
- validation_error_map[VALIDATION_ERROR_10c00984]);
- }
- if ((pCreateInfos[i].pViewportState->scissorCount < 1) ||
- (pCreateInfos[i].pViewportState->scissorCount > device_data->device_limits.maxViewports)) {
- skip |=
- log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
- __LINE__, VALIDATION_ERROR_10c00986, LayerName,
- "vkCreateGraphicsPipelines: multiViewport feature is enabled; "
- "pCreateInfos[%d].pViewportState->scissorCount is %d but must be between 1 and "
- "maxViewports (%d), inclusive. %s",
- i, pCreateInfos[i].pViewportState->scissorCount, device_data->device_limits.maxViewports,
- validation_error_map[VALIDATION_ERROR_10c00986]);
+
+ if (viewport_state.scissorCount == 0) {
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
+ VK_NULL_HANDLE, __LINE__, VALIDATION_ERROR_10c2b61b, LayerName,
+ "vkCreateGraphicsPipelines: The pCreateInfos[%" PRIu32
+ "].pViewportState->scissorCount is 0. %s",
+ i, validation_error_map[VALIDATION_ERROR_10c2b61b]);
+ } else if (viewport_state.scissorCount > device_data->device_limits.maxViewports) {
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
+ VK_NULL_HANDLE, __LINE__, VALIDATION_ERROR_10c00986, LayerName,
+ "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
+ "].pViewportState->scissorCount (=%" PRIu32
+ ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 "). %s",
+ i, viewport_state.scissorCount, device_data->device_limits.maxViewports,
+ validation_error_map[VALIDATION_ERROR_10c00986]);
}
}
+ if (viewport_state.scissorCount != viewport_state.viewportCount) {
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
+ VK_NULL_HANDLE, __LINE__, VALIDATION_ERROR_10c00988, LayerName,
+ "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
+ "].pViewportState->scissorCount (=%" PRIu32 ") is not identical to pCreateInfos[%" PRIu32
+ "].pViewportState->viewportCount (=%" PRIu32 "). %s",
+ i, viewport_state.scissorCount, i, viewport_state.viewportCount,
+ validation_error_map[VALIDATION_ERROR_10c00988]);
+ }
+
+ bool has_dynamic_viewport = false;
+ bool has_dynamic_scissor = false;
if (pCreateInfos[i].pDynamicState != nullptr) {
- bool has_dynamic_viewport = false;
- bool has_dynamic_scissor = false;
-
- for (uint32_t state_index = 0; state_index < pCreateInfos[i].pDynamicState->dynamicStateCount;
- ++state_index) {
- if (pCreateInfos[i].pDynamicState->pDynamicStates[state_index] == VK_DYNAMIC_STATE_VIEWPORT) {
- has_dynamic_viewport = true;
- } else if (pCreateInfos[i].pDynamicState->pDynamicStates[state_index] == VK_DYNAMIC_STATE_SCISSOR) {
- has_dynamic_scissor = true;
- }
- }
-
- // If no element of the pDynamicStates member of pDynamicState is VK_DYNAMIC_STATE_VIEWPORT, the pViewports
- // member of pViewportState must be a pointer to an array of pViewportState->viewportCount VkViewport
- // structures
- if (!has_dynamic_viewport && (pCreateInfos[i].pViewportState->pViewports == nullptr)) {
- skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
- __LINE__, VALIDATION_ERROR_096005d6, LayerName,
- "vkCreateGraphicsPipelines: if pCreateInfos[%d].pDynamicState->pDynamicStates does not "
- "contain VK_DYNAMIC_STATE_VIEWPORT, pCreateInfos[%d].pViewportState->pViewports must "
- "not be NULL. %s",
- i, i, validation_error_map[VALIDATION_ERROR_096005d6]);
- }
-
- // If no element of the pDynamicStates member of pDynamicState is VK_DYNAMIC_STATE_SCISSOR, the pScissors
- // member
- // of pViewportState must be a pointer to an array of pViewportState->scissorCount VkRect2D structures
- if (!has_dynamic_scissor && (pCreateInfos[i].pViewportState->pScissors == nullptr)) {
- skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
- __LINE__, VALIDATION_ERROR_096005d8, LayerName,
- "vkCreateGraphicsPipelines: if pCreateInfos[%d].pDynamicState->pDynamicStates does not "
- "contain VK_DYNAMIC_STATE_SCISSOR, pCreateInfos[%d].pViewportState->pScissors must not "
- "be NULL. %s",
- i, i, validation_error_map[VALIDATION_ERROR_096005d8]);
+ const auto &dynamic_state_info = *pCreateInfos[i].pDynamicState;
+ for (uint32_t state_index = 0; state_index < dynamic_state_info.dynamicStateCount; ++state_index) {
+ const auto &dynamic_state = dynamic_state_info.pDynamicStates[state_index];
+ if (dynamic_state == VK_DYNAMIC_STATE_VIEWPORT) has_dynamic_viewport = true;
+ if (dynamic_state == VK_DYNAMIC_STATE_SCISSOR) has_dynamic_scissor = true;
}
}
+
+ if (!has_dynamic_viewport && viewport_state.viewportCount > 0 && viewport_state.pViewports == nullptr) {
+ skip |= log_msg(
+ report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, VK_NULL_HANDLE,
+ __LINE__, VALIDATION_ERROR_096005d6, LayerName,
+ "vkCreateGraphicsPipelines: The viewport state is static (pCreateInfos[%" PRIu32
+ "].pDynamicState->pDynamicStates does not contain VK_DYNAMIC_STATE_VIEWPORT), but pCreateInfos[%" PRIu32
+ "].pViewportState->pViewports (=NULL) is a invalid pointer. %s",
+ i, i, validation_error_map[VALIDATION_ERROR_096005d6]);
+ }
+
+ if (!has_dynamic_scissor && viewport_state.scissorCount > 0 && viewport_state.pScissors == nullptr) {
+ skip |= log_msg(
+ report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, VK_NULL_HANDLE,
+ __LINE__, VALIDATION_ERROR_096005d8, LayerName,
+ "vkCreateGraphicsPipelines: The scissor state is static (pCreateInfos[%" PRIu32
+ "].pDynamicState->pDynamicStates does not contain VK_DYNAMIC_STATE_SCISSOR), but pCreateInfos[%" PRIu32
+ "].pViewportState->pScissors (=NULL) is a invalid pointer. %s",
+ i, i, validation_error_map[VALIDATION_ERROR_096005d8]);
+ }
+
+ // TODO: validate the VkViewports in pViewports here
}
if (pCreateInfos[i].pMultisampleState == nullptr) {