layers: Rework attachment use conflict checks

Previously buffer_validation covered part of this, but not everything.

V2: - Fix repeated ATTACHMENT_RESOLVE where I meant ATTACHMENT_PRESERVE
    - Fix camelcase noise in a bunch of places
    - Rename VkAttachmentReference& variables to attachment_ref to avoid
      attachment.attachment etc.
    - clang-format tidy-up
    - Move positive case to VkPositiveLayerTest
diff --git a/layers/buffer_validation.cpp b/layers/buffer_validation.cpp
index cb54870..dd44c7a 100644
--- a/layers/buffer_validation.cpp
+++ b/layers/buffer_validation.cpp
@@ -2860,22 +2860,6 @@
                                     string_VkImageLayout(subpass.pInputAttachments[j].layout));
             }
 
-            VkImageLayout layout = subpass.pInputAttachments[j].layout;
-            bool found_layout_mismatch = subpass.pDepthStencilAttachment &&
-                                         subpass.pDepthStencilAttachment->attachment == attach_index &&
-                                         subpass.pDepthStencilAttachment->layout != layout;
-            for (uint32_t c = 0; !found_layout_mismatch && c < subpass.colorAttachmentCount; ++c) {
-                found_layout_mismatch =
-                    (subpass.pColorAttachments[c].attachment == attach_index && subpass.pColorAttachments[c].layout != layout);
-            }
-            if (found_layout_mismatch) {
-                skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
-                                VALIDATION_ERROR_140006ae,
-                                "CreateRenderPass:  Subpass %u pInputAttachments[%u] (%u) has layout %u, but is also used as a "
-                                "depth/color attachment with a different layout.",
-                                i, j, attach_index, layout);
-            }
-
             if (attach_first_use[attach_index]) {
                 skip |= ValidateLayoutVsAttachmentDescription(report_data, subpass.pInputAttachments[j].layout, attach_index,
                                                               pCreateInfo->pAttachments[attach_index]);
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 444f5e0..6654045 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -8987,14 +8987,84 @@
 
 static bool IsPowerOfTwo(unsigned x) { return x && !(x & (x - 1)); }
 
+enum AttachmentType {
+    ATTACHMENT_COLOR = 1,
+    ATTACHMENT_DEPTH = 2,
+    ATTACHMENT_INPUT = 4,
+    ATTACHMENT_PRESERVE = 8,
+    ATTACHMENT_RESOLVE = 16,
+};
+
+char const *string_AttachmentType(uint8_t type) {
+    switch (type) {
+        case ATTACHMENT_COLOR:
+            return "color";
+        case ATTACHMENT_DEPTH:
+            return "depth";
+        case ATTACHMENT_INPUT:
+            return "input";
+        case ATTACHMENT_PRESERVE:
+            return "preserve";
+        case ATTACHMENT_RESOLVE:
+            return "resolve";
+        default:
+            return "(multiple)";
+    }
+}
+
+static bool AddAttachmentUse(layer_data *dev_data, uint32_t subpass, std::vector<uint8_t> &attachment_uses,
+                             std::vector<VkImageLayout> &attachment_layouts, uint32_t attachment, uint8_t new_use,
+                             VkImageLayout new_layout) {
+    if (attachment >= attachment_uses.size()) return false; /* out of range, but already reported */
+
+    bool skip = false;
+    auto &uses = attachment_uses[attachment];
+    if (uses & new_use) {
+        skip |=
+            log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
+                    DRAWSTATE_INVALID_RENDERPASS, "vkCreateRenderPass(): subpass %u already uses attachment %u as a %s attachment.",
+                    subpass, attachment, string_AttachmentType(new_use));
+    } else if (uses & ~ATTACHMENT_INPUT || (uses && (new_use == ATTACHMENT_RESOLVE || new_use == ATTACHMENT_PRESERVE))) {
+        /* Note: input attachments are assumed to be done first. */
+        skip |=
+            log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
+                    VALIDATION_ERROR_140006ac, "vkCreateRenderPass(): subpass %u uses attachment %u as both %s and %s attachment.",
+                    subpass, attachment, string_AttachmentType(uses), string_AttachmentType(new_use));
+    } else if (uses && attachment_layouts[attachment] != new_layout) {
+        skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
+                        VALIDATION_ERROR_140006ae,
+                        "vkCreateRenderPass(): subpass %u uses attachment %u with conflicting layouts: input uses %s, but %s "
+                        "attachment uses %s.",
+                        subpass, attachment, string_VkImageLayout(attachment_layouts[attachment]), string_AttachmentType(new_use),
+                        string_VkImageLayout(new_layout));
+    } else {
+        attachment_layouts[attachment] = new_layout;
+        uses |= new_use;
+    }
+
+    return skip;
+}
+
 static bool ValidateRenderpassAttachmentUsage(layer_data *dev_data, const VkRenderPassCreateInfo *pCreateInfo) {
     bool skip = false;
     for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) {
         const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i];
+        std::vector<uint8_t> attachment_uses(pCreateInfo->attachmentCount);
+        std::vector<VkImageLayout> attachment_layouts(pCreateInfo->attachmentCount);
+
         if (subpass.pipelineBindPoint != VK_PIPELINE_BIND_POINT_GRAPHICS) {
             skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                             VALIDATION_ERROR_14000698,
-                            "CreateRenderPass: Pipeline bind point for subpass %d must be VK_PIPELINE_BIND_POINT_GRAPHICS.", i);
+                            "vkCreateRenderPass(): Pipeline bind point for subpass %d must be VK_PIPELINE_BIND_POINT_GRAPHICS.", i);
+        }
+
+        for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) {
+            auto const &attachment_ref = subpass.pInputAttachments[j];
+            if (attachment_ref.attachment != VK_ATTACHMENT_UNUSED) {
+                skip |= ValidateAttachmentIndex(dev_data, attachment_ref.attachment, pCreateInfo->attachmentCount, "Input");
+                skip |= AddAttachmentUse(dev_data, i, attachment_uses, attachment_layouts, attachment_ref.attachment,
+                                         ATTACHMENT_INPUT, attachment_ref.layout);
+            }
         }
 
         for (uint32_t j = 0; j < subpass.preserveAttachmentCount; ++j) {
@@ -9002,119 +9072,110 @@
             if (attachment == VK_ATTACHMENT_UNUSED) {
                 skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                 VALIDATION_ERROR_140006aa,
-                                "CreateRenderPass:  Preserve attachment (%d) must not be VK_ATTACHMENT_UNUSED.", j);
+                                "vkCreateRenderPass():  Preserve attachment (%d) must not be VK_ATTACHMENT_UNUSED.", j);
             } else {
                 skip |= ValidateAttachmentIndex(dev_data, attachment, pCreateInfo->attachmentCount, "Preserve");
+                skip |= AddAttachmentUse(dev_data, i, attachment_uses, attachment_layouts, attachment, ATTACHMENT_PRESERVE,
+                                         VkImageLayout(0) /* preserve doesn't have any layout */);
+            }
+        }
 
-                bool found = (subpass.pDepthStencilAttachment != NULL && subpass.pDepthStencilAttachment->attachment == attachment);
-                for (uint32_t r = 0; !found && r < subpass.inputAttachmentCount; ++r) {
-                    found = (subpass.pInputAttachments[r].attachment == attachment);
-                }
-                for (uint32_t r = 0; !found && r < subpass.colorAttachmentCount; ++r) {
-                    found = (subpass.pColorAttachments[r].attachment == attachment) ||
-                            (subpass.pResolveAttachments != NULL && subpass.pResolveAttachments[r].attachment == attachment);
-                }
-                if (found) {
-                    skip |= log_msg(
-                        dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
-                        VALIDATION_ERROR_140006ac,
-                        "CreateRenderPass: subpass %u pPreserveAttachments[%u] (%u) must not be used elsewhere in the subpass.", i,
-                        j, attachment);
+        unsigned sample_count = 0;
+        bool subpass_performs_resolve = false;
+
+        for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) {
+            if (subpass.pResolveAttachments) {
+                auto const &attachment_ref = subpass.pResolveAttachments[j];
+                if (attachment_ref.attachment != VK_ATTACHMENT_UNUSED) {
+                    skip |= ValidateAttachmentIndex(dev_data, attachment_ref.attachment, pCreateInfo->attachmentCount, "Resolve");
+                    skip |= AddAttachmentUse(dev_data, i, attachment_uses, attachment_layouts, attachment_ref.attachment,
+                                             ATTACHMENT_RESOLVE, attachment_ref.layout);
+
+                    subpass_performs_resolve = true;
+
+                    if (!skip && pCreateInfo->pAttachments[attachment_ref.attachment].samples != VK_SAMPLE_COUNT_1_BIT) {
+                        skip |=
+                            log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
+                                    0, VALIDATION_ERROR_140006a2,
+                                    "vkCreateRenderPass():  Subpass %u requests multisample resolve into attachment %u, which must "
+                                    "have VK_SAMPLE_COUNT_1_BIT but has %s.",
+                                    i, attachment_ref.attachment,
+                                    string_VkSampleCountFlagBits(pCreateInfo->pAttachments[attachment_ref.attachment].samples));
+                    }
                 }
             }
         }
 
-        auto subpass_performs_resolve =
-            subpass.pResolveAttachments &&
-            std::any_of(subpass.pResolveAttachments, subpass.pResolveAttachments + subpass.colorAttachmentCount,
-                        [](VkAttachmentReference ref) { return ref.attachment != VK_ATTACHMENT_UNUSED; });
-
-        unsigned sample_count = 0;
-
         for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) {
-            uint32_t attachment;
-            if (subpass.pResolveAttachments) {
-                attachment = subpass.pResolveAttachments[j].attachment;
-                skip |= ValidateAttachmentIndex(dev_data, attachment, pCreateInfo->attachmentCount, "Resolve");
+            auto const &attachment_ref = subpass.pColorAttachments[j];
+            skip |= ValidateAttachmentIndex(dev_data, attachment_ref.attachment, pCreateInfo->attachmentCount, "Color");
+            if (!skip && attachment_ref.attachment != VK_ATTACHMENT_UNUSED) {
+                skip |= AddAttachmentUse(dev_data, i, attachment_uses, attachment_layouts, attachment_ref.attachment,
+                                         ATTACHMENT_COLOR, attachment_ref.layout);
+                sample_count |= (unsigned)pCreateInfo->pAttachments[attachment_ref.attachment].samples;
 
-                if (!skip && attachment != VK_ATTACHMENT_UNUSED &&
-                    pCreateInfo->pAttachments[attachment].samples != VK_SAMPLE_COUNT_1_BIT) {
-                    skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
-                                    0, VALIDATION_ERROR_140006a2,
-                                    "CreateRenderPass:  Subpass %u requests multisample resolve into attachment %u, which must "
-                                    "have VK_SAMPLE_COUNT_1_BIT but has %s.",
-                                    i, attachment, string_VkSampleCountFlagBits(pCreateInfo->pAttachments[attachment].samples));
-                }
-
-                if (!skip && subpass.pResolveAttachments[j].attachment != VK_ATTACHMENT_UNUSED &&
-                    subpass.pColorAttachments[j].attachment == VK_ATTACHMENT_UNUSED) {
-                    skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
-                                    0, VALIDATION_ERROR_1400069e,
-                                    "CreateRenderPass:  Subpass %u requests multisample resolve from attachment %u which has "
-                                    "attachment=VK_ATTACHMENT_UNUSED.",
-                                    i, attachment);
-                }
-            }
-            attachment = subpass.pColorAttachments[j].attachment;
-            skip |= ValidateAttachmentIndex(dev_data, attachment, pCreateInfo->attachmentCount, "Color");
-
-            if (!skip && attachment != VK_ATTACHMENT_UNUSED) {
-                sample_count |= (unsigned)pCreateInfo->pAttachments[attachment].samples;
-
-                if (subpass_performs_resolve && pCreateInfo->pAttachments[attachment].samples == VK_SAMPLE_COUNT_1_BIT) {
+                if (subpass_performs_resolve &&
+                    pCreateInfo->pAttachments[attachment_ref.attachment].samples == VK_SAMPLE_COUNT_1_BIT) {
                     skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
                                     0, VALIDATION_ERROR_140006a0,
-                                    "CreateRenderPass:  Subpass %u requests multisample resolve from attachment %u which has "
+                                    "vkCreateRenderPass():  Subpass %u requests multisample resolve from attachment %u which has "
                                     "VK_SAMPLE_COUNT_1_BIT.",
-                                    i, attachment);
-                }
-
-                if (subpass_performs_resolve && subpass.pResolveAttachments[j].attachment != VK_ATTACHMENT_UNUSED) {
-                    const auto &color_desc = pCreateInfo->pAttachments[attachment];
-                    const auto &resolve_desc = pCreateInfo->pAttachments[subpass.pResolveAttachments[j].attachment];
-                    if (color_desc.format != resolve_desc.format) {
-                        skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                        VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, VALIDATION_ERROR_140006a4,
-                                        "CreateRenderPass:  Subpass %u pColorAttachments[%u] resolves to an attachment with a "
-                                        "different format. color format: %u, resolve format: %u.",
-                                        i, j, color_desc.format, resolve_desc.format);
-                    }
+                                    i, attachment_ref.attachment);
                 }
 
                 if (dev_data->extensions.vk_amd_mixed_attachment_samples && subpass.pDepthStencilAttachment &&
                     subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
                     const auto depth_stencil_sample_count =
                         pCreateInfo->pAttachments[subpass.pDepthStencilAttachment->attachment].samples;
-                    if (pCreateInfo->pAttachments[attachment].samples > depth_stencil_sample_count) {
+                    if (pCreateInfo->pAttachments[attachment_ref.attachment].samples > depth_stencil_sample_count) {
                         skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                         VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, VALIDATION_ERROR_14000bc4,
-                                        "CreateRenderPass:  Subpass %u pColorAttachments[%u] has %s which is larger than "
+                                        "vkCreateRenderPass():  Subpass %u pColorAttachments[%u] has %s which is larger than "
                                         "depth/stencil attachment %s.",
-                                        i, j, string_VkSampleCountFlagBits(pCreateInfo->pAttachments[attachment].samples),
+                                        i, j,
+                                        string_VkSampleCountFlagBits(pCreateInfo->pAttachments[attachment_ref.attachment].samples),
                                         string_VkSampleCountFlagBits(depth_stencil_sample_count));
                     }
                 }
             }
+
+            if (!skip && subpass_performs_resolve && subpass.pResolveAttachments[j].attachment != VK_ATTACHMENT_UNUSED) {
+                if (attachment_ref.attachment == VK_ATTACHMENT_UNUSED) {
+                    skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
+                                    0, VALIDATION_ERROR_1400069e,
+                                    "vkCreateRenderPass():  Subpass %u requests multisample resolve from attachment %u which has "
+                                    "attachment=VK_ATTACHMENT_UNUSED.",
+                                    i, attachment_ref.attachment);
+                } else {
+                    const auto &color_desc = pCreateInfo->pAttachments[attachment_ref.attachment];
+                    const auto &resolve_desc = pCreateInfo->pAttachments[subpass.pResolveAttachments[j].attachment];
+                    if (color_desc.format != resolve_desc.format) {
+                        skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                        VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, VALIDATION_ERROR_140006a4,
+                                        "vkCreateRenderPass():  Subpass %u pColorAttachments[%u] resolves to an attachment with a "
+                                        "different format. color format: %u, resolve format: %u.",
+                                        i, j, color_desc.format, resolve_desc.format);
+                    }
+                }
+            }
         }
 
         if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
-            uint32_t attachment = subpass.pDepthStencilAttachment->attachment;
-            skip |= ValidateAttachmentIndex(dev_data, attachment, pCreateInfo->attachmentCount, "Depth stencil");
+            auto const &attachment_ref = *subpass.pDepthStencilAttachment;
+            skip |= ValidateAttachmentIndex(dev_data, attachment_ref.attachment, pCreateInfo->attachmentCount, "Depth stencil");
 
-            if (!skip && attachment != VK_ATTACHMENT_UNUSED) {
-                sample_count |= (unsigned)pCreateInfo->pAttachments[attachment].samples;
+            if (!skip && attachment_ref.attachment != VK_ATTACHMENT_UNUSED) {
+                skip |= AddAttachmentUse(dev_data, i, attachment_uses, attachment_layouts, attachment_ref.attachment,
+                                         ATTACHMENT_DEPTH, attachment_ref.layout);
+                sample_count |= (unsigned)pCreateInfo->pAttachments[attachment_ref.attachment].samples;
             }
         }
 
-        for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) {
-            uint32_t attachment = subpass.pInputAttachments[j].attachment;
-            skip |= ValidateAttachmentIndex(dev_data, attachment, pCreateInfo->attachmentCount, "Input");
-        }
-
         if (!dev_data->extensions.vk_amd_mixed_attachment_samples && sample_count && !IsPowerOfTwo(sample_count)) {
-            skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
-                            VALIDATION_ERROR_0082b401,
-                            "CreateRenderPass:  Subpass %u attempts to render to attachments with inconsistent sample counts.", i);
+            skip |=
+                log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
+                        VALIDATION_ERROR_0082b401,
+                        "vkCreateRenderPass():  Subpass %u attempts to render to attachments with inconsistent sample counts.", i);
         }
     }
     return skip;
diff --git a/tests/layer_validation_tests.cpp b/tests/layer_validation_tests.cpp
index c1f3283..796693b 100644
--- a/tests/layer_validation_tests.cpp
+++ b/tests/layer_validation_tests.cpp
@@ -4241,6 +4241,101 @@
     m_errorMonitor->VerifyFound();
 }
 
+TEST_F(VkLayerTest, RenderPassAttachmentUsedTwiceColor) {
+    ASSERT_NO_FATAL_FAILURE(Init());
+    TEST_DESCRIPTION("Attachment is used simultaneously as two color attachments. This is not acceptable.");
+
+    VkAttachmentDescription attach[] = {
+        {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
+         VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
+         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
+    };
+    VkAttachmentReference refs[] = {
+        {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
+        {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
+    };
+    VkSubpassDescription subpasses[] = {
+        {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 2, refs, nullptr, nullptr, 0, nullptr},
+    };
+
+    VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 0, nullptr};
+    VkRenderPass rp;
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         "subpass 0 already uses attachment 0 as a color attachment");
+    vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
+    m_errorMonitor->VerifyFound();
+}
+
+TEST_F(VkLayerTest, RenderPassAttachmentUsedTwiceMismatchingLayout) {
+    ASSERT_NO_FATAL_FAILURE(Init());
+
+    TEST_DESCRIPTION("Attachment is used simultaneously as color and input. The layouts differ, which is not acceptable.");
+
+    VkAttachmentDescription attach[] = {
+        {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_DONT_CARE,
+         VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
+    };
+    VkAttachmentReference color_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
+    VkAttachmentReference input_ref = {0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
+    VkSubpassDescription subpasses[] = {
+        {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input_ref, 1, &color_ref, nullptr, nullptr, 0, nullptr},
+    };
+
+    VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 0, nullptr};
+    VkRenderPass rp;
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_140006ae);
+    vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
+    m_errorMonitor->VerifyFound();
+}
+
+TEST_F(VkPositiveLayerTest, RenderPassAttachmentUsedTwiceOK) {
+    ASSERT_NO_FATAL_FAILURE(Init());
+
+    TEST_DESCRIPTION("Attachment is used simultaneously as color and input, with the same layout. This is OK.");
+
+    VkAttachmentDescription attach[] = {
+        {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_DONT_CARE,
+         VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
+    };
+    VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_GENERAL};
+    VkSubpassDescription subpasses[] = {
+        {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &ref, 1, &ref, nullptr, nullptr, 0, nullptr},
+    };
+
+    VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 0, nullptr};
+    VkRenderPass rp;
+
+    m_errorMonitor->ExpectSuccess();
+    vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
+    m_errorMonitor->VerifyNotFound();
+    vkDestroyRenderPass(m_device->device(), rp, nullptr);
+}
+
+TEST_F(VkLayerTest, RenderPassAttachmentUsedTwicePreserveAndColor) {
+    ASSERT_NO_FATAL_FAILURE(Init());
+
+    TEST_DESCRIPTION("Attachment is used simultaneously as color and preserve. This is not acceptable.");
+
+    VkAttachmentDescription attach[] = {
+        {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_DONT_CARE,
+         VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
+    };
+    VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_GENERAL};
+    uint32_t preserve_attachment = 0;
+    VkSubpassDescription subpasses[] = {
+        {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 1, &preserve_attachment},
+    };
+
+    VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 0, nullptr};
+    VkRenderPass rp;
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_140006ac);
+    vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
+    m_errorMonitor->VerifyFound();
+}
+
 TEST_F(VkLayerTest, RenderPassPipelineSubpassMismatch) {
     TEST_DESCRIPTION("Use a pipeline for the wrong subpass in a render pass instance");
     ASSERT_NO_FATAL_FAILURE(Init());