/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2015 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief RenderPass tests
 *//*--------------------------------------------------------------------*/

#include "vktRenderPassTests.hpp"
#include "vktRenderPassTestsUtil.hpp"

#include "vktRenderPassMultisampleTests.hpp"
#include "vktRenderPassMultisampleResolveTests.hpp"
#include "vktRenderPassSampleReadTests.hpp"
#ifndef CTS_USES_VULKANSC
#include "vktRenderPassSparseRenderTargetTests.hpp"
#endif // CTS_USES_VULKANSC
#include "vktRenderPassSubpassDependencyTests.hpp"
#include "vktRenderPassUnusedAttachmentTests.hpp"
#include "vktRenderPassUnusedClearAttachmentTests.hpp"
#include "vktRenderPassDepthStencilResolveTests.hpp"
#include "vktRenderPassUnusedAttachmentSparseFillingTests.hpp"
#include "vktRenderPassFragmentDensityMapTests.hpp"
#include "vktRenderPassMultipleSubpassesMultipleCommandBuffersTests.hpp"
#ifndef CTS_USES_VULKANSC
#include "vktRenderPassLoadStoreOpNoneTests.hpp"
#endif // CTS_USES_VULKANSC

#include "vktTestCaseUtil.hpp"
#include "vktTestGroupUtil.hpp"

#include "vkDefs.hpp"
#include "vkDeviceUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkPlatform.hpp"
#include "vkPrograms.hpp"
#include "vkQueryUtil.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vkStrUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"

#include "tcuFloat.hpp"
#include "tcuFormatUtil.hpp"
#include "tcuMaybe.hpp"
#include "tcuResultCollector.hpp"
#include "tcuTestLog.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuVectorUtil.hpp"

#include "deRandom.hpp"
#include "deSTLUtil.hpp"
#include "deSharedPtr.hpp"
#include "deStringUtil.hpp"
#include "deUniquePtr.hpp"

#include <limits>
#include <set>
#include <string>
#include <vector>
#include <memory>

using namespace vk;

using tcu::BVec4;
using tcu::IVec2;
using tcu::IVec4;
using tcu::UVec2;
using tcu::UVec4;
using tcu::Vec2;
using tcu::Vec4;

using tcu::just;
using tcu::Maybe;

using tcu::ConstPixelBufferAccess;
using tcu::PixelBufferAccess;

using tcu::TestLog;

using de::UniquePtr;

using std::pair;
using std::set;
using std::string;
using std::vector;

namespace vkt
{
namespace
{
using namespace renderpass;

typedef vector<uint8_t> DepthValuesArray;

static const uint8_t DEPTH_VALUES[] = {0u, 255u, 1u};

enum AllocationKind
{
    ALLOCATION_KIND_SUBALLOCATED,
    ALLOCATION_KIND_DEDICATED,
};

struct TestConfigExternal
{
    TestConfigExternal(AllocationKind allocationKind_, RenderPassType renderPassType_)
        : allocationKind(allocationKind_)
        , renderPassType(renderPassType_)
    {
    }

    AllocationKind allocationKind;
    RenderPassType renderPassType;
};

de::MovePtr<Allocation> allocateBuffer(const InstanceInterface &vki, const DeviceInterface &vkd,
                                       const VkPhysicalDevice &physDevice, const VkDevice device,
                                       const VkBuffer &buffer, const MemoryRequirement requirement,
                                       Allocator &allocator, AllocationKind allocationKind)
{
    switch (allocationKind)
    {
    case ALLOCATION_KIND_SUBALLOCATED:
    {
        const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);

        return allocator.allocate(memoryRequirements, requirement);
    }

    case ALLOCATION_KIND_DEDICATED:
    {
        return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
    }

    default:
    {
        TCU_THROW(InternalError, "Invalid allocation kind");
    }
    }
}

de::MovePtr<Allocation> allocateImage(const InstanceInterface &vki, const DeviceInterface &vkd,
                                      const VkPhysicalDevice &physDevice, const VkDevice device, const VkImage &image,
                                      const MemoryRequirement requirement, Allocator &allocator,
                                      AllocationKind allocationKind)
{
    switch (allocationKind)
    {
    case ALLOCATION_KIND_SUBALLOCATED:
    {
        const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);

        return allocator.allocate(memoryRequirements, requirement);
    }

    case ALLOCATION_KIND_DEDICATED:
    {
        return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
    }

    default:
    {
        TCU_THROW(InternalError, "Invalid allocation kind");
    }
    }
}

enum BoolOp
{
    BOOLOP_AND,
    BOOLOP_OR,
    BOOLOP_EQ,
    BOOLOP_NEQ
};

const char *boolOpToString(BoolOp op)
{
    switch (op)
    {
    case BOOLOP_OR:
        return "||";

    case BOOLOP_AND:
        return "&&";

    case BOOLOP_EQ:
        return "==";

    case BOOLOP_NEQ:
        return "!=";

    default:
        DE_FATAL("Unknown boolean operation.");
        return DE_NULL;
    }
}

bool performBoolOp(BoolOp op, bool a, bool b)
{
    switch (op)
    {
    case BOOLOP_OR:
        return a || b;

    case BOOLOP_AND:
        return a && b;

    case BOOLOP_EQ:
        return a == b;

    case BOOLOP_NEQ:
        return a != b;

    default:
        DE_FATAL("Unknown boolean operation.");
        return false;
    }
}

BoolOp boolOpFromIndex(size_t index)
{
    const BoolOp ops[] = {BOOLOP_OR, BOOLOP_AND, BOOLOP_EQ, BOOLOP_NEQ};

    return ops[index % DE_LENGTH_OF_ARRAY(ops)];
}

static float requiredDepthEpsilon(VkFormat format)
{
    // Possible precision loss in the unorm depth pipeline means that we need to check depths
    // that go in and back out of the depth buffer with an epsilon rather than an exact match
    uint32_t unormBits = 0;

    switch (format)
    {
    case VK_FORMAT_D16_UNORM:
        unormBits = 16;
        break;
    case VK_FORMAT_X8_D24_UNORM_PACK32:
    case VK_FORMAT_D24_UNORM_S8_UINT:
        unormBits = 24;
        break;
    case VK_FORMAT_D32_SFLOAT:
    case VK_FORMAT_D32_SFLOAT_S8_UINT:
    default:
        unormBits = 0;
        break;
    }

    if (unormBits > 0)
        return 1.0f / (float)((1 << unormBits) - 1);

    return 0.0f; // Require exact match
}

static bool depthsEqual(float a, float b, float epsilon)
{
    return fabs(a - b) <= epsilon;
}

Move<VkFramebuffer> createFramebuffer(const DeviceInterface &vk, VkDevice device,
                                      VkFramebufferCreateFlags pCreateInfo_flags, VkRenderPass pCreateInfo_renderPass,
                                      uint32_t pCreateInfo_attachmentCount, const VkImageView *pCreateInfo_pAttachments,
                                      uint32_t pCreateInfo_width, uint32_t pCreateInfo_height,
                                      uint32_t pCreateInfo_layers)
{
    const VkFramebufferCreateInfo pCreateInfo = {
        VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
        DE_NULL,
        pCreateInfo_flags,
        pCreateInfo_renderPass,
        pCreateInfo_attachmentCount,
        pCreateInfo_pAttachments,
        pCreateInfo_width,
        pCreateInfo_height,
        pCreateInfo_layers,
    };
    return createFramebuffer(vk, device, &pCreateInfo);
}

Move<VkImage> createImage(const DeviceInterface &vk, VkDevice device, VkImageCreateFlags pCreateInfo_flags,
                          VkImageType pCreateInfo_imageType, VkFormat pCreateInfo_format, VkExtent3D pCreateInfo_extent,
                          uint32_t pCreateInfo_mipLevels, uint32_t pCreateInfo_arrayLayers,
                          VkSampleCountFlagBits pCreateInfo_samples, VkImageTiling pCreateInfo_tiling,
                          VkImageUsageFlags pCreateInfo_usage, VkSharingMode pCreateInfo_sharingMode,
                          uint32_t pCreateInfo_queueFamilyCount, const uint32_t *pCreateInfo_pQueueFamilyIndices,
                          VkImageLayout pCreateInfo_initialLayout)
{
    const VkImageCreateInfo pCreateInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
                                           DE_NULL,
                                           pCreateInfo_flags,
                                           pCreateInfo_imageType,
                                           pCreateInfo_format,
                                           pCreateInfo_extent,
                                           pCreateInfo_mipLevels,
                                           pCreateInfo_arrayLayers,
                                           pCreateInfo_samples,
                                           pCreateInfo_tiling,
                                           pCreateInfo_usage,
                                           pCreateInfo_sharingMode,
                                           pCreateInfo_queueFamilyCount,
                                           pCreateInfo_pQueueFamilyIndices,
                                           pCreateInfo_initialLayout};
    return createImage(vk, device, &pCreateInfo);
}

void bindBufferMemory(const DeviceInterface &vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem,
                      VkDeviceSize memOffset)
{
    VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset));
}

void bindImageMemory(const DeviceInterface &vk, VkDevice device, VkImage image, VkDeviceMemory mem,
                     VkDeviceSize memOffset)
{
    VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset));
}

Move<VkImageView> createImageView(const DeviceInterface &vk, VkDevice device, VkImageViewCreateFlags pCreateInfo_flags,
                                  VkImage pCreateInfo_image, VkImageViewType pCreateInfo_viewType,
                                  VkFormat pCreateInfo_format, VkComponentMapping pCreateInfo_components,
                                  VkImageSubresourceRange pCreateInfo_subresourceRange)
{
    const VkImageViewCreateInfo pCreateInfo = {
        VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
        DE_NULL,
        pCreateInfo_flags,
        pCreateInfo_image,
        pCreateInfo_viewType,
        pCreateInfo_format,
        pCreateInfo_components,
        pCreateInfo_subresourceRange,
    };
    return createImageView(vk, device, &pCreateInfo);
}

Move<VkBuffer> createBuffer(const DeviceInterface &vk, VkDevice device, VkBufferCreateFlags pCreateInfo_flags,
                            VkDeviceSize pCreateInfo_size, VkBufferUsageFlags pCreateInfo_usage,
                            VkSharingMode pCreateInfo_sharingMode, uint32_t pCreateInfo_queueFamilyCount,
                            const uint32_t *pCreateInfo_pQueueFamilyIndices)
{
    const VkBufferCreateInfo pCreateInfo = {
        VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
        DE_NULL,
        pCreateInfo_flags,
        pCreateInfo_size,
        pCreateInfo_usage,
        pCreateInfo_sharingMode,
        pCreateInfo_queueFamilyCount,
        pCreateInfo_pQueueFamilyIndices,
    };
    return createBuffer(vk, device, &pCreateInfo);
}

VkRenderPassBeginInfo createRenderPassBeginInfo(VkRenderPass pRenderPassBegin_renderPass,
                                                VkFramebuffer pRenderPassBegin_framebuffer,
                                                VkRect2D pRenderPassBegin_renderArea,
                                                uint32_t pRenderPassBegin_clearValueCount,
                                                const VkClearValue *pRenderPassBegin_pAttachmentClearValues)
{
    const VkRenderPassBeginInfo renderPassBeginInfo = {
        VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
        DE_NULL,
        pRenderPassBegin_renderPass,
        pRenderPassBegin_framebuffer,
        pRenderPassBegin_renderArea,
        pRenderPassBegin_clearValueCount,
        pRenderPassBegin_pAttachmentClearValues,
    };

    return renderPassBeginInfo;
}

void beginCommandBuffer(const DeviceInterface &vk, VkCommandBuffer cmdBuffer,
                        VkCommandBufferUsageFlags pBeginInfo_flags, VkRenderPass pInheritanceInfo_renderPass,
                        uint32_t pInheritanceInfo_subpass, VkFramebuffer pInheritanceInfo_framebuffer,
                        VkBool32 pInheritanceInfo_occlusionQueryEnable, VkQueryControlFlags pInheritanceInfo_queryFlags,
                        VkQueryPipelineStatisticFlags pInheritanceInfo_pipelineStatistics)
{
    const VkCommandBufferInheritanceInfo pInheritanceInfo = {
        VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
        DE_NULL,
        pInheritanceInfo_renderPass,
        pInheritanceInfo_subpass,
        pInheritanceInfo_framebuffer,
        pInheritanceInfo_occlusionQueryEnable,
        pInheritanceInfo_queryFlags,
        pInheritanceInfo_pipelineStatistics,
    };
    const VkCommandBufferBeginInfo pBeginInfo = {
        VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
        DE_NULL,
        pBeginInfo_flags,
        &pInheritanceInfo,
    };
    VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &pBeginInfo));
}

void queueSubmit(const DeviceInterface &vk, VkQueue queue, uint32_t cmdBufferCount, const VkCommandBuffer *pCmdBuffers,
                 VkFence fence)
{
    const VkSubmitInfo submitInfo = {
        VK_STRUCTURE_TYPE_SUBMIT_INFO,
        DE_NULL,
        0u,                           // waitSemaphoreCount
        (const VkSemaphore *)DE_NULL, // pWaitSemaphores
        (const VkPipelineStageFlags *)DE_NULL,
        cmdBufferCount, // commandBufferCount
        pCmdBuffers,
        0u,                           // signalSemaphoreCount
        (const VkSemaphore *)DE_NULL, // pSignalSemaphores
    };
    VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence));
}

void waitForFences(const DeviceInterface &vk, VkDevice device, uint32_t fenceCount, const VkFence *pFences,
                   VkBool32 waitAll, uint64_t timeout)
{
    VK_CHECK(vk.waitForFences(device, fenceCount, pFences, waitAll, timeout));
}

VkImageAspectFlags getImageAspectFlags(VkFormat vkFormat)
{
    const tcu::TextureFormat format = mapVkFormat(vkFormat);

    DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 22);

    switch (format.order)
    {
    case tcu::TextureFormat::DS:
        return VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;

    case tcu::TextureFormat::D:
        return VK_IMAGE_ASPECT_DEPTH_BIT;

    case tcu::TextureFormat::S:
        return VK_IMAGE_ASPECT_STENCIL_BIT;

    default:
        return VK_IMAGE_ASPECT_COLOR_BIT;
    }
}

VkAccessFlags getAllMemoryReadFlags(void)
{
    return VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_UNIFORM_READ_BIT | VK_ACCESS_HOST_READ_BIT |
           VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT |
           VK_ACCESS_INDIRECT_COMMAND_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
           VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
}

VkAccessFlags getAllMemoryWriteFlags(void)
{
    return VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_SHADER_WRITE_BIT |
           VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
}

VkAccessFlags getMemoryFlagsForLayout(const VkImageLayout layout)
{
    switch (layout)
    {
    case VK_IMAGE_LAYOUT_GENERAL:
        return getAllMemoryReadFlags() | getAllMemoryWriteFlags();
    case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
        return VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
    case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
        return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
    case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
        return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
    case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
        return VK_ACCESS_SHADER_READ_BIT;
    case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
        return VK_ACCESS_TRANSFER_READ_BIT;
    case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
        return VK_ACCESS_TRANSFER_WRITE_BIT;
    case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:
        return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
               VK_ACCESS_SHADER_READ_BIT;
    case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:
        return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
               VK_ACCESS_SHADER_READ_BIT;
    default:
        return (VkAccessFlags)0;
    }
}

VkPipelineStageFlags getAllPipelineStageFlags(void)
{
    /* All relevant flags for a pipeline containing VS+PS. */
    return VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT |
           VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
           VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
           VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
           VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_HOST_BIT;
}

class AttachmentReference
{
public:
    AttachmentReference(uint32_t attachment, VkImageLayout layout,
                        VkImageAspectFlags aspectMask = static_cast<VkImageAspectFlags>(0u))
        : m_attachment(attachment)
        , m_layout(layout)
        , m_aspectMask(aspectMask)
    {
    }

    uint32_t getAttachment(void) const
    {
        return m_attachment;
    }
    VkImageLayout getImageLayout(void) const
    {
        return m_layout;
    }
    VkImageAspectFlags getAspectMask(void) const
    {
        return m_aspectMask;
    }
    void setImageLayout(VkImageLayout layout)
    {
        m_layout = layout;
    }

private:
    uint32_t m_attachment;
    VkImageLayout m_layout;
    VkImageAspectFlags m_aspectMask;
};

class Subpass
{
public:
    Subpass(VkPipelineBindPoint pipelineBindPoint, VkSubpassDescriptionFlags flags,
            const vector<AttachmentReference> &inputAttachments, const vector<AttachmentReference> &colorAttachments,
            const vector<AttachmentReference> &resolveAttachments, AttachmentReference depthStencilAttachment,
            const vector<uint32_t> &preserveAttachments, bool omitBlendState = false)
        : m_pipelineBindPoint(pipelineBindPoint)
        , m_flags(flags)
        , m_inputAttachments(inputAttachments)
        , m_colorAttachments(colorAttachments)
        , m_resolveAttachments(resolveAttachments)
        , m_depthStencilAttachment(depthStencilAttachment)
        , m_preserveAttachments(preserveAttachments)
        , m_omitBlendState(omitBlendState)
    {
    }

    VkPipelineBindPoint getPipelineBindPoint(void) const
    {
        return m_pipelineBindPoint;
    }
    VkSubpassDescriptionFlags getFlags(void) const
    {
        return m_flags;
    }
    const vector<AttachmentReference> &getInputAttachments(void) const
    {
        return m_inputAttachments;
    }
    const vector<AttachmentReference> &getColorAttachments(void) const
    {
        return m_colorAttachments;
    }
    const vector<AttachmentReference> &getResolveAttachments(void) const
    {
        return m_resolveAttachments;
    }
    const AttachmentReference &getDepthStencilAttachment(void) const
    {
        return m_depthStencilAttachment;
    }
    const vector<uint32_t> &getPreserveAttachments(void) const
    {
        return m_preserveAttachments;
    }
    bool getOmitBlendState(void) const
    {
        return m_omitBlendState;
    }

private:
    VkPipelineBindPoint m_pipelineBindPoint;
    VkSubpassDescriptionFlags m_flags;

    vector<AttachmentReference> m_inputAttachments;
    vector<AttachmentReference> m_colorAttachments;
    vector<AttachmentReference> m_resolveAttachments;
    AttachmentReference m_depthStencilAttachment;

    vector<uint32_t> m_preserveAttachments;
    bool m_omitBlendState;
};

class SubpassDependency
{
public:
    SubpassDependency(uint32_t srcPass, uint32_t dstPass,

                      VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,

                      VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask,

                      VkDependencyFlags flags)
        : m_srcPass(srcPass)
        , m_dstPass(dstPass)

        , m_srcStageMask(srcStageMask)
        , m_dstStageMask(dstStageMask)

        , m_srcAccessMask(srcAccessMask)
        , m_dstAccessMask(dstAccessMask)
        , m_flags(flags)
    {
    }

    uint32_t getSrcPass(void) const
    {
        return m_srcPass;
    }
    uint32_t getDstPass(void) const
    {
        return m_dstPass;
    }

    VkPipelineStageFlags getSrcStageMask(void) const
    {
        return m_srcStageMask;
    }
    VkPipelineStageFlags getDstStageMask(void) const
    {
        return m_dstStageMask;
    }

    VkAccessFlags getSrcAccessMask(void) const
    {
        return m_srcAccessMask;
    }
    VkAccessFlags getDstAccessMask(void) const
    {
        return m_dstAccessMask;
    }

    VkDependencyFlags getFlags(void) const
    {
        return m_flags;
    }

    void setSrcAccessMask(const VkAccessFlags &flags)
    {
        m_srcAccessMask = flags;
    }
    void setDstAccessMask(const VkAccessFlags &flags)
    {
        m_dstAccessMask = flags;
    }

private:
    uint32_t m_srcPass;
    uint32_t m_dstPass;

    VkPipelineStageFlags m_srcStageMask;
    VkPipelineStageFlags m_dstStageMask;

    VkAccessFlags m_srcAccessMask;
    VkAccessFlags m_dstAccessMask;
    VkDependencyFlags m_flags;
};

class Attachment
{
public:
    Attachment(VkFormat format, VkSampleCountFlagBits samples,

               VkAttachmentLoadOp loadOp, VkAttachmentStoreOp storeOp,

               VkAttachmentLoadOp stencilLoadOp, VkAttachmentStoreOp stencilStoreOp,

               VkImageLayout initialLayout, VkImageLayout finalLayout)
        : m_format(format)
        , m_samples(samples)

        , m_loadOp(loadOp)
        , m_storeOp(storeOp)

        , m_stencilLoadOp(stencilLoadOp)
        , m_stencilStoreOp(stencilStoreOp)

        , m_initialLayout(initialLayout)
        , m_finalLayout(finalLayout)
    {
    }

    VkFormat getFormat(void) const
    {
        return m_format;
    }
    VkSampleCountFlagBits getSamples(void) const
    {
        return m_samples;
    }

    VkAttachmentLoadOp getLoadOp(void) const
    {
        return m_loadOp;
    }
    VkAttachmentStoreOp getStoreOp(void) const
    {
        return m_storeOp;
    }

    VkAttachmentLoadOp getStencilLoadOp(void) const
    {
        return m_stencilLoadOp;
    }
    VkAttachmentStoreOp getStencilStoreOp(void) const
    {
        return m_stencilStoreOp;
    }

    VkImageLayout getInitialLayout(void) const
    {
        return m_initialLayout;
    }
    VkImageLayout getFinalLayout(void) const
    {
        return m_finalLayout;
    }

private:
    VkFormat m_format;
    VkSampleCountFlagBits m_samples;

    VkAttachmentLoadOp m_loadOp;
    VkAttachmentStoreOp m_storeOp;

    VkAttachmentLoadOp m_stencilLoadOp;
    VkAttachmentStoreOp m_stencilStoreOp;

    VkImageLayout m_initialLayout;
    VkImageLayout m_finalLayout;
};

class RenderPass
{
public:
    RenderPass(const vector<Attachment> &attachments, const vector<Subpass> &subpasses,
               const vector<SubpassDependency> &dependencies,
               const vector<VkInputAttachmentAspectReference> inputAspects = vector<VkInputAttachmentAspectReference>())
        : m_attachments(attachments)
        , m_subpasses(subpasses)
        , m_dependencies(dependencies)
        , m_inputAspects(inputAspects)
    {
    }

    const vector<Attachment> &getAttachments(void) const
    {
        return m_attachments;
    }
    const vector<Subpass> &getSubpasses(void) const
    {
        return m_subpasses;
    }
    const vector<SubpassDependency> &getDependencies(void) const
    {
        return m_dependencies;
    }
    const vector<VkInputAttachmentAspectReference> &getInputAspects(void) const
    {
        return m_inputAspects;
    }

private:
    const vector<Attachment> m_attachments;
    const vector<Subpass> m_subpasses;
    const vector<SubpassDependency> m_dependencies;
    const vector<VkInputAttachmentAspectReference> m_inputAspects;
};

struct TestConfig
{
    enum RenderTypes
    {
        RENDERTYPES_NONE  = 0,
        RENDERTYPES_CLEAR = (1 << 1),
        RENDERTYPES_DRAW  = (1 << 2)
    };

    enum CommandBufferTypes
    {
        COMMANDBUFFERTYPES_INLINE    = (1 << 0),
        COMMANDBUFFERTYPES_SECONDARY = (1 << 1)
    };

    enum ImageMemory
    {
        IMAGEMEMORY_STRICT = (1 << 0),
        IMAGEMEMORY_LAZY   = (1 << 1)
    };

    TestConfig(const RenderPass &renderPass_, RenderTypes renderTypes_, CommandBufferTypes commandBufferTypes_,
               ImageMemory imageMemory_, const UVec2 &targetSize_, const UVec2 &renderPos_, const UVec2 &renderSize_,
               bool useFormatCompCount_, uint32_t seed_, uint32_t drawStartNdx_, AllocationKind allocationKind_,
               RenderPassType renderPassType_,
               vector<DeviceCoreFeature> requiredFeatures_ = vector<DeviceCoreFeature>())
        : renderPass(renderPass_)
        , renderTypes(renderTypes_)
        , commandBufferTypes(commandBufferTypes_)
        , imageMemory(imageMemory_)
        , targetSize(targetSize_)
        , renderPos(renderPos_)
        , renderSize(renderSize_)
        , useFormatCompCount(useFormatCompCount_)
        , seed(seed_)
        , drawStartNdx(drawStartNdx_)
        , allocationKind(allocationKind_)
        , renderPassType(renderPassType_)
        , requiredFeatures(requiredFeatures_)
    {
        DepthValuesArray shuffledDepthValues(&DEPTH_VALUES[0], &DEPTH_VALUES[DE_LENGTH_OF_ARRAY(DEPTH_VALUES)]);
        de::Random rng(seed + 1);

        rng.shuffle(shuffledDepthValues.begin(), shuffledDepthValues.end());

        depthValues.push_back(shuffledDepthValues[0]);
        depthValues.push_back(shuffledDepthValues[1]);
    }

    RenderPass renderPass;
    RenderTypes renderTypes;
    CommandBufferTypes commandBufferTypes;
    ImageMemory imageMemory;
    UVec2 targetSize;
    UVec2 renderPos;
    UVec2 renderSize;
    bool useFormatCompCount;
    uint32_t seed;
    uint32_t drawStartNdx;
    AllocationKind allocationKind;
    RenderPassType renderPassType;
    vector<DeviceCoreFeature> requiredFeatures;
    DepthValuesArray depthValues;
};

TestConfig::RenderTypes operator|(TestConfig::RenderTypes a, TestConfig::RenderTypes b)
{
    return (TestConfig::RenderTypes)(((uint32_t)a) | ((uint32_t)b));
}

TestConfig::CommandBufferTypes operator|(TestConfig::CommandBufferTypes a, TestConfig::CommandBufferTypes b)
{
    return (TestConfig::CommandBufferTypes)(((uint32_t)a) | ((uint32_t)b));
}

TestConfig::ImageMemory operator|(TestConfig::ImageMemory a, TestConfig::ImageMemory b)
{
    return (TestConfig::ImageMemory)(((uint32_t)a) | ((uint32_t)b));
}

void checkSupport(Context &context, TestConfig config)
{
    for (size_t featureNdx = 0; featureNdx < config.requiredFeatures.size(); featureNdx++)
        context.requireDeviceCoreFeature(config.requiredFeatures[featureNdx]);
}

void logRenderPassInfo(TestLog &log, const RenderPass &renderPass)
{
    const bool useExternalInputAspect = !renderPass.getInputAspects().empty();
    const tcu::ScopedLogSection section(log, "RenderPass", "RenderPass");

    {
        const tcu::ScopedLogSection attachmentsSection(log, "Attachments", "Attachments");
        const vector<Attachment> &attachments = renderPass.getAttachments();

        for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
        {
            const tcu::ScopedLogSection attachmentSection(log, "Attachment" + de::toString(attachmentNdx),
                                                          "Attachment " + de::toString(attachmentNdx));
            const Attachment &attachment = attachments[attachmentNdx];

            log << TestLog::Message << "Format: " << attachment.getFormat() << TestLog::EndMessage;
            log << TestLog::Message << "Samples: " << attachment.getSamples() << TestLog::EndMessage;

            log << TestLog::Message << "LoadOp: " << attachment.getLoadOp() << TestLog::EndMessage;
            log << TestLog::Message << "StoreOp: " << attachment.getStoreOp() << TestLog::EndMessage;

            log << TestLog::Message << "StencilLoadOp: " << attachment.getStencilLoadOp() << TestLog::EndMessage;
            log << TestLog::Message << "StencilStoreOp: " << attachment.getStencilStoreOp() << TestLog::EndMessage;

            log << TestLog::Message << "InitialLayout: " << attachment.getInitialLayout() << TestLog::EndMessage;
            log << TestLog::Message << "FinalLayout: " << attachment.getFinalLayout() << TestLog::EndMessage;
        }
    }

    if (useExternalInputAspect)
    {
        const tcu::ScopedLogSection inputAspectSection(log, "InputAspects", "InputAspects");

        for (size_t aspectNdx = 0; aspectNdx < renderPass.getInputAspects().size(); aspectNdx++)
        {
            const VkInputAttachmentAspectReference &inputAspect(renderPass.getInputAspects()[aspectNdx]);

            log << TestLog::Message << "Subpass: " << inputAspect.subpass << TestLog::EndMessage;
            log << TestLog::Message << "InputAttachmentIndex: " << inputAspect.inputAttachmentIndex
                << TestLog::EndMessage;
            log << TestLog::Message << "AspectFlags: " << getImageAspectFlagsStr(inputAspect.aspectMask)
                << TestLog::EndMessage;
        }
    }

    {
        const tcu::ScopedLogSection subpassesSection(log, "Subpasses", "Subpasses");
        const vector<Subpass> &subpasses = renderPass.getSubpasses();

        for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
        {
            const tcu::ScopedLogSection subpassSection(log, "Subpass" + de::toString(subpassNdx),
                                                       "Subpass " + de::toString(subpassNdx));
            const Subpass &subpass = subpasses[subpassNdx];

            const vector<AttachmentReference> &inputAttachments   = subpass.getInputAttachments();
            const vector<AttachmentReference> &colorAttachments   = subpass.getColorAttachments();
            const vector<AttachmentReference> &resolveAttachments = subpass.getResolveAttachments();
            const vector<uint32_t> &preserveAttachments           = subpass.getPreserveAttachments();

            if (!inputAttachments.empty())
            {
                const tcu::ScopedLogSection inputAttachmentsSection(log, "Inputs", "Inputs");

                for (size_t inputNdx = 0; inputNdx < inputAttachments.size(); inputNdx++)
                {
                    const tcu::ScopedLogSection inputAttachmentSection(log, "Input" + de::toString(inputNdx),
                                                                       "Input " + de::toString(inputNdx));
                    const AttachmentReference &inputAttachment = inputAttachments[inputNdx];

                    log << TestLog::Message << "Attachment: " << inputAttachment.getAttachment() << TestLog::EndMessage;
                    log << TestLog::Message << "Layout: " << inputAttachment.getImageLayout() << TestLog::EndMessage;
                    if (!useExternalInputAspect)
                        log << TestLog::Message << "AspectMask: " << inputAttachment.getAspectMask()
                            << TestLog::EndMessage;
                }
            }

            if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
            {
                const tcu::ScopedLogSection depthStencilAttachmentSection(log, "DepthStencil", "DepthStencil");
                const AttachmentReference &depthStencilAttachment = subpass.getDepthStencilAttachment();

                log << TestLog::Message << "Attachment: " << depthStencilAttachment.getAttachment()
                    << TestLog::EndMessage;
                log << TestLog::Message << "Layout: " << depthStencilAttachment.getImageLayout() << TestLog::EndMessage;
            }

            if (!colorAttachments.empty())
            {
                const tcu::ScopedLogSection colorAttachmentsSection(log, "Colors", "Colors");

                for (size_t colorNdx = 0; colorNdx < colorAttachments.size(); colorNdx++)
                {
                    const tcu::ScopedLogSection colorAttachmentSection(log, "Color" + de::toString(colorNdx),
                                                                       "Color " + de::toString(colorNdx));
                    const AttachmentReference &colorAttachment = colorAttachments[colorNdx];

                    log << TestLog::Message << "Attachment: " << colorAttachment.getAttachment() << TestLog::EndMessage;
                    log << TestLog::Message << "Layout: " << colorAttachment.getImageLayout() << TestLog::EndMessage;
                }
            }

            if (!resolveAttachments.empty())
            {
                const tcu::ScopedLogSection resolveAttachmentsSection(log, "Resolves", "Resolves");

                for (size_t resolveNdx = 0; resolveNdx < resolveAttachments.size(); resolveNdx++)
                {
                    const tcu::ScopedLogSection resolveAttachmentSection(log, "Resolve" + de::toString(resolveNdx),
                                                                         "Resolve " + de::toString(resolveNdx));
                    const AttachmentReference &resolveAttachment = resolveAttachments[resolveNdx];

                    log << TestLog::Message << "Attachment: " << resolveAttachment.getAttachment()
                        << TestLog::EndMessage;
                    log << TestLog::Message << "Layout: " << resolveAttachment.getImageLayout() << TestLog::EndMessage;
                }
            }

            if (!preserveAttachments.empty())
            {
                const tcu::ScopedLogSection preserveAttachmentsSection(log, "Preserves", "Preserves");

                for (size_t preserveNdx = 0; preserveNdx < preserveAttachments.size(); preserveNdx++)
                {
                    const tcu::ScopedLogSection preserveAttachmentSection(log, "Preserve" + de::toString(preserveNdx),
                                                                          "Preserve " + de::toString(preserveNdx));
                    const uint32_t preserveAttachment = preserveAttachments[preserveNdx];

                    log << TestLog::Message << "Attachment: " << preserveAttachment << TestLog::EndMessage;
                }
            }
        }
    }

    if (!renderPass.getDependencies().empty())
    {
        const tcu::ScopedLogSection dependenciesSection(log, "Dependencies", "Dependencies");

        for (size_t depNdx = 0; depNdx < renderPass.getDependencies().size(); depNdx++)
        {
            const tcu::ScopedLogSection dependencySection(log, "Dependency" + de::toString(depNdx),
                                                          "Dependency " + de::toString(depNdx));
            const SubpassDependency &dep = renderPass.getDependencies()[depNdx];

            log << TestLog::Message << "Source: " << dep.getSrcPass() << TestLog::EndMessage;
            log << TestLog::Message << "Destination: " << dep.getDstPass() << TestLog::EndMessage;

            log << TestLog::Message << "Source Stage Mask: " << dep.getSrcStageMask() << TestLog::EndMessage;
            log << TestLog::Message << "Destination Stage Mask: " << dep.getDstStageMask() << TestLog::EndMessage;

            log << TestLog::Message << "Input Mask: " << dep.getDstAccessMask() << TestLog::EndMessage;
            log << TestLog::Message << "Output Mask: " << dep.getSrcAccessMask() << TestLog::EndMessage;
            log << TestLog::Message << "Dependency Flags: " << getDependencyFlagsStr(dep.getFlags())
                << TestLog::EndMessage;
        }
    }
}

std::string clearColorToString(VkFormat vkFormat, VkClearColorValue value, bool useFormatCompCount)
{
    const tcu::TextureFormat format             = mapVkFormat(vkFormat);
    const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
    const tcu::BVec4 channelMask                = tcu::getTextureFormatChannelMask(format);
    const uint32_t componentCount = (useFormatCompCount ? (uint32_t)tcu::getNumUsedChannels(format.order) : 4);

    std::ostringstream stream;

    stream << "(";

    switch (channelClass)
    {
    case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
        for (uint32_t i = 0; i < componentCount; i++)
        {
            if (i > 0)
                stream << ", ";

            if (channelMask[i])
                stream << value.int32[i];
            else
                stream << "Undef";
        }
        break;

    case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
        for (uint32_t i = 0; i < componentCount; i++)
        {
            if (i > 0)
                stream << ", ";

            if (channelMask[i])
                stream << value.uint32[i];
            else
                stream << "Undef";
        }
        break;

    case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
    case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
    case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
        for (uint32_t i = 0; i < componentCount; i++)
        {
            if (i > 0)
                stream << ", ";

            if (channelMask[i])
                stream << value.float32[i];
            else
                stream << "Undef";
        }
        break;

    default:
        DE_FATAL("Unknown channel class");
    }

    stream << ")";

    return stream.str();
}

std::string clearValueToString(VkFormat vkFormat, VkClearValue value, bool useFormatCompCount)
{
    const tcu::TextureFormat format = mapVkFormat(vkFormat);

    if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
    {
        std::ostringstream stream;

        stream << "(";

        if (tcu::hasStencilComponent(format.order))
            stream << "stencil: " << value.depthStencil.stencil;

        if (tcu::hasStencilComponent(format.order) && tcu::hasDepthComponent(format.order))
            stream << ", ";

        if (tcu::hasDepthComponent(format.order))
            stream << "depth: " << value.depthStencil.depth;

        stream << ")";

        return stream.str();
    }
    else
        return clearColorToString(vkFormat, value.color, useFormatCompCount);
}

VkClearColorValue randomColorClearValue(const Attachment &attachment, de::Random &rng, bool useFormatCompCount)
{
    const float clearNan                        = tcu::Float32::nan().asFloat();
    const tcu::TextureFormat format             = mapVkFormat(attachment.getFormat());
    const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
    const tcu::BVec4 channelMask                = tcu::getTextureFormatChannelMask(format);
    const uint32_t componentCount = (useFormatCompCount ? (uint32_t)tcu::getNumUsedChannels(format.order) : 4);
    VkClearColorValue clearColor;

    switch (channelClass)
    {
    case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
    {
        for (uint32_t ndx = 0; ndx < componentCount; ndx++)
        {
            if (!channelMask[ndx])
                clearColor.int32[ndx] = std::numeric_limits<int32_t>::min();
            else
                clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u;
        }
        break;
    }

    case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
    {
        for (uint32_t ndx = 0; ndx < componentCount; ndx++)
        {
            if (!channelMask[ndx])
                clearColor.uint32[ndx] = std::numeric_limits<uint32_t>::max();
            else
                clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u;
        }
        break;
    }

    case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
    case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
    case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
    {
        for (uint32_t ndx = 0; ndx < componentCount; ndx++)
        {
            if (!channelMask[ndx])
                clearColor.float32[ndx] = clearNan;
            else
                clearColor.float32[ndx] = rng.getBool() ? 1.0f : 0.0f;
        }
        break;
    }

    default:
        DE_FATAL("Unknown channel class");
    }

    return clearColor;
}

template <typename AttachmentDesc>
AttachmentDesc createAttachmentDescription(const Attachment &attachment)
{
    const AttachmentDesc
        attachmentDescription //  VkAttachmentDescription                                        ||  VkAttachmentDescription2KHR
        (
            //  ||  VkStructureType sType;
            DE_NULL,                 //   ||  const void* pNext;
            0u,                      //  VkAttachmentDescriptionFlags flags; ||  VkAttachmentDescriptionFlags flags;
            attachment.getFormat(),  //  VkFormat format; ||  VkFormat format;
            attachment.getSamples(), //  VkSampleCountFlagBits samples; ||  VkSampleCountFlagBits samples;
            attachment.getLoadOp(),  //  VkAttachmentLoadOp loadOp; ||  VkAttachmentLoadOp loadOp;
            attachment.getStoreOp(), //  VkAttachmentStoreOp storeOp; ||  VkAttachmentStoreOp storeOp;
            attachment.getStencilLoadOp(), //  VkAttachmentLoadOp stencilLoadOp; ||  VkAttachmentLoadOp stencilLoadOp;
            attachment
                .getStencilStoreOp(), //  VkAttachmentStoreOp stencilStoreOp; ||  VkAttachmentStoreOp stencilStoreOp;
            attachment.getInitialLayout(), //  VkImageLayout initialLayout; ||  VkImageLayout initialLayout;
            attachment.getFinalLayout()    //  VkImageLayout finalLayout; ||  VkImageLayout finalLayout;
        );

    return attachmentDescription;
}

template <typename AttachmentRef>
AttachmentRef createAttachmentReference(const AttachmentReference &referenceInfo)
{
    const AttachmentRef
        reference //  VkAttachmentReference                                        ||  VkAttachmentReference2KHR
        (
            //  ||  VkStructureType sType;
            DE_NULL,                        //   ||  const void* pNext;
            referenceInfo.getAttachment(),  //  uint32_t attachment; ||  uint32_t attachment;
            referenceInfo.getImageLayout(), //  VkImageLayout layout; ||  VkImageLayout layout;
            referenceInfo.getAspectMask()   // ||  VkImageAspectFlags aspectMask;
        );

    return reference;
}

template <typename SubpassDesc, typename AttachmentRef>
SubpassDesc createSubpassDescription(const Subpass &subpass, vector<AttachmentRef> *attachmentReferenceLists,
                                     vector<uint32_t> *preserveAttachmentReferences)
{
    vector<AttachmentRef> &inputAttachmentReferences        = attachmentReferenceLists[0];
    vector<AttachmentRef> &colorAttachmentReferences        = attachmentReferenceLists[1];
    vector<AttachmentRef> &resolveAttachmentReferences      = attachmentReferenceLists[2];
    vector<AttachmentRef> &depthStencilAttachmentReferences = attachmentReferenceLists[3];

    for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
        colorAttachmentReferences.push_back(
            createAttachmentReference<AttachmentRef>(subpass.getColorAttachments()[attachmentNdx]));

    for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
        inputAttachmentReferences.push_back(
            createAttachmentReference<AttachmentRef>(subpass.getInputAttachments()[attachmentNdx]));

    for (size_t attachmentNdx = 0; attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
        resolveAttachmentReferences.push_back(
            createAttachmentReference<AttachmentRef>(subpass.getResolveAttachments()[attachmentNdx]));

    depthStencilAttachmentReferences.push_back(
        createAttachmentReference<AttachmentRef>(subpass.getDepthStencilAttachment()));

    for (size_t attachmentNdx = 0; attachmentNdx < subpass.getPreserveAttachments().size(); attachmentNdx++)
        preserveAttachmentReferences->push_back(subpass.getPreserveAttachments()[attachmentNdx]);

    DE_ASSERT(resolveAttachmentReferences.empty() ||
              colorAttachmentReferences.size() == resolveAttachmentReferences.size());

    {
        const SubpassDesc
            subpassDescription //  VkSubpassDescription                                        ||  VkSubpassDescription2KHR
            (
                //  ||  VkStructureType sType;
                DE_NULL,            //   ||  const void* pNext;
                subpass.getFlags(), //  VkSubpassDescriptionFlags flags; ||  VkSubpassDescriptionFlags flags;
                subpass
                    .getPipelineBindPoint(), //  VkPipelineBindPoint pipelineBindPoint; ||  VkPipelineBindPoint pipelineBindPoint;
                0u,                          //   ||  uint32_t viewMask;
                (uint32_t)inputAttachmentReferences
                    .size(), //  uint32_t inputAttachmentCount; ||  uint32_t inputAttachmentCount;
                inputAttachmentReferences.empty() ?
                    DE_NULL :
                    &inputAttachmentReferences
                        [0], //  const VkAttachmentReference* pInputAttachments; ||  const VkAttachmentReference2KHR* pInputAttachments;
                (uint32_t)colorAttachmentReferences
                    .size(), //  uint32_t colorAttachmentCount; ||  uint32_t colorAttachmentCount;
                colorAttachmentReferences.empty() ?
                    DE_NULL :
                    &colorAttachmentReferences
                        [0], //  const VkAttachmentReference* pColorAttachments; ||  const VkAttachmentReference2KHR* pColorAttachments;
                resolveAttachmentReferences.empty() ?
                    DE_NULL :
                    &resolveAttachmentReferences
                        [0], //  const VkAttachmentReference* pResolveAttachments; ||  const VkAttachmentReference2KHR* pResolveAttachments;
                &depthStencilAttachmentReferences
                    [0], //  const VkAttachmentReference* pDepthStencilAttachment; ||  const VkAttachmentReference2KHR* pDepthStencilAttachment;
                (uint32_t)preserveAttachmentReferences
                    ->size(), //  uint32_t preserveAttachmentCount; ||  uint32_t preserveAttachmentCount;
                preserveAttachmentReferences->empty() ?
                    DE_NULL :
                    &(*preserveAttachmentReferences)
                        [0] //  const uint32_t* pPreserveAttachments; ||  const uint32_t* pPreserveAttachments;
            );

        return subpassDescription;
    }
}

template <typename SubpassDep>
SubpassDep createSubpassDependency(const SubpassDependency &dependencyInfo)
{
    const SubpassDep
        dependency //  VkSubpassDependency                                            ||  VkSubpassDependency2KHR
        (
            //  || VkStructureType sType;
            DE_NULL,                     //   || const void* pNext;
            dependencyInfo.getSrcPass(), //  uint32_t srcSubpass; || uint32_t srcSubpass;
            dependencyInfo.getDstPass(), //  uint32_t dstSubpass; || uint32_t dstSubpass;
            dependencyInfo
                .getSrcStageMask(), //  VkPipelineStageFlags srcStageMask; || VkPipelineStageFlags srcStageMask;
            dependencyInfo
                .getDstStageMask(), //  VkPipelineStageFlags dstStageMask; || VkPipelineStageFlags dstStageMask;
            dependencyInfo.getSrcAccessMask(), //  VkAccessFlags srcAccessMask; || VkAccessFlags srcAccessMask;
            dependencyInfo.getDstAccessMask(), //  VkAccessFlags dstAccessMask; || VkAccessFlags dstAccessMask;
            dependencyInfo.getFlags(), //  VkDependencyFlags dependencyFlags; || VkDependencyFlags dependencyFlags;
            0u                         //    || int32_t viewOffset;
        );

    return dependency;
}

de::MovePtr<VkRenderPassInputAttachmentAspectCreateInfo> createRenderPassInputAttachmentAspectCreateInfo(
    const RenderPass &renderPassInfo)
{
    de::MovePtr<VkRenderPassInputAttachmentAspectCreateInfo> result(DE_NULL);

    if (!renderPassInfo.getInputAspects().empty())
    {
        const VkRenderPassInputAttachmentAspectCreateInfo inputAspectCreateInfo = {
            VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO,
            DE_NULL,

            (uint32_t)renderPassInfo.getInputAspects().size(),
            renderPassInfo.getInputAspects().data(),
        };

        result = de::MovePtr<VkRenderPassInputAttachmentAspectCreateInfo>(
            new VkRenderPassInputAttachmentAspectCreateInfo(inputAspectCreateInfo));
    }

    return result;
}

template <typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep,
          typename RenderPassCreateInfo>
Move<VkRenderPass> createRenderPass(const DeviceInterface &vk, VkDevice device, const RenderPass &renderPassInfo)
{
    const size_t perSubpassAttachmentReferenceLists = 4;
    vector<AttachmentDesc> attachments;
    vector<SubpassDesc> subpasses;
    vector<SubpassDep> dependencies;
    vector<vector<AttachmentRef>> attachmentReferenceLists(renderPassInfo.getSubpasses().size() *
                                                           perSubpassAttachmentReferenceLists);
    vector<vector<uint32_t>> preserveAttachments(renderPassInfo.getSubpasses().size());
    de::MovePtr<VkRenderPassInputAttachmentAspectCreateInfo> inputAspectCreateInfo(
        createRenderPassInputAttachmentAspectCreateInfo(renderPassInfo));

    for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
        attachments.push_back(
            createAttachmentDescription<AttachmentDesc>(renderPassInfo.getAttachments()[attachmentNdx]));

    for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
        subpasses.push_back(createSubpassDescription<SubpassDesc>(
            renderPassInfo.getSubpasses()[subpassNdx],
            &(attachmentReferenceLists[subpassNdx * perSubpassAttachmentReferenceLists]),
            &preserveAttachments[subpassNdx]));

    for (size_t depNdx = 0; depNdx < renderPassInfo.getDependencies().size(); depNdx++)
        dependencies.push_back(createSubpassDependency<SubpassDep>(renderPassInfo.getDependencies()[depNdx]));

    const RenderPassCreateInfo
        renderPassCreator //  VkRenderPassCreateInfo                                        ||  VkRenderPassCreateInfo2KHR
        (
            //  VkStructureType sType; ||  VkStructureType sType;
            inputAspectCreateInfo.get(),  //  const void* pNext; ||  const void* pNext;
            (VkRenderPassCreateFlags)0u,  //  VkRenderPassCreateFlags flags; ||  VkRenderPassCreateFlags flags;
            (uint32_t)attachments.size(), //  uint32_t attachmentCount; ||  uint32_t attachmentCount;
            (attachments.empty() ?
                 DE_NULL :
                 &attachments
                     [0]), //  const VkAttachmentDescription* pAttachments; ||  const VkAttachmentDescription2KHR* pAttachments;
            (uint32_t)subpasses.size(), //  uint32_t subpassCount; ||  uint32_t subpassCount;
            (subpasses.empty() ?
                 DE_NULL :
                 &subpasses
                     [0]), //  const VkSubpassDescription* pSubpasses; ||  const VkSubpassDescription2KHR* pSubpasses;
            (uint32_t)dependencies.size(), //  uint32_t dependencyCount; ||  uint32_t dependencyCount;
            (dependencies.empty() ?
                 DE_NULL :
                 &dependencies
                     [0]), //  const VkSubpassDependency* pDependencies; ||  const VkSubpassDependency2KHR* pDependencies;
            0u,            //   ||  uint32_t correlatedViewMaskCount;
            DE_NULL        //  ||  const uint32_t* pCorrelatedViewMasks;
        );

    return renderPassCreator.createRenderPass(vk, device);
}

Move<VkRenderPass> createRenderPass(const DeviceInterface &vk, VkDevice device, const RenderPass &renderPassInfo,
                                    const RenderPassType renderPassType)
{
    switch (renderPassType)
    {
    case RENDERPASS_TYPE_LEGACY:
        return createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1,
                                RenderPassCreateInfo1>(vk, device, renderPassInfo);
    case RENDERPASS_TYPE_RENDERPASS2:
        return createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2,
                                RenderPassCreateInfo2>(vk, device, renderPassInfo);
    default:
        TCU_THROW(InternalError, "Impossible");
    }
}

Move<VkFramebuffer> createFramebuffer(const DeviceInterface &vk, VkDevice device, VkRenderPass renderPass,
                                      const UVec2 &size, const vector<VkImageView> &attachments)
{
    return createFramebuffer(vk, device, 0u, renderPass, (uint32_t)attachments.size(),
                             attachments.empty() ? DE_NULL : &attachments[0], size.x(), size.y(), 1u);
}

Move<VkImage> createAttachmentImage(const DeviceInterface &vk, VkDevice device, uint32_t queueIndex, const UVec2 &size,
                                    VkFormat format, VkSampleCountFlagBits samples, VkImageUsageFlags usageFlags,
                                    VkImageLayout layout)
{
    VkImageUsageFlags targetUsageFlags     = 0;
    const tcu::TextureFormat textureFormat = mapVkFormat(format);

    DE_ASSERT(!(tcu::hasDepthComponent(vk::mapVkFormat(format).order) ||
                tcu::hasStencilComponent(vk::mapVkFormat(format).order)) ||
              ((usageFlags & vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) == 0));

    DE_ASSERT((tcu::hasDepthComponent(vk::mapVkFormat(format).order) ||
               tcu::hasStencilComponent(vk::mapVkFormat(format).order)) ||
              ((usageFlags & vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0));

    if (tcu::hasDepthComponent(textureFormat.order) || tcu::hasStencilComponent(textureFormat.order))
        targetUsageFlags |= vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
    else
        targetUsageFlags |= vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;

    return createImage(vk, device, (VkImageCreateFlags)0, VK_IMAGE_TYPE_2D, format,
                       vk::makeExtent3D(size.x(), size.y(), 1u), 1u /* mipLevels */, 1u /* arraySize */, samples,
                       VK_IMAGE_TILING_OPTIMAL, usageFlags | targetUsageFlags, VK_SHARING_MODE_EXCLUSIVE, 1,
                       &queueIndex, layout);
}

de::MovePtr<Allocation> createImageMemory(const InstanceInterface &vki, const VkPhysicalDevice &vkd,
                                          const DeviceInterface &vk, VkDevice device, Allocator &allocator,
                                          VkImage image, bool lazy, AllocationKind allocationKind)
{
    const MemoryRequirement memoryRequirement = lazy ? MemoryRequirement::LazilyAllocated : MemoryRequirement::Any;
    de::MovePtr<Allocation> allocation =
        allocateImage(vki, vk, vkd, device, image, memoryRequirement, allocator, allocationKind);

    bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());

    return allocation;
}

Move<VkImageView> createImageAttachmentView(const DeviceInterface &vk, VkDevice device, VkImage image, VkFormat format,
                                            VkImageAspectFlags aspect)
{
    const VkImageSubresourceRange range = {aspect, 0, 1, 0, 1};

    return createImageView(vk, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
}

VkClearValue randomClearValue(const Attachment &attachment, de::Random &rng, bool useFormatCompCount,
                              const DepthValuesArray &depthValues)
{
    const float clearNan            = tcu::Float32::nan().asFloat();
    const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());

    if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
    {
        VkClearValue clearValue;

        clearValue.depthStencil.depth   = clearNan;
        clearValue.depthStencil.stencil = 0xCDu;

        if (tcu::hasStencilComponent(format.order))
            clearValue.depthStencil.stencil = rng.getBool() ? 0xFFu : 0x0u;

        if (tcu::hasDepthComponent(format.order))
            clearValue.depthStencil.depth = float(depthValues[rng.getBool() ? 1 : 0]) / 255.0f;

        return clearValue;
    }
    else
    {
        VkClearValue clearValue;

        clearValue.color = randomColorClearValue(attachment, rng, useFormatCompCount);

        return clearValue;
    }
}

class AttachmentResources
{
public:
    AttachmentResources(const InstanceInterface &vki, const VkPhysicalDevice &physDevice, const DeviceInterface &vk,
                        VkDevice device, Allocator &allocator, uint32_t queueIndex, const UVec2 &size,
                        const Attachment &attachmentInfo, VkImageUsageFlags usageFlags,
                        const AllocationKind allocationKind)
        : m_image(createAttachmentImage(vk, device, queueIndex, size, attachmentInfo.getFormat(),
                                        attachmentInfo.getSamples(), usageFlags, VK_IMAGE_LAYOUT_UNDEFINED))
        , m_imageMemory(createImageMemory(vki, physDevice, vk, device, allocator, *m_image,
                                          ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0),
                                          allocationKind))
        , m_attachmentView(createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(),
                                                     getImageAspectFlags(attachmentInfo.getFormat())))
    {
        const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
        const bool isDepthFormat        = tcu::hasDepthComponent(format.order);
        const bool isStencilFormat      = tcu::hasStencilComponent(format.order);

        if (isDepthFormat && isStencilFormat)
        {
            m_depthInputAttachmentView =
                createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), VK_IMAGE_ASPECT_DEPTH_BIT);
            m_stencilInputAttachmentView = createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(),
                                                                     VK_IMAGE_ASPECT_STENCIL_BIT);

            m_inputAttachmentViews = std::make_pair(*m_depthInputAttachmentView, *m_stencilInputAttachmentView);
        }
        else
            m_inputAttachmentViews = std::make_pair(*m_attachmentView, (vk::VkImageView)0u);

        if ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) == 0)
        {
            if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
            {
                const tcu::TextureFormat depthFormat   = getDepthCopyFormat(attachmentInfo.getFormat());
                const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachmentInfo.getFormat());

                m_bufferSize          = size.x() * size.y() * depthFormat.getPixelSize();
                m_secondaryBufferSize = size.x() * size.y() * stencilFormat.getPixelSize();

                m_buffer       = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT,
                                              VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
                m_bufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_buffer, MemoryRequirement::HostVisible,
                                                allocator, allocationKind);

                bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());

                m_secondaryBuffer = createBuffer(vk, device, 0, m_secondaryBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT,
                                                 VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
                m_secondaryBufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_secondaryBuffer,
                                                         MemoryRequirement::HostVisible, allocator, allocationKind);

                bindBufferMemory(vk, device, *m_secondaryBuffer, m_secondaryBufferMemory->getMemory(),
                                 m_secondaryBufferMemory->getOffset());
            }
            else
            {
                m_bufferSize = size.x() * size.y() * format.getPixelSize();

                m_buffer       = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT,
                                              VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
                m_bufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_buffer, MemoryRequirement::HostVisible,
                                                allocator, allocationKind);

                bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
            }
        }
    }

    const pair<VkImageView, VkImageView> &getInputAttachmentViews(void) const
    {
        return m_inputAttachmentViews;
    }

    ~AttachmentResources(void)
    {
    }

    VkImageView getAttachmentView(void) const
    {
        return *m_attachmentView;
    }

    VkImage getImage(void) const
    {
        return *m_image;
    }

    VkBuffer getBuffer(void) const
    {
        DE_ASSERT(*m_buffer != DE_NULL);
        return *m_buffer;
    }

    VkDeviceSize getBufferSize(void) const
    {
        DE_ASSERT(*m_buffer != DE_NULL);
        return m_bufferSize;
    }

    const Allocation &getResultMemory(void) const
    {
        DE_ASSERT(m_bufferMemory);
        return *m_bufferMemory;
    }

    VkBuffer getSecondaryBuffer(void) const
    {
        DE_ASSERT(*m_secondaryBuffer != DE_NULL);
        return *m_secondaryBuffer;
    }

    VkDeviceSize getSecondaryBufferSize(void) const
    {
        DE_ASSERT(*m_secondaryBuffer != DE_NULL);
        return m_secondaryBufferSize;
    }

    const Allocation &getSecondaryResultMemory(void) const
    {
        DE_ASSERT(m_secondaryBufferMemory);
        return *m_secondaryBufferMemory;
    }

private:
    const Unique<VkImage> m_image;
    const UniquePtr<Allocation> m_imageMemory;
    const Unique<VkImageView> m_attachmentView;

    Move<VkImageView> m_depthInputAttachmentView;
    Move<VkImageView> m_stencilInputAttachmentView;
    pair<VkImageView, VkImageView> m_inputAttachmentViews;

    Move<VkBuffer> m_buffer;
    VkDeviceSize m_bufferSize;
    de::MovePtr<Allocation> m_bufferMemory;

    Move<VkBuffer> m_secondaryBuffer;
    VkDeviceSize m_secondaryBufferSize;
    de::MovePtr<Allocation> m_secondaryBufferMemory;
};

void uploadBufferData(const DeviceInterface &vk, VkDevice device, const Allocation &memory, size_t size,
                      const void *data, VkDeviceSize nonCoherentAtomSize)
{
    // Expand the range to flush to account for the nonCoherentAtomSize
    const VkDeviceSize roundedOffset = de::roundDown(memory.getOffset(), nonCoherentAtomSize);
    const VkDeviceSize roundedSize =
        de::roundUp(memory.getOffset() - roundedOffset + static_cast<VkDeviceSize>(size), nonCoherentAtomSize);

    const VkMappedMemoryRange range = {
        VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
        DE_NULL,                               // pNext;
        memory.getMemory(),                    // mem;
        roundedOffset,                         // offset;
        roundedSize,                           // size;
    };
    void *const ptr = memory.getHostPtr();

    deMemcpy(ptr, data, size);
    VK_CHECK(vk.flushMappedMemoryRanges(device, 1, &range));
}

VkImageAspectFlagBits getPrimaryImageAspect(tcu::TextureFormat::ChannelOrder order)
{
    DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 22);

    switch (order)
    {
    case tcu::TextureFormat::D:
    case tcu::TextureFormat::DS:
        return VK_IMAGE_ASPECT_DEPTH_BIT;

    case tcu::TextureFormat::S:
        return VK_IMAGE_ASPECT_STENCIL_BIT;

    default:
        return VK_IMAGE_ASPECT_COLOR_BIT;
    }
}

uint32_t getAttachmentNdx(const vector<AttachmentReference> &colorAttachments, size_t ndx)
{
    return (colorAttachments[ndx].getAttachment() == VK_ATTACHMENT_UNUSED) ? (uint32_t)ndx :
                                                                             colorAttachments[ndx].getAttachment();
}

class RenderQuad
{
public:
    RenderQuad(const Vec2 &posA, const Vec2 &posB) : m_vertices(6)
    {
        m_vertices[0] = posA;
        m_vertices[1] = Vec2(posA[0], posB[1]);
        m_vertices[2] = posB;

        m_vertices[3] = posB;
        m_vertices[4] = Vec2(posB[0], posA[1]);
        m_vertices[5] = posA;
    }

    const Vec2 &getCornerA(void) const
    {
        return m_vertices[0];
    }

    const Vec2 &getCornerB(void) const
    {
        return m_vertices[2];
    }

    const void *getVertexPointer(void) const
    {
        return &m_vertices[0];
    }

    size_t getVertexDataSize(void) const
    {
        return sizeof(Vec2) * m_vertices.size();
    }

private:
    vector<Vec2> m_vertices;
};

class ColorClear
{
public:
    ColorClear(const UVec2 &offset, const UVec2 &size, const VkClearColorValue &color)
        : m_offset(offset)
        , m_size(size)
        , m_color(color)
    {
    }

    const UVec2 &getOffset(void) const
    {
        return m_offset;
    }
    const UVec2 &getSize(void) const
    {
        return m_size;
    }
    const VkClearColorValue &getColor(void) const
    {
        return m_color;
    }

private:
    UVec2 m_offset;
    UVec2 m_size;
    VkClearColorValue m_color;
};

class DepthStencilClear
{
public:
    DepthStencilClear(const UVec2 &offset, const UVec2 &size, float depth, uint32_t stencil)
        : m_offset(offset)
        , m_size(size)
        , m_depth(depth)
        , m_stencil(stencil)
    {
    }

    const UVec2 &getOffset(void) const
    {
        return m_offset;
    }
    const UVec2 &getSize(void) const
    {
        return m_size;
    }
    float getDepth(void) const
    {
        return m_depth;
    }
    uint32_t getStencil(void) const
    {
        return m_stencil;
    }

private:
    const UVec2 m_offset;
    const UVec2 m_size;

    const float m_depth;
    const uint32_t m_stencil;
};

class SubpassRenderInfo
{
public:
    SubpassRenderInfo(const RenderPass &renderPass, uint32_t subpassIndex, uint32_t drawStartNdx,

                      bool isSecondary_, bool omitBlendState_,

                      const UVec2 &viewportOffset, const UVec2 &viewportSize,

                      const Maybe<RenderQuad> &renderQuad, const vector<ColorClear> &colorClears,
                      const Maybe<DepthStencilClear> &depthStencilClear)
        : m_viewportOffset(viewportOffset)
        , m_viewportSize(viewportSize)
        , m_subpassIndex(subpassIndex)
        , m_drawStartNdx(drawStartNdx)
        , m_isSecondary(isSecondary_)
        , m_omitBlendState(omitBlendState_)
        , m_flags(renderPass.getSubpasses()[subpassIndex].getFlags())
        , m_renderQuad(renderQuad)
        , m_colorClears(colorClears)
        , m_depthStencilClear(depthStencilClear)
        , m_colorAttachments(renderPass.getSubpasses()[subpassIndex].getColorAttachments())
        , m_inputAttachments(renderPass.getSubpasses()[subpassIndex].getInputAttachments())
    {
        for (uint32_t attachmentNdx = 0; attachmentNdx < (uint32_t)m_colorAttachments.size(); attachmentNdx++)
            m_colorAttachmentInfo.push_back(
                renderPass.getAttachments()[getAttachmentNdx(m_colorAttachments, attachmentNdx)]);

        if (renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
        {
            m_depthStencilAttachment = tcu::just(renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment());
            m_depthStencilAttachmentInfo =
                tcu::just(renderPass.getAttachments()
                              [renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment()]);
        }
    }

    const UVec2 &getViewportOffset(void) const
    {
        return m_viewportOffset;
    }
    const UVec2 &getViewportSize(void) const
    {
        return m_viewportSize;
    }

    uint32_t getSubpassIndex(void) const
    {
        return m_subpassIndex;
    }
    uint32_t getDrawStartNdx(void) const
    {
        return m_drawStartNdx;
    }
    bool isSecondary(void) const
    {
        return m_isSecondary;
    }
    bool getOmitBlendState(void) const
    {
        return m_omitBlendState;
    }

    const Maybe<RenderQuad> &getRenderQuad(void) const
    {
        return m_renderQuad;
    }
    const vector<ColorClear> &getColorClears(void) const
    {
        return m_colorClears;
    }
    const Maybe<DepthStencilClear> &getDepthStencilClear(void) const
    {
        return m_depthStencilClear;
    }

    uint32_t getInputAttachmentCount(void) const
    {
        return (uint32_t)m_inputAttachments.size();
    }
    uint32_t getInputAttachmentIndex(uint32_t attachmentNdx) const
    {
        return m_inputAttachments[attachmentNdx].getAttachment();
    }
    VkImageLayout getInputAttachmentLayout(uint32_t attachmentNdx) const
    {
        return m_inputAttachments[attachmentNdx].getImageLayout();
    }

    uint32_t getColorAttachmentCount(void) const
    {
        return (uint32_t)m_colorAttachments.size();
    }
    VkImageLayout getColorAttachmentLayout(uint32_t attachmentNdx) const
    {
        return m_colorAttachments[attachmentNdx].getImageLayout();
    }
    uint32_t getColorAttachmentIndex(uint32_t attachmentNdx) const
    {
        return m_colorAttachments[attachmentNdx].getAttachment();
    }
    const Attachment &getColorAttachment(uint32_t attachmentNdx) const
    {
        return m_colorAttachmentInfo[attachmentNdx];
    }
    Maybe<VkImageLayout> getDepthStencilAttachmentLayout(void) const
    {
        return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getImageLayout()) : tcu::Nothing;
    }
    Maybe<uint32_t> getDepthStencilAttachmentIndex(void) const
    {
        return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getAttachment()) : tcu::Nothing;
    }
    const Maybe<Attachment> &getDepthStencilAttachment(void) const
    {
        return m_depthStencilAttachmentInfo;
    }
    VkSubpassDescriptionFlags getSubpassFlags(void) const
    {
        return m_flags;
    }

private:
    UVec2 m_viewportOffset;
    UVec2 m_viewportSize;

    uint32_t m_subpassIndex;
    uint32_t m_drawStartNdx;
    bool m_isSecondary;
    bool m_omitBlendState;
    VkSubpassDescriptionFlags m_flags;

    Maybe<RenderQuad> m_renderQuad;
    vector<ColorClear> m_colorClears;
    Maybe<DepthStencilClear> m_depthStencilClear;

    vector<AttachmentReference> m_colorAttachments;
    vector<Attachment> m_colorAttachmentInfo;

    Maybe<AttachmentReference> m_depthStencilAttachment;
    Maybe<Attachment> m_depthStencilAttachmentInfo;

    vector<AttachmentReference> m_inputAttachments;
};

Move<VkPipeline> createSubpassPipeline(const DeviceInterface &vk, VkDevice device, VkRenderPass renderPass,
                                       VkShaderModule vertexShaderModule, VkShaderModule fragmentShaderModule,
                                       VkPipelineLayout pipelineLayout, const SubpassRenderInfo &renderInfo)
{
    Maybe<VkSampleCountFlagBits> rasterSamples;
    vector<VkPipelineColorBlendAttachmentState> attachmentBlendStates;

    for (uint32_t attachmentNdx = 0; attachmentNdx < renderInfo.getColorAttachmentCount(); attachmentNdx++)
    {
        const Attachment &attachment = renderInfo.getColorAttachment(attachmentNdx);

        DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());

        rasterSamples = attachment.getSamples();

        {
            const VkPipelineColorBlendAttachmentState attachmentBlendState = {
                VK_FALSE,                            // blendEnable
                VK_BLEND_FACTOR_SRC_ALPHA,           // srcBlendColor
                VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // destBlendColor
                VK_BLEND_OP_ADD,                     // blendOpColor
                VK_BLEND_FACTOR_ONE,                 // srcBlendAlpha
                VK_BLEND_FACTOR_ONE,                 // destBlendAlpha
                VK_BLEND_OP_ADD,                     // blendOpAlpha
                (attachmentNdx < renderInfo.getDrawStartNdx() ?
                     (uint32_t)0 :
                     VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT |
                         VK_COLOR_COMPONENT_A_BIT) // channelWriteMask
            };

            attachmentBlendStates.push_back(attachmentBlendState);
        }
    }

    if (renderInfo.getDepthStencilAttachment())
    {
        const Attachment &attachment = *renderInfo.getDepthStencilAttachment();

        DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
        rasterSamples = attachment.getSamples();
    }

    // If there are no attachment use single sample
    if (!rasterSamples)
        rasterSamples = VK_SAMPLE_COUNT_1_BIT;

    const VkVertexInputBindingDescription vertexBinding = {
        0u,                          // binding
        (uint32_t)sizeof(tcu::Vec2), // strideInBytes
        VK_VERTEX_INPUT_RATE_VERTEX, // stepRate
    };

    const VkVertexInputAttributeDescription vertexAttrib = {
        0u,                      // location
        0u,                      // binding
        VK_FORMAT_R32G32_SFLOAT, // format
        0u,                      // offsetInBytes
    };

    const VkPipelineVertexInputStateCreateInfo vertexInputState = {
        VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, //    sType
        DE_NULL,                                                   //    pNext
        (VkPipelineVertexInputStateCreateFlags)0u,
        1u,             //    bindingCount
        &vertexBinding, //    pVertexBindingDescriptions
        1u,             //    attributeCount
        &vertexAttrib,  //    pVertexAttributeDescriptions
    };

    const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = {
        VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType                            sType
        DE_NULL,                                                     // const void*                                pNext
        0u,                                                          // VkPipelineInputAssemblyStateCreateFlags    flags
        VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology                        topology
        VK_FALSE                             // VkBool32                                   primitiveRestartEnable
    };

    const VkViewport viewport = {(float)renderInfo.getViewportOffset().x(),
                                 (float)renderInfo.getViewportOffset().y(),
                                 (float)renderInfo.getViewportSize().x(),
                                 (float)renderInfo.getViewportSize().y(),
                                 0.0f,
                                 1.0f};

    const VkRect2D scissor = {
        {(int32_t)renderInfo.getViewportOffset().x(), (int32_t)renderInfo.getViewportOffset().y()},
        {renderInfo.getViewportSize().x(), renderInfo.getViewportSize().y()}};

    const VkPipelineViewportStateCreateInfo viewportState = {
        VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType                             sType
        DE_NULL,                                               // const void*                                 pNext
        (VkPipelineViewportStateCreateFlags)0,                 // VkPipelineViewportStateCreateFlags          flags
        1u,        // uint32_t                                    viewportCount
        &viewport, // const VkViewport*                           pViewports
        1u,        // uint32_t                                    scissorCount
        &scissor   // const VkRect2D*                             pScissors
    };

    const VkPipelineRasterizationStateCreateInfo rasterizationState = {
        VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType                            sType
        DE_NULL,                                                    // const void*                                pNext
        0u,                                                         // VkPipelineRasterizationStateCreateFlags    flags
        VK_FALSE,                        // VkBool32                                   depthClampEnable
        VK_FALSE,                        // VkBool32                                   rasterizerDiscardEnable
        VK_POLYGON_MODE_FILL,            // VkPolygonMode                              polygonMode
        VK_CULL_MODE_NONE,               // VkCullModeFlags                            cullMode
        VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace                                frontFace
        VK_FALSE,                        // VkBool32                                   depthBiasEnable
        0.0f,                            // float                                      depthBiasConstantFactor
        0.0f,                            // float                                      depthBiasClamp
        0.0f,                            // float                                      depthBiasSlopeFactor
        1.0f                             // float                                      lineWidth
    };

    const VkPipelineMultisampleStateCreateInfo multisampleState = {
        VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // sType
        DE_NULL,                                                  // pNext
        (VkPipelineMultisampleStateCreateFlags)0u,
        *rasterSamples, // rasterSamples
        VK_FALSE,       // sampleShadingEnable
        0.0f,           // minSampleShading
        DE_NULL,        // pSampleMask
        VK_FALSE,       // alphaToCoverageEnable
        VK_FALSE,       // alphaToOneEnable
    };
    const size_t stencilIndex = renderInfo.getSubpassIndex();

    const VkBool32 writeDepth =
        renderInfo.getDepthStencilAttachmentLayout() &&
                *renderInfo.getDepthStencilAttachmentLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
                *renderInfo.getDepthStencilAttachmentLayout() !=
                    VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL ?
            VK_TRUE :
            VK_FALSE;

    const VkBool32 writeStencil =
        renderInfo.getDepthStencilAttachmentLayout() &&
                *renderInfo.getDepthStencilAttachmentLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
                *renderInfo.getDepthStencilAttachmentLayout() !=
                    VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ?
            VK_TRUE :
            VK_FALSE;

    const VkPipelineDepthStencilStateCreateInfo depthStencilState = {
        VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // sType
        DE_NULL,                                                    // pNext
        (VkPipelineDepthStencilStateCreateFlags)0u,
        writeDepth,           // depthTestEnable
        writeDepth,           // depthWriteEnable
        VK_COMPARE_OP_ALWAYS, // depthCompareOp
        VK_FALSE,             // depthBoundsEnable
        writeStencil,         // stencilTestEnable
        {
            VK_STENCIL_OP_REPLACE,                   // stencilFailOp
            VK_STENCIL_OP_REPLACE,                   // stencilPassOp
            VK_STENCIL_OP_REPLACE,                   // stencilDepthFailOp
            VK_COMPARE_OP_ALWAYS,                    // stencilCompareOp
            ~0u,                                     // stencilCompareMask
            ~0u,                                     // stencilWriteMask
            ((stencilIndex % 2) == 0) ? ~0x0u : 0x0u // stencilReference
        },                                           // front
        {
            VK_STENCIL_OP_REPLACE,                   // stencilFailOp
            VK_STENCIL_OP_REPLACE,                   // stencilPassOp
            VK_STENCIL_OP_REPLACE,                   // stencilDepthFailOp
            VK_COMPARE_OP_ALWAYS,                    // stencilCompareOp
            ~0u,                                     // stencilCompareMask
            ~0u,                                     // stencilWriteMask
            ((stencilIndex % 2) == 0) ? ~0x0u : 0x0u // stencilReference
        },                                           // back

        0.0f, // minDepthBounds;
        1.0f  // maxDepthBounds;
    };

    const VkPipelineColorBlendStateCreateInfo blendState = {
        VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // sType
        DE_NULL,                                                  // pNext
        (VkPipelineColorBlendStateCreateFlags)0u,
        VK_FALSE,                                                            // logicOpEnable
        VK_LOGIC_OP_COPY,                                                    // logicOp
        (uint32_t)attachmentBlendStates.size(),                              // attachmentCount
        attachmentBlendStates.empty() ? DE_NULL : &attachmentBlendStates[0], // pAttachments
        {0.0f, 0.0f, 0.0f, 0.0f}                                             // blendConst
    };

    return makeGraphicsPipeline(
        vk,                           // const DeviceInterface&                        vk
        device,                       // const VkDevice                                device
        pipelineLayout,               // const VkPipelineLayout                        pipelineLayout
        vertexShaderModule,           // const VkShaderModule                          vertexShaderModule
        DE_NULL,                      // const VkShaderModule                          tessellationControlShaderModule
        DE_NULL,                      // const VkShaderModule                          tessellationEvalShaderModule
        DE_NULL,                      // const VkShaderModule                          geometryShaderModule
        fragmentShaderModule,         // const VkShaderModule                          fragmentShaderModule
        renderPass,                   // const VkRenderPass                            renderPass
        renderInfo.getSubpassIndex(), // const uint32_t                                subpass
        &vertexInputState,            // const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
        &inputAssemblyState,          // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
        DE_NULL,                      // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
        &viewportState,               // const VkPipelineViewportStateCreateInfo*      pViewportStat;
        &rasterizationState,          // const VkPipelineRasterizationStateCreateInfo* pRasterizationState
        &multisampleState,            // const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
        &depthStencilState,           // const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
        renderInfo.getOmitBlendState() ?
            DE_NULL :
            &blendState); // const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
}

class SubpassRenderer
{
public:
    SubpassRenderer(Context &context, const DeviceInterface &vk, VkDevice device, Allocator &allocator,
                    VkRenderPass renderPass, VkFramebuffer framebuffer, VkCommandPool commandBufferPool,
                    uint32_t queueFamilyIndex, const vector<VkImage> &attachmentImages,
                    const vector<pair<VkImageView, VkImageView>> &attachmentViews, const SubpassRenderInfo &renderInfo,
                    const vector<Attachment> &attachmentInfos, const AllocationKind allocationKind)
        : m_renderInfo(renderInfo)
    {
        const InstanceInterface &vki       = context.getInstanceInterface();
        const VkPhysicalDevice &physDevice = context.getPhysicalDevice();
        const uint32_t subpassIndex        = renderInfo.getSubpassIndex();
        vector<VkDescriptorSetLayoutBinding> bindings;

        for (uint32_t colorAttachmentNdx = 0; colorAttachmentNdx < renderInfo.getColorAttachmentCount();
             colorAttachmentNdx++)
        {
            const uint32_t attachmentNdx =
                (renderInfo.getColorAttachmentIndex(colorAttachmentNdx) == VK_ATTACHMENT_UNUSED) ?
                    colorAttachmentNdx :
                    renderInfo.getColorAttachmentIndex(colorAttachmentNdx);

            m_colorAttachmentImages.push_back(attachmentImages[attachmentNdx]);
        }

        if (renderInfo.getDepthStencilAttachmentIndex())
            m_depthStencilAttachmentImage = attachmentImages[*renderInfo.getDepthStencilAttachmentIndex()];

        if (renderInfo.getRenderQuad())
        {
            const RenderQuad &renderQuad = *renderInfo.getRenderQuad();

            if (renderInfo.getInputAttachmentCount() > 0)
            {
                uint32_t bindingIndex = 0;

                for (uint32_t inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount();
                     inputAttachmentNdx++)
                {
                    const Attachment attachmentInfo =
                        attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
                    const VkImageLayout layout      = renderInfo.getInputAttachmentLayout(inputAttachmentNdx);
                    const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
                    const bool isDepthFormat        = tcu::hasDepthComponent(format.order);
                    const bool isStencilFormat      = tcu::hasStencilComponent(format.order);
                    const uint32_t bindingCount =
                        (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) &&
                                (isStencilFormat &&
                                 layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL) ?
                            2u :
                            1u;

                    for (uint32_t bindingNdx = 0; bindingNdx < bindingCount; bindingNdx++)
                    {
                        const VkDescriptorSetLayoutBinding binding = {bindingIndex,
                                                                      vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u,
                                                                      vk::VK_SHADER_STAGE_FRAGMENT_BIT, DE_NULL};

                        bindings.push_back(binding);
                        bindingIndex++;
                    }
                }

                const VkDescriptorSetLayoutCreateInfo createInfo = {
                    vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, DE_NULL,

                    0u, (uint32_t)bindings.size(), &bindings[0]};

                m_descriptorSetLayout = vk::createDescriptorSetLayout(vk, device, &createInfo);
            }

            const VkDescriptorSetLayout descriptorSetLayout       = *m_descriptorSetLayout;
            const VkPipelineLayoutCreateInfo pipelineLayoutParams = {
                VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType;
                DE_NULL,                                       // pNext;
                (vk::VkPipelineLayoutCreateFlags)0,
                m_descriptorSetLayout ? 1u : 0u,                        // setLayoutCount;
                m_descriptorSetLayout ? &descriptorSetLayout : DE_NULL, // pSetLayouts;
                0u,                                                     // pushConstantRangeCount;
                DE_NULL,                                                // pPushConstantRanges;
            };

            m_vertexShaderModule = createShaderModule(
                vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-vert"), 0u);
            m_fragmentShaderModule = createShaderModule(
                vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-frag"), 0u);
            m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutParams);
            m_pipeline = createSubpassPipeline(vk, device, renderPass, *m_vertexShaderModule, *m_fragmentShaderModule,
                                               *m_pipelineLayout, m_renderInfo);

            // Round up the vertex buffer size to honor nonCoherentAtomSize.
            const auto properties =
                vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice());
            const auto vertexBufferSize = de::roundUp(static_cast<VkDeviceSize>(renderQuad.getVertexDataSize()),
                                                      properties.limits.nonCoherentAtomSize);

            m_vertexBuffer       = createBuffer(vk, device, 0u, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
                                                VK_SHARING_MODE_EXCLUSIVE, 1u, &queueFamilyIndex);
            m_vertexBufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_vertexBuffer,
                                                  MemoryRequirement::HostVisible, allocator, allocationKind);

            bindBufferMemory(vk, device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(),
                             m_vertexBufferMemory->getOffset());

            uploadBufferData(vk, device, *m_vertexBufferMemory, renderQuad.getVertexDataSize(),
                             renderQuad.getVertexPointer(), properties.limits.nonCoherentAtomSize);

            if (renderInfo.getInputAttachmentCount() > 0)
            {
                {
                    const VkDescriptorPoolSize poolSize = {
                        vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
                        // \note Reserve 2 per input attachment since depthStencil attachments require 2.
                        renderInfo.getInputAttachmentCount() * 2u};
                    const VkDescriptorPoolCreateInfo createInfo = {
                        vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, DE_NULL,
                        VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,

                        // \note Reserve 2 per input attachment since depthStencil attachments require 2.
                        renderInfo.getInputAttachmentCount() * 2u, 1u, &poolSize};

                    m_descriptorPool = vk::createDescriptorPool(vk, device, &createInfo);
                }
                {
                    const VkDescriptorSetAllocateInfo allocateInfo = {
                        vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, DE_NULL,

                        *m_descriptorPool, 1u, &descriptorSetLayout};

                    m_descriptorSet = vk::allocateDescriptorSet(vk, device, &allocateInfo);
                }
                {
                    vector<VkWriteDescriptorSet> writes(bindings.size());
                    vector<VkDescriptorImageInfo> imageInfos(bindings.size());
                    uint32_t bindingIndex = 0;

                    for (uint32_t inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount();
                         inputAttachmentNdx++)
                    {
                        const Attachment attachmentInfo =
                            attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
                        const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
                        const bool isDepthFormat        = tcu::hasDepthComponent(format.order);
                        const bool isStencilFormat      = tcu::hasStencilComponent(format.order);
                        const VkImageLayout inputAttachmentLayout =
                            renderInfo.getInputAttachmentLayout(inputAttachmentNdx);

                        if (isDepthFormat && isStencilFormat)
                        {
                            if (inputAttachmentLayout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
                            {
                                const VkDescriptorImageInfo imageInfo = {
                                    (VkSampler)0,
                                    attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
                                    inputAttachmentLayout};
                                imageInfos[bindingIndex] = imageInfo;

                                {
                                    const VkWriteDescriptorSet write = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
                                                                        DE_NULL,

                                                                        *m_descriptorSet,
                                                                        bindingIndex,
                                                                        0u,
                                                                        1u,
                                                                        VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
                                                                        &imageInfos[bindingIndex],
                                                                        DE_NULL,
                                                                        DE_NULL};
                                    writes[bindingIndex]             = write;

                                    bindingIndex++;
                                }
                            }

                            if (inputAttachmentLayout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
                            {
                                const VkDescriptorImageInfo imageInfo = {
                                    (VkSampler)0,
                                    attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].second,
                                    inputAttachmentLayout};
                                imageInfos[bindingIndex] = imageInfo;

                                {
                                    const VkWriteDescriptorSet write = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
                                                                        DE_NULL,

                                                                        *m_descriptorSet,
                                                                        bindingIndex,
                                                                        0u,
                                                                        1u,
                                                                        VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
                                                                        &imageInfos[bindingIndex],
                                                                        DE_NULL,
                                                                        DE_NULL};
                                    writes[bindingIndex]             = write;

                                    bindingIndex++;
                                }
                            }
                        }
                        else
                        {
                            const VkDescriptorImageInfo imageInfo = {
                                (VkSampler)0,
                                attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
                                inputAttachmentLayout};
                            imageInfos[bindingIndex] = imageInfo;

                            {
                                const VkWriteDescriptorSet write = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
                                                                    DE_NULL,

                                                                    *m_descriptorSet,
                                                                    bindingIndex,
                                                                    0u,
                                                                    1u,
                                                                    VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
                                                                    &imageInfos[bindingIndex],
                                                                    DE_NULL,
                                                                    DE_NULL};
                                writes[bindingIndex]             = write;

                                bindingIndex++;
                            }
                        }
                    }

                    vk.updateDescriptorSets(device, (uint32_t)writes.size(), &writes[0], 0u, DE_NULL);
                }
            }
        }

        if (renderInfo.isSecondary())
        {
            m_commandBuffer = allocateCommandBuffer(vk, device, commandBufferPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);

            beginCommandBuffer(vk, *m_commandBuffer, vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, renderPass,
                               subpassIndex, framebuffer, VK_FALSE, (VkQueryControlFlags)0,
                               (VkQueryPipelineStatisticFlags)0);
            pushRenderCommands(vk, *m_commandBuffer);
            endCommandBuffer(vk, *m_commandBuffer);
        }
    }

    bool isSecondary(void) const
    {
        return m_commandBuffer;
    }

    VkCommandBuffer getCommandBuffer(void) const
    {
        DE_ASSERT(isSecondary());
        return *m_commandBuffer;
    }

    void pushRenderCommands(const DeviceInterface &vk, VkCommandBuffer commandBuffer)
    {
        if (!m_renderInfo.getColorClears().empty())
        {
            const vector<ColorClear> &colorClears(m_renderInfo.getColorClears());

            for (uint32_t attachmentNdx = 0; attachmentNdx < m_renderInfo.getColorAttachmentCount(); attachmentNdx++)
            {
                const ColorClear &colorClear       = colorClears[attachmentNdx];
                const VkClearAttachment attachment = {
                    VK_IMAGE_ASPECT_COLOR_BIT,
                    attachmentNdx,
                    makeClearValue(colorClear.getColor()),
                };
                const VkClearRect rect = {
                    {{(int32_t)colorClear.getOffset().x(), (int32_t)colorClear.getOffset().y()},
                     {colorClear.getSize().x(), colorClear.getSize().y()}}, // rect
                    0u,                                                     // baseArrayLayer
                    1u,                                                     // layerCount
                };

                vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
            }
        }

        if (m_renderInfo.getDepthStencilClear())
        {
            const DepthStencilClear &depthStencilClear = *m_renderInfo.getDepthStencilClear();
            const uint32_t attachmentNdx               = m_renderInfo.getColorAttachmentCount();
            tcu::TextureFormat format          = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
            const VkImageLayout layout         = *m_renderInfo.getDepthStencilAttachmentLayout();
            const VkClearAttachment attachment = {
                (VkImageAspectFlags)((hasDepthComponent(format.order) &&
                                              layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL ?
                                          VK_IMAGE_ASPECT_DEPTH_BIT :
                                          0) |
                                     (hasStencilComponent(format.order) &&
                                              layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ?
                                          VK_IMAGE_ASPECT_STENCIL_BIT :
                                          0)),
                attachmentNdx,
                makeClearValueDepthStencil(depthStencilClear.getDepth(), depthStencilClear.getStencil())};
            const VkClearRect rect = {
                {{(int32_t)depthStencilClear.getOffset().x(), (int32_t)depthStencilClear.getOffset().y()},
                 {depthStencilClear.getSize().x(), depthStencilClear.getSize().y()}}, // rect
                0u,                                                                   // baseArrayLayer
                1u,                                                                   // layerCount
            };

            if ((tcu::hasDepthComponent(format.order) &&
                 layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) ||
                (tcu::hasStencilComponent(format.order) &&
                 layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL))
            {
                vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
            }
        }

        vector<VkImageMemoryBarrier> selfDeps;
        VkPipelineStageFlags srcStages = 0;
        VkPipelineStageFlags dstStages = 0;

        for (uint32_t inputAttachmentNdx = 0; inputAttachmentNdx < m_renderInfo.getInputAttachmentCount();
             inputAttachmentNdx++)
        {
            for (uint32_t colorAttachmentNdx = 0; colorAttachmentNdx < m_renderInfo.getColorAttachmentCount();
                 colorAttachmentNdx++)
            {
                if (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) ==
                    m_renderInfo.getColorAttachmentIndex(colorAttachmentNdx))
                {
                    const VkImageMemoryBarrier barrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
                                                          DE_NULL,                                // pNext

                                                          VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask
                                                          VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,  // dstAccessMask

                                                          VK_IMAGE_LAYOUT_GENERAL, // oldLayout
                                                          VK_IMAGE_LAYOUT_GENERAL, // newLayout

                                                          VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
                                                          VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex

                                                          m_colorAttachmentImages[colorAttachmentNdx], // image
                                                          {
                                                              // subresourceRange
                                                              VK_IMAGE_ASPECT_COLOR_BIT, // aspect
                                                              0,                         // baseMipLevel
                                                              1,                         // mipLevels
                                                              0,                         // baseArraySlice
                                                              1                          // arraySize
                                                          }};

                    srcStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
                    dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;

                    selfDeps.push_back(barrier);
                }
            }

            if (m_renderInfo.getDepthStencilAttachmentIndex() &&
                (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) ==
                 *m_renderInfo.getDepthStencilAttachmentIndex()))
            {
                const tcu::TextureFormat format    = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
                const bool hasDepth                = hasDepthComponent(format.order);
                const bool hasStencil              = hasStencilComponent(format.order);
                const VkImageMemoryBarrier barrier = {
                    VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
                    DE_NULL,                                // pNext;

                    VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // srcAccessMask
                    VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,          // dstAccessMask

                    m_renderInfo.getInputAttachmentLayout(inputAttachmentNdx), // oldLayout
                    m_renderInfo.getInputAttachmentLayout(inputAttachmentNdx), // newLayout;

                    VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex;
                    VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex;

                    m_depthStencilAttachmentImage, // image;
                    {
                        // subresourceRange;
                        (hasDepth ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) |
                            (hasStencil ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u), // aspect;
                        0,                                                                       // baseMipLevel;
                        1,                                                                       // mipLevels;
                        0,                                                                       // baseArraySlice;
                        1                                                                        // arraySize;
                    }};

                srcStages |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
                dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;

                selfDeps.push_back(barrier);
            }
        }

        if (!selfDeps.empty())
        {
            DE_ASSERT(srcStages != 0);
            DE_ASSERT(dstStages != 0);
            vk.cmdPipelineBarrier(commandBuffer, srcStages, dstStages, VK_DEPENDENCY_BY_REGION_BIT, 0, DE_NULL, 0,
                                  DE_NULL, (uint32_t)selfDeps.size(), &selfDeps[0]);
        }

        if (m_renderInfo.getRenderQuad())
        {
            const VkDeviceSize offset   = 0;
            const VkBuffer vertexBuffer = *m_vertexBuffer;

            vk.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);

            if (m_descriptorSet)
            {
                const VkDescriptorSet descriptorSet = *m_descriptorSet;
                vk.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u,
                                         &descriptorSet, 0u, NULL);
            }

            vk.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &vertexBuffer, &offset);
            vk.cmdDraw(commandBuffer, 6u, 1u, 0u, 0u);
        }
    }

private:
    const SubpassRenderInfo m_renderInfo;
    Move<VkCommandBuffer> m_commandBuffer;
    Move<VkPipeline> m_pipeline;
    Move<VkDescriptorSetLayout> m_descriptorSetLayout;
    Move<VkPipelineLayout> m_pipelineLayout;

    Move<VkShaderModule> m_vertexShaderModule;
    Move<VkShaderModule> m_fragmentShaderModule;

    Move<VkDescriptorPool> m_descriptorPool;
    Move<VkDescriptorSet> m_descriptorSet;
    Move<VkBuffer> m_vertexBuffer;
    de::MovePtr<Allocation> m_vertexBufferMemory;
    vector<VkImage> m_colorAttachmentImages;
    VkImage m_depthStencilAttachmentImage;
};

void pushImageInitializationCommands(const DeviceInterface &vk, VkCommandBuffer commandBuffer,
                                     const vector<Attachment> &attachmentInfo,
                                     const vector<de::SharedPtr<AttachmentResources>> &attachmentResources,
                                     uint32_t queueIndex, const vector<Maybe<VkClearValue>> &clearValues)
{
    {
        vector<VkImageMemoryBarrier> initializeLayouts;

        for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
        {
            if (!clearValues[attachmentNdx])
                continue;

            const VkImageMemoryBarrier barrier = {
                VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
                DE_NULL,                                // pNext;

                (VkAccessFlags)0,                                       // srcAccessMask
                getAllMemoryReadFlags() | VK_ACCESS_TRANSFER_WRITE_BIT, // dstAccessMask

                VK_IMAGE_LAYOUT_UNDEFINED,            // oldLayout
                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // newLayout;

                queueIndex, // srcQueueFamilyIndex;
                queueIndex, // destQueueFamilyIndex;

                attachmentResources[attachmentNdx]->getImage(), // image;
                {
                    // subresourceRange;
                    getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
                    0,                                                              // baseMipLevel;
                    1,                                                              // mipLevels;
                    0,                                                              // baseArraySlice;
                    1                                                               // arraySize;
                }};

            initializeLayouts.push_back(barrier);
        }

        if (!initializeLayouts.empty())
            vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
                                  (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
                                  (const VkBufferMemoryBarrier *)DE_NULL, (uint32_t)initializeLayouts.size(),
                                  &initializeLayouts[0]);
    }

    for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
    {
        if (!clearValues[attachmentNdx])
            continue;

        const tcu::TextureFormat format = mapVkFormat(attachmentInfo[attachmentNdx].getFormat());

        if (hasStencilComponent(format.order) || hasDepthComponent(format.order))
        {
            const float clearNan = tcu::Float32::nan().asFloat();
            const float clearDepth =
                hasDepthComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.depth : clearNan;
            const uint32_t clearStencil =
                hasStencilComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.stencil : 0xDEu;
            const VkClearDepthStencilValue depthStencil = {clearDepth, clearStencil};
            const VkImageSubresourceRange range         = {
                (VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) |
                                     (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
                0, 1, 0, 1};

            vk.cmdClearDepthStencilImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(),
                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencil, 1, &range);
        }
        else
        {
            const VkImageSubresourceRange range = {
                VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask;
                0,                         // baseMipLevel;
                1,                         // mipLevels;
                0,                         // baseArrayLayer;
                1                          // layerCount;
            };
            const VkClearColorValue clearColor = clearValues[attachmentNdx]->color;

            vk.cmdClearColorImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(),
                                  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
        }
    }

    {
        vector<VkImageMemoryBarrier> renderPassLayouts;

        for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
        {
            const VkImageLayout oldLayout =
                clearValues[attachmentNdx] ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
            const VkImageMemoryBarrier barrier = {
                VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
                DE_NULL,                                // pNext;

                getMemoryFlagsForLayout(oldLayout), // srcAccessMask
                getAllMemoryReadFlags() |
                    getMemoryFlagsForLayout(attachmentInfo[attachmentNdx].getInitialLayout()), // dstAccessMask

                oldLayout,                                        // oldLayout
                attachmentInfo[attachmentNdx].getInitialLayout(), // newLayout;

                queueIndex, // srcQueueFamilyIndex;
                queueIndex, // destQueueFamilyIndex;

                attachmentResources[attachmentNdx]->getImage(), // image;
                {
                    // subresourceRange;
                    getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
                    0,                                                              // baseMipLevel;
                    1,                                                              // mipLevels;
                    0,                                                              // baseArraySlice;
                    1                                                               // arraySize;
                }};

            renderPassLayouts.push_back(barrier);
        }

        if (!renderPassLayouts.empty())
            vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
                                  (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
                                  (const VkBufferMemoryBarrier *)DE_NULL, (uint32_t)renderPassLayouts.size(),
                                  &renderPassLayouts[0]);
    }
}

template <typename RenderpassSubpass>
void pushRenderPassCommands(const DeviceInterface &vk, VkCommandBuffer commandBuffer, VkRenderPass renderPass,
                            VkFramebuffer framebuffer, const vector<de::SharedPtr<SubpassRenderer>> &subpassRenderers,
                            const UVec2 &renderPos, const UVec2 &renderSize,
                            const vector<Maybe<VkClearValue>> &renderPassClearValues, TestConfig::RenderTypes render)
{
    const float clearNan = tcu::Float32::nan().asFloat();
    vector<VkClearValue> attachmentClearValues;
    const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);

    for (size_t attachmentNdx = 0; attachmentNdx < renderPassClearValues.size(); attachmentNdx++)
    {
        if (renderPassClearValues[attachmentNdx])
            attachmentClearValues.push_back(*renderPassClearValues[attachmentNdx]);
        else
            attachmentClearValues.push_back(makeClearValueColorF32(clearNan, clearNan, clearNan, clearNan));
    }

    {
        const VkRect2D renderArea = {{(int32_t)renderPos.x(), (int32_t)renderPos.y()},
                                     {renderSize.x(), renderSize.y()}};

        for (size_t subpassNdx = 0; subpassNdx < subpassRenderers.size(); subpassNdx++)
        {
            const VkSubpassContents contents = subpassRenderers[subpassNdx]->isSecondary() ?
                                                   VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS :
                                                   VK_SUBPASS_CONTENTS_INLINE;
            const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, contents);
            const VkRenderPassBeginInfo renderPassBeginInfo =
                createRenderPassBeginInfo(renderPass, framebuffer, renderArea, (uint32_t)attachmentClearValues.size(),
                                          attachmentClearValues.empty() ? DE_NULL : &attachmentClearValues[0]);

            if (subpassNdx == 0)
                RenderpassSubpass::cmdBeginRenderPass(vk, commandBuffer, &renderPassBeginInfo, &subpassBeginInfo);
            else
                RenderpassSubpass::cmdNextSubpass(vk, commandBuffer, &subpassBeginInfo, &subpassEndInfo);

            if (render)
            {
                if (contents == VK_SUBPASS_CONTENTS_INLINE)
                {
                    subpassRenderers[subpassNdx]->pushRenderCommands(vk, commandBuffer);
                }
                else if (contents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS)
                {
                    const VkCommandBuffer cmd = subpassRenderers[subpassNdx]->getCommandBuffer();
                    vk.cmdExecuteCommands(commandBuffer, 1, &cmd);
                }
                else
                    DE_FATAL("Invalid contents");
            }
        }

        RenderpassSubpass::cmdEndRenderPass(vk, commandBuffer, &subpassEndInfo);
    }
}

void pushRenderPassCommands(const DeviceInterface &vk, VkCommandBuffer commandBuffer, VkRenderPass renderPass,
                            VkFramebuffer framebuffer, const vector<de::SharedPtr<SubpassRenderer>> &subpassRenderers,
                            const UVec2 &renderPos, const UVec2 &renderSize,
                            const vector<Maybe<VkClearValue>> &renderPassClearValues, TestConfig::RenderTypes render,
                            RenderPassType renderPassType)
{
    switch (renderPassType)
    {
    case RENDERPASS_TYPE_LEGACY:
        return pushRenderPassCommands<RenderpassSubpass1>(vk, commandBuffer, renderPass, framebuffer, subpassRenderers,
                                                          renderPos, renderSize, renderPassClearValues, render);
    case RENDERPASS_TYPE_RENDERPASS2:
        return pushRenderPassCommands<RenderpassSubpass2>(vk, commandBuffer, renderPass, framebuffer, subpassRenderers,
                                                          renderPos, renderSize, renderPassClearValues, render);
    default:
        TCU_THROW(InternalError, "Impossible");
    }
}

void pushReadImagesToBuffers(const DeviceInterface &vk, VkCommandBuffer commandBuffer, uint32_t queueIndex,

                             const vector<de::SharedPtr<AttachmentResources>> &attachmentResources,
                             const vector<Attachment> &attachmentInfo, const vector<bool> &isLazy,

                             const UVec2 &targetSize)
{
    {
        vector<VkImageMemoryBarrier> imageBarriers;

        for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
        {
            if (isLazy[attachmentNdx])
                continue;

            const VkImageLayout oldLayout      = attachmentInfo[attachmentNdx].getFinalLayout();
            const VkImageMemoryBarrier barrier = {
                VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
                DE_NULL,                                // pNext

                getAllMemoryWriteFlags() | getMemoryFlagsForLayout(oldLayout), // srcAccessMask
                getAllMemoryReadFlags(),                                       // dstAccessMask

                oldLayout,                            // oldLayout
                VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout

                queueIndex, // srcQueueFamilyIndex
                queueIndex, // destQueueFamilyIndex

                attachmentResources[attachmentNdx]->getImage(), // image
                {
                    // subresourceRange
                    getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
                    0,                                                              // baseMipLevel
                    1,                                                              // mipLevels
                    0,                                                              // baseArraySlice
                    1                                                               // arraySize
                }};

            imageBarriers.push_back(barrier);
        }

        if (!imageBarriers.empty())
            vk.cmdPipelineBarrier(commandBuffer, getAllPipelineStageFlags(), getAllPipelineStageFlags(),
                                  (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
                                  (const VkBufferMemoryBarrier *)DE_NULL, (uint32_t)imageBarriers.size(),
                                  &imageBarriers[0]);
    }

    for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
    {
        if (isLazy[attachmentNdx])
            continue;

        const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
        const VkBufferImageCopy rect                 = {
            0, // bufferOffset
            0, // bufferRowLength
            0, // bufferImageHeight
            {
                // imageSubresource
                (vk::VkImageAspectFlags)getPrimaryImageAspect(
                    mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order), // aspect
                0,                                                                 // mipLevel
                0,                                                                 // arraySlice
                1                                                                  // arraySize
            },
            {0, 0, 0},                           // imageOffset
            {targetSize.x(), targetSize.y(), 1u} // imageExtent
        };

        vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(),
                                VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getBuffer(),
                                1, &rect);

        if (tcu::TextureFormat::DS == order)
        {
            const VkBufferImageCopy stencilRect = {
                0, // bufferOffset
                0, // bufferRowLength
                0, // bufferImageHeight
                {
                    // imageSubresource
                    VK_IMAGE_ASPECT_STENCIL_BIT, // aspect
                    0,                           // mipLevel
                    0,                           // arraySlice
                    1                            // arraySize
                },
                {0, 0, 0},                           // imageOffset
                {targetSize.x(), targetSize.y(), 1u} // imageExtent
            };

            vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(),
                                    VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
                                    attachmentResources[attachmentNdx]->getSecondaryBuffer(), 1, &stencilRect);
        }
    }

    {
        vector<VkBufferMemoryBarrier> bufferBarriers;

        for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
        {
            if (isLazy[attachmentNdx])
                continue;

            const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
            const VkBufferMemoryBarrier bufferBarrier    = {VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
                                                            DE_NULL,

                                                            getAllMemoryWriteFlags(),
                                                            getAllMemoryReadFlags(),

                                                            queueIndex,
                                                            queueIndex,

                                                            attachmentResources[attachmentNdx]->getBuffer(),
                                                            0,
                                                            attachmentResources[attachmentNdx]->getBufferSize()};

            bufferBarriers.push_back(bufferBarrier);

            if (tcu::TextureFormat::DS == order)
            {
                const VkBufferMemoryBarrier secondaryBufferBarrier = {
                    VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
                    DE_NULL,

                    getAllMemoryWriteFlags(),
                    getAllMemoryReadFlags(),

                    queueIndex,
                    queueIndex,

                    attachmentResources[attachmentNdx]->getSecondaryBuffer(),
                    0,
                    attachmentResources[attachmentNdx]->getSecondaryBufferSize()};

                bufferBarriers.push_back(secondaryBufferBarrier);
            }
        }

        if (!bufferBarriers.empty())
            vk.cmdPipelineBarrier(commandBuffer, getAllPipelineStageFlags(), getAllPipelineStageFlags(),
                                  (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL,
                                  (uint32_t)bufferBarriers.size(), &bufferBarriers[0], 0,
                                  (const VkImageMemoryBarrier *)DE_NULL);
    }
}

class PixelValue
{
public:
    PixelValue(const Maybe<bool> &x = tcu::Nothing, const Maybe<bool> &y = tcu::Nothing,
               const Maybe<bool> &z = tcu::Nothing, const Maybe<bool> &w = tcu::Nothing);

    void setUndefined(size_t ndx);
    void setValue(size_t ndx, bool value);
    Maybe<bool> getValue(size_t ndx) const;

private:
    uint16_t m_status;
};

PixelValue::PixelValue(const Maybe<bool> &x, const Maybe<bool> &y, const Maybe<bool> &z, const Maybe<bool> &w)
    : m_status(0)
{
    const Maybe<bool> values[] = {x, y, z, w};

    for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(values); ndx++)
    {
        if (values[ndx])
            setValue(ndx, *values[ndx]);
        else
            setUndefined(ndx);
    }

    DE_ASSERT(m_status <= 0xFFu);
}

void PixelValue::setUndefined(size_t ndx)
{
    DE_ASSERT(ndx < 4);
    DE_ASSERT(m_status <= 0xFFu);

    m_status &= (uint16_t) ~(0x1u << (uint16_t)(ndx * 2));
    DE_ASSERT(m_status <= 0xFFu);
}

void PixelValue::setValue(size_t ndx, bool value)
{
    DE_ASSERT(ndx < 4);
    DE_ASSERT(m_status <= 0xFFu);

    m_status = (uint16_t)(m_status | (uint16_t)(0x1u << (ndx * 2)));

    if (value)
        m_status = (uint16_t)(m_status | (uint16_t)(0x1u << (ndx * 2 + 1)));
    else
        m_status &= (uint16_t) ~(0x1u << (uint16_t)(ndx * 2 + 1));

    DE_ASSERT(m_status <= 0xFFu);
}

Maybe<bool> PixelValue::getValue(size_t ndx) const
{
    DE_ASSERT(ndx < 4);
    DE_ASSERT(m_status <= 0xFFu);

    if ((m_status & (0x1u << (uint16_t)(ndx * 2))) != 0)
    {
        return just((m_status & (0x1u << (uint32_t)(ndx * 2 + 1))) != 0);
    }
    else
        return tcu::Nothing;
}

void clearReferenceValues(vector<PixelValue> &values, const UVec2 &targetSize, const UVec2 &offset, const UVec2 &size,
                          const BVec4 &mask, const PixelValue &value)
{
    DE_ASSERT(targetSize.x() * targetSize.y() == (uint32_t)values.size());
    DE_ASSERT(offset.x() + size.x() <= targetSize.x());
    DE_ASSERT(offset.y() + size.y() <= targetSize.y());

    for (uint32_t y = offset.y(); y < offset.y() + size.y(); y++)
        for (uint32_t x = offset.x(); x < offset.x() + size.x(); x++)
        {
            for (int compNdx = 0; compNdx < 4; compNdx++)
            {
                if (mask[compNdx])
                {
                    if (value.getValue(compNdx))
                        values[x + y * targetSize.x()].setValue(compNdx, *value.getValue(compNdx));
                    else
                        values[x + y * targetSize.x()].setUndefined(compNdx);
                }
            }
        }
}

void markUndefined(vector<PixelValue> &values, const BVec4 &mask, const UVec2 &targetSize, const UVec2 &offset,
                   const UVec2 &size)
{
    DE_ASSERT(targetSize.x() * targetSize.y() == (uint32_t)values.size());

    for (uint32_t y = offset.y(); y < offset.y() + size.y(); y++)
        for (uint32_t x = offset.x(); x < offset.x() + size.x(); x++)
        {
            for (int compNdx = 0; compNdx < 4; compNdx++)
            {
                if (mask[compNdx])
                    values[x + y * targetSize.x()].setUndefined(compNdx);
            }
        }
}

PixelValue clearValueToPixelValue(const VkClearValue &value, const tcu::TextureFormat &format,
                                  const DepthValuesArray &depthValues)
{
    const bool isDepthAttachment          = hasDepthComponent(format.order);
    const bool isStencilAttachment        = hasStencilComponent(format.order);
    const bool isDepthOrStencilAttachment = isDepthAttachment || isStencilAttachment;
    PixelValue pixelValue;

    if (isDepthOrStencilAttachment)
    {
        if (isDepthAttachment)
        {
            if (value.depthStencil.depth == float(depthValues[1]) / 255.0f)
                pixelValue.setValue(0, true);
            else if (value.depthStencil.depth == float(depthValues[0]) / 255.0f)
                pixelValue.setValue(0, false);
            else
                DE_FATAL("Unknown depth value");
        }

        if (isStencilAttachment)
        {
            if (value.depthStencil.stencil == 0xFFu)
                pixelValue.setValue(1, true);
            else if (value.depthStencil.stencil == 0x0u)
                pixelValue.setValue(1, false);
            else
                DE_FATAL("Unknown stencil value");
        }
    }
    else
    {
        const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
        const tcu::BVec4 channelMask                = tcu::getTextureFormatChannelMask(format);

        switch (channelClass)
        {
        case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
            for (int i = 0; i < 4; i++)
            {
                if (channelMask[i])
                {
                    if (value.color.int32[i] == 1)
                        pixelValue.setValue(i, true);
                    else if (value.color.int32[i] == 0)
                        pixelValue.setValue(i, false);
                    else
                        DE_FATAL("Unknown clear color value");
                }
            }
            break;

        case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
            for (int i = 0; i < 4; i++)
            {
                if (channelMask[i])
                {
                    if (value.color.uint32[i] == 1u)
                        pixelValue.setValue(i, true);
                    else if (value.color.uint32[i] == 0u)
                        pixelValue.setValue(i, false);
                    else
                        DE_FATAL("Unknown clear color value");
                }
            }
            break;

        case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
        case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
        case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
            for (int i = 0; i < 4; i++)
            {
                if (channelMask[i])
                {
                    if (value.color.float32[i] == 1.0f)
                        pixelValue.setValue(i, true);
                    else if (value.color.float32[i] == 0.0f)
                        pixelValue.setValue(i, false);
                    else
                        DE_FATAL("Unknown clear color value");
                }
            }
            break;

        default:
            DE_FATAL("Unknown channel class");
        }
    }

    return pixelValue;
}

void renderReferenceValues(vector<vector<PixelValue>> &referenceAttachments, const RenderPass &renderPassInfo,
                           const UVec2 &targetSize, const vector<Maybe<VkClearValue>> &imageClearValues,
                           const vector<Maybe<VkClearValue>> &renderPassClearValues,
                           const vector<SubpassRenderInfo> &subpassRenderInfo, const UVec2 &renderPos,
                           const UVec2 &renderSize, const uint32_t drawStartNdx, const DepthValuesArray &depthValues)
{
    const vector<Subpass> &subpasses = renderPassInfo.getSubpasses();
    vector<bool> attachmentUsed(renderPassInfo.getAttachments().size(), false);

    referenceAttachments.resize(renderPassInfo.getAttachments().size());

    for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
    {
        const Attachment attachment     = renderPassInfo.getAttachments()[attachmentNdx];
        const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
        vector<PixelValue> &reference   = referenceAttachments[attachmentNdx];

        reference.resize(targetSize.x() * targetSize.y());

        if (imageClearValues[attachmentNdx])
            clearReferenceValues(reference, targetSize, UVec2(0, 0), targetSize, BVec4(true),
                                 clearValueToPixelValue(*imageClearValues[attachmentNdx], format, depthValues));
    }

    for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
    {
        const Subpass &subpass                              = subpasses[subpassNdx];
        const SubpassRenderInfo &renderInfo                 = subpassRenderInfo[subpassNdx];
        const vector<AttachmentReference> &colorAttachments = subpass.getColorAttachments();

        // Apply load op if attachment was used for the first time
        for (size_t attachmentNdx = 0; attachmentNdx < colorAttachments.size(); attachmentNdx++)
        {
            const uint32_t attachmentIndex = getAttachmentNdx(colorAttachments, attachmentNdx);

            if (!attachmentUsed[attachmentIndex] &&
                colorAttachments[attachmentNdx].getAttachment() != VK_ATTACHMENT_UNUSED)
            {
                const Attachment &attachment    = renderPassInfo.getAttachments()[attachmentIndex];
                vector<PixelValue> &reference   = referenceAttachments[attachmentIndex];
                const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());

                DE_ASSERT(!tcu::hasDepthComponent(format.order));
                DE_ASSERT(!tcu::hasStencilComponent(format.order));

                if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
                    clearReferenceValues(
                        reference, targetSize, renderPos, renderSize, BVec4(true),
                        clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format, depthValues));
                else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
                    markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);

                attachmentUsed[attachmentIndex] = true;
            }
        }

        // Apply load op to depth/stencil attachment if it was used for the first time
        if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
        {
            const uint32_t attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();

            // Apply load op if attachment was used for the first time
            if (!attachmentUsed[attachmentIndex])
            {
                const Attachment &attachment    = renderPassInfo.getAttachments()[attachmentIndex];
                vector<PixelValue> &reference   = referenceAttachments[attachmentIndex];
                const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());

                if (tcu::hasDepthComponent(format.order))
                {
                    if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
                        clearReferenceValues(
                            reference, targetSize, renderPos, renderSize, BVec4(true, false, false, false),
                            clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format, depthValues));
                    else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
                        markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
                }

                if (tcu::hasStencilComponent(format.order))
                {
                    if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
                        clearReferenceValues(
                            reference, targetSize, renderPos, renderSize, BVec4(false, true, false, false),
                            clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format, depthValues));
                    else if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
                        markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
                }

                attachmentUsed[attachmentIndex] = true;
            }
        }

        for (size_t colorClearNdx = 0; colorClearNdx < renderInfo.getColorClears().size(); colorClearNdx++)
        {
            const ColorClear &colorClear    = renderInfo.getColorClears()[colorClearNdx];
            const UVec2 offset              = colorClear.getOffset();
            const UVec2 size                = colorClear.getSize();
            const uint32_t attachmentIndex  = subpass.getColorAttachments()[colorClearNdx].getAttachment();
            const Attachment &attachment    = renderPassInfo.getAttachments()[attachmentIndex];
            const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
            vector<PixelValue> &reference   = referenceAttachments[attachmentIndex];
            VkClearValue value;

            value.color = colorClear.getColor();

            clearReferenceValues(reference, targetSize, offset, size, BVec4(true),
                                 clearValueToPixelValue(value, format, depthValues));
        }

        if (renderInfo.getDepthStencilClear())
        {
            const DepthStencilClear &dsClear = *renderInfo.getDepthStencilClear();
            const UVec2 offset               = dsClear.getOffset();
            const UVec2 size                 = dsClear.getSize();
            const uint32_t attachmentIndex   = subpass.getDepthStencilAttachment().getAttachment();
            const VkImageLayout layout       = subpass.getDepthStencilAttachment().getImageLayout();
            const Attachment &attachment     = renderPassInfo.getAttachments()[attachmentIndex];
            const tcu::TextureFormat format  = mapVkFormat(attachment.getFormat());
            const bool hasStencil            = tcu::hasStencilComponent(format.order) &&
                                    layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL;
            const bool hasDepth = tcu::hasDepthComponent(format.order) &&
                                  layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
            vector<PixelValue> &reference = referenceAttachments[attachmentIndex];
            VkClearValue value;

            value.depthStencil.depth   = dsClear.getDepth();
            value.depthStencil.stencil = dsClear.getStencil();

            clearReferenceValues(reference, targetSize, offset, size, BVec4(hasDepth, hasStencil, false, false),
                                 clearValueToPixelValue(value, format, depthValues));
        }

        if (renderInfo.getRenderQuad())
        {
            const RenderQuad &renderQuad = *renderInfo.getRenderQuad();
            const Vec2 posA              = renderQuad.getCornerA();
            const Vec2 posB              = renderQuad.getCornerB();
            const Vec2 origin =
                Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) +
                Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
            const Vec2 p =
                Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
            const IVec2 posAI(deRoundFloatToInt32(origin.x() + (p.x() * posA.x())),
                              deRoundFloatToInt32(origin.y() + (p.y() * posA.y())));
            const IVec2 posBI(deRoundFloatToInt32(origin.x() + (p.x() * posB.x())),
                              deRoundFloatToInt32(origin.y() + (p.y() * posB.y())));

            DE_ASSERT(posAI.x() < posBI.x());
            DE_ASSERT(posAI.y() < posBI.y());

            if (subpass.getInputAttachments().empty())
            {
                for (size_t attachmentRefNdx = drawStartNdx; attachmentRefNdx < subpass.getColorAttachments().size();
                     attachmentRefNdx++)
                {
                    const uint32_t attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();

                    if (attachmentIndex == VK_ATTACHMENT_UNUSED)
                        continue;

                    const Attachment &attachment    = renderPassInfo.getAttachments()[attachmentIndex];
                    const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
                    const tcu::BVec4 channelMask    = tcu::getTextureFormatChannelMask(format);
                    vector<PixelValue> &reference   = referenceAttachments[attachmentIndex];

                    for (int y = posAI.y(); y < (int)posBI.y(); y++)
                        for (int x = posAI.x(); x < (int)posBI.x(); x++)
                        {
                            for (int compNdx = 0; compNdx < 4; compNdx++)
                            {
                                const size_t index = subpassNdx + attachmentIndex + compNdx;
                                const BoolOp op    = boolOpFromIndex(index);
                                const bool boolX   = x % 2 == (int)(index % 2);
                                const bool boolY   = y % 2 == (int)((index / 2) % 2);

                                if (channelMask[compNdx])
                                    reference[x + y * targetSize.x()].setValue(compNdx,
                                                                               performBoolOp(op, boolX, boolY));
                            }
                        }
                }

                if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
                {
                    const uint32_t attachmentIndex  = subpass.getDepthStencilAttachment().getAttachment();
                    const VkImageLayout layout      = subpass.getDepthStencilAttachment().getImageLayout();
                    const Attachment &attachment    = renderPassInfo.getAttachments()[attachmentIndex];
                    const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
                    vector<PixelValue> &reference   = referenceAttachments[attachmentIndex];

                    for (int y = posAI.y(); y < (int)posBI.y(); y++)
                        for (int x = posAI.x(); x < (int)posBI.x(); x++)
                        {
                            if (tcu::hasDepthComponent(format.order) &&
                                layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
                                layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
                            {
                                const size_t index = subpassNdx + 1;
                                const BoolOp op    = boolOpFromIndex(index);
                                const bool boolX   = x % 2 == (int)(index % 2);
                                const bool boolY   = y % 2 == (int)((index / 2) % 2);

                                reference[x + y * targetSize.x()].setValue(0, performBoolOp(op, boolX, boolY));
                            }

                            if (tcu::hasStencilComponent(format.order) &&
                                layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
                                layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
                            {
                                const size_t index = subpassNdx;
                                reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
                            }
                        }
                }
            }
            else
            {
                size_t outputComponentCount = 0;
                vector<Maybe<bool>> inputs;

                DE_ASSERT(posAI.x() < posBI.x());
                DE_ASSERT(posAI.y() < posBI.y());

                for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size();
                     attachmentRefNdx++)
                {
                    const uint32_t attachmentIndex  = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
                    const Attachment &attachment    = renderPassInfo.getAttachments()[attachmentIndex];
                    const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
                    const int componentCount        = tcu::getNumUsedChannels(format.order);

                    outputComponentCount += (size_t)componentCount;
                }

                if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED &&
                    subpass.getDepthStencilAttachment().getImageLayout() !=
                        VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
                    subpass.getDepthStencilAttachment().getImageLayout() !=
                        VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
                {
                    const Attachment &attachment(
                        renderPassInfo.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()]);
                    const tcu::TextureFormat format(mapVkFormat(attachment.getFormat()));

                    if (tcu::hasDepthComponent(format.order))
                        outputComponentCount++;
                }

                if (outputComponentCount > 0)
                {
                    for (int y = posAI.y(); y < (int)posBI.y(); y++)
                        for (int x = posAI.x(); x < (int)posBI.x(); x++)
                        {
                            for (size_t inputAttachmentNdx = 0;
                                 inputAttachmentNdx < subpass.getInputAttachments().size(); inputAttachmentNdx++)
                            {
                                const uint32_t attachmentIndex =
                                    subpass.getInputAttachments()[inputAttachmentNdx].getAttachment();
                                const VkImageLayout layout =
                                    subpass.getInputAttachments()[inputAttachmentNdx].getImageLayout();
                                const Attachment &attachment    = renderPassInfo.getAttachments()[attachmentIndex];
                                const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
                                const int componentCount        = tcu::getNumUsedChannels(format.order);

                                for (int compNdx = 0; compNdx < componentCount; compNdx++)
                                {
                                    if ((compNdx != 0 ||
                                         layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL) &&
                                        (compNdx != 1 ||
                                         layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL))
                                    {
                                        inputs.push_back(
                                            referenceAttachments[attachmentIndex][x + y * targetSize.x()].getValue(
                                                compNdx));
                                    }
                                }
                            }

                            const size_t inputsPerOutput = inputs.size() >= outputComponentCount ?
                                                               ((inputs.size() / outputComponentCount) +
                                                                ((inputs.size() % outputComponentCount) != 0 ? 1 : 0)) :
                                                               1;

                            size_t outputValueNdx = 0;

                            for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size();
                                 attachmentRefNdx++)
                            {
                                const uint32_t attachmentIndex =
                                    subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
                                const Attachment &attachment    = renderPassInfo.getAttachments()[attachmentIndex];
                                const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
                                vector<PixelValue> &reference   = referenceAttachments[attachmentIndex];
                                const int componentCount        = tcu::getNumUsedChannels(format.order);

                                for (int compNdx = 0; compNdx < componentCount; compNdx++)
                                {
                                    const size_t index = subpassNdx + attachmentIndex + outputValueNdx;
                                    const BoolOp op    = boolOpFromIndex(index);
                                    const bool boolX   = x % 2 == (int)(index % 2);
                                    const bool boolY   = y % 2 == (int)((index / 2) % 2);
                                    Maybe<bool> output = tcu::just(performBoolOp(op, boolX, boolY));

                                    for (size_t i = 0; i < inputsPerOutput; i++)
                                    {
                                        if (!output)
                                            break;
                                        else if (!inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) %
                                                         inputs.size()])
                                            output = tcu::Nothing;
                                        else
                                            output = (*output) ==
                                                     (*inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) %
                                                              inputs.size()]);
                                    }

                                    if (output)
                                        reference[x + y * targetSize.x()].setValue(compNdx, *output);
                                    else
                                        reference[x + y * targetSize.x()].setUndefined(compNdx);
                                }

                                outputValueNdx += componentCount;
                            }

                            if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED &&
                                subpass.getDepthStencilAttachment().getImageLayout() !=
                                    VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
                                subpass.getDepthStencilAttachment().getImageLayout() !=
                                    VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
                            {
                                const uint32_t attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
                                vector<PixelValue> &reference  = referenceAttachments[attachmentIndex];
                                const size_t index             = subpassNdx + attachmentIndex;
                                const BoolOp op                = boolOpFromIndex(index);
                                const bool boolX               = x % 2 == (int)(index % 2);
                                const bool boolY               = y % 2 == (int)((index / 2) % 2);
                                Maybe<bool> output             = tcu::just(performBoolOp(op, boolX, boolY));

                                for (size_t i = 0; i < inputsPerOutput; i++)
                                {
                                    if (!output)
                                        break;
                                    else if (inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()])
                                        output = (*output) ==
                                                 (*inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()]);
                                    else
                                        output = tcu::Nothing;
                                }

                                if (output)
                                    reference[x + y * targetSize.x()].setValue(0, *output);
                                else
                                    reference[x + y * targetSize.x()].setUndefined(0);
                            }

                            inputs.clear();
                        }
                }

                if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED &&
                    subpass.getDepthStencilAttachment().getImageLayout() !=
                        VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
                    subpass.getDepthStencilAttachment().getImageLayout() !=
                        VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
                {
                    const uint32_t attachmentIndex  = subpass.getDepthStencilAttachment().getAttachment();
                    const Attachment &attachment    = renderPassInfo.getAttachments()[attachmentIndex];
                    const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
                    vector<PixelValue> &reference   = referenceAttachments[attachmentIndex];

                    if (tcu::hasStencilComponent(format.order))
                    {
                        for (int y = posAI.y(); y < (int)posBI.y(); y++)
                            for (int x = posAI.x(); x < (int)posBI.x(); x++)
                            {
                                const size_t index = subpassNdx;
                                reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
                            }
                    }
                }
            }
        }
    }

    // Mark all attachments that were used but not stored as undefined
    for (size_t attachmentIndex = 0; attachmentIndex < renderPassInfo.getAttachments().size(); attachmentIndex++)
    {
        const Attachment attachment           = renderPassInfo.getAttachments()[attachmentIndex];
        const tcu::TextureFormat format       = mapVkFormat(attachment.getFormat());
        vector<PixelValue> &reference         = referenceAttachments[attachmentIndex];
        const bool isStencilAttachment        = hasStencilComponent(format.order);
        const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || isStencilAttachment;

        if (attachmentUsed[attachmentIndex] &&
            renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
        {
            if (isDepthOrStencilAttachment)
                markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
            else
                markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
        }

        if (attachmentUsed[attachmentIndex] && isStencilAttachment &&
            renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
            markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
    }
}

void renderReferenceImagesFromValues(vector<tcu::TextureLevel> &referenceImages,
                                     const vector<vector<PixelValue>> &referenceValues, const UVec2 &targetSize,
                                     const RenderPass &renderPassInfo, const DepthValuesArray &depthValues)
{
    referenceImages.resize(referenceValues.size());

    for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
    {
        const Attachment attachment         = renderPassInfo.getAttachments()[attachmentNdx];
        const tcu::TextureFormat format     = mapVkFormat(attachment.getFormat());
        const vector<PixelValue> &reference = referenceValues[attachmentNdx];
        const bool hasDepth                 = tcu::hasDepthComponent(format.order);
        const bool hasStencil               = tcu::hasStencilComponent(format.order);
        const bool hasDepthOrStencil        = hasDepth || hasStencil;
        tcu::TextureLevel &referenceImage   = referenceImages[attachmentNdx];

        referenceImage.setStorage(format, targetSize.x(), targetSize.y());

        if (hasDepthOrStencil)
        {
            if (hasDepth)
            {
                const PixelBufferAccess depthAccess(
                    tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_DEPTH));

                for (uint32_t y = 0; y < targetSize.y(); y++)
                    for (uint32_t x = 0; x < targetSize.x(); x++)
                    {
                        if (reference[x + y * targetSize.x()].getValue(0))
                        {
                            if (*reference[x + y * targetSize.x()].getValue(0))
                                depthAccess.setPixDepth(float(depthValues[1]) / 255.0f, x, y);
                            else
                                depthAccess.setPixDepth(float(depthValues[0]) / 255.0f, x, y);
                        }
                        else // Fill with 3x3 grid
                            depthAccess.setPixDepth(((x / 3) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f, x, y);
                    }
            }

            if (hasStencil)
            {
                const PixelBufferAccess stencilAccess(
                    tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_STENCIL));

                for (uint32_t y = 0; y < targetSize.y(); y++)
                    for (uint32_t x = 0; x < targetSize.x(); x++)
                    {
                        if (reference[x + y * targetSize.x()].getValue(1))
                        {
                            if (*reference[x + y * targetSize.x()].getValue(1))
                                stencilAccess.setPixStencil(0xFFu, x, y);
                            else
                                stencilAccess.setPixStencil(0x0u, x, y);
                        }
                        else // Fill with 3x3 grid
                            stencilAccess.setPixStencil(((x / 3) % 2) == ((y / 3) % 2) ? 85 : 170, x, y);
                    }
            }
        }
        else
        {
            for (uint32_t y = 0; y < targetSize.y(); y++)
                for (uint32_t x = 0; x < targetSize.x(); x++)
                {
                    tcu::Vec4 color;

                    for (int compNdx = 0; compNdx < 4; compNdx++)
                    {
                        if (reference[x + y * targetSize.x()].getValue(compNdx))
                        {
                            if (*reference[x + y * targetSize.x()].getValue(compNdx))
                                color[compNdx] = 1.0f;
                            else
                                color[compNdx] = 0.0f;
                        }
                        else // Fill with 3x3 grid
                            color[compNdx] = ((compNdx + (x / 3)) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f;
                    }

                    referenceImage.getAccess().setPixel(color, x, y);
                }
        }
    }
}

bool verifyColorAttachment(const vector<PixelValue> &reference, const ConstPixelBufferAccess &result,
                           const PixelBufferAccess &errorImage, const bool useFormatCompCount)
{
    const Vec4 red(1.0f, 0.0f, 0.0f, 1.0f);
    const Vec4 green(0.0f, 1.0f, 0.0f, 1.0f);
    bool ok = true;

    DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
    DE_ASSERT(result.getWidth() == errorImage.getWidth());
    DE_ASSERT(result.getHeight() == errorImage.getHeight());

    for (int y = 0; y < result.getHeight(); y++)
        for (int x = 0; x < result.getWidth(); x++)
        {
            const Vec4 resultColor           = result.getPixel(x, y);
            const PixelValue &referenceValue = reference[x + y * result.getWidth()];
            bool pixelOk                     = true;
            const uint32_t componentCount =
                useFormatCompCount ? (uint32_t)tcu::getNumUsedChannels(result.getFormat().order) : 4;

            for (uint32_t compNdx = 0; compNdx < componentCount; compNdx++)
            {
                const Maybe<bool> maybeValue = referenceValue.getValue(compNdx);

                if (maybeValue)
                {
                    const bool value = *maybeValue;

                    if ((value && (resultColor[compNdx] != 1.0f)) || (!value && resultColor[compNdx] != 0.0f))
                        pixelOk = false;
                }
            }

            if (!pixelOk)
            {
                errorImage.setPixel(red, x, y);
                ok = false;
            }
            else
                errorImage.setPixel(green, x, y);
        }

    return ok;
}

// Setting the alpha value to 1.0f by default helps visualization when the alpha channel is not used.
const tcu::Vec4 kDefaultColorForLog{0.0f, 0.0f, 0.0f, 1.0f};
const float kTrueComponent      = 1.0f;
const float kFalseComponent     = 0.5f;
const float kUnsetComponentLow  = 0.0f;
const float kUnsetComponentHigh = 0.25f;

std::unique_ptr<tcu::TextureLevel> renderColorImageForLog(const ConstPixelBufferAccess &image, int numChannels)
{
    // Same channel order, but using UNORM_INT8 for the color format.
    const auto order = image.getFormat().order;
    const tcu::TextureFormat loggableFormat{order, tcu::TextureFormat::UNORM_INT8};
    const int width  = image.getWidth();
    const int height = image.getHeight();
    std::unique_ptr<tcu::TextureLevel> result{new tcu::TextureLevel{loggableFormat, width, height}};
    auto access        = result->getAccess();
    tcu::Vec4 outColor = kDefaultColorForLog;

    for (int x = 0; x < width; ++x)
        for (int y = 0; y < height; ++y)
        {
            const auto value = image.getPixel(x, y);
            for (int c = 0; c < numChannels; ++c)
            {
                if (value[c] == 0.0f)
                    outColor[c] = kFalseComponent;
                else if (value[c] == 1.0f)
                    outColor[c] = kTrueComponent;
                else
                    DE_ASSERT(false);
            }
            access.setPixel(outColor, x, y);
        }

    return result;
}

std::unique_ptr<tcu::TextureLevel> renderColorImageForLog(const vector<PixelValue> &reference, const UVec2 &targetSize,
                                                          int numChannels)
{
    const tcu::TextureFormat loggableFormat{tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8};
    const int width  = static_cast<int>(targetSize.x());
    const int height = static_cast<int>(targetSize.y());
    std::unique_ptr<tcu::TextureLevel> result{new tcu::TextureLevel{loggableFormat, width, height}};
    auto access        = result->getAccess();
    tcu::Vec4 outColor = kDefaultColorForLog;

    for (int x = 0; x < width; ++x)
        for (int y = 0; y < height; ++y)
        {
            const int index = x + y * width;
            for (int c = 0; c < numChannels; ++c)
            {
                const auto maybeValue = reference[index].getValue(c);
                if (maybeValue)
                    outColor[c] = ((*maybeValue) ? kTrueComponent : kFalseComponent);
                else
                    outColor[c] = ((((x / 3) % 2) == ((y / 3) % 2)) ? kUnsetComponentLow : kUnsetComponentHigh);
            }
            access.setPixel(outColor, x, y);
        }

    return result;
}

bool verifyDepthAttachment(const vector<PixelValue> &reference, const ConstPixelBufferAccess &result,
                           const PixelBufferAccess &errorImage, const DepthValuesArray &depthValues, float epsilon)
{
    const Vec4 red(1.0f, 0.0f, 0.0f, 1.0f);
    const Vec4 green(0.0f, 1.0f, 0.0f, 1.0f);
    bool ok = true;

    DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
    DE_ASSERT(result.getWidth() == errorImage.getWidth());
    DE_ASSERT(result.getHeight() == errorImage.getHeight());

    for (int y = 0; y < result.getHeight(); y++)
        for (int x = 0; x < result.getWidth(); x++)
        {
            bool pixelOk = true;

            const float resultDepth          = result.getPixDepth(x, y);
            const PixelValue &referenceValue = reference[x + y * result.getWidth()];
            const Maybe<bool> maybeValue     = referenceValue.getValue(0);

            if (maybeValue)
            {
                const bool value = *maybeValue;

                if ((value && !depthsEqual(resultDepth, float(depthValues[1]) / 255.0f, epsilon)) ||
                    (!value && !depthsEqual(resultDepth, float(depthValues[0]) / 255.0f, epsilon)))
                    pixelOk = false;
            }

            if (!pixelOk)
            {
                errorImage.setPixel(red, x, y);
                ok = false;
            }
            else
                errorImage.setPixel(green, x, y);
        }

    return ok;
}

bool verifyStencilAttachment(const vector<PixelValue> &reference, const ConstPixelBufferAccess &result,
                             const PixelBufferAccess &errorImage)
{
    const Vec4 red(1.0f, 0.0f, 0.0f, 1.0f);
    const Vec4 green(0.0f, 1.0f, 0.0f, 1.0f);
    bool ok = true;

    DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
    DE_ASSERT(result.getWidth() == errorImage.getWidth());
    DE_ASSERT(result.getHeight() == errorImage.getHeight());

    for (int y = 0; y < result.getHeight(); y++)
        for (int x = 0; x < result.getWidth(); x++)
        {
            bool pixelOk = true;

            const uint32_t resultStencil     = result.getPixStencil(x, y);
            const PixelValue &referenceValue = reference[x + y * result.getWidth()];
            const Maybe<bool> maybeValue     = referenceValue.getValue(1);

            if (maybeValue)
            {
                const bool value = *maybeValue;

                if ((value && (resultStencil != 0xFFu)) || (!value && resultStencil != 0x0u))
                    pixelOk = false;
            }

            if (!pixelOk)
            {
                errorImage.setPixel(red, x, y);
                ok = false;
            }
            else
                errorImage.setPixel(green, x, y);
        }

    return ok;
}

bool logAndVerifyImages(TestLog &log, const DeviceInterface &vk, VkDevice device,
                        const vector<de::SharedPtr<AttachmentResources>> &attachmentResources,
                        const vector<bool> &attachmentIsLazy, const RenderPass &renderPassInfo,
                        const vector<Maybe<VkClearValue>> &renderPassClearValues,
                        const vector<Maybe<VkClearValue>> &imageClearValues,
                        const vector<SubpassRenderInfo> &subpassRenderInfo, const UVec2 &targetSize,
                        const TestConfig &config)
{
    vector<vector<PixelValue>> referenceValues;
    vector<tcu::TextureLevel> referenceAttachments;
    bool isOk = true;

    log << TestLog::Message << "Reference images fill undefined pixels with 3x3 grid pattern." << TestLog::EndMessage;

    renderReferenceValues(referenceValues, renderPassInfo, targetSize, imageClearValues, renderPassClearValues,
                          subpassRenderInfo, config.renderPos, config.renderSize, config.drawStartNdx,
                          config.depthValues);
    renderReferenceImagesFromValues(referenceAttachments, referenceValues, targetSize, renderPassInfo,
                                    config.depthValues);

    for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
    {
        if (!attachmentIsLazy[attachmentNdx])
        {
            bool attachmentOK               = true;
            const Attachment attachment     = renderPassInfo.getAttachments()[attachmentNdx];
            const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());

            if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
            {
                const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachment.getFormat());
                void *const depthPtr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();

                const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachment.getFormat());
                void *const stencilPtr = attachmentResources[attachmentNdx]->getSecondaryResultMemory().getHostPtr();

                invalidateAlloc(vk, device, attachmentResources[attachmentNdx]->getResultMemory());
                invalidateAlloc(vk, device, attachmentResources[attachmentNdx]->getSecondaryResultMemory());

                {
                    bool depthOK   = true;
                    bool stencilOK = true;
                    const ConstPixelBufferAccess depthAccess(depthFormat, targetSize.x(), targetSize.y(), 1, depthPtr);
                    const ConstPixelBufferAccess stencilAccess(stencilFormat, targetSize.x(), targetSize.y(), 1,
                                                               stencilPtr);
                    tcu::TextureLevel depthErrorImage(
                        tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(),
                        targetSize.y());
                    tcu::TextureLevel stencilErrorImage(
                        tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(),
                        targetSize.y());

                    if (renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE &&
                        !verifyDepthAttachment(referenceValues[attachmentNdx], depthAccess, depthErrorImage.getAccess(),
                                               config.depthValues, requiredDepthEpsilon(attachment.getFormat())))
                    {
                        depthOK = false;
                    }

                    if (renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() ==
                            VK_ATTACHMENT_STORE_OP_STORE &&
                        !verifyStencilAttachment(referenceValues[attachmentNdx], stencilAccess,
                                                 stencilErrorImage.getAccess()))
                    {
                        stencilOK = false;
                    }

                    if (!depthOK || !stencilOK)
                    {
                        const auto attachmentNdxStr = de::toString(attachmentNdx);

                        // Output images.
                        log << TestLog::ImageSet("OutputAttachments" + attachmentNdxStr,
                                                 "Output depth and stencil attachments " + attachmentNdxStr);
                        log << TestLog::Image("Attachment" + attachmentNdxStr + "Depth",
                                              "Attachment " + attachmentNdxStr + " Depth", depthAccess);
                        log << TestLog::Image("Attachment" + attachmentNdxStr + "Stencil",
                                              "Attachment " + attachmentNdxStr + " Stencil", stencilAccess);
                        log << TestLog::EndImageSet;

                        // Reference images. These will be logged as image sets due to having depth and stencil aspects.
                        log << TestLog::Image("AttachmentReferences" + attachmentNdxStr,
                                              "Reference images " + attachmentNdxStr,
                                              referenceAttachments[attachmentNdx].getAccess());

                        // Error masks.
                        log << TestLog::ImageSet("ErrorMasks" + attachmentNdxStr, "Error masks " + attachmentNdxStr);
                        if (!depthOK)
                            log << TestLog::Image("DepthAttachmentError" + attachmentNdxStr,
                                                  "Depth Attachment Error " + attachmentNdxStr,
                                                  depthErrorImage.getAccess());
                        if (!stencilOK)
                            log << TestLog::Image("StencilAttachmentError" + attachmentNdxStr,
                                                  "Stencil Attachment Error " + attachmentNdxStr,
                                                  stencilErrorImage.getAccess());
                        log << TestLog::EndImageSet;

                        attachmentOK = false;
                    }
                }
            }
            else
            {
                void *const ptr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();

                invalidateAlloc(vk, device, attachmentResources[attachmentNdx]->getResultMemory());

                bool depthOK   = true;
                bool stencilOK = true;
                bool colorOK   = true;
                const ConstPixelBufferAccess access(format, targetSize.x(), targetSize.y(), 1, ptr);
                tcu::TextureLevel errorImage(
                    tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(),
                    targetSize.y());

                if (tcu::hasDepthComponent(format.order))
                {
                    if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE ||
                         renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() ==
                             VK_ATTACHMENT_STORE_OP_STORE) &&
                        !verifyDepthAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess(),
                                               config.depthValues, requiredDepthEpsilon(attachment.getFormat())))
                    {
                        depthOK = false;
                    }
                }
                else if (tcu::hasStencilComponent(format.order))
                {
                    if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE ||
                         renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() ==
                             VK_ATTACHMENT_STORE_OP_STORE) &&
                        !verifyStencilAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
                    {
                        stencilOK = false;
                    }
                }
                else
                {
                    if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE ||
                         renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() ==
                             VK_ATTACHMENT_STORE_OP_STORE) &&
                        !verifyColorAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess(),
                                               config.useFormatCompCount))
                    {
                        colorOK = false;
                    }
                }

                if (!depthOK || !stencilOK || !colorOK)
                {
                    log << TestLog::ImageSet("TestImages", "Output attachment, reference image and error mask");
                    if (!depthOK || !stencilOK)
                    {
                        // Log without conversions.
                        log << TestLog::Image("Attachment" + de::toString(attachmentNdx),
                                              "Attachment " + de::toString(attachmentNdx), access);
                        log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx),
                                              "Attachment reference " + de::toString(attachmentNdx),
                                              referenceAttachments[attachmentNdx].getAccess());
                    }
                    else
                    {
                        // Convert color images to better reflect test status and output in any format.
                        const auto numChannels      = tcu::getNumUsedChannels(access.getFormat().order);
                        const auto attachmentForLog = renderColorImageForLog(access, numChannels);
                        const auto referenceForLog =
                            renderColorImageForLog(referenceValues[attachmentNdx], targetSize, numChannels);

                        log << TestLog::Message
                            << "Check the attachment formats and test data to verify which components affect the test "
                               "result."
                            << TestLog::EndMessage;
                        log << TestLog::Message
                            << "In the reference image, unset pixel components are marked with a 3x3 grid storing "
                               "values 0.0 and 0.25, pixel components set to false are stored as 0.5 and pixel "
                               "components set to true are stored as 1.0."
                            << TestLog::EndMessage;
                        log << TestLog::Message
                            << "Output attachment pixel components are always set to 0.5 or 1.0 but may not be taken "
                               "into account if not set in the reference image."
                            << TestLog::EndMessage;

                        log << TestLog::Image("Attachment" + de::toString(attachmentNdx),
                                              "Attachment " + de::toString(attachmentNdx),
                                              attachmentForLog->getAccess());
                        log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx),
                                              "Attachment reference " + de::toString(attachmentNdx),
                                              referenceForLog->getAccess());
                    }
                    log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx),
                                          "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
                    log << TestLog::EndImageSet;

                    attachmentOK = false;
                }
            }

            if (!attachmentOK)
                isOk = false;
        }
    }

    return isOk;
}

std::string getInputAttachmentType(VkFormat vkFormat)
{
    const tcu::TextureFormat format             = mapVkFormat(vkFormat);
    const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);

    switch (channelClass)
    {
    case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
        return "isubpassInput";

    case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
        return "usubpassInput";

    case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
    case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
    case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
        return "subpassInput";

    default:
        DE_FATAL("Unknown channel class");
        return "";
    }
}

std::string getAttachmentType(VkFormat vkFormat, bool useFormatCompCount)
{
    const tcu::TextureFormat format             = mapVkFormat(vkFormat);
    const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
    const size_t componentCount                 = (size_t)tcu::getNumUsedChannels(format.order);

    switch (channelClass)
    {
    case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
        if (useFormatCompCount)
            return (componentCount == 1 ? "int" : "ivec" + de::toString(componentCount));
        else
            return "ivec4";

    case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
        if (useFormatCompCount)
            return (componentCount == 1 ? "uint" : "uvec" + de::toString(componentCount));
        else
            return "uvec4";

    case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
    case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
    case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
        if (useFormatCompCount)
            return (componentCount == 1 ? "float" : "vec" + de::toString(componentCount));
        else
            return "vec4";

    default:
        DE_FATAL("Unknown channel class");
        return "";
    }
}

void createTestShaders(SourceCollections &dst, TestConfig config)
{
    if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
    {
        const vector<Subpass> &subpasses = config.renderPass.getSubpasses();

        for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
        {
            const Subpass &subpass          = subpasses[subpassNdx];
            uint32_t inputAttachmentBinding = 0;
            std::ostringstream vertexShader;
            std::ostringstream fragmentShader;

            vertexShader << "#version 310 es\n"
                         << "layout(location = 0) in highp vec2 a_position;\n"
                         << "void main (void) {\n"
                         << "\tgl_Position = vec4(a_position, 1.0, 1.0);\n"
                         << "}\n";

            fragmentShader << "#version 310 es\n"
                           << "precision highp float;\n";

            bool hasAnyDepthFormats = false;

            for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getInputAttachments().size();
                 attachmentNdx++)
            {
                const uint32_t attachmentIndex  = subpass.getInputAttachments()[attachmentNdx].getAttachment();
                const VkImageLayout layout      = subpass.getInputAttachments()[attachmentNdx].getImageLayout();
                const Attachment attachment     = config.renderPass.getAttachments()[attachmentIndex];
                const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
                const bool isDepthFormat        = tcu::hasDepthComponent(format.order);
                const bool isStencilFormat      = tcu::hasStencilComponent(format.order);

                if (isDepthFormat || isStencilFormat)
                {
                    if (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
                    {
                        hasAnyDepthFormats = true;
                        fragmentShader << "layout(input_attachment_index = " << attachmentNdx
                                       << ", set=0, binding=" << inputAttachmentBinding
                                       << ") uniform highp subpassInput i_depth" << attachmentNdx << ";\n";
                        inputAttachmentBinding++;
                    }

                    if (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
                    {
                        fragmentShader << "layout(input_attachment_index = " << attachmentNdx
                                       << ", set=0, binding=" << inputAttachmentBinding
                                       << ") uniform highp usubpassInput i_stencil" << attachmentNdx << ";\n";
                        inputAttachmentBinding++;
                    }
                }
                else
                {
                    const std::string attachmentType = getInputAttachmentType(attachment.getFormat());

                    fragmentShader << "layout(input_attachment_index = " << attachmentNdx
                                   << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp "
                                   << attachmentType << " i_color" << attachmentNdx << ";\n";
                    inputAttachmentBinding++;
                }
            }

            for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size();
                 attachmentNdx++)
            {
                const std::string attachmentType = getAttachmentType(
                    config.renderPass.getAttachments()[getAttachmentNdx(subpass.getColorAttachments(), attachmentNdx)]
                        .getFormat(),
                    config.useFormatCompCount);
                fragmentShader << "layout(location = " << attachmentNdx << ") out highp " << attachmentType
                               << " o_color" << attachmentNdx << ";\n";
            }

            if (hasAnyDepthFormats)
                fragmentShader << "\nbool depthsEqual(float a, float b, float epsilon) {\n"
                               << "\treturn abs(a - b) <= epsilon;\n}\n\n";

            fragmentShader << "void main (void) {\n";

            if (subpass.getInputAttachments().empty())
            {
                for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size();
                     attachmentNdx++)
                {
                    const uint32_t attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();

                    if (attachmentIndex == VK_ATTACHMENT_UNUSED)
                        continue;

                    const Attachment attachment     = config.renderPass.getAttachments()[attachmentIndex];
                    const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
                    const size_t componentCount =
                        config.useFormatCompCount ? (size_t)tcu::getNumUsedChannels(format.order) : 4;
                    const std::string attachmentType =
                        getAttachmentType(attachment.getFormat(), config.useFormatCompCount);

                    fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "("
                                   << attachmentType + "(";

                    for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
                    {
                        const size_t index = subpassNdx + attachmentIndex + compNdx;
                        const BoolOp op    = boolOpFromIndex(index);

                        if (compNdx > 0)
                            fragmentShader << ",\n\t\t";

                        fragmentShader << "((int(gl_FragCoord.x) % 2 == " << (index % 2) << ") " << boolOpToString(op)
                                       << " ("
                                       << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2) << ") ? 1.0 : 0.0)";
                    }

                    fragmentShader << "));\n";
                }

                if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED &&
                    subpass.getDepthStencilAttachment().getImageLayout() !=
                        VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
                    subpass.getDepthStencilAttachment().getImageLayout() !=
                        VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
                {
                    const size_t index = subpassNdx + 1;
                    const BoolOp op    = boolOpFromIndex(index);

                    fragmentShader << "\tgl_FragDepth = ((int(gl_FragCoord.x) % 2 == " << (index % 2) << ") "
                                   << boolOpToString(op) << " ("
                                   << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2) << ") ? "
                                   << uint32_t(config.depthValues[1])
                                   << ".0f/255.0f : " << uint32_t(config.depthValues[0]) << ".0f/255.0f);\n";
                }
            }
            else
            {
                size_t inputComponentCount  = 0;
                size_t outputComponentCount = 0;

                for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getInputAttachments().size();
                     attachmentNdx++)
                {
                    const uint32_t attachmentIndex  = subpass.getInputAttachments()[attachmentNdx].getAttachment();
                    const VkImageLayout layout      = subpass.getInputAttachments()[attachmentNdx].getImageLayout();
                    const Attachment attachment     = config.renderPass.getAttachments()[attachmentIndex];
                    const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
                    const size_t componentCount     = (size_t)tcu::getNumUsedChannels(format.order);

                    if (layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
                        inputComponentCount += 1;
                    else if (layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
                        inputComponentCount += 1;
                    else
                        inputComponentCount += componentCount;
                }

                for (size_t attachmentNdx = config.drawStartNdx; attachmentNdx < subpass.getColorAttachments().size();
                     attachmentNdx++)
                {
                    const uint32_t attachmentIndex  = subpass.getColorAttachments()[attachmentNdx].getAttachment();
                    const Attachment attachment     = config.renderPass.getAttachments()[attachmentIndex];
                    const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
                    const size_t componentCount     = (size_t)tcu::getNumUsedChannels(format.order);

                    outputComponentCount += componentCount;
                }

                if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED &&
                    subpass.getDepthStencilAttachment().getImageLayout() !=
                        VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
                    subpass.getDepthStencilAttachment().getImageLayout() !=
                        VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
                {
                    outputComponentCount++;
                }

                if (outputComponentCount > 0)
                {
                    const size_t inputsPerOutput = inputComponentCount >= outputComponentCount ?
                                                       ((inputComponentCount / outputComponentCount) +
                                                        ((inputComponentCount % outputComponentCount) != 0 ? 1 : 0)) :
                                                       1;

                    fragmentShader << "\tbool inputs[" << inputComponentCount << "];\n";

                    if (outputComponentCount > 0)
                        fragmentShader << "\tbool outputs[" << outputComponentCount << "];\n";

                    size_t inputValueNdx = 0;

                    for (size_t attachmentNdx = config.drawStartNdx;
                         attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
                    {
                        const char *const components[]  = {"x", "y", "z", "w"};
                        const uint32_t attachmentIndex  = subpass.getInputAttachments()[attachmentNdx].getAttachment();
                        const VkImageLayout layout      = subpass.getInputAttachments()[attachmentNdx].getImageLayout();
                        const Attachment attachment     = config.renderPass.getAttachments()[attachmentIndex];
                        const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
                        const size_t componentCount     = (size_t)tcu::getNumUsedChannels(format.order);
                        const bool isDepthFormat        = tcu::hasDepthComponent(format.order);
                        const bool isStencilFormat      = tcu::hasStencilComponent(format.order);

                        if (isDepthFormat || isStencilFormat)
                        {
                            if (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
                            {
                                fragmentShader << "\tinputs[" << inputValueNdx << "] = depthsEqual("
                                               << uint32_t(config.depthValues[1])
                                               << ".0f/255.0f, float(subpassLoad(i_depth" << attachmentNdx << ").x), "
                                               << std::fixed << std::setprecision(12)
                                               << requiredDepthEpsilon(attachment.getFormat()) << ");\n";
                                inputValueNdx++;
                            }

                            if (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
                            {
                                fragmentShader << "\tinputs[" << inputValueNdx << "] = 255u == subpassLoad(i_stencil"
                                               << attachmentNdx << ").x;\n";
                                inputValueNdx++;
                            }
                        }
                        else
                        {
                            for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
                            {
                                fragmentShader << "\tinputs[" << inputValueNdx << "] = 1.0 == float(subpassLoad(i_color"
                                               << attachmentNdx << ")." << components[compNdx] << ");\n";
                                inputValueNdx++;
                            }
                        }
                    }

                    size_t outputValueNdx = 0;

                    for (size_t attachmentNdx = config.drawStartNdx;
                         attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
                    {
                        const uint32_t attachmentIndex   = subpass.getColorAttachments()[attachmentNdx].getAttachment();
                        const Attachment attachment      = config.renderPass.getAttachments()[attachmentIndex];
                        const std::string attachmentType = getAttachmentType(
                            config.renderPass.getAttachments()[attachmentIndex].getFormat(), config.useFormatCompCount);
                        const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
                        const size_t componentCount     = (size_t)tcu::getNumUsedChannels(format.order);

                        for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
                        {
                            const size_t index = subpassNdx + attachmentIndex + outputValueNdx;
                            const BoolOp op    = boolOpFromIndex(index);

                            fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = "
                                           << "(int(gl_FragCoord.x) % 2 == " << (index % 2) << ") "
                                           << boolOpToString(op) << " ("
                                           << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2) << ");\n";

                            for (size_t i = 0; i < inputsPerOutput; i++)
                                fragmentShader
                                    << "\toutputs[" << outputValueNdx + compNdx << "] = outputs["
                                    << outputValueNdx + compNdx << "] == inputs["
                                    << ((outputValueNdx + compNdx) * inputsPerOutput + i) % inputComponentCount
                                    << "];\n";
                        }

                        fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(";

                        for (size_t compNdx = 0; compNdx < (config.useFormatCompCount ? componentCount : 4); compNdx++)
                        {
                            if (compNdx > 0)
                                fragmentShader << ", ";

                            if (compNdx < componentCount)
                                fragmentShader << "outputs[" << outputValueNdx + compNdx << "]";
                            else
                                fragmentShader << "0";
                        }

                        outputValueNdx += componentCount;

                        fragmentShader << ");\n";
                    }

                    if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED &&
                        subpass.getDepthStencilAttachment().getImageLayout() !=
                            VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
                        subpass.getDepthStencilAttachment().getImageLayout() !=
                            VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
                    {
                        const uint32_t attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
                        const size_t index             = subpassNdx + attachmentIndex;
                        const BoolOp op                = boolOpFromIndex(index);

                        fragmentShader << "\toutputs[" << outputValueNdx << "] = "
                                       << "(int(gl_FragCoord.x) % 2 == " << (index % 2) << ") " << boolOpToString(op)
                                       << " ("
                                       << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2) << ");\n";

                        for (size_t i = 0; i < inputsPerOutput; i++)
                            fragmentShader << "\toutputs[" << outputValueNdx << "] = outputs[" << outputValueNdx
                                           << "] == inputs["
                                           << (outputValueNdx * inputsPerOutput + i) % inputComponentCount << "];\n";

                        fragmentShader << "\tgl_FragDepth = outputs[" << outputValueNdx << "] ? "
                                       << uint32_t(config.depthValues[1])
                                       << ".0f/255.0f : " << uint32_t(config.depthValues[0]) << ".0f/255.0f;\n";
                    }
                }
            }

            fragmentShader << "}\n";

            dst.glslSources.add(de::toString(subpassNdx) + "-vert") << glu::VertexSource(vertexShader.str());
            dst.glslSources.add(de::toString(subpassNdx) + "-frag") << glu::FragmentSource(fragmentShader.str());
        }
    }
}

void initializeAttachmentIsLazy(vector<bool> &attachmentIsLazy, const vector<Attachment> &attachments,
                                TestConfig::ImageMemory imageMemory)
{
    bool lastAttachmentWasLazy = false;

    for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
    {
        if (attachments[attachmentNdx].getLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD &&
            attachments[attachmentNdx].getStoreOp() != VK_ATTACHMENT_STORE_OP_STORE &&
            attachments[attachmentNdx].getStencilLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD &&
            attachments[attachmentNdx].getStencilStoreOp() != VK_ATTACHMENT_STORE_OP_STORE)
        {
            if (imageMemory == TestConfig::IMAGEMEMORY_LAZY ||
                (imageMemory & TestConfig::IMAGEMEMORY_LAZY && !lastAttachmentWasLazy))
            {
                attachmentIsLazy.push_back(true);

                lastAttachmentWasLazy = true;
            }
            else if (imageMemory & TestConfig::IMAGEMEMORY_STRICT)
            {
                attachmentIsLazy.push_back(false);
                lastAttachmentWasLazy = false;
            }
            else
                DE_FATAL("Unknown imageMemory");
        }
        else
            attachmentIsLazy.push_back(false);
    }
}

enum AttachmentRefType
{
    ATTACHMENTREFTYPE_COLOR,
    ATTACHMENTREFTYPE_DEPTH_STENCIL,
    ATTACHMENTREFTYPE_INPUT,
    ATTACHMENTREFTYPE_RESOLVE,
};

VkImageUsageFlags getImageUsageFromLayout(VkImageLayout layout)
{
    switch (layout)
    {
    case VK_IMAGE_LAYOUT_GENERAL:
    case VK_IMAGE_LAYOUT_PREINITIALIZED:
        return 0;

    case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
        return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;

    case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
    case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
        return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;

    case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
        return VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;

    case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
        return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;

    case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
        return VK_IMAGE_USAGE_TRANSFER_DST_BIT;

    default:
        DE_FATAL("Unexpected image layout");
        return 0;
    }
}

void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags> &attachmentImageUsage, AttachmentRefType refType,
                                           size_t count, const AttachmentReference *references)
{
    for (size_t referenceNdx = 0; referenceNdx < count; ++referenceNdx)
    {
        const uint32_t attachment = references[referenceNdx].getAttachment();

        if (attachment != VK_ATTACHMENT_UNUSED)
        {
            VkImageUsageFlags usage;

            switch (refType)
            {
            case ATTACHMENTREFTYPE_COLOR:
            case ATTACHMENTREFTYPE_RESOLVE:
                usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
                break;

            case ATTACHMENTREFTYPE_DEPTH_STENCIL:
                usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
                break;

            case ATTACHMENTREFTYPE_INPUT:
                usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
                break;

            default:
                DE_FATAL("Unexpected attachment reference type");
                usage = 0;
                break;
            }

            attachmentImageUsage[attachment] |= usage;
        }
    }
}

void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags> &attachmentImageUsage, AttachmentRefType refType,
                                           const vector<AttachmentReference> &references)
{
    if (!references.empty())
    {
        getImageUsageFromAttachmentReferences(attachmentImageUsage, refType, references.size(), &references[0]);
    }
}

void initializeAttachmentImageUsage(Context &context, vector<VkImageUsageFlags> &attachmentImageUsage,
                                    const RenderPass &renderPassInfo, const vector<bool> &attachmentIsLazy,
                                    const vector<Maybe<VkClearValue>> &clearValues)
{
    attachmentImageUsage.resize(renderPassInfo.getAttachments().size(), VkImageUsageFlags(0));

    for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); ++subpassNdx)
    {
        const Subpass &subpass = renderPassInfo.getSubpasses()[subpassNdx];

        getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_COLOR,
                                              subpass.getColorAttachments());
        getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_DEPTH_STENCIL, 1,
                                              &subpass.getDepthStencilAttachment());
        getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_INPUT,
                                              subpass.getInputAttachments());
        getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_RESOLVE,
                                              subpass.getResolveAttachments());
    }

    for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
    {
        const Attachment &attachment              = renderPassInfo.getAttachments()[attachmentNdx];
        const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(
            context.getInstanceInterface(), context.getPhysicalDevice(), attachment.getFormat());
        const VkFormatFeatureFlags supportedFeatures = formatProperties.optimalTilingFeatures;

        if ((supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
            attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_SAMPLED_BIT;

        if ((supportedFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0)
            attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_STORAGE_BIT;

        attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getInitialLayout());
        attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getFinalLayout());

        if (!attachmentIsLazy[attachmentNdx])
        {
            if (clearValues[attachmentNdx])
                attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;

            attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
        }
        else
        {
            const VkImageUsageFlags allowedTransientBits = static_cast<VkImageUsageFlags>(
                VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
                VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);

            attachmentImageUsage[attachmentNdx] &= allowedTransientBits;
            attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
        }
    }
}

void initializeSubpassIsSecondary(vector<bool> &subpassIsSecondary, const vector<Subpass> &subpasses,
                                  TestConfig::CommandBufferTypes commandBuffer)
{
    bool lastSubpassWasSecondary = false;

    for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
    {
        if (commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY ||
            (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary))
        {
            subpassIsSecondary.push_back(true);
            lastSubpassWasSecondary = true;
        }
        else if (commandBuffer & TestConfig::COMMANDBUFFERTYPES_INLINE)
        {
            subpassIsSecondary.push_back(false);
            lastSubpassWasSecondary = false;
        }
        else
            DE_FATAL("Unknown commandBuffer");
    }
}

void initializeImageClearValues(de::Random &rng, vector<Maybe<VkClearValue>> &clearValues,
                                const vector<Attachment> &attachments, const vector<bool> &isLazy,
                                bool useFormatCompCount, const DepthValuesArray &depthValues)
{
    for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
    {
        if (!isLazy[attachmentNdx])
            clearValues.push_back(
                just(randomClearValue(attachments[attachmentNdx], rng, useFormatCompCount, depthValues)));
        else
            clearValues.push_back(tcu::Nothing);
    }
}

void initializeRenderPassClearValues(de::Random &rng, vector<Maybe<VkClearValue>> &clearValues,
                                     const vector<Attachment> &attachments, bool useFormatCompCount,
                                     const DepthValuesArray &depthValues)
{
    for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
    {
        if (attachments[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR ||
            attachments[attachmentNdx].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
        {
            clearValues.push_back(
                just(randomClearValue(attachments[attachmentNdx], rng, useFormatCompCount, depthValues)));
        }
        else
            clearValues.push_back(tcu::Nothing);
    }
}

void logSubpassRenderInfo(TestLog &log, const SubpassRenderInfo &info, TestConfig config)
{
    log << TestLog::Message << "Viewport, offset: " << info.getViewportOffset() << ", size: " << info.getViewportSize()
        << TestLog::EndMessage;

    if (info.isSecondary())
        log << TestLog::Message << "Subpass uses secondary command buffers" << TestLog::EndMessage;
    else
        log << TestLog::Message << "Subpass uses inlined commands" << TestLog::EndMessage;

    for (uint32_t attachmentNdx = 0; attachmentNdx < info.getColorClears().size(); attachmentNdx++)
    {
        const ColorClear &colorClear = info.getColorClears()[attachmentNdx];

        log << TestLog::Message << "Clearing color attachment " << attachmentNdx
            << ". Offset: " << colorClear.getOffset() << ", Size: " << colorClear.getSize() << ", Color: "
            << clearColorToString(info.getColorAttachment(attachmentNdx).getFormat(), colorClear.getColor(),
                                  config.useFormatCompCount)
            << TestLog::EndMessage;
    }

    if (info.getDepthStencilClear())
    {
        const DepthStencilClear &depthStencilClear = *info.getDepthStencilClear();

        log << TestLog::Message << "Clearing depth stencil attachment"
            << ". Offset: " << depthStencilClear.getOffset() << ", Size: " << depthStencilClear.getSize()
            << ", Depth: " << depthStencilClear.getDepth() << ", Stencil: " << depthStencilClear.getStencil()
            << TestLog::EndMessage;
    }

    if (info.getRenderQuad())
    {
        const RenderQuad &renderQuad = *info.getRenderQuad();

        log << TestLog::Message << "Rendering grid quad to " << renderQuad.getCornerA() << " -> "
            << renderQuad.getCornerB() << TestLog::EndMessage;
    }
}

void logTestCaseInfo(TestLog &log, const TestConfig &config, const vector<bool> &attachmentIsLazy,
                     const vector<Maybe<VkClearValue>> &imageClearValues,
                     const vector<Maybe<VkClearValue>> &renderPassClearValues,
                     const vector<SubpassRenderInfo> &subpassRenderInfo)
{
    const RenderPass &renderPass = config.renderPass;

    logRenderPassInfo(log, renderPass);

    DE_ASSERT(attachmentIsLazy.size() == renderPass.getAttachments().size());
    DE_ASSERT(imageClearValues.size() == renderPass.getAttachments().size());
    DE_ASSERT(renderPassClearValues.size() == renderPass.getAttachments().size());

    log << TestLog::Message << "TargetSize: " << config.targetSize << TestLog::EndMessage;
    log << TestLog::Message << "Render area, Offset: " << config.renderPos << ", Size: " << config.renderSize
        << TestLog::EndMessage;

    for (size_t attachmentNdx = 0; attachmentNdx < attachmentIsLazy.size(); attachmentNdx++)
    {
        const tcu::ScopedLogSection section(log, "Attachment" + de::toString(attachmentNdx),
                                            "Attachment " + de::toString(attachmentNdx));

        if (attachmentIsLazy[attachmentNdx])
            log << TestLog::Message << "Is lazy." << TestLog::EndMessage;

        if (imageClearValues[attachmentNdx])
            log << TestLog::Message << "Image is cleared to "
                << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(),
                                      *imageClearValues[attachmentNdx], config.useFormatCompCount)
                << " before rendering." << TestLog::EndMessage;

        if (renderPass.getAttachments()[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR &&
            renderPassClearValues[attachmentNdx])
            log << TestLog::Message << "Attachment is cleared to "
                << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(),
                                      *renderPassClearValues[attachmentNdx], config.useFormatCompCount)
                << " in the beginning of the render pass." << TestLog::EndMessage;
    }

    for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
    {
        const tcu::ScopedLogSection section(log, "Subpass" + de::toString(subpassNdx),
                                            "Subpass " + de::toString(subpassNdx));

        logSubpassRenderInfo(log, subpassRenderInfo[subpassNdx], config);
    }
}

float roundToViewport(float x, uint32_t offset, uint32_t size)
{
    const float origin = (float)(offset) + ((float(size) / 2.0f));
    const float p      = (float)(size) / 2.0f;
    const int32_t xi   = deRoundFloatToInt32(origin + (p * x));

    return (((float)xi) - origin) / p;
}

void initializeSubpassRenderInfo(vector<SubpassRenderInfo> &renderInfos, de::Random &rng, const RenderPass &renderPass,
                                 const TestConfig &config)
{
    const TestConfig::CommandBufferTypes commandBuffer = config.commandBufferTypes;
    const vector<Subpass> &subpasses                   = renderPass.getSubpasses();
    bool lastSubpassWasSecondary                       = false;

    for (uint32_t subpassNdx = 0; subpassNdx < (uint32_t)subpasses.size(); subpassNdx++)
    {
        const Subpass &subpass = subpasses[subpassNdx];
        const bool subpassIsSecondary =
            commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY ||
                    (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary) ?
                true :
                false;
        const bool omitBlendState = subpass.getOmitBlendState();
        const UVec2 viewportSize((config.renderSize * UVec2(2)) / UVec2(3));
        const UVec2 viewportOffset(config.renderPos.x() + (subpassNdx % 2) * (config.renderSize.x() / 3),
                                   config.renderPos.y() + ((subpassNdx / 2) % 2) * (config.renderSize.y() / 3));

        vector<ColorClear> colorClears;
        Maybe<DepthStencilClear> depthStencilClear;
        Maybe<RenderQuad> renderQuad;

        lastSubpassWasSecondary = subpassIsSecondary;

        if (config.renderTypes & TestConfig::RENDERTYPES_CLEAR)
        {
            const vector<AttachmentReference> &colorAttachments = subpass.getColorAttachments();

            for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
            {
                const AttachmentReference &attachmentRef = colorAttachments[attachmentRefNdx];
                const Attachment &attachment             = renderPass.getAttachments()[attachmentRef.getAttachment()];
                const UVec2 size((viewportSize * UVec2(2)) / UVec2(3));
                const UVec2 offset(viewportOffset.x() + ((uint32_t)attachmentRefNdx % 2u) * (viewportSize.x() / 3u),
                                   viewportOffset.y() +
                                       (((uint32_t)attachmentRefNdx / 2u) % 2u) * (viewportSize.y() / 3u));
                const VkClearColorValue color = randomColorClearValue(attachment, rng, config.useFormatCompCount);

                colorClears.push_back(ColorClear(offset, size, color));
            }

            if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
            {
                const Attachment &attachment =
                    renderPass.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()];
                const UVec2 size((viewportSize * UVec2(2)) / UVec2(3));
                const UVec2 offset(
                    viewportOffset.x() + ((uint32_t)colorAttachments.size() % 2u) * (viewportSize.x() / 3u),
                    viewportOffset.y() + (((uint32_t)colorAttachments.size() / 2u) % 2u) * (viewportSize.y() / 3u));
                const VkClearValue value =
                    randomClearValue(attachment, rng, config.useFormatCompCount, config.depthValues);

                depthStencilClear =
                    tcu::just(DepthStencilClear(offset, size, value.depthStencil.depth, value.depthStencil.stencil));
            }
        }

        if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
        {
            const float w = (subpassNdx % 2) == 0 ? 1.0f : 1.25f;
            const float h = (subpassNdx % 2) == 0 ? 1.25f : 1.0f;

            const float x0 =
                roundToViewport((subpassNdx % 2) == 0 ? 1.0f - w : -1.0f, viewportOffset.x(), viewportSize.x());
            const float x1 =
                roundToViewport((subpassNdx % 2) == 0 ? 1.0f : -1.0f + w, viewportOffset.x(), viewportSize.x());

            const float y0 =
                roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f - h : -1.0f, viewportOffset.y(), viewportSize.y());
            const float y1 =
                roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f : -1.0f + h, viewportOffset.y(), viewportSize.y());

            renderQuad = tcu::just(RenderQuad(tcu::Vec2(x0, y0), tcu::Vec2(x1, y1)));
        }

        renderInfos.push_back(SubpassRenderInfo(renderPass, subpassNdx, config.drawStartNdx, subpassIsSecondary,
                                                omitBlendState, viewportOffset, viewportSize, renderQuad, colorClears,
                                                depthStencilClear));
    }
}

void checkTextureFormatSupport(TestLog &log, const InstanceInterface &vk, VkPhysicalDevice device,
                               const vector<Attachment> &attachments)
{
    bool supported = true;

    for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
    {
        const Attachment &attachment          = attachments[attachmentNdx];
        const tcu::TextureFormat format       = mapVkFormat(attachment.getFormat());
        const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || hasStencilComponent(format.order);
        const VkFormatFeatureFlags flags = isDepthOrStencilAttachment ? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT :
                                                                        VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
        VkFormatProperties properties;

        vk.getPhysicalDeviceFormatProperties(device, attachment.getFormat(), &properties);

        if ((properties.optimalTilingFeatures & flags) != flags)
        {
            supported = false;
            log << TestLog::Message << "Format: " << attachment.getFormat() << " not supported as "
                << (isDepthOrStencilAttachment ? "depth stencil attachment" : "color attachment")
                << TestLog::EndMessage;
        }
    }

    if (!supported)
        TCU_THROW(NotSupportedError, "Format not supported");
}

tcu::TestStatus renderPassTest(Context &context, TestConfig config)
{
    const UVec2 targetSize           = config.targetSize;
    const UVec2 renderPos            = config.renderPos;
    const UVec2 renderSize           = config.renderSize;
    const RenderPass &renderPassInfo = config.renderPass;

    TestLog &log = context.getTestContext().getLog();
    de::Random rng(config.seed);

    vector<bool> attachmentIsLazy;
    vector<VkImageUsageFlags> attachmentImageUsage;
    vector<Maybe<VkClearValue>> imageClearValues;
    vector<Maybe<VkClearValue>> renderPassClearValues;

    vector<bool> subpassIsSecondary;
    vector<SubpassRenderInfo> subpassRenderInfo;

    if (config.renderPassType == RENDERPASS_TYPE_RENDERPASS2)
        context.requireDeviceFunctionality("VK_KHR_create_renderpass2");

    if (config.allocationKind == ALLOCATION_KIND_DEDICATED)
    {
        if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
            TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
    }

    if (!renderPassInfo.getInputAspects().empty())
    {
        if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance2"))
            TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance2 not supported.");
    }

    {
        bool requireDepthStencilLayout = false;

        for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
        {
            if (renderPassInfo.getAttachments()[attachmentNdx].getInitialLayout() ==
                    VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ||
                renderPassInfo.getAttachments()[attachmentNdx].getInitialLayout() ==
                    VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL ||
                renderPassInfo.getAttachments()[attachmentNdx].getFinalLayout() ==
                    VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ||
                renderPassInfo.getAttachments()[attachmentNdx].getFinalLayout() ==
                    VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
            {
                requireDepthStencilLayout = true;
                break;
            }
        }

        for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size() && !requireDepthStencilLayout;
             subpassNdx++)
        {
            const Subpass &subpass(renderPassInfo.getSubpasses()[subpassNdx]);

            for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
            {
                if (subpass.getColorAttachments()[attachmentNdx].getImageLayout() ==
                        VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ||
                    subpass.getColorAttachments()[attachmentNdx].getImageLayout() ==
                        VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
                {
                    requireDepthStencilLayout = true;
                    break;
                }
            }

            for (size_t attachmentNdx = 0;
                 !requireDepthStencilLayout && attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
            {
                if (subpass.getInputAttachments()[attachmentNdx].getImageLayout() ==
                        VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ||
                    subpass.getInputAttachments()[attachmentNdx].getImageLayout() ==
                        VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
                {
                    requireDepthStencilLayout = true;
                    break;
                }
            }

            for (size_t attachmentNdx = 0;
                 !requireDepthStencilLayout && attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
            {
                if (subpass.getResolveAttachments()[attachmentNdx].getImageLayout() ==
                        VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ||
                    subpass.getResolveAttachments()[attachmentNdx].getImageLayout() ==
                        VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
                {
                    requireDepthStencilLayout = true;
                    break;
                }
            }

            if (subpass.getDepthStencilAttachment().getImageLayout() ==
                    VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ||
                subpass.getDepthStencilAttachment().getImageLayout() ==
                    VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL)
            {
                requireDepthStencilLayout = true;
                break;
            }
        }

        if (requireDepthStencilLayout && !context.isDeviceFunctionalitySupported("VK_KHR_maintenance2"))
            TCU_THROW(NotSupportedError, "VK_KHR_maintenance2 is not supported");
    }

    initializeAttachmentIsLazy(attachmentIsLazy, renderPassInfo.getAttachments(), config.imageMemory);
    initializeImageClearValues(rng, imageClearValues, renderPassInfo.getAttachments(), attachmentIsLazy,
                               config.useFormatCompCount, config.depthValues);
    initializeAttachmentImageUsage(context, attachmentImageUsage, renderPassInfo, attachmentIsLazy, imageClearValues);
    initializeRenderPassClearValues(rng, renderPassClearValues, renderPassInfo.getAttachments(),
                                    config.useFormatCompCount, config.depthValues);

    initializeSubpassIsSecondary(subpassIsSecondary, renderPassInfo.getSubpasses(), config.commandBufferTypes);
    initializeSubpassRenderInfo(subpassRenderInfo, rng, renderPassInfo, config);

    logTestCaseInfo(log, config, attachmentIsLazy, imageClearValues, renderPassClearValues, subpassRenderInfo);

    checkTextureFormatSupport(log, context.getInstanceInterface(), context.getPhysicalDevice(),
                              config.renderPass.getAttachments());

    {
        const vk::VkPhysicalDeviceProperties properties =
            vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice());

        log << TestLog::Message << "Max color attachments: " << properties.limits.maxColorAttachments
            << TestLog::EndMessage;

        for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
        {
            if (renderPassInfo.getSubpasses()[subpassNdx].getColorAttachments().size() >
                (size_t)properties.limits.maxColorAttachments)
                TCU_THROW(NotSupportedError, "Subpass uses more than maxColorAttachments.");
        }
    }

    {
        const InstanceInterface &vki       = context.getInstanceInterface();
        const VkPhysicalDevice &physDevice = context.getPhysicalDevice();
        const VkDevice device              = context.getDevice();
        const DeviceInterface &vk          = context.getDeviceInterface();
        const VkQueue queue                = context.getUniversalQueue();
        const uint32_t queueIndex          = context.getUniversalQueueFamilyIndex();
        Allocator &allocator               = context.getDefaultAllocator();

        const Unique<VkRenderPass> renderPass(createRenderPass(vk, device, renderPassInfo, config.renderPassType));
        const Unique<VkCommandPool> commandBufferPool(createCommandPool(vk, device, 0, queueIndex));
        const Unique<VkCommandBuffer> initializeImagesCommandBuffer(
            allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
        const Unique<VkCommandBuffer> renderCommandBuffer(
            allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
        const Unique<VkCommandBuffer> readImagesToBuffersCommandBuffer(
            allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

        vector<de::SharedPtr<AttachmentResources>> attachmentResources;
        vector<de::SharedPtr<SubpassRenderer>> subpassRenderers;
        vector<VkImage> attachmentImages;
        vector<VkImageView> attachmentViews;
        vector<pair<VkImageView, VkImageView>> inputAttachmentViews;

        for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
        {
            const Attachment &attachmentInfo = renderPassInfo.getAttachments()[attachmentNdx];

            attachmentResources.push_back(de::SharedPtr<AttachmentResources>(
                new AttachmentResources(vki, physDevice, vk, device, allocator, queueIndex, targetSize, attachmentInfo,
                                        attachmentImageUsage[attachmentNdx], config.allocationKind)));
            attachmentViews.push_back(attachmentResources[attachmentNdx]->getAttachmentView());
            attachmentImages.push_back(attachmentResources[attachmentNdx]->getImage());

            inputAttachmentViews.push_back(attachmentResources[attachmentNdx]->getInputAttachmentViews());
        }

        beginCommandBuffer(vk, *initializeImagesCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL,
                           VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
        pushImageInitializationCommands(vk, *initializeImagesCommandBuffer, renderPassInfo.getAttachments(),
                                        attachmentResources, queueIndex, imageClearValues);
        endCommandBuffer(vk, *initializeImagesCommandBuffer);

        {
            const Unique<VkFramebuffer> framebuffer(
                createFramebuffer(vk, device, *renderPass, targetSize, attachmentViews));

            for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
                subpassRenderers.push_back(de::SharedPtr<SubpassRenderer>(new SubpassRenderer(
                    context, vk, device, allocator, *renderPass, *framebuffer, *commandBufferPool, queueIndex,
                    attachmentImages, inputAttachmentViews, subpassRenderInfo[subpassNdx],
                    config.renderPass.getAttachments(), config.allocationKind)));

            beginCommandBuffer(vk, *renderCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE,
                               (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
            pushRenderPassCommands(vk, *renderCommandBuffer, *renderPass, *framebuffer, subpassRenderers, renderPos,
                                   renderSize, renderPassClearValues, config.renderTypes, config.renderPassType);
            endCommandBuffer(vk, *renderCommandBuffer);

            beginCommandBuffer(vk, *readImagesToBuffersCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL,
                               VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
            pushReadImagesToBuffers(vk, *readImagesToBuffersCommandBuffer, queueIndex, attachmentResources,
                                    renderPassInfo.getAttachments(), attachmentIsLazy, targetSize);
            endCommandBuffer(vk, *readImagesToBuffersCommandBuffer);
            {
                const VkCommandBuffer commandBuffers[] = {*initializeImagesCommandBuffer, *renderCommandBuffer,
                                                          *readImagesToBuffersCommandBuffer};
                const Unique<VkFence> fence(createFence(vk, device, 0u));

                queueSubmit(vk, queue, DE_LENGTH_OF_ARRAY(commandBuffers), commandBuffers, *fence);
                waitForFences(vk, device, 1, &fence.get(), VK_TRUE, ~0ull);
            }
        }
#ifdef CTS_USES_VULKANSC
        if (!context.getTestContext().getCommandLine().isSubProcess())
            return tcu::TestStatus::pass("Pass");
#endif
        if (logAndVerifyImages(log, vk, device, attachmentResources, attachmentIsLazy, renderPassInfo,
                               renderPassClearValues, imageClearValues, subpassRenderInfo, targetSize, config))
            return tcu::TestStatus::pass("Pass");
        else
            return tcu::TestStatus::fail("Result verification failed");
    }
}

static const VkFormat s_coreColorFormats[] = {VK_FORMAT_R5G6B5_UNORM_PACK16,
                                              VK_FORMAT_R8_UNORM,
                                              VK_FORMAT_R8_SNORM,
                                              VK_FORMAT_R8_UINT,
                                              VK_FORMAT_R8_SINT,
                                              VK_FORMAT_R8G8_UNORM,
                                              VK_FORMAT_R8G8_SNORM,
                                              VK_FORMAT_R8G8_UINT,
                                              VK_FORMAT_R8G8_SINT,
                                              VK_FORMAT_R8G8B8A8_UNORM,
                                              VK_FORMAT_R8G8B8A8_SNORM,
                                              VK_FORMAT_R8G8B8A8_UINT,
                                              VK_FORMAT_R8G8B8A8_SINT,
                                              VK_FORMAT_R8G8B8A8_SRGB,
                                              VK_FORMAT_A8B8G8R8_UNORM_PACK32,
                                              VK_FORMAT_A8B8G8R8_SNORM_PACK32,
                                              VK_FORMAT_A8B8G8R8_UINT_PACK32,
                                              VK_FORMAT_A8B8G8R8_SINT_PACK32,
                                              VK_FORMAT_A8B8G8R8_SRGB_PACK32,
                                              VK_FORMAT_B8G8R8A8_UNORM,
                                              VK_FORMAT_B8G8R8A8_SRGB,
                                              VK_FORMAT_A2R10G10B10_UNORM_PACK32,
                                              VK_FORMAT_A2B10G10R10_UNORM_PACK32,
                                              VK_FORMAT_A2B10G10R10_UINT_PACK32,
                                              VK_FORMAT_R16_UNORM,
                                              VK_FORMAT_R16_SNORM,
                                              VK_FORMAT_R16_UINT,
                                              VK_FORMAT_R16_SINT,
                                              VK_FORMAT_R16_SFLOAT,
                                              VK_FORMAT_R16G16_UNORM,
                                              VK_FORMAT_R16G16_SNORM,
                                              VK_FORMAT_R16G16_UINT,
                                              VK_FORMAT_R16G16_SINT,
                                              VK_FORMAT_R16G16_SFLOAT,
                                              VK_FORMAT_R16G16B16A16_UNORM,
                                              VK_FORMAT_R16G16B16A16_SNORM,
                                              VK_FORMAT_R16G16B16A16_UINT,
                                              VK_FORMAT_R16G16B16A16_SINT,
                                              VK_FORMAT_R16G16B16A16_SFLOAT,
                                              VK_FORMAT_R32_UINT,
                                              VK_FORMAT_R32_SINT,
                                              VK_FORMAT_R32_SFLOAT,
                                              VK_FORMAT_R32G32_UINT,
                                              VK_FORMAT_R32G32_SINT,
                                              VK_FORMAT_R32G32_SFLOAT,
                                              VK_FORMAT_R32G32B32A32_UINT,
                                              VK_FORMAT_R32G32B32A32_SINT,
                                              VK_FORMAT_R32G32B32A32_SFLOAT};

static const VkFormat s_coreDepthStencilFormats[] = {VK_FORMAT_D16_UNORM,

                                                     VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D32_SFLOAT,

                                                     VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT};

void addAttachmentTests(tcu::TestCaseGroup *group, const TestConfigExternal testConfigExternal)
{
    const uint32_t attachmentCounts[]  = {1, 3, 4, 8};
    const VkAttachmentLoadOp loadOps[] = {VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR,
                                          VK_ATTACHMENT_LOAD_OP_DONT_CARE};

    const VkAttachmentStoreOp storeOps[] = {VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_STORE_OP_DONT_CARE};

    const VkImageLayout initialAndFinalColorLayouts[] = {
        VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
        VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL};

    const VkImageLayout initialAndFinalColorLayoutsLazy[] = {
        VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};

    const VkImageLayout initialAndFinalDepthStencilLayouts[] = {VK_IMAGE_LAYOUT_GENERAL,
                                                                VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
                                                                VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
                                                                VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
                                                                VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
                                                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL};

    const VkImageLayout initialAndFinalDepthStencilLayoutsLazy[] = {
        VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
        VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};

    const VkImageLayout subpassLayouts[] = {VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};

    const VkImageLayout depthStencilLayouts[] = {VK_IMAGE_LAYOUT_GENERAL,
                                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};

    const TestConfig::RenderTypes renderCommands[] = {
        TestConfig::RENDERTYPES_NONE,
        TestConfig::RENDERTYPES_CLEAR,
        TestConfig::RENDERTYPES_DRAW,
        TestConfig::RENDERTYPES_CLEAR | TestConfig::RENDERTYPES_DRAW,
    };

    const TestConfig::CommandBufferTypes commandBuffers[] = {
        TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::COMMANDBUFFERTYPES_SECONDARY,
        TestConfig::COMMANDBUFFERTYPES_INLINE | TestConfig::COMMANDBUFFERTYPES_SECONDARY};

    const TestConfig::ImageMemory imageMemories[] = {TestConfig::IMAGEMEMORY_STRICT, TestConfig::IMAGEMEMORY_LAZY,
                                                     TestConfig::IMAGEMEMORY_STRICT | TestConfig::IMAGEMEMORY_LAZY};

    const UVec2 targetSizes[] = {UVec2(64, 64), UVec2(63, 65)};

    const UVec2 renderPositions[] = {UVec2(0, 0), UVec2(3, 17)};

    const UVec2 renderSizes[] = {UVec2(32, 32), UVec2(60, 47)};

    tcu::TestContext &testCtx = group->getTestContext();
    de::Random rng(1433774382u);

    for (size_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
    {
        const uint32_t attachmentCount = attachmentCounts[attachmentCountNdx];
        const uint32_t testCaseCount   = (attachmentCount == 1 ? 100 : 200);
        de::MovePtr<tcu::TestCaseGroup> attachmentCountGroup(new tcu::TestCaseGroup(
            testCtx, de::toString(attachmentCount).c_str(), de::toString(attachmentCount).c_str()));

        for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
        {
            const bool useDepthStencil = rng.getBool();
            const TestConfig::ImageMemory imageMemory =
                rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
            VkImageLayout depthStencilLayout = VK_IMAGE_LAYOUT_GENERAL;
            vector<Attachment> attachments;
            vector<AttachmentReference> colorAttachmentReferences;

            for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
            {
                const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
                const VkFormat format =
                    rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
                const VkAttachmentLoadOp loadOp =
                    rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
                const VkAttachmentStoreOp storeOp =
                    rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));

                const VkImageLayout initialLayout =
                    (imageMemory == TestConfig::IMAGEMEMORY_STRICT) ?
                        rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts),
                                                  DE_ARRAY_END(initialAndFinalColorLayouts)) :
                        rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayoutsLazy),
                                                  DE_ARRAY_END(initialAndFinalColorLayoutsLazy));
                const VkImageLayout finalizeLayout =
                    (imageMemory == TestConfig::IMAGEMEMORY_STRICT) ?
                        rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts),
                                                  DE_ARRAY_END(initialAndFinalColorLayouts)) :
                        rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayoutsLazy),
                                                  DE_ARRAY_END(initialAndFinalColorLayoutsLazy));
                const VkImageLayout subpassLayout =
                    rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));

                const VkAttachmentLoadOp stencilLoadOp =
                    rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
                const VkAttachmentStoreOp stencilStoreOp =
                    rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));

                attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp,
                                                 initialLayout, finalizeLayout));
                colorAttachmentReferences.push_back(AttachmentReference((uint32_t)attachmentNdx, subpassLayout));
            }

            if (useDepthStencil)
            {
                const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
                const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats),
                                                             DE_ARRAY_END(s_coreDepthStencilFormats));
                const VkAttachmentLoadOp loadOp =
                    rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
                const VkAttachmentStoreOp storeOp =
                    rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));

                const VkImageLayout initialLayout =
                    (imageMemory == TestConfig::IMAGEMEMORY_STRICT) ?
                        rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts),
                                                  DE_ARRAY_END(initialAndFinalDepthStencilLayouts)) :
                        rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayoutsLazy),
                                                  DE_ARRAY_END(initialAndFinalDepthStencilLayoutsLazy));
                const VkImageLayout finalizeLayout =
                    (imageMemory == TestConfig::IMAGEMEMORY_STRICT) ?
                        rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts),
                                                  DE_ARRAY_END(initialAndFinalDepthStencilLayouts)) :
                        rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayoutsLazy),
                                                  DE_ARRAY_END(initialAndFinalDepthStencilLayoutsLazy));

                const VkAttachmentLoadOp stencilLoadOp =
                    rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
                const VkAttachmentStoreOp stencilStoreOp =
                    rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));

                depthStencilLayout =
                    rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(depthStencilLayouts), DE_ARRAY_END(depthStencilLayouts));
                attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp,
                                                 initialLayout, finalizeLayout));
            }

            {
                const TestConfig::RenderTypes render =
                    rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
                const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(
                    DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
                const vector<Subpass> subpasses(
                    1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                               colorAttachmentReferences, vector<AttachmentReference>(),
                               AttachmentReference(
                                   (useDepthStencil ? (uint32_t)(attachments.size() - 1) : VK_ATTACHMENT_UNUSED),
                                   depthStencilLayout),
                               vector<uint32_t>()));
                const vector<SubpassDependency> deps;

                const string testCaseName = de::toString(attachmentCountNdx * testCaseCount + testCaseNdx);
                const RenderPass renderPass(attachments, subpasses, deps);
                const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
                const UVec2 renderPos =
                    rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
                const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
                const TestConfig testConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos,
                                            renderSize, false, 1293809, 0, testConfigExternal.allocationKind,
                                            testConfigExternal.renderPassType);

                addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(),
                                                        testCaseName.c_str(), createTestShaders, renderPassTest,
                                                        testConfig);
            }
        }

        group->addChild(attachmentCountGroup.release());
    }
}

void addAttachmentWriteMaskTests(tcu::TestCaseGroup *group, const TestConfigExternal testConfigExternal)
{
    const uint32_t attachmentCounts[] = {1, 2, 3, 4, 8};

    const VkFormat attachmentFormats[] = {VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_R8G8B8A8_UNORM,
                                          VK_FORMAT_R5G6B5_UNORM_PACK16, VK_FORMAT_R8G8_UNORM};

    tcu::TestContext &testCtx = group->getTestContext();

    for (uint32_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts);
         attachmentCountNdx++)
    {
        const uint32_t attachmentCount = attachmentCounts[attachmentCountNdx];
        const string groupName         = "attachment_count_" + de::toString(attachmentCount);

        de::MovePtr<tcu::TestCaseGroup> attachmentCountGroup(
            new tcu::TestCaseGroup(testCtx, groupName.c_str(), de::toString(attachmentCount).c_str()));

        for (uint32_t drawStartNdx = 0; drawStartNdx < (attachmentCount); drawStartNdx++)
        {
            uint32_t formatNdx = 0;
            vector<Attachment> attachments;
            vector<AttachmentReference> colorAttachmentReferences;

            for (uint32_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
            {
                const VkFormat format                    = attachmentFormats[formatNdx];
                const VkSampleCountFlagBits sampleCount  = VK_SAMPLE_COUNT_1_BIT;
                const VkAttachmentLoadOp loadOp          = VK_ATTACHMENT_LOAD_OP_CLEAR;
                const VkAttachmentStoreOp storeOp        = VK_ATTACHMENT_STORE_OP_STORE;
                const VkAttachmentLoadOp stencilLoadOp   = VK_ATTACHMENT_LOAD_OP_CLEAR;
                const VkAttachmentStoreOp stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
                const VkImageLayout initialLayout        = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
                const VkImageLayout finalizeLayout       = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
                const VkImageLayout subpassLayout        = VK_IMAGE_LAYOUT_GENERAL;

                attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp,
                                                 initialLayout, finalizeLayout));
                colorAttachmentReferences.push_back(AttachmentReference((uint32_t)attachmentNdx, subpassLayout));

                if (++formatNdx == DE_LENGTH_OF_ARRAY(attachmentFormats))
                    formatNdx = 0;
            }

            {
                const VkImageLayout depthStencilLayout = VK_IMAGE_LAYOUT_GENERAL;
                const vector<Subpass> subpass(
                    1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                               colorAttachmentReferences, vector<AttachmentReference>(),
                               AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<uint32_t>()));
                const vector<SubpassDependency> deps;

                const string testCaseName = "start_index_" + de::toString(drawStartNdx);
                const RenderPass renderPass(attachments, subpass, deps);

                const TestConfig::RenderTypes render               = TestConfig::RENDERTYPES_DRAW;
                const TestConfig::CommandBufferTypes commandBuffer = TestConfig::COMMANDBUFFERTYPES_INLINE;
                const TestConfig::ImageMemory imageMemory          = TestConfig::IMAGEMEMORY_LAZY;
                const UVec2 targetSize                             = UVec2(64, 64);
                const UVec2 renderPos                              = UVec2(0, 0);
                const UVec2 renderSize                             = UVec2(64, 64);
                const bool useFormatCompCount                      = true;
                const vector<DeviceCoreFeature> requiredFeatures   = {DEVICE_CORE_FEATURE_INDEPENDENT_BLEND};
                const TestConfig testConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos,
                                            renderSize, useFormatCompCount, 1293809, drawStartNdx,
                                            testConfigExternal.allocationKind, testConfigExternal.renderPassType,
                                            requiredFeatures);

                addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(),
                                                        testCaseName.c_str(), checkSupport, createTestShaders,
                                                        renderPassTest, testConfig);
            }
        }

        group->addChild(attachmentCountGroup.release());
    }
}

template <typename T>
T chooseRandom(de::Random &rng, const set<T> &values)
{
    size_t ndx                           = ((size_t)rng.getUint32()) % values.size();
    typename set<T>::const_iterator iter = values.begin();

    for (; ndx > 0; ndx--)
        iter++;

    return *iter;
}

void addAttachmentAllocationTests(tcu::TestCaseGroup *group, const TestConfigExternal testConfigExternal)
{
    const uint32_t attachmentCounts[]  = {4, 8};
    const VkAttachmentLoadOp loadOps[] = {VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR,
                                          VK_ATTACHMENT_LOAD_OP_DONT_CARE};

    const VkAttachmentStoreOp storeOps[] = {VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_STORE_OP_DONT_CARE};

    const VkImageLayout initialAndFinalColorLayouts[] = {
        VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
        VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL};

    const VkImageLayout initialAndFinalDepthStencilLayouts[] = {VK_IMAGE_LAYOUT_GENERAL,
                                                                VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
                                                                VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
                                                                VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
                                                                VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
                                                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL};

    const VkImageLayout subpassLayoutsColor[] = {VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};

    const VkImageLayout subpassLayoutsDepthStencil[] = {VK_IMAGE_LAYOUT_GENERAL,
                                                        VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};

    const VkImageLayout subpassLayoutsInput[] = {VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};

    enum AllocationType
    {
        // Each pass uses one more attachmen than previous one
        ALLOCATIONTYPE_GROW,
        // Each pass uses one less attachment than previous one
        ALLOCATIONTYPE_SHRINK,
        // Each pass drops one attachment and picks up new one
        ALLOCATIONTYPE_ROLL,
        // Start by growing and end by shrinking
        ALLOCATIONTYPE_GROW_SHRINK,
        // Each subpass has single input and single output attachment
        ALLOCATIONTYPE_IO_CHAIN,
        // Each subpass has multiple inputs and multiple outputs attachment
        ALLOCATIONTYPE_IO_GENERIC
    };

    const AllocationType allocationTypes[] = {ALLOCATIONTYPE_GROW,     ALLOCATIONTYPE_SHRINK,
                                              ALLOCATIONTYPE_ROLL,     ALLOCATIONTYPE_GROW_SHRINK,
                                              ALLOCATIONTYPE_IO_CHAIN, ALLOCATIONTYPE_IO_GENERIC};

    const char *const allocationTypeStr[] = {
        "grow", "shrink", "roll", "grow_shrink", "input_output_chain", "input_output",
    };

    const TestConfig::RenderTypes renderCommands[] = {
        TestConfig::RENDERTYPES_NONE,
        TestConfig::RENDERTYPES_CLEAR,
        TestConfig::RENDERTYPES_DRAW,
        TestConfig::RENDERTYPES_CLEAR | TestConfig::RENDERTYPES_DRAW,
    };

    const TestConfig::CommandBufferTypes commandBuffers[] = {
        TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::COMMANDBUFFERTYPES_SECONDARY,
        TestConfig::COMMANDBUFFERTYPES_INLINE | TestConfig::COMMANDBUFFERTYPES_SECONDARY};

    const TestConfig::ImageMemory imageMemories[] = {TestConfig::IMAGEMEMORY_STRICT, TestConfig::IMAGEMEMORY_LAZY,
                                                     TestConfig::IMAGEMEMORY_STRICT | TestConfig::IMAGEMEMORY_LAZY};

    const UVec2 targetSizes[] = {UVec2(64, 64), UVec2(63, 65)};

    const UVec2 renderPositions[] = {UVec2(0, 0), UVec2(3, 17)};

    const UVec2 renderSizes[] = {UVec2(32, 32), UVec2(60, 47)};

    tcu::TestContext &testCtx = group->getTestContext();
    de::Random rng(3700649827u);

    for (size_t allocationTypeNdx = 0; allocationTypeNdx < DE_LENGTH_OF_ARRAY(allocationTypes); allocationTypeNdx++)
    {
        const AllocationType allocationType = allocationTypes[allocationTypeNdx];
        const size_t testCaseCount          = 100;
        de::MovePtr<tcu::TestCaseGroup> allocationTypeGroup(new tcu::TestCaseGroup(
            testCtx, allocationTypeStr[allocationTypeNdx], allocationTypeStr[allocationTypeNdx]));

        for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
        {
            if (allocationType == ALLOCATIONTYPE_IO_GENERIC)
            {
                const uint32_t attachmentCount = 4u + rng.getUint32() % 31u;
                const uint32_t subpassCount    = 4u + rng.getUint32() % 31u;
                vector<Attachment> attachments;

                set<uint32_t> definedAttachments;

                vector<Subpass> subpasses;
                set<uint32_t> colorAttachments;
                set<uint32_t> depthStencilAttachments;

                for (uint32_t attachmentIndex = 0; attachmentIndex < attachmentCount; attachmentIndex++)
                {
                    const bool isDepthStencilAttachment     = rng.getFloat() < 0.01f;
                    const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
                    const VkAttachmentLoadOp loadOp =
                        rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
                    const VkAttachmentStoreOp storeOp =
                        rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));

                    const VkImageLayout initialLayout =
                        isDepthStencilAttachment ?
                            rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts),
                                                      DE_ARRAY_END(initialAndFinalDepthStencilLayouts)) :
                            rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts),
                                                      DE_ARRAY_END(initialAndFinalColorLayouts));
                    const VkImageLayout finalizeLayout =
                        isDepthStencilAttachment ?
                            rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts),
                                                      DE_ARRAY_END(initialAndFinalDepthStencilLayouts)) :
                            rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts),
                                                      DE_ARRAY_END(initialAndFinalColorLayouts));

                    const VkAttachmentLoadOp stencilLoadOp =
                        rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
                    const VkAttachmentStoreOp stencilStoreOp =
                        rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));

                    if (isDepthStencilAttachment)
                    {
                        const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats),
                                                                     DE_ARRAY_END(s_coreDepthStencilFormats));

                        if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR ||
                            stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
                            definedAttachments.insert(attachmentIndex);

                        depthStencilAttachments.insert(attachmentIndex);

                        attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp,
                                                         stencilStoreOp, initialLayout, finalizeLayout));
                    }
                    else
                    {
                        const VkFormat format =
                            rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));

                        if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
                            definedAttachments.insert(attachmentIndex);

                        colorAttachments.insert(attachmentIndex);

                        attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp,
                                                         stencilStoreOp, initialLayout, finalizeLayout));
                    }
                }
                vector<Maybe<uint32_t>> lastUseOfAttachment(attachments.size(), tcu::Nothing);
                vector<SubpassDependency> deps;

                for (uint32_t subpassIndex = 0; subpassIndex < subpassCount; subpassIndex++)
                {
                    const uint32_t colorAttachmentCount =
                        depthStencilAttachments.empty() ?
                            1 + rng.getUint32() % de::min(4u, (uint32_t)colorAttachments.size()) :
                            rng.getUint32() % (de::min(4u, (uint32_t)colorAttachments.size()) + 1u);
                    const uint32_t inputAttachmentCount =
                        rng.getUint32() % (uint32_t)(de::min<size_t>(4, definedAttachments.size()) + 1);
                    const bool useDepthStencilAttachment =
                        !depthStencilAttachments.empty() && (colorAttachmentCount == 0 || rng.getBool());
                    std::vector<uint32_t> subpassColorAttachments(colorAttachmentCount);
                    std::vector<uint32_t> subpassInputAttachments(inputAttachmentCount);
                    Maybe<uint32_t> depthStencilAttachment(
                        useDepthStencilAttachment ? just(chooseRandom(rng, depthStencilAttachments)) : tcu::Nothing);
                    std::vector<uint32_t> subpassPreserveAttachments;

                    rng.choose(colorAttachments.begin(), colorAttachments.end(), subpassColorAttachments.begin(),
                               colorAttachmentCount);
                    rng.choose(definedAttachments.begin(), definedAttachments.end(), subpassInputAttachments.begin(),
                               inputAttachmentCount);

                    for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size();
                         colorAttachmentNdx++)
                        definedAttachments.insert(subpassColorAttachments[colorAttachmentNdx]);

                    if (depthStencilAttachment)
                        definedAttachments.insert(*depthStencilAttachment);

                    {
                        std::vector<AttachmentReference> inputAttachmentReferences;
                        std::vector<AttachmentReference> colorAttachmentReferences;
                        AttachmentReference depthStencilAttachmentReference(VK_ATTACHMENT_UNUSED,
                                                                            VK_IMAGE_LAYOUT_GENERAL);

                        for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size();
                             colorAttachmentNdx++)
                        {
                            const uint32_t colorAttachmentIndex = subpassColorAttachments[colorAttachmentNdx];

                            if (lastUseOfAttachment[colorAttachmentIndex])
                            {
                                bool foundDuplicate = false;

                                const uint32_t srcPass = *lastUseOfAttachment[colorAttachmentIndex];
                                const uint32_t dstPass = subpassIndex;
                                const VkDependencyFlags dependencyFlags =
                                    rng.getBool() ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u;

                                const SubpassDependency newDependency(
                                    srcPass, dstPass,
                                    VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
                                        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
                                        VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
                                        VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,

                                    VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
                                        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
                                        VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
                                        VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,

                                    VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,

                                    dependencyFlags);

                                for (SubpassDependency &dependency : deps)
                                {
                                    if (dependency.getSrcPass() == srcPass && dependency.getDstPass() == dstPass)
                                    {
                                        const VkAccessFlags newDstFlags =
                                            dependency.getDstAccessMask() | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
                                        dependency.setDstAccessMask(newDstFlags);
                                        foundDuplicate = true;
                                        break;
                                    }
                                }

                                if (!foundDuplicate)
                                {
                                    deps.push_back(newDependency);
                                }
                            }

                            lastUseOfAttachment[colorAttachmentIndex] = just(subpassIndex);

                            colorAttachmentReferences.push_back(AttachmentReference(
                                (uint32_t)subpassColorAttachments[colorAttachmentNdx], VK_IMAGE_LAYOUT_GENERAL));
                        }

                        for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpassInputAttachments.size();
                             inputAttachmentNdx++)
                        {
                            const uint32_t inputAttachmentIndex = subpassInputAttachments[inputAttachmentNdx];

                            if (lastUseOfAttachment[inputAttachmentIndex])
                            {
                                bool foundDuplicate = false;

                                const uint32_t srcPass = *lastUseOfAttachment[inputAttachmentIndex];
                                const uint32_t dstPass = subpassIndex;
                                const VkDependencyFlags dependencyFlags =
                                    ((srcPass == subpassIndex) || rng.getBool()) ?
                                        (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT :
                                        0u;

                                const SubpassDependency newDependency(
                                    srcPass, dstPass,
                                    VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
                                        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
                                        VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
                                        VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,

                                    VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
                                        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
                                        VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
                                        VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,

                                    VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
                                    VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,

                                    dependencyFlags);
                                for (SubpassDependency &dependency : deps)
                                {
                                    if (dependency.getSrcPass() == srcPass && dependency.getDstPass() == dstPass)
                                    {
                                        const VkAccessFlags newSrcFlags = dependency.getSrcAccessMask() |
                                                                          VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
                                        const VkAccessFlags newDstFlags =
                                            dependency.getDstAccessMask() | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
                                        dependency.setDstAccessMask(newSrcFlags);
                                        dependency.setDstAccessMask(newDstFlags);
                                        foundDuplicate = true;
                                        break;
                                    }
                                }

                                if (!foundDuplicate)
                                {
                                    deps.push_back(newDependency);
                                }

                                lastUseOfAttachment[inputAttachmentIndex] = just(subpassIndex);

                                VkImageAspectFlags aspect = 0u;
                                if (testConfigExternal.renderPassType == RENDERPASS_TYPE_RENDERPASS2)
                                {
                                    bool col = colorAttachments.find(inputAttachmentIndex) != colorAttachments.end();
                                    aspect   = col ? VK_IMAGE_ASPECT_COLOR_BIT : VK_IMAGE_ASPECT_DEPTH_BIT;
                                }
                                inputAttachmentReferences.push_back(
                                    AttachmentReference((uint32_t)subpassInputAttachments[inputAttachmentNdx],
                                                        VK_IMAGE_LAYOUT_GENERAL, aspect));
                            }
                        }

                        if (depthStencilAttachment)
                        {
                            if (lastUseOfAttachment[*depthStencilAttachment])
                            {
                                bool foundDuplicate = false;

                                const uint32_t srcPass = *lastUseOfAttachment[*depthStencilAttachment];
                                const uint32_t dstPass = subpassIndex;
                                const VkDependencyFlags dependencyFlags =
                                    ((srcPass == subpassIndex) || rng.getBool()) ?
                                        (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT :
                                        0u;

                                const SubpassDependency newDependency(
                                    srcPass, dstPass,
                                    VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
                                        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
                                        VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
                                        VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,

                                    VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
                                        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
                                        VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
                                        VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,

                                    VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
                                    VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,

                                    dependencyFlags);
                                for (SubpassDependency &dependency : deps)
                                {
                                    if (dependency.getSrcPass() == srcPass && dependency.getDstPass() == dstPass)
                                    {
                                        const VkAccessFlags newSrcFlags = dependency.getSrcAccessMask() |
                                                                          VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
                                        const VkAccessFlags newDstFlags =
                                            dependency.getDstAccessMask() | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
                                        dependency.setDstAccessMask(newSrcFlags);
                                        dependency.setDstAccessMask(newDstFlags);
                                        foundDuplicate = true;
                                        break;
                                    }
                                }

                                if (!foundDuplicate)
                                {
                                    deps.push_back(newDependency);
                                }
                            }

                            lastUseOfAttachment[*depthStencilAttachment] = just(subpassIndex);

                            depthStencilAttachmentReference =
                                AttachmentReference(*depthStencilAttachment, VK_IMAGE_LAYOUT_GENERAL);
                        }
                        else
                            depthStencilAttachmentReference =
                                AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);

                        vector<uint32_t> preserveAttachments;
                        for (uint32_t attachmentIndex = 0; attachmentIndex < (uint32_t)attachments.size();
                             attachmentIndex++)
                        {
                            if (lastUseOfAttachment[attachmentIndex] &&
                                (*lastUseOfAttachment[attachmentIndex]) != subpassIndex)
                                preserveAttachments.push_back(attachmentIndex);
                        }

                        // Use random image layout when possible
                        for (size_t colorRefIdx = 0; colorRefIdx < colorAttachmentReferences.size(); ++colorRefIdx)
                        {
                            bool usedAsInput = false;
                            for (size_t inputRefIdx = 0; inputRefIdx < inputAttachmentReferences.size(); ++inputRefIdx)
                                if (colorAttachmentReferences[colorRefIdx].getAttachment() ==
                                    inputAttachmentReferences[inputRefIdx].getAttachment())
                                    usedAsInput = true;

                            if (!usedAsInput)
                                colorAttachmentReferences[colorRefIdx].setImageLayout(rng.choose<VkImageLayout>(
                                    DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor)));
                        }
                        for (size_t inputRefIdx = 0; inputRefIdx < inputAttachmentReferences.size(); ++inputRefIdx)
                        {
                            bool usedAsDepthStencil = inputAttachmentReferences[inputRefIdx].getAttachment() ==
                                                      depthStencilAttachmentReference.getAttachment();
                            bool usedAsColor = false;
                            for (size_t colorRefIdx = 0; colorRefIdx < colorAttachmentReferences.size(); ++colorRefIdx)
                                if (inputAttachmentReferences[inputRefIdx].getAttachment() ==
                                    colorAttachmentReferences[colorRefIdx].getAttachment())
                                    usedAsColor = true;

                            if (!usedAsColor && !usedAsDepthStencil)
                                inputAttachmentReferences[inputRefIdx].setImageLayout(rng.choose<VkImageLayout>(
                                    DE_ARRAY_BEGIN(subpassLayoutsInput), DE_ARRAY_END(subpassLayoutsInput)));
                        }
                        {
                            bool usedAsInput = false;
                            for (size_t inputRefIdx = 0; inputRefIdx < inputAttachmentReferences.size(); ++inputRefIdx)
                                if (depthStencilAttachmentReference.getAttachment() ==
                                    inputAttachmentReferences[inputRefIdx].getAttachment())
                                    usedAsInput = true;

                            if (!usedAsInput)
                                depthStencilAttachmentReference.setImageLayout(
                                    rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsDepthStencil),
                                                              DE_ARRAY_END(subpassLayoutsDepthStencil)));
                        }

                        subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, inputAttachmentReferences,
                                                    colorAttachmentReferences, vector<AttachmentReference>(),
                                                    depthStencilAttachmentReference, preserveAttachments));
                    }
                }
                {
                    const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(
                        DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
                    const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(
                        DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
                    const TestConfig::ImageMemory imageMemory =
                        rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));

                    const string testCaseName = de::toString(testCaseNdx);
                    const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
                    const UVec2 renderPos =
                        rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
                    const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));

                    const RenderPass renderPass(attachments, subpasses, deps);
                    const TestConfig testConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos,
                                                renderSize, false, 80329, 0, testConfigExternal.allocationKind,
                                                testConfigExternal.renderPassType);

                    addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(),
                                                            testCaseName.c_str(), createTestShaders, renderPassTest,
                                                            testConfig);
                }
            }
            else
            {
                const uint32_t attachmentCount =
                    rng.choose<uint32_t>(DE_ARRAY_BEGIN(attachmentCounts), DE_ARRAY_END(attachmentCounts));
                vector<Attachment> attachments;
                vector<Subpass> subpasses;

                for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
                {
                    const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
                    const VkFormat format =
                        rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
                    const VkAttachmentLoadOp loadOp =
                        rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
                    const VkAttachmentStoreOp storeOp =
                        rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));

                    const VkImageLayout initialLayout = rng.choose<VkImageLayout>(
                        DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
                    const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(
                        DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));

                    const VkAttachmentLoadOp stencilLoadOp =
                        rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
                    const VkAttachmentStoreOp stencilStoreOp =
                        rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));

                    attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp,
                                                     stencilStoreOp, initialLayout, finalizeLayout));
                }

                if (allocationType == ALLOCATIONTYPE_GROW)
                {
                    for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
                    {
                        vector<AttachmentReference> colorAttachmentReferences;

                        for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
                        {
                            const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(
                                DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));

                            colorAttachmentReferences.push_back(
                                AttachmentReference((uint32_t)attachmentNdx, subpassLayout));
                        }

                        subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                                                    colorAttachmentReferences, vector<AttachmentReference>(),
                                                    AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
                                                    vector<uint32_t>()));
                    }
                }
                else if (allocationType == ALLOCATIONTYPE_SHRINK)
                {
                    for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
                    {
                        vector<AttachmentReference> colorAttachmentReferences;

                        for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
                        {
                            const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(
                                DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));

                            colorAttachmentReferences.push_back(
                                AttachmentReference((uint32_t)attachmentNdx, subpassLayout));
                        }

                        subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                                                    colorAttachmentReferences, vector<AttachmentReference>(),
                                                    AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
                                                    vector<uint32_t>()));
                    }
                }
                else if (allocationType == ALLOCATIONTYPE_ROLL)
                {
                    for (size_t subpassNdx = 0; subpassNdx < attachmentCount / 2; subpassNdx++)
                    {
                        vector<AttachmentReference> colorAttachmentReferences;

                        for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount / 2; attachmentNdx++)
                        {
                            const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(
                                DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));

                            colorAttachmentReferences.push_back(
                                AttachmentReference((uint32_t)(subpassNdx + attachmentNdx), subpassLayout));
                        }

                        subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                                                    colorAttachmentReferences, vector<AttachmentReference>(),
                                                    AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
                                                    vector<uint32_t>()));
                    }
                }
                else if (allocationType == ALLOCATIONTYPE_GROW_SHRINK)
                {
                    for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
                    {
                        vector<AttachmentReference> colorAttachmentReferences;

                        for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
                        {
                            const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(
                                DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));

                            colorAttachmentReferences.push_back(
                                AttachmentReference((uint32_t)attachmentNdx, subpassLayout));
                        }

                        subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                                                    colorAttachmentReferences, vector<AttachmentReference>(),
                                                    AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
                                                    vector<uint32_t>()));
                    }
                    for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
                    {
                        vector<AttachmentReference> colorAttachmentReferences;

                        for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
                        {
                            const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(
                                DE_ARRAY_BEGIN(subpassLayoutsColor), DE_ARRAY_END(subpassLayoutsColor));

                            colorAttachmentReferences.push_back(
                                AttachmentReference((uint32_t)attachmentNdx, subpassLayout));
                        }

                        subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                                                    colorAttachmentReferences, vector<AttachmentReference>(),
                                                    AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
                                                    vector<uint32_t>()));
                    }
                }
                else if (allocationType == ALLOCATIONTYPE_IO_CHAIN)
                {
                    subpasses.push_back(Subpass(
                        VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                        vector<AttachmentReference>(
                            1, AttachmentReference(0, rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor),
                                                                                DE_ARRAY_END(subpassLayoutsColor)))),
                        vector<AttachmentReference>(),
                        AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<uint32_t>()));

                    for (size_t subpassNdx = 1; subpassNdx < attachmentCount; subpassNdx++)
                    {
                        const VkImageAspectFlags inputAttachmentAspectMask =
                            (testConfigExternal.renderPassType == RENDERPASS_TYPE_RENDERPASS2) ?
                                VK_IMAGE_ASPECT_COLOR_BIT :
                                static_cast<VkImageAspectFlagBits>(0);
                        subpasses.push_back(Subpass(
                            VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
                            vector<AttachmentReference>(1, AttachmentReference((uint32_t)(subpassNdx - 1),
                                                                               VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
                                                                               inputAttachmentAspectMask)),
                            vector<AttachmentReference>(
                                1, AttachmentReference((uint32_t)(subpassNdx),
                                                       rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayoutsColor),
                                                                                 DE_ARRAY_END(subpassLayoutsColor)))),
                            vector<AttachmentReference>(),
                            AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<uint32_t>()));
                    }
                }
                else
                    DE_FATAL("Unknown allocation type");

                {
                    const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(
                        DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
                    const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(
                        DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
                    const TestConfig::ImageMemory imageMemory =
                        rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));

                    const string testCaseName = de::toString(testCaseNdx);
                    const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
                    const UVec2 renderPos =
                        rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
                    const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));

                    vector<SubpassDependency> deps;

                    for (size_t subpassNdx = 0; subpassNdx < subpasses.size() - 1; subpassNdx++)
                    {
                        const bool byRegion = rng.getBool();
                        deps.push_back(SubpassDependency(
                            (uint32_t)subpassNdx, (uint32_t)subpassNdx + 1,
                            VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
                                VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,

                            VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
                                VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,

                            VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,

                            byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
                    }

                    const RenderPass renderPass(attachments, subpasses, deps);
                    const TestConfig testConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos,
                                                renderSize, false, 80329, 0, testConfigExternal.allocationKind,
                                                testConfigExternal.renderPassType);

                    addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(),
                                                            testCaseName.c_str(), createTestShaders, renderPassTest,
                                                            testConfig);
                }
            }
        }
        group->addChild(allocationTypeGroup.release());
    }
}

void addSimpleTests(tcu::TestCaseGroup *group, const TestConfigExternal testConfigExternal)
{
    const UVec2 targetSize(64, 64);
    const UVec2 renderPos(0, 0);
    const UVec2 renderSize(64, 64);

    // color
    {
        const RenderPass renderPass(
            vector<Attachment>(1,
                               Attachment(VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
                                          VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
                                          VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
                                          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
            vector<Subpass>(
                1, Subpass(
                       VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                       vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
                       vector<AttachmentReference>(),
                       AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<uint32_t>())),
            vector<SubpassDependency>());
        const TestConfig testConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE,
                                    TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
                                    testConfigExternal.allocationKind, testConfigExternal.renderPassType);

        addFunctionCaseWithPrograms<TestConfig>(group, "color", "Single color attachment case.", createTestShaders,
                                                renderPassTest, testConfig);
    }

    // depth
    {
        const RenderPass renderPass(
            vector<Attachment>(1, Attachment(VK_FORMAT_X8_D24_UNORM_PACK32, VK_SAMPLE_COUNT_1_BIT,
                                             VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
                                             VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
                                             VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
                                             VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
            vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                                       vector<AttachmentReference>(), vector<AttachmentReference>(),
                                       AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
                                       vector<uint32_t>())),
            vector<SubpassDependency>());
        const TestConfig testConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE,
                                    TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
                                    testConfigExternal.allocationKind, testConfigExternal.renderPassType);

        addFunctionCaseWithPrograms<TestConfig>(group, "depth", "Single depth attachment case.", createTestShaders,
                                                renderPassTest, testConfig);
    }

    // stencil
    {
        const RenderPass renderPass(
            vector<Attachment>(1, Attachment(VK_FORMAT_S8_UINT, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
                                             VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_CLEAR,
                                             VK_ATTACHMENT_STORE_OP_STORE,
                                             VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
                                             VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
            vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                                       vector<AttachmentReference>(), vector<AttachmentReference>(),
                                       AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
                                       vector<uint32_t>())),
            vector<SubpassDependency>());
        const TestConfig testConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE,
                                    TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
                                    testConfigExternal.allocationKind, testConfigExternal.renderPassType);

        addFunctionCaseWithPrograms<TestConfig>(group, "stencil", "Single stencil attachment case.", createTestShaders,
                                                renderPassTest, testConfig);
    }

    // depth_stencil
    {
        const RenderPass renderPass(
            vector<Attachment>(1, Attachment(VK_FORMAT_D24_UNORM_S8_UINT, VK_SAMPLE_COUNT_1_BIT,
                                             VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
                                             VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
                                             VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
                                             VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
            vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                                       vector<AttachmentReference>(), vector<AttachmentReference>(),
                                       AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
                                       vector<uint32_t>())),
            vector<SubpassDependency>());
        const TestConfig testConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE,
                                    TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
                                    testConfigExternal.allocationKind, testConfigExternal.renderPassType);

        addFunctionCaseWithPrograms<TestConfig>(group, "depth_stencil", "Single depth stencil attachment case.",
                                                createTestShaders, renderPassTest, testConfig);
    }

    // color_depth
    {
        const Attachment attachments[] = {
            Attachment(VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
                       VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
            Attachment(VK_FORMAT_X8_D24_UNORM_PACK32, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
                       VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
                       VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
                       VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
        };

        const RenderPass renderPass(
            vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
            vector<Subpass>(
                1, Subpass(
                       VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                       vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
                       vector<AttachmentReference>(),
                       AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), vector<uint32_t>())),
            vector<SubpassDependency>());
        const TestConfig testConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE,
                                    TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
                                    testConfigExternal.allocationKind, testConfigExternal.renderPassType);

        addFunctionCaseWithPrograms<TestConfig>(group, "color_depth", "Color and depth attachment case.",
                                                createTestShaders, renderPassTest, testConfig);
    }

    // color_stencil
    {
        const Attachment attachments[] = {
            Attachment(VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
                       VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
            Attachment(VK_FORMAT_S8_UINT, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
                       VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
                       VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
                       VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
        };

        const RenderPass renderPass(
            vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
            vector<Subpass>(
                1, Subpass(
                       VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                       vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
                       vector<AttachmentReference>(),
                       AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), vector<uint32_t>())),
            vector<SubpassDependency>());
        const TestConfig testConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE,
                                    TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
                                    testConfigExternal.allocationKind, testConfigExternal.renderPassType);

        addFunctionCaseWithPrograms<TestConfig>(group, "color_stencil", "Color and stencil attachment case.",
                                                createTestShaders, renderPassTest, testConfig);
    }

    // color_depth_stencil
    {
        const Attachment attachments[] = {
            Attachment(VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
                       VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
            Attachment(VK_FORMAT_D24_UNORM_S8_UINT, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
                       VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
                       VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
                       VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
        };

        const RenderPass renderPass(
            vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
            vector<Subpass>(
                1, Subpass(
                       VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                       vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
                       vector<AttachmentReference>(),
                       AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), vector<uint32_t>())),
            vector<SubpassDependency>());
        const TestConfig testConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE,
                                    TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
                                    testConfigExternal.allocationKind, testConfigExternal.renderPassType);

        addFunctionCaseWithPrograms<TestConfig>(group, "color_depth_stencil",
                                                "Color, depth and stencil attachment case.", createTestShaders,
                                                renderPassTest, testConfig);
    }

    // no attachments
    {
        const RenderPass renderPass(
            vector<Attachment>(),
            vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                                       vector<AttachmentReference>(), vector<AttachmentReference>(),
                                       AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
                                       vector<uint32_t>())),
            vector<SubpassDependency>());
        const TestConfig testConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE,
                                    TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
                                    testConfigExternal.allocationKind, testConfigExternal.renderPassType);

        addFunctionCaseWithPrograms<TestConfig>(group, "no_attachments", "No attachments case.", createTestShaders,
                                                renderPassTest, testConfig);
    }

    // color_unused_omit_blend_state
    {
        vector<Subpass> subpasses;

        // First subpass: use color attachment, create pipeline with color blend state
        subpasses.push_back(
            Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                    vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
                    vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
                    vector<uint32_t>(), false));

        // Second subpass: don't use color attachment, create pipeline without color blend state
        subpasses.push_back(
            Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                    vector<AttachmentReference>(
                        1, AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
                    vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
                    vector<uint32_t>(), true));

        const RenderPass renderPass(
            vector<Attachment>(1,
                               Attachment(VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
                                          VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
                                          VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
                                          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
            subpasses, vector<SubpassDependency>());

        const TestConfig testConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE,
                                    TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
                                    testConfigExternal.allocationKind, testConfigExternal.renderPassType);
        addFunctionCaseWithPrograms<TestConfig>(group, "color_unused_omit_blend_state",
                                                "Two unused color attachment case without blend state",
                                                createTestShaders, renderPassTest, testConfig);
    }
}

std::string formatToName(VkFormat format)
{
    const std::string formatStr = de::toString(format);
    const std::string prefix    = "VK_FORMAT_";

    DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);

    return de::toLower(formatStr.substr(prefix.length()));
}

void addFormatTests(tcu::TestCaseGroup *group, const TestConfigExternal testConfigExternal)
{
    tcu::TestContext &testCtx = group->getTestContext();

    const UVec2 targetSize(64, 64);
    const UVec2 renderPos(0, 0);
    const UVec2 renderSize(64, 64);

    const struct
    {
        const char *const str;
        const VkAttachmentStoreOp op;
    } storeOps[] = {{"store", VK_ATTACHMENT_STORE_OP_STORE}, {"dont_care", VK_ATTACHMENT_STORE_OP_DONT_CARE}};

    const struct
    {
        const char *const str;
        const VkAttachmentLoadOp op;
    } loadOps[] = {{"clear", VK_ATTACHMENT_LOAD_OP_CLEAR},
                   {"load", VK_ATTACHMENT_LOAD_OP_LOAD},
                   {"dont_care", VK_ATTACHMENT_LOAD_OP_DONT_CARE}};

    const struct
    {
        const char *const str;
        const TestConfig::RenderTypes types;
    } renderTypes[] = {{"clear", TestConfig::RENDERTYPES_CLEAR},
                       {"draw", TestConfig::RENDERTYPES_DRAW},
                       {"clear_draw", TestConfig::RENDERTYPES_CLEAR | TestConfig::RENDERTYPES_DRAW}};

    // Color formats
    for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreColorFormats); formatNdx++)
    {
        const VkFormat format = s_coreColorFormats[formatNdx];
        de::MovePtr<tcu::TestCaseGroup> formatGroup(
            new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str()));

        for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
        {
            const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
            de::MovePtr<tcu::TestCaseGroup> loadOpGroup(
                new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));

            for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
            {
                const RenderPass renderPass(
                    vector<Attachment>(1,
                                       Attachment(format, VK_SAMPLE_COUNT_1_BIT, loadOp, VK_ATTACHMENT_STORE_OP_STORE,
                                                  VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
                                                  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
                                                  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
                    vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                                               vector<AttachmentReference>(
                                                   1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
                                               vector<AttachmentReference>(),
                                               AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
                                               vector<uint32_t>())),
                    vector<SubpassDependency>());
                const TestConfig testConfig(renderPass, renderTypes[renderTypeNdx].types,
                                            TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT,
                                            targetSize, renderPos, renderSize, false, 90239, 0,
                                            testConfigExternal.allocationKind, testConfigExternal.renderPassType);

                addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str,
                                                        renderTypes[renderTypeNdx].str, createTestShaders,
                                                        renderPassTest, testConfig);
            }

            formatGroup->addChild(loadOpGroup.release());
        }

        {
            de::MovePtr<tcu::TestCaseGroup> inputGroup(
                new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));

            for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
            {
                const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
                de::MovePtr<tcu::TestCaseGroup> loadOpGroup(
                    new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));

                for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
                {
                    const VkImageAspectFlags inputAttachmentAspectMask =
                        (testConfigExternal.renderPassType == RENDERPASS_TYPE_RENDERPASS2) ?
                            static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT) :
                            static_cast<VkImageAspectFlags>(0);
                    const VkAttachmentStoreOp storeOp = storeOps[storeOpNdx].op;
                    de::MovePtr<tcu::TestCaseGroup> storeOpGroup(
                        new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));

                    for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++)
                    {
                        const bool useInputAspect = useInputAspectNdx != 0;

                        if (testConfigExternal.renderPassType == RENDERPASS_TYPE_RENDERPASS2 && useInputAspect)
                            continue;

                        for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
                        {
                            {
                                vector<Attachment> attachments;
                                vector<Subpass> subpasses;
                                vector<SubpassDependency> deps;
                                vector<VkInputAttachmentAspectReference> inputAspects;

                                attachments.push_back(Attachment(
                                    format, VK_SAMPLE_COUNT_1_BIT, loadOp, storeOp, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
                                    VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
                                    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));

                                attachments.push_back(
                                    Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
                                               VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE,
                                               VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
                                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
                                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));

                                subpasses.push_back(
                                    Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                                            vector<AttachmentReference>(
                                                1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
                                            vector<AttachmentReference>(),
                                            AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
                                            vector<uint32_t>()));
                                subpasses.push_back(
                                    Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
                                            vector<AttachmentReference>(
                                                1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
                                                                       inputAttachmentAspectMask)),
                                            vector<AttachmentReference>(
                                                1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
                                            vector<AttachmentReference>(),
                                            AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
                                            vector<uint32_t>()));

                                deps.push_back(SubpassDependency(0, 1,

                                                                 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
                                                                 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,

                                                                 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
                                                                 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
                                                                 vk::VK_DEPENDENCY_BY_REGION_BIT));

                                if (useInputAspect)
                                {
                                    const VkInputAttachmentAspectReference inputAspect = {1u, 0u,
                                                                                          VK_IMAGE_ASPECT_COLOR_BIT};

                                    inputAspects.push_back(inputAspect);
                                }

                                {
                                    const RenderPass renderPass(attachments, subpasses, deps, inputAspects);
                                    const TestConfig testConfig(
                                        renderPass, renderTypes[renderTypeNdx].types,
                                        TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT,
                                        targetSize, renderPos, renderSize, false, 89246, 0,
                                        testConfigExternal.allocationKind, testConfigExternal.renderPassType);
                                    const string testName(renderTypes[renderTypeNdx].str +
                                                          string(useInputAspect ? "_use_input_aspect" : ""));

                                    addFunctionCaseWithPrograms<TestConfig>(
                                        storeOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders,
                                        renderPassTest, testConfig);
                                }
                            }
                            {
                                vector<Attachment> attachments;
                                vector<Subpass> subpasses;
                                vector<SubpassDependency> deps;
                                vector<VkInputAttachmentAspectReference> inputAspects;

                                attachments.push_back(Attachment(
                                    format, VK_SAMPLE_COUNT_1_BIT, loadOp, storeOp, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
                                    VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
                                    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));

                                subpasses.push_back(
                                    Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                                            vector<AttachmentReference>(
                                                1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
                                            vector<AttachmentReference>(),
                                            AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
                                            vector<uint32_t>()));
                                subpasses.push_back(Subpass(
                                    VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
                                    vector<AttachmentReference>(
                                        1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask)),
                                    vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
                                    vector<AttachmentReference>(),
                                    AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
                                    vector<uint32_t>()));

                                deps.push_back(SubpassDependency(
                                    0, 1, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
                                    vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,

                                    vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
                                    vk::VK_DEPENDENCY_BY_REGION_BIT));

                                deps.push_back(SubpassDependency(
                                    1, 1, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
                                    vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,

                                    vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
                                    vk::VK_DEPENDENCY_BY_REGION_BIT));

                                if (useInputAspect)
                                {
                                    const VkInputAttachmentAspectReference inputAspect = {1u, 0u,
                                                                                          VK_IMAGE_ASPECT_COLOR_BIT};

                                    inputAspects.push_back(inputAspect);
                                }

                                {
                                    const RenderPass renderPass(attachments, subpasses, deps, inputAspects);
                                    const TestConfig testConfig(
                                        renderPass, renderTypes[renderTypeNdx].types,
                                        TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT,
                                        targetSize, renderPos, renderSize, false, 89246, 0,
                                        testConfigExternal.allocationKind, testConfigExternal.renderPassType);
                                    const string testName(string("self_dep_") + renderTypes[renderTypeNdx].str +
                                                          (useInputAspect ? "_use_input_aspect" : ""));

                                    addFunctionCaseWithPrograms<TestConfig>(
                                        storeOpGroup.get(), testName,
                                        string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders,
                                        renderPassTest, testConfig);
                                }
                            }
                        }
                    }

                    loadOpGroup->addChild(storeOpGroup.release());
                }

                inputGroup->addChild(loadOpGroup.release());
            }

            formatGroup->addChild(inputGroup.release());
        }

        group->addChild(formatGroup.release());
    }

    // Depth stencil formats
    for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreDepthStencilFormats); formatNdx++)
    {
        const VkFormat vkFormat         = s_coreDepthStencilFormats[formatNdx];
        const tcu::TextureFormat format = mapVkFormat(vkFormat);
        const bool isStencilAttachment  = hasStencilComponent(format.order);
        const bool isDepthAttachment    = hasDepthComponent(format.order);
        const VkImageAspectFlags formatAspectFlags =
            (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) |
            (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u);
        de::MovePtr<tcu::TestCaseGroup> formatGroup(
            new tcu::TestCaseGroup(testCtx, formatToName(vkFormat).c_str(), de::toString(vkFormat).c_str()));

        for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
        {
            const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
            de::MovePtr<tcu::TestCaseGroup> loadOpGroup(
                new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));

            for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
            {
                {
                    const RenderPass renderPass(
                        vector<Attachment>(1, Attachment(vkFormat, VK_SAMPLE_COUNT_1_BIT,
                                                         isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
                                                         isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :
                                                                             VK_ATTACHMENT_STORE_OP_DONT_CARE,
                                                         isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
                                                         isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :
                                                                               VK_ATTACHMENT_STORE_OP_DONT_CARE,
                                                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
                                                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
                        vector<Subpass>(
                            1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                                       vector<AttachmentReference>(), vector<AttachmentReference>(),
                                       AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
                                       vector<uint32_t>())),
                        vector<SubpassDependency>());
                    const TestConfig testConfig(renderPass, renderTypes[renderTypeNdx].types,
                                                TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT,
                                                targetSize, renderPos, renderSize, false, 90239, 0,
                                                testConfigExternal.allocationKind, testConfigExternal.renderPassType);

                    addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str,
                                                            renderTypes[renderTypeNdx].str, createTestShaders,
                                                            renderPassTest, testConfig);
                }

                if (isStencilAttachment && isDepthAttachment && loadOp != VK_ATTACHMENT_LOAD_OP_CLEAR)
                {
                    {
                        const RenderPass renderPass(
                            vector<Attachment>(
                                1, Attachment(vkFormat, VK_SAMPLE_COUNT_1_BIT,
                                              isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
                                              isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :
                                                                  VK_ATTACHMENT_STORE_OP_DONT_CARE,
                                              isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
                                              isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :
                                                                    VK_ATTACHMENT_STORE_OP_DONT_CARE,
                                              VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
                                              VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
                            vector<Subpass>(1,
                                            Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                                                    vector<AttachmentReference>(), vector<AttachmentReference>(),
                                                    AttachmentReference(
                                                        0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL),
                                                    vector<uint32_t>())),
                            vector<SubpassDependency>());
                        const TestConfig testConfig(
                            renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE,
                            TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
                            testConfigExternal.allocationKind, testConfigExternal.renderPassType);
                        const string testName(string(renderTypes[renderTypeNdx].str) + "_depth_read_only");

                        addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), testName,
                                                                renderTypes[renderTypeNdx].str, createTestShaders,
                                                                renderPassTest, testConfig);
                    }

                    {
                        const RenderPass renderPass(
                            vector<Attachment>(
                                1, Attachment(vkFormat, VK_SAMPLE_COUNT_1_BIT,
                                              isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
                                              isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :
                                                                  VK_ATTACHMENT_STORE_OP_DONT_CARE,
                                              isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
                                              isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :
                                                                    VK_ATTACHMENT_STORE_OP_DONT_CARE,
                                              VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
                                              VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
                            vector<Subpass>(1,
                                            Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                                                    vector<AttachmentReference>(), vector<AttachmentReference>(),
                                                    AttachmentReference(
                                                        0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL),
                                                    vector<uint32_t>())),
                            vector<SubpassDependency>());
                        const TestConfig testConfig(
                            renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE,
                            TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, false, 90239, 0,
                            testConfigExternal.allocationKind, testConfigExternal.renderPassType);
                        const string testName(string(renderTypes[renderTypeNdx].str) + "_stencil_read_only");

                        addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), testName,
                                                                renderTypes[renderTypeNdx].str, createTestShaders,
                                                                renderPassTest, testConfig);
                    }
                }
            }

            formatGroup->addChild(loadOpGroup.release());
        }

        {
            de::MovePtr<tcu::TestCaseGroup> inputGroup(
                new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));

            for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
            {
                const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
                de::MovePtr<tcu::TestCaseGroup> loadOpGroup(
                    new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));

                for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
                {
                    const VkImageAspectFlags inputAttachmentAspectMask =
                        (testConfigExternal.renderPassType == RENDERPASS_TYPE_RENDERPASS2) ?
                            formatAspectFlags :
                            static_cast<VkImageAspectFlags>(0);
                    const VkAttachmentStoreOp storeOp = storeOps[storeOpNdx].op;
                    de::MovePtr<tcu::TestCaseGroup> storeOpGroup(
                        new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));

                    for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++)
                    {
                        const bool useInputAspect = useInputAspectNdx != 0;

                        if (testConfigExternal.renderPassType == RENDERPASS_TYPE_RENDERPASS2 && useInputAspect)
                            continue;

                        for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
                        {
                            {
                                vector<Attachment> attachments;
                                vector<Subpass> subpasses;
                                vector<SubpassDependency> deps;
                                vector<VkInputAttachmentAspectReference> inputAspects;

                                attachments.push_back(Attachment(vkFormat, VK_SAMPLE_COUNT_1_BIT, loadOp, storeOp,
                                                                 loadOp, storeOp,
                                                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
                                                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));

                                attachments.push_back(
                                    Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
                                               VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE,
                                               VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
                                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
                                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));

                                subpasses.push_back(
                                    Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                                            vector<AttachmentReference>(), vector<AttachmentReference>(),
                                            AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
                                            vector<uint32_t>()));
                                subpasses.push_back(
                                    Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
                                            vector<AttachmentReference>(
                                                1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
                                                                       inputAttachmentAspectMask)),
                                            vector<AttachmentReference>(
                                                1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
                                            vector<AttachmentReference>(),
                                            AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
                                            vector<uint32_t>()));

                                deps.push_back(SubpassDependency(0, 1,
                                                                 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
                                                                     vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
                                                                 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,

                                                                 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
                                                                 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 0u));

                                if (useInputAspect)
                                {
                                    const VkInputAttachmentAspectReference inputAspect = {
                                        1u, 0u,
                                        (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) |
                                            (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT :
                                                                   0u)};

                                    inputAspects.push_back(inputAspect);
                                }

                                {
                                    const RenderPass renderPass(attachments, subpasses, deps, inputAspects);
                                    const TestConfig testConfig(
                                        renderPass, renderTypes[renderTypeNdx].types,
                                        TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT,
                                        targetSize, renderPos, renderSize, false, 89246, 0,
                                        testConfigExternal.allocationKind, testConfigExternal.renderPassType);
                                    const string testName(renderTypes[renderTypeNdx].str +
                                                          string(useInputAspect ? "_use_input_aspect" : ""));

                                    addFunctionCaseWithPrograms<TestConfig>(
                                        storeOpGroup.get(), testName, renderTypes[renderTypeNdx].str, createTestShaders,
                                        renderPassTest, testConfig);
                                }
                            }
                            {
                                vector<Attachment> attachments;
                                vector<Subpass> subpasses;
                                vector<SubpassDependency> deps;
                                vector<VkInputAttachmentAspectReference> inputAspects;

                                attachments.push_back(Attachment(
                                    vkFormat, VK_SAMPLE_COUNT_1_BIT, loadOp, storeOp, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
                                    VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
                                    VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));

                                subpasses.push_back(
                                    Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                                            vector<AttachmentReference>(), vector<AttachmentReference>(),
                                            AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
                                            vector<uint32_t>()));
                                subpasses.push_back(Subpass(
                                    VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
                                    vector<AttachmentReference>(
                                        1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask)),
                                    vector<AttachmentReference>(), vector<AttachmentReference>(),
                                    AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL), vector<uint32_t>()));

                                deps.push_back(SubpassDependency(0, 1,
                                                                 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
                                                                     vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
                                                                 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,

                                                                 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
                                                                 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
                                                                 vk::VK_DEPENDENCY_BY_REGION_BIT));

                                deps.push_back(SubpassDependency(1, 1,
                                                                 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
                                                                     vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
                                                                 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
                                                                 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
                                                                 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
                                                                 vk::VK_DEPENDENCY_BY_REGION_BIT));

                                if (useInputAspect)
                                {
                                    const VkInputAttachmentAspectReference inputAspect = {
                                        1u, 0u,

                                        (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) |
                                            (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT :
                                                                   0u)};

                                    inputAspects.push_back(inputAspect);
                                }

                                {
                                    const RenderPass renderPass(attachments, subpasses, deps, inputAspects);
                                    const TestConfig testConfig(
                                        renderPass, renderTypes[renderTypeNdx].types,
                                        TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT,
                                        targetSize, renderPos, renderSize, false, 89246, 0,
                                        testConfigExternal.allocationKind, testConfigExternal.renderPassType);
                                    const string testName(string("self_dep_") + renderTypes[renderTypeNdx].str +
                                                          (useInputAspect ? "_use_input_aspect" : ""));

                                    addFunctionCaseWithPrograms<TestConfig>(
                                        storeOpGroup.get(), testName,
                                        string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders,
                                        renderPassTest, testConfig);
                                }
                            }

                            if (isStencilAttachment && isDepthAttachment)
                            {
                                // Depth read only
                                {
                                    vector<Attachment> attachments;
                                    vector<Subpass> subpasses;
                                    vector<SubpassDependency> deps;
                                    vector<VkInputAttachmentAspectReference> inputAspects;

                                    attachments.push_back(Attachment(vkFormat, VK_SAMPLE_COUNT_1_BIT, loadOp, storeOp,
                                                                     loadOp, storeOp,
                                                                     VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
                                                                     VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));

                                    attachments.push_back(
                                        Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
                                                   VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE,
                                                   VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
                                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
                                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));

                                    subpasses.push_back(Subpass(
                                        VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                                        vector<AttachmentReference>(), vector<AttachmentReference>(),
                                        AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
                                        vector<uint32_t>()));
                                    subpasses.push_back(Subpass(
                                        VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
                                        vector<AttachmentReference>(
                                            1, AttachmentReference(
                                                   0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,
                                                   inputAttachmentAspectMask)),
                                        vector<AttachmentReference>(
                                            1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
                                        vector<AttachmentReference>(),
                                        AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
                                        vector<uint32_t>()));

                                    deps.push_back(SubpassDependency(0, 1,
                                                                     vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
                                                                         vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
                                                                     vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,

                                                                     vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
                                                                     vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 0u));

                                    if (useInputAspect)
                                    {
                                        const VkInputAttachmentAspectReference inputAspect = {
                                            1u, 0u,

                                            (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) |
                                                (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT :
                                                                       0u)};

                                        inputAspects.push_back(inputAspect);
                                    }

                                    {
                                        const RenderPass renderPass(attachments, subpasses, deps, inputAspects);
                                        const TestConfig testConfig(
                                            renderPass, renderTypes[renderTypeNdx].types,
                                            TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT,
                                            targetSize, renderPos, renderSize, false, 89246, 0,
                                            testConfigExternal.allocationKind, testConfigExternal.renderPassType);
                                        const string testName(renderTypes[renderTypeNdx].str +
                                                              string(useInputAspect ? "_use_input_aspect" : "") +
                                                              "_depth_read_only");

                                        addFunctionCaseWithPrograms<TestConfig>(
                                            storeOpGroup.get(), testName, renderTypes[renderTypeNdx].str,
                                            createTestShaders, renderPassTest, testConfig);
                                    }
                                }
                                {
                                    vector<Attachment> attachments;
                                    vector<Subpass> subpasses;
                                    vector<SubpassDependency> deps;
                                    vector<VkInputAttachmentAspectReference> inputAspects;

                                    attachments.push_back(Attachment(vkFormat, VK_SAMPLE_COUNT_1_BIT, loadOp, storeOp,
                                                                     loadOp, storeOp,
                                                                     VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
                                                                     VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));

                                    subpasses.push_back(Subpass(
                                        VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                                        vector<AttachmentReference>(), vector<AttachmentReference>(),
                                        AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
                                        vector<uint32_t>()));
                                    subpasses.push_back(Subpass(
                                        VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
                                        vector<AttachmentReference>(
                                            1, AttachmentReference(
                                                   0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,
                                                   inputAttachmentAspectMask)),
                                        vector<AttachmentReference>(), vector<AttachmentReference>(),
                                        AttachmentReference(0,
                                                            VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL),
                                        vector<uint32_t>()));

                                    deps.push_back(SubpassDependency(0, 1,
                                                                     vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
                                                                         vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
                                                                     vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,

                                                                     vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
                                                                     vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
                                                                     vk::VK_DEPENDENCY_BY_REGION_BIT));

                                    deps.push_back(SubpassDependency(1, 1,
                                                                     vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
                                                                         vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
                                                                     vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,

                                                                     vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
                                                                     vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
                                                                     vk::VK_DEPENDENCY_BY_REGION_BIT));

                                    if (useInputAspect)
                                    {
                                        const VkInputAttachmentAspectReference inputAspect = {
                                            1u, 0u,

                                            (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) |
                                                (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT :
                                                                       0u)};

                                        inputAspects.push_back(inputAspect);
                                    }

                                    {
                                        const RenderPass renderPass(attachments, subpasses, deps, inputAspects);
                                        const TestConfig testConfig(
                                            renderPass, renderTypes[renderTypeNdx].types,
                                            TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT,
                                            targetSize, renderPos, renderSize, false, 89246, 0,
                                            testConfigExternal.allocationKind, testConfigExternal.renderPassType);
                                        const string testName(string("self_dep_") + renderTypes[renderTypeNdx].str +
                                                              (useInputAspect ? "_use_input_aspect" : "") +
                                                              "_depth_read_only");

                                        addFunctionCaseWithPrograms<TestConfig>(
                                            storeOpGroup.get(), testName,
                                            string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders,
                                            renderPassTest, testConfig);
                                    }
                                }
                                // Stencil read only
                                {
                                    vector<Attachment> attachments;
                                    vector<Subpass> subpasses;
                                    vector<SubpassDependency> deps;
                                    vector<VkInputAttachmentAspectReference> inputAspects;

                                    attachments.push_back(Attachment(vkFormat, VK_SAMPLE_COUNT_1_BIT, loadOp, storeOp,
                                                                     loadOp, storeOp,
                                                                     VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
                                                                     VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));

                                    attachments.push_back(
                                        Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
                                                   VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE,
                                                   VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
                                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
                                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));

                                    subpasses.push_back(Subpass(
                                        VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                                        vector<AttachmentReference>(), vector<AttachmentReference>(),
                                        AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
                                        vector<uint32_t>()));
                                    subpasses.push_back(Subpass(
                                        VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
                                        vector<AttachmentReference>(
                                            1, AttachmentReference(
                                                   0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,
                                                   inputAttachmentAspectMask)),
                                        vector<AttachmentReference>(
                                            1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
                                        vector<AttachmentReference>(),
                                        AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
                                        vector<uint32_t>()));

                                    deps.push_back(
                                        SubpassDependency(0, 1,
                                                          vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
                                                              vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
                                                              vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
                                                          vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,

                                                          vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
                                                              VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
                                                          vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 0u));

                                    if (useInputAspect)
                                    {
                                        const VkInputAttachmentAspectReference inputAspect = {
                                            1u, 0u,

                                            (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) |
                                                (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT :
                                                                       0u)};

                                        inputAspects.push_back(inputAspect);
                                    }

                                    {
                                        const RenderPass renderPass(attachments, subpasses, deps, inputAspects);
                                        const TestConfig testConfig(
                                            renderPass, renderTypes[renderTypeNdx].types,
                                            TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT,
                                            targetSize, renderPos, renderSize, false, 89246, 0,
                                            testConfigExternal.allocationKind, testConfigExternal.renderPassType);
                                        const string testName(renderTypes[renderTypeNdx].str +
                                                              string(useInputAspect ? "_use_input_aspect" : "") +
                                                              "_stencil_read_only");

                                        addFunctionCaseWithPrograms<TestConfig>(
                                            storeOpGroup.get(), testName, renderTypes[renderTypeNdx].str,
                                            createTestShaders, renderPassTest, testConfig);
                                    }
                                }
                                {
                                    vector<Attachment> attachments;
                                    vector<Subpass> subpasses;
                                    vector<SubpassDependency> deps;
                                    vector<VkInputAttachmentAspectReference> inputAspects;

                                    attachments.push_back(Attachment(vkFormat, VK_SAMPLE_COUNT_1_BIT, loadOp, storeOp,
                                                                     loadOp, storeOp,
                                                                     VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
                                                                     VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));

                                    subpasses.push_back(Subpass(
                                        VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
                                        vector<AttachmentReference>(), vector<AttachmentReference>(),
                                        AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
                                        vector<uint32_t>()));
                                    subpasses.push_back(Subpass(
                                        VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
                                        vector<AttachmentReference>(
                                            1, AttachmentReference(
                                                   0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,
                                                   inputAttachmentAspectMask)),
                                        vector<AttachmentReference>(), vector<AttachmentReference>(),
                                        AttachmentReference(0,
                                                            VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL),
                                        vector<uint32_t>()));

                                    deps.push_back(SubpassDependency(0, 1,
                                                                     vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
                                                                         vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
                                                                     vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,

                                                                     vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
                                                                     vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
                                                                     vk::VK_DEPENDENCY_BY_REGION_BIT));

                                    deps.push_back(SubpassDependency(1, 1,
                                                                     vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
                                                                         vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
                                                                     vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,

                                                                     vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
                                                                     vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
                                                                     vk::VK_DEPENDENCY_BY_REGION_BIT));

                                    if (useInputAspect)
                                    {
                                        const VkInputAttachmentAspectReference inputAspect = {
                                            1u, 0u,

                                            (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u) |
                                                (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT :
                                                                       0u)};

                                        inputAspects.push_back(inputAspect);
                                    }

                                    {
                                        const RenderPass renderPass(attachments, subpasses, deps, inputAspects);
                                        const TestConfig testConfig(
                                            renderPass, renderTypes[renderTypeNdx].types,
                                            TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT,
                                            targetSize, renderPos, renderSize, false, 89246, 0,
                                            testConfigExternal.allocationKind, testConfigExternal.renderPassType);
                                        const string testName(string("self_dep_") + renderTypes[renderTypeNdx].str +
                                                              (useInputAspect ? "_use_input_aspect" : "") +
                                                              "_stencil_read_only");

                                        addFunctionCaseWithPrograms<TestConfig>(
                                            storeOpGroup.get(), testName,
                                            string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders,
                                            renderPassTest, testConfig);
                                    }
                                }
                            }
                        }
                    }

                    loadOpGroup->addChild(storeOpGroup.release());
                }

                inputGroup->addChild(loadOpGroup.release());
            }

            formatGroup->addChild(inputGroup.release());
        }

        group->addChild(formatGroup.release());
    }
}

void addRenderPassTests(tcu::TestCaseGroup *group, const AllocationKind allocationKind,
                        const RenderPassType renderPassType)
{
    const TestConfigExternal testConfigExternal(allocationKind, renderPassType);

    addTestGroup(group, "simple", "Simple basic render pass tests", addSimpleTests, testConfigExternal);
    addTestGroup(group, "formats", "Tests for different image formats.", addFormatTests, testConfigExternal);
    addTestGroup(group, "attachment", "Attachment format and count tests with load and store ops and image layouts",
                 addAttachmentTests, testConfigExternal);
    addTestGroup(group, "attachment_allocation", "Attachment allocation tests", addAttachmentAllocationTests,
                 testConfigExternal);
    addTestGroup(group, "attachment_write_mask", "Attachment write mask tests", addAttachmentWriteMaskTests,
                 testConfigExternal);
}

de::MovePtr<tcu::TestCaseGroup> createSuballocationTests(tcu::TestContext &testCtx, RenderPassType renderPassType)
{
    de::MovePtr<tcu::TestCaseGroup> suballocationTestsGroup(
        new tcu::TestCaseGroup(testCtx, "suballocation", "Suballocation RenderPass Tests"));

    addRenderPassTests(suballocationTestsGroup.get(), ALLOCATION_KIND_SUBALLOCATED, renderPassType);

    return suballocationTestsGroup;
}

de::MovePtr<tcu::TestCaseGroup> createDedicatedAllocationTests(tcu::TestContext &testCtx, RenderPassType renderPassType)
{
    de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestsGroup(
        new tcu::TestCaseGroup(testCtx, "dedicated_allocation", "RenderPass Tests For Dedicated Allocation"));

    addRenderPassTests(dedicatedAllocationTestsGroup.get(), ALLOCATION_KIND_DEDICATED, renderPassType);

    return dedicatedAllocationTestsGroup;
}

tcu::TestCaseGroup *createRenderPassTestsInternal(tcu::TestContext &testCtx, RenderPassType renderPassType)
{
    const char *renderpassTestsGroupName        = (renderPassType == RENDERPASS_TYPE_LEGACY)      ? "renderpass" :
                                                  (renderPassType == RENDERPASS_TYPE_RENDERPASS2) ? "renderpass2" :
                                                                                                    "";
    const char *renderpassTestsGroupDescription = (renderPassType == RENDERPASS_TYPE_LEGACY) ? "RenderPass Tests" :
                                                  (renderPassType == RENDERPASS_TYPE_RENDERPASS2) ?
                                                                                               "RenderPass2 Tests" :
                                                                                               "";
    de::MovePtr<tcu::TestCaseGroup> renderpassTests(
        new tcu::TestCaseGroup(testCtx, renderpassTestsGroupName, renderpassTestsGroupDescription));
    de::MovePtr<tcu::TestCaseGroup> suballocationTestGroup = createSuballocationTests(testCtx, renderPassType);
    de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestGroup =
        createDedicatedAllocationTests(testCtx, renderPassType);

    suballocationTestGroup->addChild((renderPassType == RENDERPASS_TYPE_LEGACY) ?
                                         createRenderPassMultisampleTests(testCtx) :
                                         createRenderPass2MultisampleTests(testCtx));
    suballocationTestGroup->addChild((renderPassType == RENDERPASS_TYPE_LEGACY) ?
                                         createRenderPassMultisampleResolveTests(testCtx) :
                                         createRenderPass2MultisampleResolveTests(testCtx));
    suballocationTestGroup->addChild((renderPassType == RENDERPASS_TYPE_LEGACY) ?
                                         createRenderPassSubpassDependencyTests(testCtx) :
                                         createRenderPass2SubpassDependencyTests(testCtx));
    suballocationTestGroup->addChild((renderPassType == RENDERPASS_TYPE_LEGACY) ?
                                         createRenderPassSampleReadTests(testCtx) :
                                         createRenderPass2SampleReadTests(testCtx));
#ifndef CTS_USES_VULKANSC
    suballocationTestGroup->addChild((renderPassType == RENDERPASS_TYPE_LEGACY) ?
                                         createRenderPassSparseRenderTargetTests(testCtx) :
                                         createRenderPass2SparseRenderTargetTests(testCtx));
#endif // CTS_USES_VULKANSC
    suballocationTestGroup->addChild(createRenderPassUnusedAttachmentTests(testCtx, renderPassType));
    suballocationTestGroup->addChild(createRenderPassUnusedClearAttachmentTests(testCtx, renderPassType));
    suballocationTestGroup->addChild(createRenderPassUnusedAttachmentSparseFillingTests(testCtx, renderPassType));
#ifndef CTS_USES_VULKANSC
    suballocationTestGroup->addChild(createRenderPassLoadStoreOpNoneTests(testCtx, renderPassType));
#endif // CTS_USES_VULKANSC

    renderpassTests->addChild(suballocationTestGroup.release());
    renderpassTests->addChild(dedicatedAllocationTestGroup.release());
    renderpassTests->addChild(createRenderPassMultipleSubpassesMultipleCommandBuffersTests(testCtx));

    if (renderPassType != RENDERPASS_TYPE_LEGACY)
    {
        renderpassTests->addChild(createRenderPass2DepthStencilResolveTests(testCtx));
#ifndef CTS_USES_VULKANSC
        renderpassTests->addChild(createFragmentDensityMapTests(testCtx));
#endif
    }

    return renderpassTests.release();
}

} // namespace

tcu::TestCaseGroup *createRenderPassTests(tcu::TestContext &testCtx)
{
    return createRenderPassTestsInternal(testCtx, RENDERPASS_TYPE_LEGACY);
}

tcu::TestCaseGroup *createRenderPass2Tests(tcu::TestContext &testCtx)
{
    return createRenderPassTestsInternal(testCtx, RENDERPASS_TYPE_RENDERPASS2);
}

} // namespace vkt
