layers: More noautovalidity processing for structs

Apply 'noautovalidity' code generation logic to struct members.
Previously, struct pointers tagged as noautovalidity were ignored by
the code generator, but the members of non-NULL struct pointers
were still processed.  Now both the struct pointer and the struct
members are ignored when the struct pointer has the 'noautovalidity'
attribute.

Change-Id: I14bc231210f2440fb8bb3df8c73ef165100f0daa
diff --git a/layers/parameter_validation.cpp b/layers/parameter_validation.cpp
index e0e29c6..e584d46 100644
--- a/layers/parameter_validation.cpp
+++ b/layers/parameter_validation.cpp
@@ -2780,12 +2780,22 @@
                                              i, i);
                     }
                 }
-            } else if (pCreateInfos[i].pTessellationState->sType != VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO) {
-                skip_call |= 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].pTessellationState->sType must be "
-                                     "VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO",
-                                     i);
+            } else {
+                skip_call |=
+                    validate_struct_pnext(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pTessellationState->pNext",
+                                          NULL, pCreateInfos[i].pTessellationState->pNext, 0, NULL);
+
+                skip_call |=
+                    validate_reserved_flags(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pTessellationState->flags",
+                                            pCreateInfos[i].pTessellationState->flags);
+
+                if (pCreateInfos[i].pTessellationState->sType != VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO) {
+                    skip_call |= 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].pTessellationState->sType must be "
+                                         "VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO",
+                                         i);
+                }
             }
 
             if (pCreateInfos[i].pViewportState == nullptr) {
@@ -2801,6 +2811,14 @@
                         i, i);
                 }
             } else {
+                skip_call |=
+                    validate_struct_pnext(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pViewportState->pNext", NULL,
+                                          pCreateInfos[i].pViewportState->pNext, 0, NULL);
+
+                skip_call |=
+                    validate_reserved_flags(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pViewportState->flags",
+                                            pCreateInfos[i].pViewportState->flags);
+
                 if (pCreateInfos[i].pViewportState->sType != VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO) {
                     skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                          __LINE__, INVALID_STRUCT_STYPE, LayerName,
@@ -2879,26 +2897,181 @@
                                                                "VK_FALSE, pCreateInfos[%d].pMultisampleState must not be NULL",
                                 i, i);
                 }
-            } else if (pCreateInfos[i].pMultisampleState->sType != VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO) {
-                skip_call |= 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].pMultisampleState->sType must be "
-                                     "VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO",
-                                     i);
+            } else {
+                skip_call |=
+                    validate_struct_pnext(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pMultisampleState->pNext",
+                                          NULL, pCreateInfos[i].pMultisampleState->pNext, 0, NULL);
+
+                skip_call |=
+                    validate_reserved_flags(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pMultisampleState->flags",
+                                            pCreateInfos[i].pMultisampleState->flags);
+
+                skip_call |= validate_bool32(report_data, "vkCreateGraphicsPipelines",
+                                             "pCreateInfos[i].pMultisampleState->sampleShadingEnable",
+                                             pCreateInfos[i].pMultisampleState->sampleShadingEnable);
+
+                skip_call |= validate_array(
+                    report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pMultisampleState->rasterizationSamples",
+                    "pCreateInfos[i].pMultisampleState->pSampleMask", pCreateInfos[i].pMultisampleState->rasterizationSamples,
+                    pCreateInfos[i].pMultisampleState->pSampleMask, true, false);
+
+                skip_call |= validate_bool32(report_data, "vkCreateGraphicsPipelines",
+                                             "pCreateInfos[i].pMultisampleState->alphaToCoverageEnable",
+                                             pCreateInfos[i].pMultisampleState->alphaToCoverageEnable);
+
+                skip_call |=
+                    validate_bool32(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pMultisampleState->alphaToOneEnable",
+                                    pCreateInfos[i].pMultisampleState->alphaToOneEnable);
+
+                if (pCreateInfos[i].pMultisampleState->sType != VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO) {
+                    skip_call |= 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].pMultisampleState->sType must be "
+                                         "VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO",
+                                         i);
+                }
             }
 
             // TODO: Conditional NULL check based on rasterizerDiscardEnable and subpass
-            if ((pCreateInfos[i].pDepthStencilState != nullptr) &&
-                (pCreateInfos[i].pDepthStencilState->sType != VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO)) {
-                skip_call |= 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].pDepthStencilState->sType must be "
-                                     "VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO",
-                                     i);
+            if (pCreateInfos[i].pDepthStencilState != nullptr) {
+                skip_call |=
+                    validate_struct_pnext(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->pNext",
+                                          NULL, pCreateInfos[i].pDepthStencilState->pNext, 0, NULL);
+
+                skip_call |=
+                    validate_reserved_flags(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->flags",
+                                            pCreateInfos[i].pDepthStencilState->flags);
+
+                skip_call |=
+                    validate_bool32(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->depthTestEnable",
+                                    pCreateInfos[i].pDepthStencilState->depthTestEnable);
+
+                skip_call |= validate_bool32(report_data, "vkCreateGraphicsPipelines",
+                                             "pCreateInfos[i].pDepthStencilState->depthWriteEnable",
+                                             pCreateInfos[i].pDepthStencilState->depthWriteEnable);
+
+                skip_call |= validate_ranged_enum(
+                    report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->depthCompareOp", "VkCompareOp",
+                    VK_COMPARE_OP_BEGIN_RANGE, VK_COMPARE_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->depthCompareOp);
+
+                skip_call |= validate_bool32(report_data, "vkCreateGraphicsPipelines",
+                                             "pCreateInfos[i].pDepthStencilState->depthBoundsTestEnable",
+                                             pCreateInfos[i].pDepthStencilState->depthBoundsTestEnable);
+
+                skip_call |= validate_bool32(report_data, "vkCreateGraphicsPipelines",
+                                             "pCreateInfos[i].pDepthStencilState->stencilTestEnable",
+                                             pCreateInfos[i].pDepthStencilState->stencilTestEnable);
+
+                skip_call |= validate_ranged_enum(
+                    report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->front.failOp", "VkStencilOp",
+                    VK_STENCIL_OP_BEGIN_RANGE, VK_STENCIL_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->front.failOp);
+
+                skip_call |= validate_ranged_enum(
+                    report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->front.passOp", "VkStencilOp",
+                    VK_STENCIL_OP_BEGIN_RANGE, VK_STENCIL_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->front.passOp);
+
+                skip_call |= validate_ranged_enum(report_data, "vkCreateGraphicsPipelines",
+                                                  "pCreateInfos[i].pDepthStencilState->front.depthFailOp", "VkStencilOp",
+                                                  VK_STENCIL_OP_BEGIN_RANGE, VK_STENCIL_OP_END_RANGE,
+                                                  pCreateInfos[i].pDepthStencilState->front.depthFailOp);
+
+                skip_call |= validate_ranged_enum(
+                    report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->front.compareOp", "VkCompareOp",
+                    VK_COMPARE_OP_BEGIN_RANGE, VK_COMPARE_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->front.compareOp);
+
+                skip_call |= validate_ranged_enum(
+                    report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->back.failOp", "VkStencilOp",
+                    VK_STENCIL_OP_BEGIN_RANGE, VK_STENCIL_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->back.failOp);
+
+                skip_call |= validate_ranged_enum(
+                    report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->back.passOp", "VkStencilOp",
+                    VK_STENCIL_OP_BEGIN_RANGE, VK_STENCIL_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->back.passOp);
+
+                skip_call |= validate_ranged_enum(
+                    report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->back.depthFailOp", "VkStencilOp",
+                    VK_STENCIL_OP_BEGIN_RANGE, VK_STENCIL_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->back.depthFailOp);
+
+                skip_call |= validate_ranged_enum(
+                    report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->back.compareOp", "VkCompareOp",
+                    VK_COMPARE_OP_BEGIN_RANGE, VK_COMPARE_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->back.compareOp);
+
+                if (pCreateInfos[i].pDepthStencilState->sType != VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO) {
+                    skip_call |= 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].pDepthStencilState->sType must be "
+                                         "VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO",
+                                         i);
+                }
             }
 
             // TODO: Conditional NULL check based on rasterizerDiscardEnable and subpass
             if (pCreateInfos[i].pColorBlendState != nullptr) {
+                skip_call |=
+                    validate_struct_pnext(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pColorBlendState->pNext", NULL,
+                                          pCreateInfos[i].pColorBlendState->pNext, 0, NULL);
+
+                skip_call |=
+                    validate_reserved_flags(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pColorBlendState->flags",
+                                            pCreateInfos[i].pColorBlendState->flags);
+
+                skip_call |=
+                    validate_bool32(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pColorBlendState->logicOpEnable",
+                                    pCreateInfos[i].pColorBlendState->logicOpEnable);
+
+                skip_call |= validate_array(
+                    report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pColorBlendState->attachmentCount",
+                    "pCreateInfos[i].pColorBlendState->pAttachments", pCreateInfos[i].pColorBlendState->attachmentCount,
+                    pCreateInfos[i].pColorBlendState->pAttachments, false, true);
+
+                if (pCreateInfos[i].pColorBlendState->pAttachments != NULL) {
+                    for (uint32_t attachmentIndex = 0; attachmentIndex < pCreateInfos[i].pColorBlendState->attachmentCount;
+                         ++attachmentIndex) {
+                        skip_call |= validate_bool32(report_data, "vkCreateGraphicsPipelines",
+                                                     "pCreateInfos[i].pColorBlendState->pAttachments[i].blendEnable",
+                                                     pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].blendEnable);
+
+                        skip_call |= validate_ranged_enum(
+                            report_data, "vkCreateGraphicsPipelines",
+                            "pCreateInfos[i].pColorBlendState->pAttachments[i].srcColorBlendFactor", "VkBlendFactor",
+                            VK_BLEND_FACTOR_BEGIN_RANGE, VK_BLEND_FACTOR_END_RANGE,
+                            pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].srcColorBlendFactor);
+
+                        skip_call |= validate_ranged_enum(
+                            report_data, "vkCreateGraphicsPipelines",
+                            "pCreateInfos[i].pColorBlendState->pAttachments[i].dstColorBlendFactor", "VkBlendFactor",
+                            VK_BLEND_FACTOR_BEGIN_RANGE, VK_BLEND_FACTOR_END_RANGE,
+                            pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].dstColorBlendFactor);
+
+                        skip_call |= validate_ranged_enum(
+                            report_data, "vkCreateGraphicsPipelines",
+                            "pCreateInfos[i].pColorBlendState->pAttachments[i].colorBlendOp", "VkBlendOp", VK_BLEND_OP_BEGIN_RANGE,
+                            VK_BLEND_OP_END_RANGE, pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].colorBlendOp);
+
+                        skip_call |= validate_ranged_enum(
+                            report_data, "vkCreateGraphicsPipelines",
+                            "pCreateInfos[i].pColorBlendState->pAttachments[i].srcAlphaBlendFactor", "VkBlendFactor",
+                            VK_BLEND_FACTOR_BEGIN_RANGE, VK_BLEND_FACTOR_END_RANGE,
+                            pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].srcAlphaBlendFactor);
+
+                        skip_call |= validate_ranged_enum(
+                            report_data, "vkCreateGraphicsPipelines",
+                            "pCreateInfos[i].pColorBlendState->pAttachments[i].dstAlphaBlendFactor", "VkBlendFactor",
+                            VK_BLEND_FACTOR_BEGIN_RANGE, VK_BLEND_FACTOR_END_RANGE,
+                            pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].dstAlphaBlendFactor);
+
+                        skip_call |= validate_ranged_enum(
+                            report_data, "vkCreateGraphicsPipelines",
+                            "pCreateInfos[i].pColorBlendState->pAttachments[i].alphaBlendOp", "VkBlendOp", VK_BLEND_OP_BEGIN_RANGE,
+                            VK_BLEND_OP_END_RANGE, pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].alphaBlendOp);
+
+                        skip_call |=
+                            validate_flags(report_data, "vkCreateGraphicsPipelines",
+                                           "pCreateInfos[i].pColorBlendState->pAttachments[i].colorWriteMask",
+                                           "VkColorComponentFlagBits", AllVkColorComponentFlagBits,
+                                           pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].colorWriteMask, false);
+                    }
+                }
+
                 if (pCreateInfos[i].pColorBlendState->sType != VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO) {
                     skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                          __LINE__, INVALID_STRUCT_STYPE, LayerName,
@@ -3298,6 +3471,12 @@
                                          "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, "
                                          "pDescriptorWrites[%d].pBufferInfo must not be NULL",
                                          i, i);
+                } else {
+                    for (uint32_t descriptorIndex = 0; descriptorIndex < pDescriptorWrites[i].descriptorCount; ++descriptorIndex) {
+                        skip_call |= validate_required_handle(report_data, "vkUpdateDescriptorSets",
+                                                              "pDescriptorWrites[i].pBufferInfo[i].buffer",
+                                                              pDescriptorWrites[i].pBufferInfo[descriptorIndex].buffer);
+                    }
                 }
             } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) ||
                        (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
@@ -3515,6 +3694,12 @@
                                       VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, false);
 
     if (pBeginInfo->pInheritanceInfo != NULL) {
+        skip_call |= validate_struct_pnext(report_data, "vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo->pNext", NULL,
+                                           pBeginInfo->pInheritanceInfo->pNext, 0, NULL);
+
+        skip_call |= validate_bool32(report_data, "vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo->occlusionQueryEnable",
+                                     pBeginInfo->pInheritanceInfo->occlusionQueryEnable);
+
         // TODO: This only needs to be validated when the inherited queries feature is enabled
         // skip_call |= validate_flags(report_data, "vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo->queryFlags",
         // "VkQueryControlFlagBits", AllVkQueryControlFlagBits, pBeginInfo->pInheritanceInfo->queryFlags, false);