/* Copyright (c) 2021 The Khronos Group Inc.
 * Copyright (c) 2021 NVIDIA Corporation
 *
 * 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
 *
 * Author: David Zhao Akeley <dakeley@nvidia.com>
 */

#include <array>
#include <cassert>
#include <stdio.h>
#include <vector>

#include "layer_validation_tests.h"

// Common data structures needed for tests.
class ViewportInheritanceTestData {
    // Borrowed owner device.
    VkDevice m_device{};

    // Renderpass, draw to one attachment of format m_colorFormat.
    VkFormat m_colorFormat{};
    VkRenderPass m_renderPass{};

    // Framebuffer data.
    VkImageObj m_colorImageObj;
    VkImageView m_colorImageView{};
    VkFramebuffer m_framebuffer{};

    // Do-nothing vertex and fragment programs.
    static const uint32_t kVertexSpirV[166];
    static const uint32_t kFragmentSpirV[83];
    std::array<VkPipelineShaderStageCreateInfo, 2> m_shaderStages{};

    // Do-nothing graphics pipelines.
    // dynamic state pipelines have viewport/scissor as sole dynamic state; static state pipelines have no dynamic state.
    // the i-th pipeline needs i viewports/scissors (0th uses EXT dynamic viewport/scissor count).
    // m_staticStatePipelines[0] is unused.
    VkPipelineLayout m_pipelineLayout{};
    std::array<VkPipeline, 33> m_dynamicStatePipelines{}, m_staticStatePipelines{};

    // Various premade state structs for graphics pipeline.
    static const VkPipelineVertexInputStateCreateInfo kVertexInputState;
    static const VkPipelineInputAssemblyStateCreateInfo kInputAssemblyState;
    static const VkPipelineRasterizationStateCreateInfo kRasterizationState;
    static const VkPipelineMultisampleStateCreateInfo kMultisampleState;
    static const VkPipelineDepthStencilStateCreateInfo kDepthStencilState;
    static const VkPipelineColorBlendAttachmentState kBlendAttachmentState;
    static const VkPipelineColorBlendStateCreateInfo kBlendState;
    static const VkPipelineDynamicStateCreateInfo kStaticState;
    static const VkPipelineDynamicStateCreateInfo kDynamicState;
    static const VkPipelineDynamicStateCreateInfo kDynamicStateWithCount;

  public:
    // Premade viewport and scissor arrays for testing.
    static const VkViewport kViewportArray[32];
    static const VkViewport kViewportDepthOnlyArray[32];
    static const VkViewport kViewportAlternateDepthArray[32];
    static const VkRect2D kScissorArray[32];

  private:
    // Set to a failure message if initialization failed.
    const char* m_failureReason = nullptr;

    void PickColorFormat(VkPhysicalDevice physical_device) {
        std::array<VkFormat, 7> formats = {VK_FORMAT_R8G8B8A8_SRGB,      VK_FORMAT_B8G8R8A8_SRGB,  VK_FORMAT_R8G8B8A8_UNORM,
                                           VK_FORMAT_B8G8R8A8_UNORM,     VK_FORMAT_R8G8B8A8_SNORM, VK_FORMAT_B8G8R8A8_SNORM,
                                           VK_FORMAT_R32G32B32A32_SFLOAT};
        for (VkFormat candidate : formats) {
            VkImageFormatProperties properties;
            VkResult result =
                vk::GetPhysicalDeviceImageFormatProperties(physical_device, candidate, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
                                                           VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0, &properties);
            if (result == VK_SUCCESS) {
                m_colorFormat = candidate;
                return;
            }
        }
        m_failureReason = "No color attachment format found";
    }

    void CreateRenderPass() {
        assert(m_colorFormat != VK_FORMAT_UNDEFINED);
        VkAttachmentDescription color_attachment = {0,
                                                    m_colorFormat,
                                                    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_UNDEFINED,
                                                    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
        VkAttachmentReference color_reference = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
        VkSubpassDescription subpass = {
            0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &color_reference, nullptr, nullptr, 0, nullptr};
        VkRenderPassCreateInfo info = {
            VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &color_attachment, 1, &subpass, 0, nullptr};
        VkResult result = vk::CreateRenderPass(m_device, &info, nullptr, &m_renderPass);
        if (result != VK_SUCCESS) m_failureReason = "Could not create render pass.";
    }

    void CreateColorImageObj() {
        assert(m_colorFormat != VK_FORMAT_UNDEFINED);
        m_colorImageObj.Init(128, 128, 1, m_colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
        if (!m_colorImageObj.initialized()) {
            m_failureReason = "Image not initialized";
        }
    }

    void CreateColorView() {
        assert(!m_colorImageView);
        VkImageViewCreateInfo info = {VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
                                      nullptr,
                                      0,
                                      m_colorImageObj.handle(),
                                      VK_IMAGE_VIEW_TYPE_2D,
                                      m_colorFormat,
                                      {},
                                      {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};
        VkResult result = vk::CreateImageView(m_device, &info, nullptr, &m_colorImageView);
        if (result != VK_SUCCESS) m_failureReason = "Could not create image view";
    }

    void CreateFramebuffer() {
        assert(!m_framebuffer);
        VkFramebufferCreateInfo info = {
            VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &m_colorImageView, 128, 128, 1};
        VkResult result = vk::CreateFramebuffer(m_device, &info, nullptr, &m_framebuffer);
        if (result != VK_SUCCESS) m_failureReason = "Could not create framebuffer";
    }

    void CreatePipelineLayout() {
        assert(!m_pipelineLayout);
        VkPipelineLayoutCreateInfo info = LvlInitStruct<VkPipelineLayoutCreateInfo>();
        VkResult result = vk::CreatePipelineLayout(m_device, &info, nullptr, &m_pipelineLayout);
        if (result != VK_SUCCESS) m_failureReason = "Could not create pipeline layout";
    }

    void CreateShaderStages() {
        VkShaderModuleCreateInfo vertex_info = {VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, nullptr, 0, sizeof kVertexSpirV,
                                                kVertexSpirV};
        m_shaderStages[0] = LvlInitStruct<VkPipelineShaderStageCreateInfo>();
        m_shaderStages[0].flags = 0;
        m_shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
        VkResult result = vk::CreateShaderModule(m_device, &vertex_info, nullptr, &m_shaderStages[0].module);
        m_shaderStages[0].pName = "main";
        m_shaderStages[0].pSpecializationInfo = nullptr;
        if (result != VK_SUCCESS) {
            m_failureReason = "Could not create vertex program";
            return;
        }

        VkShaderModuleCreateInfo fragment_info = {VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, nullptr, 0, sizeof kFragmentSpirV,
                                                  kFragmentSpirV};
        m_shaderStages[1] = LvlInitStruct<VkPipelineShaderStageCreateInfo>();
        m_shaderStages[1].flags = 0;
        m_shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
        result = vk::CreateShaderModule(m_device, &fragment_info, nullptr, &m_shaderStages[1].module);
        m_shaderStages[1].pName = "main";
        m_shaderStages[1].pSpecializationInfo = nullptr;
        if (result != VK_SUCCESS) {
            m_failureReason = "Could not create fragment program";
            return;
        }
    }

    void Cleanup() {
        for (VkPipeline& pipeline : m_dynamicStatePipelines) {
            vk::DestroyPipeline(m_device, pipeline, nullptr);
            pipeline = VK_NULL_HANDLE;
        }
        for (VkPipeline& pipeline : m_staticStatePipelines) {
            vk::DestroyPipeline(m_device, pipeline, nullptr);
            pipeline = VK_NULL_HANDLE;
        }
        for (auto& stage : m_shaderStages) {
            vk::DestroyShaderModule(m_device, stage.module, nullptr);
            stage.module = VK_NULL_HANDLE;
        }
        vk::DestroyPipelineLayout(m_device, m_pipelineLayout, nullptr);
        m_pipelineLayout = VK_NULL_HANDLE;
        vk::DestroyFramebuffer(m_device, m_framebuffer, nullptr);
        m_framebuffer = VK_NULL_HANDLE;
        vk::DestroyImageView(m_device, m_colorImageView, nullptr);
        m_colorImageView = VK_NULL_HANDLE;
        vk::DestroyRenderPass(m_device, m_renderPass, nullptr);
        m_renderPass = VK_NULL_HANDLE;
    }

  public:
    // Check if the gpu has the needed features, and call InitState requesting the needed features.
    // Return whether the needed features were found or not.
    template <typename AddDeviceExtension>
    static bool InitState(VkRenderFramework* p_framework, AddDeviceExtension add_device_extension, const char** pp_reason,
                          bool inheritedViewportScissor2D, bool extended_dynamic_state_multi_viewport,
                          bool disable_multi_viewport = false) {
        VkPhysicalDeviceExtendedDynamicStateFeaturesEXT ext = LvlInitStruct<VkPhysicalDeviceExtendedDynamicStateFeaturesEXT>();
        VkPhysicalDeviceInheritedViewportScissorFeaturesNV nv =
            LvlInitStruct<VkPhysicalDeviceInheritedViewportScissorFeaturesNV>(&ext);
        VkPhysicalDeviceFeatures2 features2 = LvlInitStruct<VkPhysicalDeviceFeatures2>(&nv);
        VkPhysicalDevice gpu = p_framework->gpu();

        // Enable extended dynamic state if requested.
        if (extended_dynamic_state_multi_viewport) {
            if (!p_framework->DeviceExtensionSupported(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME)) {
                *pp_reason = "missing " VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME;
                return false;
            }
            add_device_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
        }

        // Always try to enable the tested extension (but maybe won't actually enable relevant feature.)
        if (p_framework->DeviceExtensionSupported(VK_NV_INHERITED_VIEWPORT_SCISSOR_EXTENSION_NAME)) {
            add_device_extension(VK_NV_INHERITED_VIEWPORT_SCISSOR_EXTENSION_NAME);
        } else {
            *pp_reason = "missing " VK_NV_INHERITED_VIEWPORT_SCISSOR_EXTENSION_NAME;
            return false;
        }

        vk::GetPhysicalDeviceFeatures2(gpu, &features2);

        if (extended_dynamic_state_multi_viewport) {
            if (!features2.features.multiViewport) {
                *pp_reason = "missing multiViewport feature";
                return false;
            }
            if (!ext.extendedDynamicState) {
                *pp_reason = "missing extendedDynamicState feature";
                return false;
            }
        }
        if (!nv.inheritedViewportScissor2D && !inheritedViewportScissor2D) {
            *pp_reason = "missing inheritedViewportScissor2D feature";
            return false;
        }
        nv.inheritedViewportScissor2D = inheritedViewportScissor2D;

        if (disable_multi_viewport) {
            features2.features.multiViewport = VK_FALSE;
        }

        p_framework->InitState(nullptr, &features2, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
        return true;
    }

    ViewportInheritanceTestData(VkDeviceObj* p_device_obj, VkPhysicalDevice physical_device) : m_colorImageObj(p_device_obj) {
        m_device = p_device_obj->handle();
        try {
            PickColorFormat(physical_device);
            if (m_failureReason) return;
            CreateRenderPass();
            if (m_failureReason) return;
            CreateColorImageObj();
            if (m_failureReason) return;
            CreateColorView();
            if (m_failureReason) return;
            CreateFramebuffer();
            if (m_failureReason) return;
            CreatePipelineLayout();
            if (m_failureReason) return;
            CreateShaderStages();
            if (m_failureReason) return;
        }
        catch (...) {
            Cleanup();
            throw;
        }
    }

    ~ViewportInheritanceTestData() { Cleanup(); }

    // nullptr indicates successful construction.
    const char* FailureReason() const { return m_failureReason; };

    // Get the graphics pipeline with the specified viewport/scissor state configuration, creating it if needed.
    // viewport_scissor_count == 0 and dynamic_viewport_scissor == true indicates EXT viewport/scissor with count dynamic state.
    // All pipelines are destroyed when the class is destroyed.
    VkPipeline GetGraphicsPipeline(bool dynamic_viewport_scissor, uint32_t viewport_scissor_count) {
        assert(dynamic_viewport_scissor || viewport_scissor_count != 0);
        assert(size_t(viewport_scissor_count) < m_dynamicStatePipelines.size());
        VkPipeline* p_pipeline =
            &(dynamic_viewport_scissor ? m_dynamicStatePipelines : m_staticStatePipelines)[viewport_scissor_count];
        if (*p_pipeline) {
            return *p_pipeline;
        }

        // Need some static viewport/scissors if no dynamic state. Their values don't really matter; the only purpose
        // of static viewport/scissor pipelines is to test messing up the dynamic state.
        std::vector<VkViewport> static_viewports;
        std::vector<VkRect2D>   static_scissors;
        if (!dynamic_viewport_scissor) {
            VkViewport viewport { 0, 0, 128, 128, 0, 1 };
            static_viewports = std::vector<VkViewport>(viewport_scissor_count, viewport);
            static_scissors.resize(viewport_scissor_count);
        }
        VkPipelineViewportStateCreateInfo viewport_state = {VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
                                                            nullptr,
                                                            0,
                                                            viewport_scissor_count,
                                                            static_viewports.data(),
                                                            viewport_scissor_count,
                                                            static_scissors.data()};
        const VkPipelineDynamicStateCreateInfo& dynamic_state =
            dynamic_viewport_scissor == false ? kStaticState : viewport_scissor_count == 0 ? kDynamicStateWithCount : kDynamicState;

        VkGraphicsPipelineCreateInfo info = {VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
                                             nullptr,
                                             0,
                                             uint32_t(m_shaderStages.size()),
                                             m_shaderStages.data(),
                                             &kVertexInputState,
                                             &kInputAssemblyState,
                                             nullptr,  // tess
                                             &viewport_state,
                                             &kRasterizationState,
                                             &kMultisampleState,
                                             &kDepthStencilState,
                                             &kBlendState,
                                             &dynamic_state,
                                             m_pipelineLayout,
                                             m_renderPass,
                                             0};
        VkResult result = vk::CreateGraphicsPipelines(m_device, VK_NULL_HANDLE, 1, &info, nullptr, p_pipeline);
        if (result < 0) m_failureReason = "Failed to create graphics pipeline";
        return result >= 0 ? *p_pipeline : VK_NULL_HANDLE;
    }

    // Bind the graphics pipeline with the specified viewport/scissor state configuration.
    void BindGraphicsPipeline(VkCommandBuffer cmd, bool dynamic_viewport_scissor, uint32_t viewport_scissor_count) {
        VkPipeline pipeline = GetGraphicsPipeline(dynamic_viewport_scissor, viewport_scissor_count);
        if (pipeline) vk::CmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
    }

    // Make a primary command buffer and begin recording.
    VkCommandBuffer MakeBeginPrimaryCommandBuffer(VkCommandPool pool) const {
        VkCommandBufferAllocateInfo info = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, nullptr, pool,
                                            VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1};
        VkCommandBuffer cmd;
        vk::AllocateCommandBuffers(m_device, &info, &cmd);
        BeginPrimaryCommandBuffer(cmd);
        return cmd;
    }

    // Begin recording the primary command buffer.
    VkResult BeginPrimaryCommandBuffer(VkCommandBuffer cmd) const {
        VkCommandBufferBeginInfo info = LvlInitStruct<VkCommandBufferBeginInfo>();
        return vk::BeginCommandBuffer(cmd, &info);
    }

    // Begin the render pass, with subpass contents provided by secondary command buffers.
    void BeginRenderPass(VkCommandBuffer cmd) const {
        VkRenderPassBeginInfo info = {
            VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, m_renderPass, m_framebuffer, {{0, 0}, {128, 128}}, 0, nullptr};
        vk::CmdBeginRenderPass(cmd, &info, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
    }

    // Make a secondary (non-subpass) command buffer and begin recording.
    VkCommandBuffer MakeBeginSecondaryCommandBuffer(VkCommandPool pool, VkFlags usage = 0,
                                                    const void* inheritance_pNext = nullptr) const {
        VkCommandBufferAllocateInfo info = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, nullptr, pool,
                                            VK_COMMAND_BUFFER_LEVEL_SECONDARY, 1};
        VkCommandBuffer cmd;
        vk::AllocateCommandBuffers(m_device, &info, &cmd);
        BeginSecondaryCommandBuffer(cmd, usage, inheritance_pNext);
        return cmd;
    }

    // Begin recording the (non-subpass) secondary command buffer.
    VkResult BeginSecondaryCommandBuffer(VkCommandBuffer cmd, VkFlags usage = 0, const void* inheritance_pNext = nullptr) const {
        VkCommandBufferInheritanceInfo inheritance = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, inheritance_pNext,
                                                      m_renderPass};
        VkCommandBufferBeginInfo info = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, usage, &inheritance};
        return vk::BeginCommandBuffer(cmd, &info);
    }

    // Make a subpass secondary command buffer (for the class's render pass) and begin recording.
    // If a nonzero array of viewports is given, this enabled viewport/scissor inheritance and
    // passes the list of expected viewport depths.
    VkCommandBuffer MakeBeginSubpassCommandBuffer(VkCommandPool pool, uint32_t inherited_viewport_count,
                                                  const VkViewport* p_viewport_depths) const {
        VkCommandBufferAllocateInfo info = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, nullptr, pool,
                                            VK_COMMAND_BUFFER_LEVEL_SECONDARY, 1};
        VkCommandBuffer cmd;
        vk::AllocateCommandBuffers(m_device, &info, &cmd);
        BeginSubpassCommandBuffer(cmd, inherited_viewport_count, p_viewport_depths);
        return cmd;
    }

    // Same as above, but recycle the given secondary command buffer.
    VkResult BeginSubpassCommandBuffer(VkCommandBuffer cmd, uint32_t inherited_viewport_count,
                                       const VkViewport* p_viewport_depths) const {
        VkCommandBufferInheritanceViewportScissorInfoNV viewport_scissor = {
            VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV, nullptr,
            inherited_viewport_count != 0, inherited_viewport_count, p_viewport_depths };
        VkCommandBufferInheritanceInfo inheritance = {
            VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, &viewport_scissor, m_renderPass, 0, m_framebuffer };
        VkCommandBufferBeginInfo info = {
            VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
            VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, &inheritance};
        return vk::BeginCommandBuffer(cmd, &info);
    }
};

TEST_F(VkLayerTest, ViewportInheritance) {
    TEST_DESCRIPTION("Simple correct and incorrect usage of VK_NV_inherited_viewport_scissor");
    m_instance_extension_names.push_back("VK_KHR_get_physical_device_properties2");
    ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
    bool has_features = false;
    const char* missing_feature_string = nullptr;
    auto self = this;
    ASSERT_NO_FATAL_FAILURE(has_features = ViewportInheritanceTestData::InitState(
                                this, [self](const char* extension) { self->m_device_extension_names.push_back(extension); },
                                &missing_feature_string, true, false));
    if (!has_features) {
        printf("%s\n", missing_feature_string);
        return;
    }

    m_errorMonitor->ExpectSuccess();
    ViewportInheritanceTestData test_data(m_device, gpu());
    if (test_data.FailureReason()) {
        printf("%s Test internal failure: %s\n", kSkipPrefix, test_data.FailureReason());
        return;
    }
    VkCommandPool pool = m_commandPool->handle();

    VkCommandBuffer subpass_cmd = test_data.MakeBeginSubpassCommandBuffer(pool, 1, test_data.kViewportDepthOnlyArray);
    test_data.BindGraphicsPipeline(subpass_cmd, true, 1);
    vk::CmdDraw(subpass_cmd, 3, 1, 0, 0);
    vk::EndCommandBuffer(subpass_cmd);

    // Basic correct usage, provide viewport in primary that has the correct depth.
    VkCommandBuffer primary_cmd = test_data.MakeBeginPrimaryCommandBuffer(pool);
    vk::CmdSetViewport(primary_cmd, 0, 1, test_data.kViewportArray);
    vk::CmdSetScissor(primary_cmd, 0, 1, test_data.kScissorArray);
    test_data.BeginRenderPass(primary_cmd);
    vk::CmdExecuteCommands(primary_cmd, 1, &subpass_cmd);
    vk::CmdEndRenderPass(primary_cmd);
    vk::EndCommandBuffer(primary_cmd);
    m_errorMonitor->VerifyNotFound();

    // Viewport with incorrect depth range.
    m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02701");
    test_data.BeginPrimaryCommandBuffer(primary_cmd);
    vk::CmdSetViewport(primary_cmd, 0, 1, test_data.kViewportAlternateDepthArray);
    vk::CmdSetScissor(primary_cmd, 0, 1, test_data.kScissorArray);
    test_data.BeginRenderPass(primary_cmd);
    vk::CmdExecuteCommands(primary_cmd, 1, &subpass_cmd);
    vk::CmdEndRenderPass(primary_cmd);
    vk::EndCommandBuffer(primary_cmd);
    m_errorMonitor->VerifyFound();

    // Viewport not provided.
    m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02701");
    test_data.BeginPrimaryCommandBuffer(primary_cmd);
    vk::CmdSetScissor(primary_cmd, 0, 1, test_data.kScissorArray);
    test_data.BeginRenderPass(primary_cmd);
    vk::CmdExecuteCommands(primary_cmd, 1, &subpass_cmd);
    vk::CmdEndRenderPass(primary_cmd);
    vk::EndCommandBuffer(primary_cmd);
    m_errorMonitor->VerifyFound();

    // Scissor not provided.
    m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02701");
    test_data.BeginPrimaryCommandBuffer(primary_cmd);
    vk::CmdSetViewport(primary_cmd, 0, 1, test_data.kViewportArray);
    test_data.BeginRenderPass(primary_cmd);
    vk::CmdExecuteCommands(primary_cmd, 1, &subpass_cmd);
    vk::CmdEndRenderPass(primary_cmd);
    vk::EndCommandBuffer(primary_cmd);
    m_errorMonitor->VerifyFound();

    // again (i.e. no stale state left over when resetting a secondary command buffer).
    // Don't swap the loop order or you'll mess up subpass_cmd for upcoming tests.
    for (int should_fail = 1; should_fail >= 0; --should_fail) {
        if (should_fail) {
            m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02701"); // viewport
            m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02701"); // scissor
            test_data.BeginSubpassCommandBuffer(subpass_cmd, 0, nullptr);
        }
        else {
            m_errorMonitor->ExpectSuccess();
            test_data.BeginSubpassCommandBuffer(subpass_cmd, 1, test_data.kViewportDepthOnlyArray);
        }
        test_data.BindGraphicsPipeline(subpass_cmd, true, 1);
        vk::CmdDraw(subpass_cmd, 3, 1, 0, 0);
        vk::EndCommandBuffer(subpass_cmd);

        test_data.BeginPrimaryCommandBuffer(primary_cmd);
        vk::CmdSetViewport(primary_cmd, 0, 1, test_data.kViewportArray);
        vk::CmdSetScissor(primary_cmd, 0, 1, test_data.kScissorArray);
        test_data.BeginRenderPass(primary_cmd);
        vk::CmdExecuteCommands(primary_cmd, 1, &subpass_cmd);
        vk::CmdEndRenderPass(primary_cmd);
        vk::EndCommandBuffer(primary_cmd);

        if (should_fail) m_errorMonitor->VerifyFound();
        else m_errorMonitor->VerifyNotFound();
    }

    // Secondary that binds a static viewport/scissor pipeline.
    VkCommandBuffer static_state_cmd = test_data.MakeBeginSubpassCommandBuffer(pool, 0, nullptr);
    test_data.BindGraphicsPipeline(static_state_cmd, false, 1);
    vk::EndCommandBuffer(static_state_cmd);

    // Test that the validation layers still flag missing state when inheritance is disabled, then stops flagging it when enabled
    // Test that inheritance fails if a static viewport/scissor pipeline
    // trashes the state before it is inherited (but it's okay if it's
    // trashed afterwards).
    for (int should_fail = 0; should_fail < 2; ++should_fail) {
        if (should_fail) {
            m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02701"); // viewport
            m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02701"); // scissor
        }
        else {
            m_errorMonitor->ExpectSuccess();
        }
        std::array<VkCommandBuffer, 2> secondaries = {should_fail ? static_state_cmd : subpass_cmd,
                                                      should_fail ? subpass_cmd : static_state_cmd};

        test_data.BeginPrimaryCommandBuffer(primary_cmd);
        vk::CmdSetViewport(primary_cmd, 0, 1, test_data.kViewportArray);
        vk::CmdSetScissor(primary_cmd, 0, 1, test_data.kScissorArray);
        test_data.BeginRenderPass(primary_cmd);
        vk::CmdExecuteCommands(primary_cmd, secondaries.size(), secondaries.data());
        vk::CmdEndRenderPass(primary_cmd);
        vk::EndCommandBuffer(primary_cmd);

        if (should_fail) m_errorMonitor->VerifyFound();
        else m_errorMonitor->VerifyNotFound();
    }

    // Check that the validation layers don't count the primary
    // command buffer state when overwritten by static
    // viewport/scissor pipeline.
    for (int should_fail = 0; should_fail < 2; ++should_fail) {
        if (should_fail) {
            m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02701"); // viewport
            m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02701"); // scissor
        }
        else {
            m_errorMonitor->ExpectSuccess();
        }

        test_data.BeginPrimaryCommandBuffer(primary_cmd);
        vk::CmdSetViewport(primary_cmd, 0, 1, test_data.kViewportArray);
        vk::CmdSetScissor(primary_cmd, 0, 1, test_data.kScissorArray);
        if (should_fail) test_data.BindGraphicsPipeline(primary_cmd, false, 1);
        test_data.BeginRenderPass(primary_cmd);
        vk::CmdExecuteCommands(primary_cmd, 1, &subpass_cmd);
        vk::CmdEndRenderPass(primary_cmd);
        vk::EndCommandBuffer(primary_cmd);

        if (should_fail) m_errorMonitor->VerifyFound();
        else m_errorMonitor->VerifyNotFound();
    }

    // Check that the validation layers DON'T report mismatched viewport depth when the secondary command buffer does not actually
    // consume the viewport in drawing commands (weird corner case).
    VkCommandBuffer no_draw_cmd = test_data.MakeBeginSubpassCommandBuffer(pool, 1, test_data.kViewportDepthOnlyArray);
    test_data.BindGraphicsPipeline(no_draw_cmd, true, 1); // but no subsequent draw call.
    vk::EndCommandBuffer(no_draw_cmd);

    for (int should_fail = 0; should_fail < 2; ++should_fail) {
        if (should_fail) {
            m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02701"); // viewport
        }
        else {
            m_errorMonitor->ExpectSuccess();
        }

        test_data.BeginPrimaryCommandBuffer(primary_cmd);
        vk::CmdSetViewport(primary_cmd, 0, 1, test_data.kViewportAlternateDepthArray);
        vk::CmdSetScissor(primary_cmd, 0, 1, test_data.kScissorArray);
        test_data.BeginRenderPass(primary_cmd);
        vk::CmdExecuteCommands(primary_cmd, 1, should_fail ? &subpass_cmd : &no_draw_cmd);
        vk::CmdEndRenderPass(primary_cmd);
        vk::EndCommandBuffer(primary_cmd);

        if (should_fail) m_errorMonitor->VerifyFound();
        else m_errorMonitor->VerifyNotFound();
    }

    // Check that the validation layers are not okay with binding static viewport/scissor pipelines when inheritance enabled, or
    // setting viewport/scissor explicitly, but are okay if inheritance is not enabled (no regression).
    for (int should_fail = 0; should_fail < 2; ++should_fail) {
        if (!should_fail) m_errorMonitor->ExpectSuccess();

        if (should_fail) m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindPipeline-commandBuffer-04808");
        test_data.BeginSubpassCommandBuffer(no_draw_cmd, should_fail, test_data.kViewportDepthOnlyArray);
        test_data.BindGraphicsPipeline(no_draw_cmd, false, 1);
        if (should_fail) m_errorMonitor->VerifyFound();

        // Check that the validation layers flag setting viewport/scissor with inheritance.
        if (should_fail) m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-commandBuffer-04821");
        vk::CmdSetViewport(no_draw_cmd, 0, 1, test_data.kViewportArray);
        if (should_fail) m_errorMonitor->VerifyFound();
        if (should_fail) m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-viewportScissor2D-04789");
        vk::CmdSetScissor(no_draw_cmd, 0, 1, test_data.kScissorArray);
        if (should_fail) m_errorMonitor->VerifyFound();

        vk::EndCommandBuffer(no_draw_cmd);
        if (!should_fail) m_errorMonitor->VerifyNotFound();
    }

    // Check for at least 1 viewport depth given when enabling inheritance.
    for (int should_fail = 0; should_fail < 2; ++should_fail) {
        if (should_fail) {
            m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
                                                 "VUID-VkCommandBufferInheritanceViewportScissorInfoNV-viewportScissor2D-04784");
        }
        else {
            m_errorMonitor->ExpectSuccess();
        }
        VkCommandBufferInheritanceViewportScissorInfoNV viewport_scissor = {
            VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV, nullptr, should_fail ? VK_TRUE : VK_FALSE,
            0, test_data.kViewportArray /* avoid null pointer crash still */ };
        VkCommandBuffer cmd =
            test_data.MakeBeginSecondaryCommandBuffer(pool, VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, &viewport_scissor);
        // vk::EndCommandBuffer(cmd); // seg faults.
        (void)cmd;

        if (should_fail) m_errorMonitor->VerifyFound();
        else m_errorMonitor->VerifyNotFound();
    }

    // Check for VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT
    m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCommandBufferInheritanceViewportScissorInfoNV-viewportScissor2D-04786");
    VkCommandBufferInheritanceViewportScissorInfoNV viewport_scissor = {
        VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV, nullptr, VK_TRUE, 1, test_data.kViewportArray};
    test_data.MakeBeginSecondaryCommandBuffer(pool, 0, &viewport_scissor);
    m_errorMonitor->VerifyFound();

    // Check that validation layers allow getting inherited viewport/scissor state from earlier secondary command buffer, but not
    // from a different vkCmdExecuteCommands.
    VkCommandBuffer set_viewport_cmd = test_data.MakeBeginSubpassCommandBuffer(pool, 0, nullptr);
    vk::CmdSetViewport(set_viewport_cmd, 0, 1, test_data.kViewportArray);
    vk::EndCommandBuffer(set_viewport_cmd);
    VkCommandBuffer set_scissor_cmd = test_data.MakeBeginSubpassCommandBuffer(pool, 0, nullptr);
    vk::CmdSetScissor(set_scissor_cmd, 0, 1, test_data.kScissorArray);
    vk::EndCommandBuffer(set_scissor_cmd);

    for (int should_fail = 0; should_fail < 2; ++should_fail) {
        test_data.BeginPrimaryCommandBuffer(primary_cmd);
        test_data.BeginRenderPass(primary_cmd);
        if (should_fail) {
            m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02701"); // viewport
            vk::CmdExecuteCommands(primary_cmd, 1, &set_viewport_cmd);
            VkCommandBuffer secondaries[2] = {set_scissor_cmd, subpass_cmd};
            vk::CmdExecuteCommands(primary_cmd, 2, secondaries);
        }
        else {
            m_errorMonitor->ExpectSuccess();
            VkCommandBuffer secondaries[3] = {set_viewport_cmd, set_scissor_cmd, subpass_cmd};
            vk::CmdExecuteCommands(primary_cmd, 3, secondaries);
        }
        vk::CmdEndRenderPass(primary_cmd);
        vk::EndCommandBuffer(primary_cmd);

        if (should_fail) m_errorMonitor->VerifyFound();
        else m_errorMonitor->VerifyNotFound();
    }
}

TEST_F(VkLayerTest, ViewportInheritanceMissingFeature) {
    TEST_DESCRIPTION("Error using VK_NV_inherited_viewport_scissor without enabling feature.");
    m_instance_extension_names.push_back("VK_KHR_get_physical_device_properties2");
    ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
    bool has_features = false;
    const char* missing_feature_string = nullptr;
    auto self = this;
    ASSERT_NO_FATAL_FAILURE(has_features = ViewportInheritanceTestData::InitState(
                                this, [self](const char* extension) { self->m_device_extension_names.push_back(extension); },
                                &missing_feature_string, false, false));
    if (!has_features) {
        printf("%s\n", missing_feature_string);
        return;
    }

    ViewportInheritanceTestData test_data(m_device, gpu());
    if (test_data.FailureReason()) {
        printf("%s Test internal failure: %s\n", kSkipPrefix, test_data.FailureReason());
        return;
    }
    VkCommandPool pool = m_commandPool->handle();

    m_errorMonitor->ExpectSuccess();
    test_data.MakeBeginSubpassCommandBuffer(pool, 0, nullptr);
    m_errorMonitor->VerifyNotFound();

    m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCommandBufferInheritanceViewportScissorInfoNV-viewportScissor2D-04782");
    test_data.MakeBeginSubpassCommandBuffer(pool, 1, test_data.kViewportArray);
    m_errorMonitor->VerifyFound();
}

TEST_F(VkLayerTest, ViewportInheritanceMultiViewport) {
    TEST_DESCRIPTION("VK_NV_inherited_viewport_scissor tests with multiple viewports/scissors");
    m_instance_extension_names.push_back("VK_KHR_get_physical_device_properties2");
    ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
    bool has_features = false;
    const char* missing_feature_string = nullptr;
    auto self = this;
    ASSERT_NO_FATAL_FAILURE(has_features = ViewportInheritanceTestData::InitState(
                                this, [self](const char* extension) { self->m_device_extension_names.push_back(extension); },
                                &missing_feature_string, true, true));
    if (!has_features) {
        printf("%s\n", missing_feature_string);
        return;
    }

    ViewportInheritanceTestData test_data(m_device, gpu());
    if (test_data.FailureReason()) {
        printf("%s Test internal failure: %s\n", kSkipPrefix, test_data.FailureReason());
        return;
    }
    VkCommandPool pool = m_commandPool->handle();

    // Test using viewport/scissor with count state without providing it to be inherited.
    m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02701"); // viewport
    m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02701"); // scissor
    VkCommandBuffer draw_cmd = test_data.MakeBeginSubpassCommandBuffer(pool, 1, test_data.kViewportArray);
    test_data.BindGraphicsPipeline(draw_cmd, true, 0 /* dynamic viewport and scissor count */);
    vk::CmdDraw(draw_cmd, 3, 1, 0, 0);
    vk::EndCommandBuffer(draw_cmd);

    VkCommandBuffer primary_cmd = test_data.MakeBeginPrimaryCommandBuffer(pool);
    vk::CmdSetViewport(primary_cmd, 0, 1, test_data.kViewportArray); // inadequate, needs with count
    vk::CmdSetScissor(primary_cmd, 0, 1, test_data.kScissorArray);
    test_data.BeginRenderPass(primary_cmd);
    vk::CmdExecuteCommands(primary_cmd, 1, &draw_cmd);
    vk::CmdEndRenderPass(primary_cmd);
    vk::EndCommandBuffer(primary_cmd);
    m_errorMonitor->VerifyFound();

    // Test drawing with pipeline that uses more viewports than have been inherited.
    for (int i = 0; i < 4; ++i) {
        auto should_fail = i & 1;
        if (should_fail) m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02701"); // viewport
        else m_errorMonitor->ExpectSuccess();

        test_data.BeginSubpassCommandBuffer(draw_cmd, should_fail ? 1 : 2, test_data.kViewportDepthOnlyArray);
        test_data.BindGraphicsPipeline(draw_cmd, true, 2); // Uses 2 viewports
        vk::CmdDraw(draw_cmd, 3, 1, 0, 0);
        if (i & 2) {
            // Uses only 1 viewport, should not cause us to "forget" the earlier need for 2 viewports.
            test_data.BindGraphicsPipeline(draw_cmd, true, 1);
            vk::CmdDraw(draw_cmd, 3, 1, 0, 0);
        }
        vk::EndCommandBuffer(draw_cmd);

        test_data.BeginPrimaryCommandBuffer(primary_cmd);
        vk::CmdSetViewport(primary_cmd, 0, 2, test_data.kViewportArray);
        vk::CmdSetScissor(primary_cmd, 0, 2, test_data.kScissorArray);
        test_data.BeginRenderPass(primary_cmd);
        vk::CmdExecuteCommands(primary_cmd, 1, &draw_cmd);
        vk::CmdEndRenderPass(primary_cmd);
        vk::EndCommandBuffer(primary_cmd);

        if (should_fail) m_errorMonitor->VerifyFound();
        else m_errorMonitor->VerifyNotFound();
    }

    // Test providing needed viewports in secondary command buffer, and trashing it by binding static state pipeline in another
    // secondary command buffer.
    VkCommandBuffer set_state_fixed_count_cmd = test_data.MakeBeginSubpassCommandBuffer(pool, 0, nullptr);
    vk::CmdSetViewport(set_state_fixed_count_cmd, 0, 2, test_data.kViewportArray);
    vk::CmdSetScissor(set_state_fixed_count_cmd, 0, 2, test_data.kScissorArray);
    vk::EndCommandBuffer(set_state_fixed_count_cmd);

    auto vkCmdSetViewportWithCountEXT =
        PFN_vkCmdSetViewportWithCountEXT(vk::GetDeviceProcAddr(m_device->handle(), "vkCmdSetViewportWithCountEXT"));
    assert(vkCmdSetViewportWithCountEXT);
    auto vkCmdSetScissorWithCountEXT =
        PFN_vkCmdSetScissorWithCountEXT(vk::GetDeviceProcAddr(m_device->handle(), "vkCmdSetScissorWithCountEXT"));
    assert(vkCmdSetScissorWithCountEXT);

    VkCommandBuffer set_state_with_count_cmd = test_data.MakeBeginSubpassCommandBuffer(pool, 0, nullptr);
    vkCmdSetViewportWithCountEXT(set_state_with_count_cmd, 2, test_data.kViewportArray);
    vkCmdSetScissorWithCountEXT(set_state_with_count_cmd, 2, test_data.kScissorArray);
    vk::EndCommandBuffer(set_state_with_count_cmd);

    VkCommandBuffer static_state_cmd = test_data.MakeBeginSubpassCommandBuffer(pool, 0, nullptr);
    test_data.BindGraphicsPipeline(static_state_cmd, false, 2);
    test_data.BindGraphicsPipeline(static_state_cmd, true, 1);  // Should not "forgive" eariler static state pipeline.
    vk::EndCommandBuffer(static_state_cmd);

    for (int i = 0; i < 8; ++i) {
        auto should_fail = i & 1;
        auto use_with_count = i & 4;
        if (should_fail) {
            m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02701"); // viewport 0 (or with count)
            m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02701"); // scissor 0 (or with count)
            if (!use_with_count) {
                m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02701"); // viewport 1
                m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02701"); // scissor 1
            }
        }
        else {
            m_errorMonitor->ExpectSuccess();
        }

        test_data.BeginSubpassCommandBuffer(draw_cmd, 2, test_data.kViewportDepthOnlyArray);
        test_data.BindGraphicsPipeline(draw_cmd, true, use_with_count ? 0 : 2);
        vk::CmdDraw(draw_cmd, 3, 1, 0, 0);
        vk::EndCommandBuffer(draw_cmd);

        VkCommandBuffer set_state_cmd = use_with_count ? set_state_with_count_cmd : set_state_fixed_count_cmd;
        VkCommandBuffer secondaries[3];
        uint32_t secondaries_count;

        switch (i % 4) {
            case 0:
                secondaries[0] = static_state_cmd;
                secondaries[1] = set_state_cmd;
                secondaries[2] = draw_cmd;
                secondaries_count = 3;
                break;
            case 1:
                secondaries[0] = draw_cmd;
                secondaries_count = 1;
                break;
            case 2:
                secondaries[0] = set_state_cmd;
                secondaries[1] = draw_cmd;
                secondaries[2] = static_state_cmd; // Okay as it's after the drawing commands.
                secondaries_count = 3;
                break;
            case 3: default:
                secondaries[0] = set_state_cmd;
                secondaries[1] = static_state_cmd; // Trashes the dynamic state
                secondaries[2] = draw_cmd;
                secondaries_count = 3;
                break;
        }

        test_data.BeginPrimaryCommandBuffer(primary_cmd);
        test_data.BeginRenderPass(primary_cmd);
        vk::CmdExecuteCommands(primary_cmd, secondaries_count, secondaries);
        vk::CmdEndRenderPass(primary_cmd);
        vk::EndCommandBuffer(primary_cmd);

        if (should_fail) m_errorMonitor->VerifyFound();
        else m_errorMonitor->VerifyNotFound();
    }

    // Test mismatched depth count detection, but allow it if the mismatched viewport is not actually used.
    // 0: viewport 1 mismatch, passes as draw only consumes correct 0th viewport.
    // 1: fail, mismatched viewport 1.
    // 2: pass, 2 correct viewports used. (also tests vkCmdSetViewport split between primary and secondary).
    for (int i = 0; i < 3; ++i) {
        auto should_fail = i & 1;
        if (should_fail) {
            m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02701"); // viewport 1
        }
        else {
            m_errorMonitor->ExpectSuccess();
        }

        test_data.BeginSubpassCommandBuffer(draw_cmd, 2, test_data.kViewportDepthOnlyArray);
        test_data.BindGraphicsPipeline(draw_cmd, true, i == 0 ? 1 : 2);
        vk::CmdDraw(draw_cmd, 3, 1, 0, 0);
        vk::EndCommandBuffer(draw_cmd);

        test_data.BeginSubpassCommandBuffer(set_state_fixed_count_cmd, 0, nullptr);
        vk::CmdSetViewport(set_state_fixed_count_cmd, 1, 1, i == 2 ? &test_data.kViewportArray[1] : &test_data.kViewportAlternateDepthArray[1]);
        vk::CmdSetScissor(set_state_fixed_count_cmd, 1, 1, &test_data.kScissorArray[1]);
        vk::EndCommandBuffer(set_state_fixed_count_cmd);

        test_data.BeginPrimaryCommandBuffer(primary_cmd);
        vk::CmdSetViewport(primary_cmd, 0, 1, &test_data.kViewportArray[0]);
        vk::CmdSetScissor(primary_cmd, 0, 1, &test_data.kScissorArray[0]);
        test_data.BeginRenderPass(primary_cmd);
        VkCommandBuffer secondaries[] = {set_state_fixed_count_cmd, draw_cmd};
        vk::CmdExecuteCommands(primary_cmd, 2, secondaries);
        vk::CmdEndRenderPass(primary_cmd);
        vk::EndCommandBuffer(primary_cmd);

        if (should_fail) m_errorMonitor->VerifyFound();
        else m_errorMonitor->VerifyNotFound();
    }

    // Test dynamic viewport count failing due to either exceeding the viewport inheritance limit, or inheriting a viewport with
    // incorrect depth.
    for (int i = 0; i < 8; ++i) {
        auto state_in_secondary = i & 1;
        auto should_fail = i & 2;
        auto inherited_incorrect_depth = i & 4;

        if (should_fail) m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-commandBuffer-02701");
        else m_errorMonitor->ExpectSuccess();

        VkViewport viewports[3];
        viewports[0] = test_data.kViewportArray[0];
        viewports[1] = test_data.kViewportArray[1];
        if (inherited_incorrect_depth) {
            viewports[2] = test_data.kViewportAlternateDepthArray[2];  // Will be a problem only when using all 3 viewports.
        }
        else {
            viewports[2] = test_data.kViewportArray[2];
        }

        uint32_t inherited_count = should_fail && !inherited_incorrect_depth ? 2 : 3;
        test_data.BeginSubpassCommandBuffer(draw_cmd, inherited_count, test_data.kViewportDepthOnlyArray);
        test_data.BindGraphicsPipeline(draw_cmd, true, 0);
        vk::CmdDraw(draw_cmd, 3, 1, 0, 0);
        vk::EndCommandBuffer(draw_cmd);

        test_data.BeginPrimaryCommandBuffer(primary_cmd);

        // Decoy command, should be overwritten later.
        vkCmdSetViewportWithCountEXT(primary_cmd, 3, test_data.kViewportAlternateDepthArray);

        // Record state setting commands in either the primary, or auxilliary secondary, command buffer.
        VkCommandBuffer set_state_cmd;
        if (state_in_secondary) {
            set_state_cmd = set_state_with_count_cmd;
            test_data.BeginSubpassCommandBuffer(set_state_cmd, 0, nullptr);
        }
        else {
            set_state_cmd = primary_cmd;
        }
        uint32_t count = should_fail ? 3 : 2;
        vkCmdSetViewportWithCountEXT(set_state_cmd, count, viewports);
        vkCmdSetScissorWithCountEXT(set_state_cmd, count, test_data.kScissorArray);
        if (state_in_secondary) {
            vk::EndCommandBuffer(set_state_cmd);
        }

        test_data.BeginRenderPass(primary_cmd);
        if (state_in_secondary) {
            VkCommandBuffer secondaries[] = {set_state_cmd, draw_cmd};
            vk::CmdExecuteCommands(primary_cmd, 2, secondaries);
        }
        else {
            vk::CmdExecuteCommands(primary_cmd, 1, &draw_cmd);
        }
        vk::CmdEndRenderPass(primary_cmd);
        vk::EndCommandBuffer(primary_cmd);

        if (should_fail) m_errorMonitor->VerifyFound();
        else m_errorMonitor->VerifyNotFound();
    }
}

TEST_F(VkLayerTest, ViewportInheritanceScissorMissingFeature) {
    TEST_DESCRIPTION("Error using VK_NV_inherited_viewport_scissor without enabling multiViewport feature.");
    m_instance_extension_names.push_back("VK_KHR_get_physical_device_properties2");
    ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
    bool has_features = false;
    const char* missing_feature_string = nullptr;
    auto self = this;
    ASSERT_NO_FATAL_FAILURE(has_features = ViewportInheritanceTestData::InitState(
                                this, [self](const char* extension) { self->m_device_extension_names.push_back(extension); },
                                &missing_feature_string, true, false, true));
    if (!has_features) {
        printf("%s\n", missing_feature_string);
        return;
    }

    ViewportInheritanceTestData test_data(m_device, gpu());
    if (test_data.FailureReason()) {
        printf("%s Test internal failure: %s\n", kSkipPrefix, test_data.FailureReason());
        return;
    }
    VkCommandPool pool = m_commandPool->handle();

    m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCommandBufferInheritanceViewportScissorInfoNV-viewportScissor2D-04783");
    test_data.MakeBeginSubpassCommandBuffer(pool, 2, test_data.kViewportArray);
    m_errorMonitor->VerifyFound();
}

TEST_F(VkLayerTest, PipelineMissingDynamicStateDiscardRectangle) {
    TEST_DESCRIPTION("Bind pipeline with missing dynamic state discard rectangle.");

    if (!AddRequiredInstanceExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
        printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
        return;
    }
    ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
    if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME)) {
        printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME);
        return;
    }
    m_device_extension_names.push_back(VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME);
    bool has_features = false;
    const char* missing_feature_string = nullptr;
    auto self = this;
    ASSERT_NO_FATAL_FAILURE(has_features = ViewportInheritanceTestData::InitState(
                                this, [self](const char* extension) { self->m_device_extension_names.push_back(extension); },
                                &missing_feature_string, true, false, true));
    if (!has_features) {
        printf("%s\n", missing_feature_string);
        return;
    }
    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());

    VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
    VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);

    ViewportInheritanceTestData test_data(m_device, gpu());
    if (test_data.FailureReason()) {
        printf("%s Test internal failure: %s\n", kSkipPrefix, test_data.FailureReason());
        return;
    }

    VkCommandBufferInheritanceViewportScissorInfoNV viewport_scissor =
        LvlInitStruct<VkCommandBufferInheritanceViewportScissorInfoNV>();
    viewport_scissor.viewportScissor2D = VK_TRUE;
    viewport_scissor.viewportDepthCount = 1;
    viewport_scissor.pViewportDepths = test_data.kViewportArray;

    VkCommandBufferInheritanceInfo cbii = LvlInitStruct<VkCommandBufferInheritanceInfo>(&viewport_scissor);
    cbii.renderPass = m_renderPass;

    VkCommandBufferBeginInfo cbbi = LvlInitStruct<VkCommandBufferBeginInfo>();
    cbbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
    cbbi.pInheritanceInfo = &cbii;

    VkRect2D discard_rectangle = {};
    VkPipelineDiscardRectangleStateCreateInfoEXT discard_rectangle_state =
        LvlInitStruct<VkPipelineDiscardRectangleStateCreateInfoEXT>();
    discard_rectangle_state.discardRectangleCount = 1;
    discard_rectangle_state.pDiscardRectangles = &discard_rectangle;

    const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
    VkPipelineDynamicStateCreateInfo dyn_state_ci = LvlInitStruct<VkPipelineDynamicStateCreateInfo>();
    dyn_state_ci.dynamicStateCount = 2;
    dyn_state_ci.pDynamicStates = dyn_states;

    CreatePipelineHelper pipe(*this);
    pipe.InitInfo();
    pipe.gp_ci_.pNext = &discard_rectangle_state;
    pipe.gp_ci_.pDynamicState = &dyn_state_ci;
    pipe.InitState();
    pipe.CreateGraphicsPipeline();

    vk::BeginCommandBuffer(secondary.handle(), &cbbi);

    m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindPipeline-commandBuffer-04809");
    vk::CmdBindPipeline(secondary.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
    m_errorMonitor->VerifyFound();
}


// SPIR-V blobs for graphics pipeline.

// #version 460
// void main() { gl_Position = vec4(1); }
const uint32_t ViewportInheritanceTestData::kVertexSpirV[166] = {
    0x07230203, 0x00010000, 0x0008000a, 0x00000014, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, 0x00000001, 0x4c534c47,
    0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x0006000f, 0x00000000, 0x00000004, 0x6e69616d,
    0x00000000, 0x0000000d, 0x00030003, 0x00000002, 0x000001cc, 0x00040005, 0x00000004, 0x6e69616d, 0x00000000, 0x00060005,
    0x0000000b, 0x505f6c67, 0x65567265, 0x78657472, 0x00000000, 0x00060006, 0x0000000b, 0x00000000, 0x505f6c67, 0x7469736f,
    0x006e6f69, 0x00070006, 0x0000000b, 0x00000001, 0x505f6c67, 0x746e696f, 0x657a6953, 0x00000000, 0x00070006, 0x0000000b,
    0x00000002, 0x435f6c67, 0x4470696c, 0x61747369, 0x0065636e, 0x00070006, 0x0000000b, 0x00000003, 0x435f6c67, 0x446c6c75,
    0x61747369, 0x0065636e, 0x00030005, 0x0000000d, 0x00000000, 0x00050048, 0x0000000b, 0x00000000, 0x0000000b, 0x00000000,
    0x00050048, 0x0000000b, 0x00000001, 0x0000000b, 0x00000001, 0x00050048, 0x0000000b, 0x00000002, 0x0000000b, 0x00000003,
    0x00050048, 0x0000000b, 0x00000003, 0x0000000b, 0x00000004, 0x00030047, 0x0000000b, 0x00000002, 0x00020013, 0x00000002,
    0x00030021, 0x00000003, 0x00000002, 0x00030016, 0x00000006, 0x00000020, 0x00040017, 0x00000007, 0x00000006, 0x00000004,
    0x00040015, 0x00000008, 0x00000020, 0x00000000, 0x0004002b, 0x00000008, 0x00000009, 0x00000001, 0x0004001c, 0x0000000a,
    0x00000006, 0x00000009, 0x0006001e, 0x0000000b, 0x00000007, 0x00000006, 0x0000000a, 0x0000000a, 0x00040020, 0x0000000c,
    0x00000003, 0x0000000b, 0x0004003b, 0x0000000c, 0x0000000d, 0x00000003, 0x00040015, 0x0000000e, 0x00000020, 0x00000001,
    0x0004002b, 0x0000000e, 0x0000000f, 0x00000000, 0x0004002b, 0x00000006, 0x00000010, 0x3f800000, 0x0007002c, 0x00000007,
    0x00000011, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00040020, 0x00000012, 0x00000003, 0x00000007, 0x00050036,
    0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, 0x00000005, 0x00050041, 0x00000012, 0x00000013, 0x0000000d,
    0x0000000f, 0x0003003e, 0x00000013, 0x00000011, 0x000100fd, 0x00010038};

// #version 460
// layout(location = 0) out vec4 color;
// void main() { color = vec4(1); }
const uint32_t ViewportInheritanceTestData::kFragmentSpirV[83] = {
    0x07230203, 0x00010000, 0x0008000a, 0x0000000c, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, 0x00000001, 0x4c534c47,
    0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x0006000f, 0x00000004, 0x00000004, 0x6e69616d,
    0x00000000, 0x00000009, 0x00030010, 0x00000004, 0x00000007, 0x00030003, 0x00000002, 0x000001cc, 0x00040005, 0x00000004,
    0x6e69616d, 0x00000000, 0x00040005, 0x00000009, 0x6f6c6f63, 0x00000072, 0x00040047, 0x00000009, 0x0000001e, 0x00000000,
    0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, 0x00030016, 0x00000006, 0x00000020, 0x00040017, 0x00000007,
    0x00000006, 0x00000004, 0x00040020, 0x00000008, 0x00000003, 0x00000007, 0x0004003b, 0x00000008, 0x00000009, 0x00000003,
    0x0004002b, 0x00000006, 0x0000000a, 0x3f800000, 0x0007002c, 0x00000007, 0x0000000b, 0x0000000a, 0x0000000a, 0x0000000a,
    0x0000000a, 0x00050036, 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, 0x00000005, 0x0003003e, 0x00000009,
    0x0000000b, 0x000100fd, 0x00010038};

const VkPipelineVertexInputStateCreateInfo ViewportInheritanceTestData::kVertexInputState = {
    VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, nullptr, 0, 0, nullptr, 0, nullptr};

const VkPipelineInputAssemblyStateCreateInfo ViewportInheritanceTestData::kInputAssemblyState = {
    VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_FALSE};

const VkPipelineRasterizationStateCreateInfo ViewportInheritanceTestData::kRasterizationState = {
    VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
    nullptr,
    0,
    VK_FALSE,
    VK_FALSE,
    VK_POLYGON_MODE_FILL,
    VK_CULL_MODE_BACK_BIT,
    VK_FRONT_FACE_COUNTER_CLOCKWISE,
};

const VkPipelineMultisampleStateCreateInfo ViewportInheritanceTestData::kMultisampleState = {
    VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
    nullptr,
    0,
    VK_SAMPLE_COUNT_1_BIT,
};

const VkPipelineDepthStencilStateCreateInfo ViewportInheritanceTestData::kDepthStencilState =
    LvlInitStruct<VkPipelineDepthStencilStateCreateInfo>();

const VkPipelineColorBlendAttachmentState ViewportInheritanceTestData::kBlendAttachmentState = {
    VK_FALSE,
    VK_BLEND_FACTOR_ZERO,
    VK_BLEND_FACTOR_ZERO,
    VK_BLEND_OP_ADD,
    VK_BLEND_FACTOR_ZERO,
    VK_BLEND_FACTOR_ZERO,
    VK_BLEND_OP_ADD,
    VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT};

const VkPipelineColorBlendStateCreateInfo ViewportInheritanceTestData::kBlendState = {
    VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
    nullptr,
    0,
    VK_FALSE,
    VK_LOGIC_OP_CLEAR,
    1,
    &kBlendAttachmentState,
    {}};

const VkPipelineDynamicStateCreateInfo ViewportInheritanceTestData::kStaticState = {
    VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, nullptr, 0, 0, nullptr};

static const std::array<VkDynamicState, 2> kDynamicStateArray = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
const VkPipelineDynamicStateCreateInfo ViewportInheritanceTestData::kDynamicState = {
    VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, nullptr, 0,
    static_cast<uint32_t>(kDynamicStateArray.size()), kDynamicStateArray.data()};

static const std::array<VkDynamicState, 2> kDynamicStateWithCountArray = {VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT,
                                                                          VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT};
const VkPipelineDynamicStateCreateInfo ViewportInheritanceTestData::kDynamicStateWithCount = {
    VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, nullptr, 0,
    static_cast<uint32_t>(kDynamicStateWithCountArray.size()), kDynamicStateWithCountArray.data()};

const VkViewport ViewportInheritanceTestData::kViewportArray[32] = {
    {0.0f, 0.0f, 128.0f, 128.0f, 0.00f, 1.00f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.01f, 0.99f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.02f, 0.98f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.03f, 0.97f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.04f, 0.96f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.05f, 0.95f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.06f, 0.94f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.07f, 0.93f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.08f, 0.92f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.09f, 0.91f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.10f, 0.90f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.11f, 0.89f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.12f, 0.88f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.13f, 0.87f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.14f, 0.86f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.15f, 0.85f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.16f, 0.84f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.17f, 0.83f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.18f, 0.82f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.19f, 0.81f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.20f, 0.80f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.21f, 0.79f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.22f, 0.78f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.23f, 0.77f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.24f, 0.76f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.25f, 0.75f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.26f, 0.74f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.27f, 0.73f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.28f, 0.72f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.29f, 0.71f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.30f, 0.70f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.31f, 0.69f},
};

const VkViewport ViewportInheritanceTestData::kViewportDepthOnlyArray[32] = {
    {0.0f, 0.0f, 0.0f, 0.0f, 0.00f, 1.00f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.01f, 0.99f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.02f, 0.98f},
    {0.0f, 0.0f, 0.0f, 0.0f, 0.03f, 0.97f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.04f, 0.96f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.05f, 0.95f},
    {0.0f, 0.0f, 0.0f, 0.0f, 0.06f, 0.94f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.07f, 0.93f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.08f, 0.92f},
    {0.0f, 0.0f, 0.0f, 0.0f, 0.09f, 0.91f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.10f, 0.90f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.11f, 0.89f},
    {0.0f, 0.0f, 0.0f, 0.0f, 0.12f, 0.88f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.13f, 0.87f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.14f, 0.86f},
    {0.0f, 0.0f, 0.0f, 0.0f, 0.15f, 0.85f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.16f, 0.84f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.17f, 0.83f},
    {0.0f, 0.0f, 0.0f, 0.0f, 0.18f, 0.82f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.19f, 0.81f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.20f, 0.80f},
    {0.0f, 0.0f, 0.0f, 0.0f, 0.21f, 0.79f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.22f, 0.78f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.23f, 0.77f},
    {0.0f, 0.0f, 0.0f, 0.0f, 0.24f, 0.76f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.25f, 0.75f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.26f, 0.74f},
    {0.0f, 0.0f, 0.0f, 0.0f, 0.27f, 0.73f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.28f, 0.72f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.29f, 0.71f},
    {0.0f, 0.0f, 0.0f, 0.0f, 0.30f, 0.70f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.31f, 0.69f},
};

const VkViewport ViewportInheritanceTestData::kViewportAlternateDepthArray[32] = {
    {0.0f, 0.0f, 128.0f, 128.0f, 0.88f, 1.00f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.01f, 0.00f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.00f, 0.98f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.03f, 0.00f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.00f, 0.96f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.05f, 0.00f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.00f, 0.94f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.07f, 0.00f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.00f, 0.92f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.09f, 0.00f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.00f, 0.90f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.11f, 0.00f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.00f, 0.88f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.13f, 0.00f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.00f, 0.86f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.15f, 0.00f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.00f, 0.84f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.17f, 0.00f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.00f, 0.82f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.19f, 0.00f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.00f, 0.80f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.21f, 0.00f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.00f, 0.78f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.23f, 0.00f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.00f, 0.76f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.25f, 0.00f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.00f, 0.74f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.27f, 0.00f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.00f, 0.72f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.29f, 0.00f},
    {0.0f, 0.0f, 128.0f, 128.0f, 0.00f, 0.70f}, {0.0f, 0.0f, 128.0f, 128.0f, 0.31f, 0.00f},
};

const VkRect2D ViewportInheritanceTestData::kScissorArray[32] = {
    {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}},
    {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}},
    {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}},
    {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}},
    {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}},
    {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}},
    {{0, 0}, {128, 128}}, {{0, 0}, {128, 128}},
};
