diff --git a/layers/core_checks/cc_cmd_buffer.cpp b/layers/core_checks/cc_cmd_buffer.cpp index aa5d3f3d4ef..3c8ad0e834f 100644 --- a/layers/core_checks/cc_cmd_buffer.cpp +++ b/layers/core_checks/cc_cmd_buffer.cpp @@ -840,14 +840,14 @@ bool CoreChecks::PreCallValidateCmdExecuteCommands(VkCommandBuffer commandBuffer } } else { if (cb_state.activeSubpassContents != VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS && - cb_state.activeSubpassContents != VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_EXT) { + cb_state.activeSubpassContents != VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_KHR) { const LogObjectList objlist(commandBuffer, cb_state.activeRenderPass->Handle()); - skip |= LogError("VUID-vkCmdExecuteCommands-None-09681", objlist, error_obj.location, - "contents must be set to VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS or " - "VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_EXT" - "when calling vkCmdExecuteCommands() within a non-first subpass (currently subpass %" PRIu32 - ").", - cb_state.GetActiveSubpass()); + skip |= + LogError("VUID-vkCmdExecuteCommands-None-09681", objlist, error_obj.location, + "contents must be set to VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS or " + "VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_KHR" + "when calling vkCmdExecuteCommands() within a non-first subpass (currently subpass %" PRIu32 ").", + cb_state.GetActiveSubpass()); } } } diff --git a/layers/core_checks/cc_descriptor.cpp b/layers/core_checks/cc_descriptor.cpp index f19d1d81a3e..07d7a9fe2f0 100644 --- a/layers/core_checks/cc_descriptor.cpp +++ b/layers/core_checks/cc_descriptor.cpp @@ -4002,16 +4002,6 @@ bool CoreChecks::PreCallValidateCreatePipelineLayout(VkDevice device, const VkPi sum_all_stages[VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER], phys_dev_props.limits.maxDescriptorSetUniformBuffers); } - // Dynamic uniform buffers - if (sum_all_stages[VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC] > phys_dev_props.limits.maxDescriptorSetUniformBuffersDynamic) { - skip |= LogError("VUID-VkPipelineLayoutCreateInfo-descriptorType-03030", device, error_obj.location, - "sum of dynamic uniform buffer bindings among all stages (%" PRIu32 - ") exceeds device " - "maxDescriptorSetUniformBuffersDynamic limit (%" PRIu32 ").", - sum_all_stages[VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC], - phys_dev_props.limits.maxDescriptorSetUniformBuffersDynamic); - } - // Storage buffers if (sum_all_stages[VK_DESCRIPTOR_TYPE_STORAGE_BUFFER] > phys_dev_props.limits.maxDescriptorSetStorageBuffers) { skip |= LogError("VUID-VkPipelineLayoutCreateInfo-descriptorType-03031", device, error_obj.location, @@ -4021,14 +4011,59 @@ bool CoreChecks::PreCallValidateCreatePipelineLayout(VkDevice device, const VkPi sum_all_stages[VK_DESCRIPTOR_TYPE_STORAGE_BUFFER], phys_dev_props.limits.maxDescriptorSetStorageBuffers); } - // Dynamic storage buffers - if (sum_all_stages[VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC] > phys_dev_props.limits.maxDescriptorSetStorageBuffersDynamic) { - skip |= LogError("VUID-VkPipelineLayoutCreateInfo-descriptorType-03032", device, error_obj.location, - "sum of dynamic storage buffer bindings among all stages (%" PRIu32 - ") exceeds device " - "maxDescriptorSetStorageBuffersDynamic limit (%" PRIu32 ").", - sum_all_stages[VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC], - phys_dev_props.limits.maxDescriptorSetStorageBuffersDynamic); + const uint32_t sum_all_uniform_buffer_dynamic = sum_all_stages[VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC]; + const uint32_t sum_all_storage_buffer_dynamic = sum_all_stages[VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC]; + if (enabled_features.maintenance7) { + // Dynamic uniform buffers + if (sum_all_uniform_buffer_dynamic > phys_dev_ext_props.maintenance7_props.maxDescriptorSetTotalUniformBuffersDynamic) { + skip |= LogError("VUID-VkPipelineLayoutCreateInfo-maintenance7-10003", device, error_obj.location, + "sum of dynamic uniform buffer bindings among all stages (%" PRIu32 + ") exceeds device " + "maxDescriptorSetTotalUniformBuffersDynamic limit (%" PRIu32 ").", + sum_all_uniform_buffer_dynamic, + phys_dev_ext_props.maintenance7_props.maxDescriptorSetTotalUniformBuffersDynamic); + } + + // Dynamic storage buffers + if (sum_all_storage_buffer_dynamic > phys_dev_ext_props.maintenance7_props.maxDescriptorSetTotalStorageBuffersDynamic) { + skip |= LogError("VUID-VkPipelineLayoutCreateInfo-maintenance7-10004", device, error_obj.location, + "sum of dynamic storage buffer bindings among all stages (%" PRIu32 + ") exceeds device " + "maxDescriptorSetTotalStorageBuffersDynamic limit (%" PRIu32 ").", + sum_all_storage_buffer_dynamic, + phys_dev_ext_props.maintenance7_props.maxDescriptorSetTotalStorageBuffersDynamic); + } + + // prevent overflow + const uint64_t total_sum = + static_cast(sum_all_uniform_buffer_dynamic) + static_cast(sum_all_storage_buffer_dynamic); + if (total_sum > phys_dev_ext_props.maintenance7_props.maxDescriptorSetTotalBuffersDynamic) { + skip |= LogError("VUID-VkPipelineLayoutCreateInfo-None-10005", device, error_obj.location, + "sum of both dynamic storage buffer bindings (%" PRIu32 + ") and dynamic uniform buffer bindings (%" PRIu32 ") among all stages (%" PRIu64 + ") exceeds device " + "maxDescriptorSetTotalBuffersDynamic limit (%" PRIu32 ").", + sum_all_uniform_buffer_dynamic, sum_all_storage_buffer_dynamic, total_sum, + phys_dev_ext_props.maintenance7_props.maxDescriptorSetTotalBuffersDynamic); + } + } else { + // Dynamic uniform buffers + if (sum_all_uniform_buffer_dynamic > phys_dev_props.limits.maxDescriptorSetUniformBuffersDynamic) { + skip |= LogError("VUID-VkPipelineLayoutCreateInfo-descriptorType-03030", device, error_obj.location, + "sum of dynamic uniform buffer bindings among all stages (%" PRIu32 + ") exceeds device " + "maxDescriptorSetUniformBuffersDynamic limit (%" PRIu32 ").", + sum_all_uniform_buffer_dynamic, phys_dev_props.limits.maxDescriptorSetUniformBuffersDynamic); + } + + // Dynamic storage buffers + if (sum_all_storage_buffer_dynamic > phys_dev_props.limits.maxDescriptorSetStorageBuffersDynamic) { + skip |= LogError("VUID-VkPipelineLayoutCreateInfo-descriptorType-03032", device, error_obj.location, + "sum of dynamic storage buffer bindings among all stages (%" PRIu32 + ") exceeds device " + "maxDescriptorSetStorageBuffersDynamic limit (%" PRIu32 ").", + sum_all_storage_buffer_dynamic, phys_dev_props.limits.maxDescriptorSetStorageBuffersDynamic); + } } // Sampled images @@ -4223,17 +4258,6 @@ bool CoreChecks::PreCallValidateCreatePipelineLayout(VkDevice device, const VkPi phys_dev_props_core12.maxDescriptorSetUpdateAfterBindUniformBuffers); } - // Dynamic uniform buffers - if (sum_all_stages_update_after_bind[VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC] > - phys_dev_props_core12.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic) { - skip |= LogError("VUID-VkPipelineLayoutCreateInfo-pSetLayouts-03038", device, error_obj.location, - "sum of dynamic uniform buffer bindings among all stages (%" PRIu32 - ") exceeds device " - "maxDescriptorSetUpdateAfterBindUniformBuffersDynamic limit (%" PRIu32 ").", - sum_all_stages_update_after_bind[VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC], - phys_dev_props_core12.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic); - } - // Storage buffers if (sum_all_stages_update_after_bind[VK_DESCRIPTOR_TYPE_STORAGE_BUFFER] > phys_dev_props_core12.maxDescriptorSetUpdateAfterBindStorageBuffers) { @@ -4245,15 +4269,67 @@ bool CoreChecks::PreCallValidateCreatePipelineLayout(VkDevice device, const VkPi phys_dev_props_core12.maxDescriptorSetUpdateAfterBindStorageBuffers); } - // Dynamic storage buffers - if (sum_all_stages_update_after_bind[VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC] > - phys_dev_props_core12.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic) { - skip |= LogError("VUID-VkPipelineLayoutCreateInfo-pSetLayouts-03040", device, error_obj.location, - "sum of dynamic storage buffer bindings among all stages (%" PRIu32 - ") exceeds device " - "maxDescriptorSetUpdateAfterBindStorageBuffersDynamic limit (%" PRIu32 ").", - sum_all_stages_update_after_bind[VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC], - phys_dev_props_core12.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic); + const uint32_t sum_all_after_bind_uniform_buffer_dynamic = + sum_all_stages_update_after_bind[VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC]; + const uint32_t sum_all_after_bind_storage_buffer_dynamic = + sum_all_stages_update_after_bind[VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC]; + if (enabled_features.maintenance7) { + // Dynamic uniform buffers + if (sum_all_after_bind_uniform_buffer_dynamic > + phys_dev_ext_props.maintenance7_props.maxDescriptorSetUpdateAfterBindTotalUniformBuffersDynamic) { + skip |= LogError("VUID-VkPipelineLayoutCreateInfo-maintenance7-10007", device, error_obj.location, + "sum of dynamic uniform buffer bindings among all stages (%" PRIu32 + ") exceeds device " + "maxDescriptorSetUpdateAfterBindTotalUniformBuffersDynamic limit (%" PRIu32 ").", + sum_all_after_bind_uniform_buffer_dynamic, + phys_dev_ext_props.maintenance7_props.maxDescriptorSetUpdateAfterBindTotalUniformBuffersDynamic); + } + + // Dynamic storage buffers + if (sum_all_after_bind_storage_buffer_dynamic > + phys_dev_ext_props.maintenance7_props.maxDescriptorSetUpdateAfterBindTotalStorageBuffersDynamic) { + skip |= LogError("VUID-VkPipelineLayoutCreateInfo-maintenance7-10008", device, error_obj.location, + "sum of dynamic storage buffer bindings among all stages (%" PRIu32 + ") exceeds device " + "maxDescriptorSetUpdateAfterBindTotalStorageBuffersDynamic limit (%" PRIu32 ").", + sum_all_after_bind_storage_buffer_dynamic, + phys_dev_ext_props.maintenance7_props.maxDescriptorSetUpdateAfterBindTotalStorageBuffersDynamic); + } + + // prevent overflow + const uint64_t total_sum = static_cast(sum_all_after_bind_uniform_buffer_dynamic) + + static_cast(sum_all_after_bind_storage_buffer_dynamic); + if (total_sum > phys_dev_ext_props.maintenance7_props.maxDescriptorSetUpdateAfterBindTotalBuffersDynamic) { + skip |= LogError("VUID-VkPipelineLayoutCreateInfo-pSetLayouts-10006", device, error_obj.location, + "sum of both dynamic storage buffer bindings (%" PRIu32 + ") and dynamic uniform buffer bindings (%" PRIu32 ") among all stages (%" PRIu64 + ") exceeds device " + "maxDescriptorSetUpdateAfterBindTotalBuffersDynamic limit (%" PRIu32 ").", + sum_all_after_bind_uniform_buffer_dynamic, sum_all_after_bind_storage_buffer_dynamic, total_sum, + phys_dev_ext_props.maintenance7_props.maxDescriptorSetUpdateAfterBindTotalBuffersDynamic); + } + } else { + // Dynamic uniform buffers + if (sum_all_after_bind_uniform_buffer_dynamic > + phys_dev_props_core12.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic) { + skip |= LogError("VUID-VkPipelineLayoutCreateInfo-pSetLayouts-03038", device, error_obj.location, + "sum of dynamic uniform buffer bindings among all stages (%" PRIu32 + ") exceeds device " + "maxDescriptorSetUpdateAfterBindUniformBuffersDynamic limit (%" PRIu32 ").", + sum_all_after_bind_uniform_buffer_dynamic, + phys_dev_props_core12.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic); + } + + // Dynamic storage buffers + if (sum_all_after_bind_storage_buffer_dynamic > + phys_dev_props_core12.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic) { + skip |= LogError("VUID-VkPipelineLayoutCreateInfo-pSetLayouts-03040", device, error_obj.location, + "sum of dynamic storage buffer bindings among all stages (%" PRIu32 + ") exceeds device " + "maxDescriptorSetUpdateAfterBindStorageBuffersDynamic limit (%" PRIu32 ").", + sum_all_after_bind_storage_buffer_dynamic, + phys_dev_props_core12.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic); + } } // Sampled images diff --git a/layers/core_checks/cc_render_pass.cpp b/layers/core_checks/cc_render_pass.cpp index 7c207672f71..4b5c6a0ec08 100644 --- a/layers/core_checks/cc_render_pass.cpp +++ b/layers/core_checks/cc_render_pass.cpp @@ -595,16 +595,15 @@ bool CoreChecks::ValidateCmdBeginRenderPass(VkCommandBuffer commandBuffer, const } } - if (contents == VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_EXT && - !enabled_features.nestedCommandBuffer) { + if (contents == VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_KHR && !enabled_features.nestedCommandBuffer && + !enabled_features.maintenance7) { const char *vuid = error_obj.location.function == Func::vkCmdBeginRenderPass ? "VUID-vkCmdBeginRenderPass-contents-09640" : "VUID-VkSubpassBeginInfo-contents-09382"; - skip |= - LogError(vuid, commandBuffer, error_obj.location.dot(Field::contents), - " is VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_EXT, but nestedCommandBuffer was not enabled."); + skip |= LogError(vuid, commandBuffer, error_obj.location.dot(Field::contents), + "is VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_KHR, but nestedCommandBuffer nor " + "maintenance7 were not enabled."); } - return skip; } @@ -3214,6 +3213,24 @@ bool CoreChecks::ValidateBeginRenderingFragmentShadingRate(VkCommandBuffer comma string_VkComponentSwizzle(components.b), string_VkComponentSwizzle(components.a)); } + skip |= ValidateBeginRenderingFragmentShadingRateRenderArea( + commandBuffer, *view_state, *rendering_fragment_shading_rate_attachment_info, rendering_info, rendering_info_loc); + return skip; +} + +bool CoreChecks::ValidateBeginRenderingFragmentShadingRateRenderArea( + VkCommandBuffer commandBuffer, const vvl::ImageView &view_state, + const VkRenderingFragmentShadingRateAttachmentInfoKHR &fsr_attachment_info, const VkRenderingInfo &rendering_info, + const Location &rendering_info_loc) const { + bool skip = false; + + // All these VUs can be skipped if all conditions are met + if (enabled_features.maintenance7 && phys_dev_ext_props.maintenance7_props.robustFragmentShadingRateAttachmentAccess && + view_state.create_info.subresourceRange.baseMipLevel == 0) { + return skip; + } + + const LogObjectList objlist(commandBuffer, view_state.Handle()); const auto *device_group_begin_info = vku::FindStructInPNextChain(rendering_info.pNext); const bool non_zero_device_render_area = device_group_begin_info && device_group_begin_info->deviceRenderAreaCount != 0; if (!non_zero_device_render_area) { @@ -3223,32 +3240,28 @@ bool CoreChecks::ValidateBeginRenderingFragmentShadingRate(VkCommandBuffer comma const int64_t y_adjusted_extent = static_cast(rendering_info.renderArea.offset.y) + static_cast(rendering_info.renderArea.extent.height); - if (static_cast(view_state->image_state->create_info.extent.width) < - vvl::GetQuotientCeil( - x_adjusted_extent, - static_cast(rendering_fragment_shading_rate_attachment_info->shadingRateAttachmentTexelSize.width))) { + if (static_cast(view_state.image_state->create_info.extent.width) < + vvl::GetQuotientCeil(x_adjusted_extent, + static_cast(fsr_attachment_info.shadingRateAttachmentTexelSize.width))) { skip |= LogError("VUID-VkRenderingInfo-pNext-06119", objlist, rendering_info_loc.pNext(Struct::VkRenderingFragmentShadingRateAttachmentInfoKHR, Field::imageView), "width (%" PRIu32 ") must not be less than (pRenderingInfo->renderArea.offset.x (%" PRId32 ") + pRenderingInfo->renderArea.extent.width (%" PRIu32 ") ) / shadingRateAttachmentTexelSize.width (%" PRIu32 ").", - view_state->image_state->create_info.extent.width, rendering_info.renderArea.offset.x, - rendering_info.renderArea.extent.width, - rendering_fragment_shading_rate_attachment_info->shadingRateAttachmentTexelSize.width); + view_state.image_state->create_info.extent.width, rendering_info.renderArea.offset.x, + rendering_info.renderArea.extent.width, fsr_attachment_info.shadingRateAttachmentTexelSize.width); } - if (static_cast(view_state->image_state->create_info.extent.height) < - vvl::GetQuotientCeil( - y_adjusted_extent, - static_cast(rendering_fragment_shading_rate_attachment_info->shadingRateAttachmentTexelSize.height))) { + if (static_cast(view_state.image_state->create_info.extent.height) < + vvl::GetQuotientCeil(y_adjusted_extent, + static_cast(fsr_attachment_info.shadingRateAttachmentTexelSize.height))) { skip |= LogError("VUID-VkRenderingInfo-pNext-06121", objlist, rendering_info_loc.pNext(Struct::VkRenderingFragmentShadingRateAttachmentInfoKHR, Field::imageView), "height (%" PRIu32 ") must not be less than (pRenderingInfo->renderArea.offset.y (%" PRId32 ") + pRenderingInfo->renderArea.extent.height (%" PRIu32 ") ) / shadingRateAttachmentTexelSize.height (%" PRIu32 ").", - view_state->image_state->create_info.extent.height, rendering_info.renderArea.offset.y, - rendering_info.renderArea.extent.height, - rendering_fragment_shading_rate_attachment_info->shadingRateAttachmentTexelSize.height); + view_state.image_state->create_info.extent.height, rendering_info.renderArea.offset.y, + rendering_info.renderArea.extent.height, fsr_attachment_info.shadingRateAttachmentTexelSize.height); } } else { if (device_group_begin_info) { @@ -3259,10 +3272,9 @@ bool CoreChecks::ValidateBeginRenderingFragmentShadingRate(VkCommandBuffer comma const int32_t offset_y = device_group_begin_info->pDeviceRenderAreas[deviceRenderAreaIndex].offset.y; const uint32_t height = device_group_begin_info->pDeviceRenderAreas[deviceRenderAreaIndex].extent.height; - vvl::Image *image_state = view_state->image_state.get(); + vvl::Image *image_state = view_state.image_state.get(); if (image_state->create_info.extent.width < - vvl::GetQuotientCeil(offset_x + width, - rendering_fragment_shading_rate_attachment_info->shadingRateAttachmentTexelSize.width)) { + vvl::GetQuotientCeil(offset_x + width, fsr_attachment_info.shadingRateAttachmentTexelSize.width)) { skip |= LogError( "VUID-VkRenderingInfo-pNext-06120", objlist, rendering_info_loc.pNext(Struct::VkRenderingFragmentShadingRateAttachmentInfoKHR, Field::imageView), @@ -3270,11 +3282,10 @@ bool CoreChecks::ValidateBeginRenderingFragmentShadingRate(VkCommandBuffer comma "].offset.x (%" PRId32 ") + VkDeviceGroupRenderPassBeginInfo::pDeviceRenderAreas[%" PRIu32 "].extent.width (%" PRIu32 ") ) / shadingRateAttachmentTexelSize.width (%" PRIu32 ").", image_state->create_info.extent.width, deviceRenderAreaIndex, offset_x, deviceRenderAreaIndex, width, - rendering_fragment_shading_rate_attachment_info->shadingRateAttachmentTexelSize.width); + fsr_attachment_info.shadingRateAttachmentTexelSize.width); } if (image_state->create_info.extent.height < - vvl::GetQuotientCeil(offset_y + height, - rendering_fragment_shading_rate_attachment_info->shadingRateAttachmentTexelSize.height)) { + vvl::GetQuotientCeil(offset_y + height, fsr_attachment_info.shadingRateAttachmentTexelSize.height)) { skip |= LogError( "VUID-VkRenderingInfo-pNext-06122", objlist, rendering_info_loc.pNext(Struct::VkRenderingFragmentShadingRateAttachmentInfoKHR, Field::imageView), @@ -3284,7 +3295,7 @@ bool CoreChecks::ValidateBeginRenderingFragmentShadingRate(VkCommandBuffer comma ") ) / shadingRateAttachmentTexelSize.height " "(%" PRIu32 ").", image_state->create_info.extent.height, deviceRenderAreaIndex, offset_y, deviceRenderAreaIndex, height, - rendering_fragment_shading_rate_attachment_info->shadingRateAttachmentTexelSize.height); + fsr_attachment_info.shadingRateAttachmentTexelSize.height); } } } @@ -3508,9 +3519,10 @@ bool CoreChecks::PreCallValidateCmdBeginRendering(VkCommandBuffer commandBuffer, } const Location rendering_info_loc = error_obj.location.dot(Field::pRenderingInfo); - if ((pRenderingInfo->flags & VK_RENDERING_CONTENTS_INLINE_BIT_EXT) != 0 && !enabled_features.nestedCommandBuffer) { - skip |= LogError("VUID-VkRenderingInfo-flags-09381", commandBuffer, rendering_info_loc.dot(Field::flags), - "are %s, but nestedCommandBuffer feature is not enabled.", + if ((pRenderingInfo->flags & VK_RENDERING_CONTENTS_INLINE_BIT_EXT) != 0 && !enabled_features.nestedCommandBuffer && + !enabled_features.maintenance7) { + skip |= LogError("VUID-VkRenderingInfo-flags-10012", commandBuffer, rendering_info_loc.dot(Field::flags), + "are %s, but nestedCommandBuffer and maintenance7 feature were not enabled.", string_VkRenderingFlags(pRenderingInfo->flags).c_str()); } if (pRenderingInfo->layerCount > phys_dev_props.limits.maxFramebufferLayers) { @@ -4419,7 +4431,11 @@ bool CoreChecks::PreCallValidateCreateFramebuffer(VkDevice device, const VkFrame if (fsr_attachment && fsr_attachment->pFragmentShadingRateAttachment && fsr_attachment->pFragmentShadingRateAttachment->attachment == i) { used_as_fragment_shading_rate_attachment = true; - if ((mip_width * fsr_attachment->shadingRateAttachmentTexelSize.width) < pCreateInfo->width) { + const bool validate_render_area = + !enabled_features.maintenance7 || + !phys_dev_ext_props.maintenance7_props.robustFragmentShadingRateAttachmentAccess; + if (validate_render_area && + (mip_width * fsr_attachment->shadingRateAttachmentTexelSize.width) < pCreateInfo->width) { LogObjectList objlist(pCreateInfo->renderPass, image_views[i], ivci.image); skip |= LogError("VUID-VkFramebufferCreateInfo-flags-04539", objlist, attachment_loc, "mip level %" PRIu32 @@ -4434,7 +4450,8 @@ bool CoreChecks::PreCallValidateCreateFramebuffer(VkDevice device, const VkFrame subresource_range.baseMipLevel, j, mip_width, fsr_attachment->shadingRateAttachmentTexelSize.width, pCreateInfo->width); } - if ((mip_height * fsr_attachment->shadingRateAttachmentTexelSize.height) < pCreateInfo->height) { + if (validate_render_area && + (mip_height * fsr_attachment->shadingRateAttachmentTexelSize.height) < pCreateInfo->height) { LogObjectList objlist(pCreateInfo->renderPass, image_views[i], ivci.image); skip |= LogError("VUID-VkFramebufferCreateInfo-flags-04540", objlist, attachment_loc, "mip level %" PRIu32 @@ -4685,7 +4702,11 @@ bool CoreChecks::PreCallValidateCreateFramebuffer(VkDevice device, const VkFrame const auto *fsr_attachment = vku::FindStructInPNextChain(subpass.pNext); if (fsr_attachment && fsr_attachment->pFragmentShadingRateAttachment->attachment == i) { used_as_fragment_shading_rate_attachment = true; - if ((aii.width * fsr_attachment->shadingRateAttachmentTexelSize.width) < pCreateInfo->width) { + const bool validate_render_area = + !enabled_features.maintenance7 || + !phys_dev_ext_props.maintenance7_props.robustFragmentShadingRateAttachmentAccess; + if (validate_render_area && + (aii.width * fsr_attachment->shadingRateAttachmentTexelSize.width) < pCreateInfo->width) { skip |= LogError("VUID-VkFramebufferCreateInfo-flags-04543", pCreateInfo->renderPass, attachment_loc, "is used as a fragment shading rate attachment in subpass %" PRIu32 @@ -4696,7 +4717,8 @@ bool CoreChecks::PreCallValidateCreateFramebuffer(VkDevice device, const VkFrame "width (%" PRIu32 ").", j, aii.width, fsr_attachment->shadingRateAttachmentTexelSize.width, pCreateInfo->width); } - if ((aii.height * fsr_attachment->shadingRateAttachmentTexelSize.height) < pCreateInfo->height) { + if (validate_render_area && + (aii.height * fsr_attachment->shadingRateAttachmentTexelSize.height) < pCreateInfo->height) { skip |= LogError("VUID-VkFramebufferCreateInfo-flags-04544", pCreateInfo->renderPass, attachment_loc, "is used as a fragment shading rate attachment in subpass %" PRIu32 diff --git a/layers/core_checks/core_validation.h b/layers/core_checks/core_validation.h index 483bc06b994..96286ffec56 100644 --- a/layers/core_checks/core_validation.h +++ b/layers/core_checks/core_validation.h @@ -1434,6 +1434,10 @@ class CoreChecks : public ValidationStateTracker { const Location& rendering_info_loc) const; bool ValidateBeginRenderingFragmentShadingRate(VkCommandBuffer commandBuffer, const VkRenderingInfo& rendering_info, const Location& rendering_info_loc) const; + bool ValidateBeginRenderingFragmentShadingRateRenderArea( + VkCommandBuffer commandBuffer, const vvl::ImageView& view_state, + const VkRenderingFragmentShadingRateAttachmentInfoKHR& fsr_attachment_info, const VkRenderingInfo& rendering_info, + const Location& rendering_info_loc) const; bool ValidateBeginRenderingDeviceGroup(VkCommandBuffer commandBuffer, const VkRenderingInfo& rendering_info, const Location& rendering_info_loc) const; bool ValidateBeginRenderingMultisampledRenderToSingleSampled(VkCommandBuffer commandBuffer, diff --git a/layers/state_tracker/state_tracker.cpp b/layers/state_tracker/state_tracker.cpp index e8874c57806..ffbfe4a664c 100644 --- a/layers/state_tracker/state_tracker.cpp +++ b/layers/state_tracker/state_tracker.cpp @@ -951,6 +951,7 @@ void ValidationStateTracker::PostCreateDevice(const VkDeviceCreateInfo *pCreateI GetPhysicalDeviceExtProperties(physical_device, dev_ext.vk_ext_nested_command_buffer, &phys_dev_props->nested_command_buffer_props); GetPhysicalDeviceExtProperties(physical_device, dev_ext.vk_khr_maintenance6, &phys_dev_props->maintenance6_props); + GetPhysicalDeviceExtProperties(physical_device, dev_ext.vk_khr_maintenance7, &phys_dev_props->maintenance7_props); GetPhysicalDeviceExtProperties(physical_device, dev_ext.vk_ext_descriptor_buffer, &phys_dev_props->descriptor_buffer_props); GetPhysicalDeviceExtProperties(physical_device, dev_ext.vk_ext_descriptor_buffer, &phys_dev_props->descriptor_buffer_density_props); GetPhysicalDeviceExtProperties(physical_device, dev_ext.vk_ext_host_image_copy, &phys_dev_props->host_image_copy_props); diff --git a/layers/state_tracker/state_tracker.h b/layers/state_tracker/state_tracker.h index 1bbfadbfd7d..09f14082860 100644 --- a/layers/state_tracker/state_tracker.h +++ b/layers/state_tracker/state_tracker.h @@ -1843,6 +1843,7 @@ class ValidationStateTracker : public ValidationObject { VkPhysicalDeviceImageProcessingPropertiesQCOM image_processing_props; VkPhysicalDeviceImageAlignmentControlPropertiesMESA image_alignment_control_props; VkPhysicalDeviceMaintenance6PropertiesKHR maintenance6_props; + VkPhysicalDeviceMaintenance7PropertiesKHR maintenance7_props; VkPhysicalDeviceNestedCommandBufferPropertiesEXT nested_command_buffer_props; VkPhysicalDeviceDescriptorBufferPropertiesEXT descriptor_buffer_props; VkPhysicalDeviceDescriptorBufferDensityMapPropertiesEXT descriptor_buffer_density_props; diff --git a/layers/stateless/sl_instance_device.cpp b/layers/stateless/sl_instance_device.cpp index 2912a3bc0a7..f9c58a122d9 100644 --- a/layers/stateless/sl_instance_device.cpp +++ b/layers/stateless/sl_instance_device.cpp @@ -908,3 +908,33 @@ bool StatelessValidation::manual_PreCallValidateSetDebugUtilsObjectTagEXT(VkDevi } return skip; } + +bool StatelessValidation::manual_PreCallValidateGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, + VkPhysicalDeviceProperties2 *pProperties, + const ErrorObject &error_obj) const { + bool skip = false; + const auto *api_props_lists = vku::FindStructInPNextChain(pProperties->pNext); + if (api_props_lists && api_props_lists->pLayeredApis) { + for (uint32_t i = 0; i < api_props_lists->layeredApiCount; i++) { + if (const auto *api_vulkan_props = vku::FindStructInPNextChain( + api_props_lists->pLayeredApis[i].pNext)) { + const VkBaseOutStructure *current = + reinterpret_cast(api_vulkan_props->properties.pNext); + while (current) { + // only VkPhysicalDeviceDriverProperties and VkPhysicalDeviceIDProperties allowed + if (current->sType != VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES && + current->sType != VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES) { + skip |= LogError("VUID-VkPhysicalDeviceLayeredApiVulkanPropertiesKHR-pNext-10011", physicalDevice, + error_obj.location.dot(Field::pProperties) + .pNext(Struct::VkPhysicalDeviceLayeredApiPropertiesListKHR, Field::pLayeredApis, i) + .dot(Field::properties) + .dot(Field::pNext), + "contains an invalid struct (%s).", string_VkStructureType(current->sType)); + } + current = current->pNext; + } + } + } + } + return skip; +} \ No newline at end of file diff --git a/layers/stateless/stateless_validation.h b/layers/stateless/stateless_validation.h index fa02c78a761..8cbd407eaa3 100644 --- a/layers/stateless/stateless_validation.h +++ b/layers/stateless/stateless_validation.h @@ -547,6 +547,9 @@ class StatelessValidation : public ValidationObject { void PreCallRecordDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator, const RecordObject &record_obj) override; + bool manual_PreCallValidateGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, + VkPhysicalDeviceProperties2 *pProperties, + const ErrorObject &error_obj) const; bool manual_PreCallValidateCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool, const ErrorObject &error_obj) const; diff --git a/layers/vulkan/generated/stateless_validation_helper.cpp b/layers/vulkan/generated/stateless_validation_helper.cpp index 0d5161b421b..8d9acc17618 100644 --- a/layers/vulkan/generated/stateless_validation_helper.cpp +++ b/layers/vulkan/generated/stateless_validation_helper.cpp @@ -13202,6 +13202,7 @@ bool StatelessValidation::PreCallValidateGetPhysicalDeviceProperties2(VkPhysical "VUID-VkPhysicalDeviceProperties2-pNext-pNext", "VUID-VkPhysicalDeviceProperties2-sType-unique", physicalDevice, false); } + if (!skip) skip |= manual_PreCallValidateGetPhysicalDeviceProperties2(physicalDevice, pProperties, error_obj); return skip; } diff --git a/scripts/generators/stateless_validation_helper_generator.py b/scripts/generators/stateless_validation_helper_generator.py index e3c95b5f2fe..99d47571a51 100644 --- a/scripts/generators/stateless_validation_helper_generator.py +++ b/scripts/generators/stateless_validation_helper_generator.py @@ -108,6 +108,7 @@ def __init__(self, 'vkGetAccelerationStructureHandleNV', 'vkGetPhysicalDeviceImageFormatProperties', 'vkGetPhysicalDeviceImageFormatProperties2', + 'vkGetPhysicalDeviceProperties2', 'vkCmdBuildAccelerationStructureNV', 'vkCmdTraceRaysKHR', 'vkCmdTraceRaysIndirectKHR', diff --git a/tests/device_profiles/max_profile.json b/tests/device_profiles/max_profile.json index c586978e0fc..dbd506c8249 100644 --- a/tests/device_profiles/max_profile.json +++ b/tests/device_profiles/max_profile.json @@ -158,6 +158,9 @@ "VkPhysicalDeviceMaintenance6FeaturesKHR": { "maintenance6": true }, + "VkPhysicalDeviceMaintenance7FeaturesKHR": { + "maintenance7": true + }, "VkPhysicalDeviceShaderDrawParametersFeatures": { "shaderDrawParameters": true }, @@ -1235,6 +1238,16 @@ "maxCombinedImageSamplerDescriptorCount": 1073741824, "fragmentShadingRateClampCombinerInputs": true }, + "VkPhysicalDeviceMaintenance7PropertiesKHR": { + "robustFragmentShadingRateAttachmentAccess": false, + "separateDepthStencilAttachmentAccess": false, + "maxDescriptorSetTotalUniformBuffersDynamic": 15, + "maxDescriptorSetTotalStorageBuffersDynamic": 16, + "maxDescriptorSetTotalBuffersDynamic": 31, + "maxDescriptorSetUpdateAfterBindTotalUniformBuffersDynamic": 4294967000, + "maxDescriptorSetUpdateAfterBindTotalStorageBuffersDynamic": 4294967000, + "maxDescriptorSetUpdateAfterBindTotalBuffersDynamic": 4294967000 + }, "VkPhysicalDeviceFloatControlsProperties": { "shaderSignedZeroInfNanPreserveFloat16": true, "shaderSignedZeroInfNanPreserveFloat32": true, @@ -2040,6 +2053,7 @@ "VK_KHR_maintenance4": 1, "VK_KHR_maintenance5": 1, "VK_KHR_maintenance6": 1, + "VK_KHR_maintenance7": 1, "VK_KHR_multiview": 1, "VK_KHR_performance_query": 1, "VK_KHR_pipeline_executable_properties": 1, diff --git a/tests/unit/dynamic_rendering.cpp b/tests/unit/dynamic_rendering.cpp index 328ff58d761..c9a35dcc2e1 100644 --- a/tests/unit/dynamic_rendering.cpp +++ b/tests/unit/dynamic_rendering.cpp @@ -6131,7 +6131,7 @@ TEST_F(NegativeDynamicRendering, DynamicRenderingInlineContents) { rendering_info.layerCount = 1u; m_commandBuffer->begin(); - m_errorMonitor->SetDesiredError("VUID-VkRenderingInfo-flags-09381"); + m_errorMonitor->SetDesiredError("VUID-VkRenderingInfo-flags-10012"); vk::CmdBeginRenderingKHR(m_commandBuffer->handle(), &rendering_info); m_errorMonitor->VerifyFound(); m_commandBuffer->end(); diff --git a/tests/unit/others.cpp b/tests/unit/others.cpp index 96f70ec0312..b631a9afb80 100644 --- a/tests/unit/others.cpp +++ b/tests/unit/others.cpp @@ -2194,3 +2194,28 @@ TEST_F(VkLayerTest, GetDeviceFaultInfoEXT) { vk::GetDeviceFaultInfoEXT(device(), &fault_count, &fault_info); m_errorMonitor->VerifyFound(); } + +TEST_F(VkLayerTest, PhysicalDeviceLayeredApiVulkanPropertiesKHR) { + SetTargetApiVersion(VK_API_VERSION_1_2); + AddRequiredExtensions(VK_KHR_MAINTENANCE_7_EXTENSION_NAME); + AddRequiredFeature(vkt::Feature::maintenance7); + RETURN_IF_SKIP(Init()); + + VkPhysicalDeviceVulkan12Properties vulkan_12_props = vku::InitStructHelper(); // not allowed + VkPhysicalDeviceDriverProperties driver_props = vku::InitStructHelper(&vulkan_12_props); + + VkPhysicalDeviceLayeredApiVulkanPropertiesKHR api_vulkan_props = vku::InitStructHelper(); + api_vulkan_props.properties.pNext = &driver_props; + + VkPhysicalDeviceLayeredApiPropertiesKHR api_props = vku::InitStructHelper(&api_vulkan_props); + + VkPhysicalDeviceLayeredApiPropertiesListKHR api_prop_lists = vku::InitStructHelper(); + api_prop_lists.layeredApiCount = 1; + api_prop_lists.pLayeredApis = &api_props; + + VkPhysicalDeviceProperties2 phys_dev_props_2 = vku::InitStructHelper(&api_prop_lists); + + m_errorMonitor->SetDesiredError("VUID-VkPhysicalDeviceLayeredApiVulkanPropertiesKHR-pNext-10011"); + vk::GetPhysicalDeviceProperties2(gpu(), &phys_dev_props_2); + m_errorMonitor->VerifyFound(); +} diff --git a/tests/unit/render_pass.cpp b/tests/unit/render_pass.cpp index 74447ffab3f..85afcaee4e0 100644 --- a/tests/unit/render_pass.cpp +++ b/tests/unit/render_pass.cpp @@ -4222,7 +4222,7 @@ TEST_F(NegativeRenderPass, RenderPassWithRenderPassStripedQueueSubmit2) { } TEST_F(NegativeRenderPass, MissingNestedCommandBuffersFeature) { - TEST_DESCRIPTION("Use VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_EXT when nextedCommandBuffers is not enabled"); + TEST_DESCRIPTION("Use VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_KHR when nextedCommandBuffers is not enabled"); AddRequiredExtensions(VK_EXT_NESTED_COMMAND_BUFFER_EXTENSION_NAME); RETURN_IF_SKIP(Init()); InitRenderTarget(); @@ -4230,13 +4230,13 @@ TEST_F(NegativeRenderPass, MissingNestedCommandBuffersFeature) { m_commandBuffer->begin(); m_errorMonitor->SetDesiredError("VUID-vkCmdBeginRenderPass-contents-09640"); vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, - VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_EXT); + VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_KHR); m_errorMonitor->VerifyFound(); m_commandBuffer->end(); } TEST_F(NegativeRenderPass, MissingNestedCommandBuffersFeature2) { - TEST_DESCRIPTION("Use VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_EXT when nextedCommandBuffers is not enabled"); + TEST_DESCRIPTION("Use VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_KHR when nextedCommandBuffers is not enabled"); AddRequiredExtensions(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); AddRequiredExtensions(VK_EXT_NESTED_COMMAND_BUFFER_EXTENSION_NAME); @@ -4244,7 +4244,7 @@ TEST_F(NegativeRenderPass, MissingNestedCommandBuffersFeature2) { InitRenderTarget(); auto subpassBeginInfo = - vku::InitStruct(nullptr, VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_EXT); + vku::InitStruct(nullptr, VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_KHR); m_commandBuffer->begin(); m_errorMonitor->SetDesiredError("VUID-VkSubpassBeginInfo-contents-09382"); diff --git a/tests/unit/render_pass_positive.cpp b/tests/unit/render_pass_positive.cpp index e534e771429..1d8ba545a40 100644 --- a/tests/unit/render_pass_positive.cpp +++ b/tests/unit/render_pass_positive.cpp @@ -1346,4 +1346,22 @@ TEST_F(PositiveRenderPass, BeginRenderPassWithRenderPassStriped) { submit_info.pCommandBufferInfos = &cb_submit_info; vk::QueueSubmit2KHR(m_default_queue->handle(), 1, &submit_info, VK_NULL_HANDLE); m_default_queue->Wait(); -} \ No newline at end of file +} + +TEST_F(PositiveRenderPass, NestedCommandBuffersFeatureMaintenance7) { + TEST_DESCRIPTION( + "Use VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_KHR with maintenance7, but not nextedCommandBuffers is not " + "enabled"); + SetTargetApiVersion(VK_API_VERSION_1_1); + AddRequiredExtensions(VK_EXT_NESTED_COMMAND_BUFFER_EXTENSION_NAME); + AddRequiredExtensions(VK_KHR_MAINTENANCE_7_EXTENSION_NAME); + AddRequiredFeature(vkt::Feature::maintenance7); + RETURN_IF_SKIP(Init()); + InitRenderTarget(); + + m_commandBuffer->begin(); + vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, + VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_KHR); + vk::CmdEndRenderPass(m_commandBuffer->handle()); + m_commandBuffer->end(); +}