layers: Update colorWriteEnable attachment count
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 2a2a95b..818f245 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -1771,7 +1771,15 @@
}
auto color_write = lvl_find_in_chain<VkPipelineColorWriteCreateInfoEXT>(create_info.pColorBlendState->pNext);
if (color_write) {
- if (color_write->attachmentCount != color_blend_state->attachmentCount) {
+ // if over limit don't give extra redundant error of mismatch of attachmentCount
+ if (color_write->attachmentCount > phys_dev_props.limits.maxColorAttachments) {
+ skip |= LogError(
+ device, "VUID-VkPipelineColorWriteCreateInfoEXT-attachmentCount-06655",
+ "vkCreateGraphicsPipelines(): VkPipelineColorWriteCreateInfoEXT in the pNext chain of pPipelines[%" PRIu32
+ "].pColorBlendState has an attachmentCount of (%" PRIu32
+ ") which is greater than the VkPhysicalDeviceLimits::maxColorAttachments limit (%" PRIu32 ").",
+ pipelineIndex, color_write->attachmentCount, phys_dev_props.limits.maxColorAttachments);
+ } else if (color_write->attachmentCount != color_blend_state->attachmentCount) {
skip |= LogError(
device, "VUID-VkPipelineColorWriteCreateInfoEXT-attachmentCount-04802",
"vkCreateGraphicsPipelines(): VkPipelineColorWriteCreateInfoEXT in the pNext chain of pPipelines[%" PRIu32
@@ -6974,7 +6982,7 @@
}
}
- if (!(pRenderingInfo->colorAttachmentCount <= phys_dev_props.limits.maxColorAttachments)) {
+ if (pRenderingInfo->colorAttachmentCount > phys_dev_props.limits.maxColorAttachments) {
skip |= LogError(commandBuffer, "VUID-VkRenderingInfo-colorAttachmentCount-06106",
"%s(): colorAttachmentCount (%u) must be less than or equal to "
"VkPhysicalDeviceLimits::maxColorAttachments (%u).",
@@ -18512,20 +18520,16 @@
auto cb_state = GetRead<CMD_BUFFER_STATE>(commandBuffer);
+ if (attachmentCount > phys_dev_props.limits.maxColorAttachments) {
+ skip |= LogError(commandBuffer, "VUID-vkCmdSetColorWriteEnableEXT-attachmentCount-06656",
+ "vkCmdSetColorWriteEnableEXT(): attachmentCount (%" PRIu32
+ ") is greater than the VkPhysicalDeviceLimits::maxColorAttachments limit (%" PRIu32 ").",
+ attachmentCount, phys_dev_props.limits.maxColorAttachments);
+ }
+
if (!enabled_features.color_write_features.colorWriteEnable) {
skip |= LogError(commandBuffer, "VUID-vkCmdSetColorWriteEnableEXT-None-04803",
- "vkCmdSetColorWriteEnableEXT: color write is not enabled.");
- }
- auto graphics_pipeline = cb_state->GetCurrentPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS);
- if (graphics_pipeline) {
- uint32_t pipeline_attachment_count = graphics_pipeline->create_info.graphics.pColorBlendState->attachmentCount;
- if (attachmentCount != pipeline_attachment_count) {
- skip |= LogError(
- commandBuffer, "VUID-vkCmdSetColorWriteEnableEXT-attachmentCount-04804",
- "vkCmdSetColorWriteEnableEXT: attachment count (%" PRIu32
- ") is not equal to currenly bound pipelines VkPipelineColorBlendStateCreateInfo::attachmentCount (%" PRIu32 ").",
- attachmentCount, pipeline_attachment_count);
- }
+ "vkCmdSetColorWriteEnableEXT(): color write is not enabled.");
}
return skip;
diff --git a/tests/vklayertests_others.cpp b/tests/vklayertests_others.cpp
index fb58f6f..b6148ec 100644
--- a/tests/vklayertests_others.cpp
+++ b/tests/vklayertests_others.cpp
@@ -12625,8 +12625,8 @@
m_commandBuffer->end();
}
-TEST_F(VkLayerTest, InvalidColorWriteEnableAttachmentCount) {
- TEST_DESCRIPTION("Invalid usage of vkCmdSetColorWriteEnableEXT with attachment count 0");
+TEST_F(VkLayerTest, InvalidColorWriteEnableFeature) {
+ TEST_DESCRIPTION("Invalid usage of vkCmdSetColorWriteEnableEXT with feature not enabled");
if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
@@ -12646,9 +12646,9 @@
ASSERT_NO_FATAL_FAILURE(InitState());
ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
- VkBool32 colorWriteEnable[2] = {VK_TRUE, VK_FALSE};
+ VkBool32 color_write_enable[2] = {VK_TRUE, VK_FALSE};
- PFN_vkCmdSetColorWriteEnableEXT fpCmdSetColorWriteEnableEXT =
+ PFN_vkCmdSetColorWriteEnableEXT vkCmdSetColorWriteEnableEXT =
(PFN_vkCmdSetColorWriteEnableEXT)vk::GetDeviceProcAddr(m_device->handle(), "vkCmdSetColorWriteEnableEXT");
CreatePipelineHelper helper(*this);
@@ -12659,12 +12659,72 @@
m_commandBuffer->begin();
vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, helper.pipeline_);
m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetColorWriteEnableEXT-None-04803");
- m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetColorWriteEnableEXT-attachmentCount-04804");
- fpCmdSetColorWriteEnableEXT(m_commandBuffer->handle(), 2, colorWriteEnable);
+ vkCmdSetColorWriteEnableEXT(m_commandBuffer->handle(), 1, color_write_enable);
m_errorMonitor->VerifyFound();
m_commandBuffer->end();
}
+TEST_F(VkLayerTest, InvalidColorWriteEnableAttachmentCount) {
+ TEST_DESCRIPTION("Invalid usage of attachmentCount for vkCmdSetColorWriteEnableEXT");
+
+ if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
+ printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
+ VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
+ return;
+ }
+ m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
+
+ ASSERT_NO_FATAL_FAILURE(InitFramework());
+
+ if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME)) {
+ printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME);
+ return;
+ }
+ m_device_extension_names.push_back(VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME);
+
+ // Feature required to be supported for extension
+ VkPhysicalDeviceColorWriteEnableFeaturesEXT color_write_features = LvlInitStruct<VkPhysicalDeviceColorWriteEnableFeaturesEXT>();
+ color_write_features.colorWriteEnable = VK_TRUE;
+ VkPhysicalDeviceFeatures2 pd_features2 = LvlInitStruct<VkPhysicalDeviceFeatures2>(&color_write_features);
+ ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features2));
+ ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+ // need a valid array to index into
+ std::vector<VkBool32> color_write_enable(m_device->props.limits.maxColorAttachments + 1, VK_TRUE);
+
+ PFN_vkCmdSetColorWriteEnableEXT vkCmdSetColorWriteEnableEXT =
+ (PFN_vkCmdSetColorWriteEnableEXT)vk::GetDeviceProcAddr(m_device->handle(), "vkCmdSetColorWriteEnableEXT");
+
+ CreatePipelineHelper helper(*this);
+ helper.InitInfo();
+ helper.InitState();
+ helper.CreateGraphicsPipeline();
+
+ m_commandBuffer->begin();
+ vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, helper.pipeline_);
+
+ // Value can't be zero
+ // TODO: The generated code is not use the correct implicit VUID, but at least its still correctly validating
+ // m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetColorWriteEnableEXT-attachmentCount-arraylength");
+ m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID_Undefined");
+ vkCmdSetColorWriteEnableEXT(m_commandBuffer->handle(), 0, color_write_enable.data());
+ m_errorMonitor->VerifyFound();
+
+ // over the limit
+ m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetColorWriteEnableEXT-attachmentCount-06656");
+ vkCmdSetColorWriteEnableEXT(m_commandBuffer->handle(), m_device->props.limits.maxColorAttachments + 1,
+ color_write_enable.data());
+ m_errorMonitor->VerifyFound();
+
+ m_errorMonitor->ExpectSuccess();
+ // mismatch of attachmentCount value is allowed for dynamic
+ // see https://gitlab.khronos.org/vulkan/vulkan/-/issues/2868
+ vkCmdSetColorWriteEnableEXT(m_commandBuffer->handle(), 2, color_write_enable.data());
+ m_errorMonitor->VerifyNotFound();
+
+ m_commandBuffer->end();
+}
+
TEST_F(VkLayerTest, InvalidCmdSetDiscardRectangleEXTRectangleCount) {
TEST_DESCRIPTION("Test CmdSetDiscardRectangleEXT with invalid offsets in pDiscardRectangles");
diff --git a/tests/vklayertests_pipeline_shader.cpp b/tests/vklayertests_pipeline_shader.cpp
index 3f9e6aa..27dcca8 100644
--- a/tests/vklayertests_pipeline_shader.cpp
+++ b/tests/vklayertests_pipeline_shader.cpp
@@ -13256,6 +13256,13 @@
pipe.CreateGraphicsPipeline();
m_errorMonitor->VerifyFound();
+ std::vector<VkBool32> max_enabled(m_device->props.limits.maxColorAttachments + 1, VK_TRUE);
+ color_write.attachmentCount = m_device->props.limits.maxColorAttachments + 1;
+ color_write.pColorWriteEnables = max_enabled.data();
+ m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPipelineColorWriteCreateInfoEXT-attachmentCount-06655");
+ pipe.CreateGraphicsPipeline();
+ m_errorMonitor->VerifyFound();
+
VkBool32 enabled = VK_FALSE;
color_write.attachmentCount = 1;
color_write.pColorWriteEnables = &enabled;