/*
 * Copyright (c) 2015-2026 The Khronos Group Inc.
 * Copyright (c) 2015-2026 Valve Corporation
 * Copyright (c) 2015-2026 LunarG, Inc.
 * Copyright (c) 2015-2026 Google, Inc.
 * Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
 *
 * 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
 */

#include <vulkan/vulkan_core.h>
#include "../framework/layer_validation_tests.h"
#include "../framework/pipeline_helper.h"
#include "../framework/shader_object_helper.h"
#include "../framework/render_pass_helper.h"
#include "shader_helper.h"

class NegativeShaderInterface : public VkLayerTest {};

TEST_F(NegativeShaderInterface, MaxVertexComponentsWithBuiltins) {
    TEST_DESCRIPTION("Test if the max componenets checks are being checked from OpMemberDecorate built-ins");
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    // matches max_profile.json
    if (m_device->Physical().limits_.maxVertexOutputComponents != 128) {
        GTEST_SKIP() << "maxVertexOutputComponents is too high";
    } else if (m_device->Physical().limits_.maxFragmentInputComponents != 128) {
        GTEST_SKIP() << "maxFragmentInputComponents is too high";
    }

    // vec4 == 4 components
    // This gives 124 which is just below the set max limit
    const uint32_t numVec4 = 31;

    std::string vsSourceStr =
        "#version 450\n"
        "layout(location = 0) out block {\n";
    for (uint32_t i = 0; i < numVec4; i++) {
        vsSourceStr += "vec4 v" + std::to_string(i) + ";\n";
    }
    vsSourceStr +=
        "} outVs;\n"
        "\n"
        "void main() {\n"
        "    vec4 x = vec4(1.0);\n";
    for (uint32_t i = 0; i < numVec4; i++) {
        vsSourceStr += "outVs.v" + std::to_string(i) + " = x;\n";
    }

    // GLSL is defined to have a struct for the vertex shader built-in:
    //
    //    out gl_PerVertex {
    //        vec4 gl_Position;
    //        float gl_PointSize;
    //        float gl_ClipDistance[];
    //        float gl_CullDistance[];
    //    } gl_out[];
    //
    // by including gl_Position here 7 extra vertex input components are added pushing it over the 128
    // 124 + 7 > 128 limit
    vsSourceStr += "    gl_Position = x;\n";
    vsSourceStr += "}";

    std::string fsSourceStr =
        "#version 450\n"
        "layout(location = 0) in block {\n";
    for (uint32_t i = 0; i < numVec4; i++) {
        fsSourceStr += "vec4 v" + std::to_string(i) + ";\n";
    }
    fsSourceStr +=
        "} inPs;\n"
        "\n"
        "layout(location=0) out vec4 color;\n"
        "\n"
        "void main(){\n"
        "    color = vec4(1);\n"
        "}\n";

    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-Location-06272");
    VkShaderObj vs(*m_device, vsSourceStr.c_str(), VK_SHADER_STAGE_VERTEX_BIT);
    m_errorMonitor->VerifyFound();
    // maxFragmentInputComponents is not reached because GLSL should not be including any input fragment stage built-ins by default
    // only maxVertexOutputComponents is reached
    VkShaderObj fs(*m_device, fsSourceStr.c_str(), VK_SHADER_STAGE_FRAGMENT_BIT);
}

TEST_F(NegativeShaderInterface, MaxFragmentComponentsWithBuiltins) {
    TEST_DESCRIPTION("Test if the max componenets checks are being checked from OpDecorate built-ins");
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    // matches max_profile.json
    if (m_device->Physical().limits_.maxVertexOutputComponents != 128) {
        GTEST_SKIP() << "maxVertexOutputComponents is too high";
    } else if (m_device->Physical().limits_.maxFragmentInputComponents != 128) {
        GTEST_SKIP() << "maxFragmentInputComponents is too high";
    }

    // vec4 == 4 components
    // This gives 128 which is the max limit
    const uint32_t numVec4 = 32;  // 32 * 4 == 128

    std::string vsSourceStr =
        "#version 450\n"
        "layout(location = 0) out block {\n";
    for (uint32_t i = 0; i < numVec4; i++) {
        vsSourceStr += "vec4 v" + std::to_string(i) + ";\n";
    }
    vsSourceStr +=
        "} outVs;\n"
        "\n"
        "void main() {\n"
        "    vec4 x = vec4(1.0);\n";
    for (uint32_t i = 0; i < numVec4; i++) {
        vsSourceStr += "outVs.v" + std::to_string(i) + " = x;\n";
    }
    vsSourceStr += "}";

    std::string fsSourceStr =
        "#version 450\n"
        "layout(location = 0) in block {\n";
    for (uint32_t i = 0; i < numVec4; i++) {
        fsSourceStr += "vec4 v" + std::to_string(i) + ";\n";
    }
    // By added gl_PointCoord it adds 2 more components to the fragment input stage
    fsSourceStr +=
        "} inPs;\n"
        "\n"
        "layout(location=0) out vec4 color;\n"
        "\n"
        "void main(){\n"
        "    color = vec4(1) * gl_PointCoord.x;\n"
        "}\n";

    // maxVertexOutputComponents is not reached because GLSL should not be including any output vertex stage built-ins
    // only maxFragmentInputComponents is reached
    VkShaderObj vs(*m_device, vsSourceStr.c_str(), VK_SHADER_STAGE_VERTEX_BIT);

    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-Location-06272");
    VkShaderObj fs(*m_device, fsSourceStr.c_str(), VK_SHADER_STAGE_FRAGMENT_BIT);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeShaderInterface, MaxVertexOutputComponents) {
    TEST_DESCRIPTION(
        "Test that an error is produced when the number of output components from the vertex stage exceeds the device limit");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    // overflow == 0: no overflow, 1: too many components, 2: location number too large
    for (uint32_t overflow = 0; overflow < 3; ++overflow) {
        m_errorMonitor->Reset();

        const uint32_t maxVsOutComp = m_device->Physical().limits_.maxVertexOutputComponents + overflow;
        std::string vsSourceStr = "#version 450\n\n";
        const uint32_t numVec4 = maxVsOutComp / 4;
        uint32_t location = 0;
        if (overflow == 2) {
            vsSourceStr += "layout(location=" + std::to_string(numVec4 + 1) + ") out vec4 vn;\n";
        } else if (overflow == 1) {
            for (uint32_t i = 0; i < numVec4; i++) {
                vsSourceStr += "layout(location=" + std::to_string(location) + ") out vec4 v" + std::to_string(i) + ";\n";
                location += 1;
            }
            const uint32_t remainder = maxVsOutComp % 4;
            if (remainder != 0) {
                if (remainder == 1) {
                    vsSourceStr += "layout(location=" + std::to_string(location) + ") out float" + " vn;\n";
                } else {
                    vsSourceStr +=
                        "layout(location=" + std::to_string(location) + ") out vec" + std::to_string(remainder) + " vn;\n";
                }
                location += 1;
            }
        }
        vsSourceStr +=
            "void main(){\n"
            "}\n";

        switch (overflow) {
            case 0: {
                VkShaderObj vs(*m_device, vsSourceStr.c_str(), VK_SHADER_STAGE_VERTEX_BIT);
                break;
            }
            case 1: {
                // component and location limit (maxVertexOutputComponents)
                m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-Location-06272");
                VkShaderObj vs(*m_device, vsSourceStr.c_str(), VK_SHADER_STAGE_VERTEX_BIT);
                m_errorMonitor->VerifyFound();
                break;
            }
            case 2: {
                // just component limit (maxVertexOutputComponents)
                m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-Location-06272");
                VkShaderObj vs(*m_device, vsSourceStr.c_str(), VK_SHADER_STAGE_VERTEX_BIT);
                m_errorMonitor->VerifyFound();
                break;
            }
            default: {
                assert(0);
            }
        }
    }
}

TEST_F(NegativeShaderInterface, MaxComponentsBlocks) {
    TEST_DESCRIPTION("Test if the max componenets checks are done properly when in a single block");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    // To make the test simple, just make sure max is 128 or less (most HW is 64 or 128)
    if (m_device->Physical().limits_.maxVertexOutputComponents > 128 ||
        m_device->Physical().limits_.maxFragmentInputComponents > 128) {
        GTEST_SKIP() << "maxVertexOutputComponents or maxFragmentInputComponents too high for test";
    }
    // vec4 == 4 components
    // so this put the test over 128
    const uint32_t numVec4 = 33;

    std::string vsSourceStr =
        "#version 450\n"
        "layout(location = 0) out block {\n";
    for (uint32_t i = 0; i < numVec4; i++) {
        vsSourceStr += "vec4 v" + std::to_string(i) + ";\n";
    }
    vsSourceStr +=
        "} outVs;\n"
        "\n"
        "void main() {\n"
        "    vec4 x = vec4(1.0);\n";
    for (uint32_t i = 0; i < numVec4; i++) {
        vsSourceStr += "outVs.v" + std::to_string(i) + " = x;\n";
    }
    vsSourceStr += "}";

    std::string fsSourceStr =
        "#version 450\n"
        "layout(location = 0) in block {\n";
    for (uint32_t i = 0; i < numVec4; i++) {
        fsSourceStr += "vec4 v" + std::to_string(i) + ";\n";
    }
    fsSourceStr +=
        "} inPs;\n"
        "\n"
        "layout(location=0) out vec4 color;\n"
        "\n"
        "void main(){\n"
        "    color = vec4(1);\n"
        "}\n";

    // maxVertexOutputComponents
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-Location-06272");
    VkShaderObj vs(*m_device, vsSourceStr.c_str(), VK_SHADER_STAGE_VERTEX_BIT);
    m_errorMonitor->VerifyFound();

    // maxFragmentInputComponents
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-Location-06272");
    VkShaderObj fs(*m_device, fsSourceStr.c_str(), VK_SHADER_STAGE_FRAGMENT_BIT);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeShaderInterface, MaxFragmentInputComponents) {
    TEST_DESCRIPTION(
        "Test that an error is produced when the number of input components from the fragment stage exceeds the device limit");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    // overflow == 0: no overflow, 1: too many components, 2: location number too large
    for (uint32_t overflow = 0; overflow < 3; ++overflow) {
        m_errorMonitor->Reset();

        const uint32_t maxFsInComp = m_device->Physical().limits_.maxFragmentInputComponents + overflow;
        std::string fsSourceStr = "#version 450\n\n";
        const uint32_t numVec4 = maxFsInComp / 4;
        uint32_t location = 0;
        if (overflow == 2) {
            fsSourceStr += "layout(location=" + std::to_string(numVec4 + 1) + ") in float" + " vn;\n";
        } else {
            for (uint32_t i = 0; i < numVec4; i++) {
                fsSourceStr += "layout(location=" + std::to_string(location) + ") in vec4 v" + std::to_string(i) + ";\n";
                location += 1;
            }
            const uint32_t remainder = maxFsInComp % 4;
            if (remainder != 0) {
                if (remainder == 1) {
                    fsSourceStr += "layout(location=" + std::to_string(location) + ") in float" + " vn;\n";
                } else {
                    fsSourceStr +=
                        "layout(location=" + std::to_string(location) + ") in vec" + std::to_string(remainder) + " vn;\n";
                }
                location += 1;
            }
        }
        fsSourceStr +=
            "layout(location=0) out vec4 color;"
            "\n"
            "void main(){\n"
            "    color = vec4(1);\n"
            "}\n";

        switch (overflow) {
            case 0: {
                VkShaderObj fs(*m_device, fsSourceStr.c_str(), VK_SHADER_STAGE_FRAGMENT_BIT);
                break;
            }
            case 1: {
                // (maxFragmentInputComponents)
                m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-Location-06272");
                VkShaderObj fs(*m_device, fsSourceStr.c_str(), VK_SHADER_STAGE_FRAGMENT_BIT);
                m_errorMonitor->VerifyFound();
                break;
            }
            case 2: {
                // (maxFragmentInputComponents)
                m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-Location-06272");
                VkShaderObj fs(*m_device, fsSourceStr.c_str(), VK_SHADER_STAGE_FRAGMENT_BIT);
                m_errorMonitor->VerifyFound();
                break;
            }
            default: {
                assert(0);
            }
        }
    }
}

TEST_F(NegativeShaderInterface, FragmentInputNotProvided) {
    TEST_DESCRIPTION(
        "Test that an error is produced for a fragment shader input which is not present in the outputs of the previous stage");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* fsSource = R"glsl(
        #version 450
        layout(location=0) in float x;
        layout(location=0) out vec4 color;
        void main(){
           color = vec4(x);
        }
    )glsl";
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-08743");
}

TEST_F(NegativeShaderInterface, FragmentInputNotProvidedInBlock) {
    TEST_DESCRIPTION(
        "Test that an error is produced for a fragment shader input within an interface block, which is not present in the outputs "
        "of the previous stage.");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* fsSource = R"glsl(
        #version 450
        in block { layout(location=0) float x; } ins;
        layout(location=0) out vec4 color;
        void main(){
           color = vec4(ins.x);
        }
    )glsl";

    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-08743");
}

TEST_F(NegativeShaderInterface, VsFsTypeMismatch) {
    TEST_DESCRIPTION("Test that an error is produced for mismatched types across the vertex->fragment shader interface");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* vsSource = R"glsl(
        #version 450
        layout(location=0) out int x;
        void main(){
           x = 0;
           gl_Position = vec4(1);
        }
    )glsl";
    const char* fsSource = R"glsl(
        #version 450
        layout(location=0) in float x; /* VS writes int */
        layout(location=0) out vec4 color;
        void main(){
           color = vec4(x);
        }
    )glsl";

    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-07754");
}

TEST_F(NegativeShaderInterface, VsFsTypeMismatch2) {
    TEST_DESCRIPTION("https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/8443");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* vsSource = R"glsl(
        #version 450
        layout(location=0) out int x;
        void main(){
           x = 0;
           gl_Position = vec4(1);
        }
    )glsl";
    const char* fsSource = R"glsl(
        #version 450
        layout(location=0) in float x; /* VS writes int */
        layout(location=0) out vec4 color;
        void main(){
           color = vec4(x);
        }
    )glsl";

    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        // Flipped here
        helper.shader_stages_ = {fs.GetStageCreateInfo(), vs.GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-07754");
}

TEST_F(NegativeShaderInterface, VsFsTypeMismatchInBlock) {
    TEST_DESCRIPTION(
        "Test that an error is produced for mismatched types across the vertex->fragment shader interface, when the variable is "
        "contained within an interface block");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* vsSource = R"glsl(
        #version 450
        out block { layout(location=0) int x; } outs;
        void main(){
           outs.x = 0;
           gl_Position = vec4(1);
        }
    )glsl";
    const char* fsSource = R"glsl(
        #version 450
        in block { layout(location=0) float x; } ins; /* VS writes int */
        layout(location=0) out vec4 color;
        void main(){
           color = vec4(ins.x);
        }
    )glsl";

    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-07754");
}

TEST_F(NegativeShaderInterface, VsFsTypeMismatchVectorSize) {
    TEST_DESCRIPTION("OpTypeVector has larger output than input");
    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddOptionalExtensions(VK_KHR_MAINTENANCE_4_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* vsSource = R"glsl(
        #version 450
        layout(location=0) out vec4 x;
        void main(){
           gl_Position = vec4(1.0);
        }
    )glsl";
    const char* fsSource = R"glsl(
        #version 450
        layout(location=0) in vec3 x;
        layout(location=0) out vec4 color;
        void main(){
           color = vec4(1.0);
        }
    )glsl";

    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-maintenance4-06817");
}

TEST_F(NegativeShaderInterface, VsFsTypeMismatchLongVectorSize) {
    TEST_DESCRIPTION("OpTypeVector has larger output than input");
    SetTargetApiVersion(VK_API_VERSION_1_3);
    AddRequiredFeature(vkt::Feature::longVector);
    AddRequiredExtensions(VK_EXT_SHADER_LONG_VECTOR_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* vsSource = R"glsl(
        #version 450
        layout(location=0) out vec4 x;
        void main(){
           gl_Position = vec4(1.0);
        }
    )glsl";
    // fs declares a vec3 input
    const char* fsSource = R"(
               OpCapability Shader
               OpCapability LongVectorEXT
               OpExtension "SPV_EXT_long_vector"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %main "main" %v
               OpExecutionMode %main OriginUpperLeft
               OpDecorate %v Location 0
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
      %float = OpTypeFloat 32
       %uint = OpTypeInt 32 0
         %u3 = OpConstant %uint 3
    %vfloat  = OpTypeVectorIdEXT %float %u3
     %ptr_in = OpTypePointer Input %vfloat
          %v = OpVariable %ptr_in Input
        %int = OpTypeInt 32 1
      %int_0 = OpConstant %int 0
       %main = OpFunction %void None %3
          %5 = OpLabel
               OpReturn
               OpFunctionEnd
    )";

    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, SPV_ENV_VULKAN_1_3, SPV_SOURCE_ASM);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-maintenance4-06817");
}

TEST_F(NegativeShaderInterface, VsFsTypeMismatchBlockStruct) {
    TEST_DESCRIPTION("Have a struct inside a block between shaders");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* vsSource = R"glsl(
        #version 450
        struct S {
            vec4 a[2];
            float b;
            int c; // difference
        };

        out block {
            layout(location=0) float x;
            layout(location=6) S y;
            layout(location=10) int[4] z;
        } outBlock;

        void main() {
            outBlock.y.a[1] = vec4(1);
            gl_Position = vec4(1);
        }
    )glsl";

    const char* fsSource = R"glsl(
        #version 450
        struct S {
            vec4 a[2];
            float b;
            float c; // difference
        };

        in block {
            layout(location=0) float x;
            layout(location=6) S y;
            layout(location=10) int[4] z;
        } inBlock;

        layout(location=0) out vec4 color;
        void main(){
            color = inBlock.y.a[1];
        }
    )glsl";

    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-07754");
}

TEST_F(NegativeShaderInterface, VsFsTypeMismatchBlockStruct64bit) {
    TEST_DESCRIPTION("Have a struct inside a block between shaders");

    AddRequiredFeature(vkt::Feature::shaderFloat64);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* vsSource = R"glsl(
        #version 450
        #extension GL_EXT_shader_explicit_arithmetic_types_float64 : enable

        struct S {
            vec4 a[2];
            float b;
            f64vec3 c; // difference (takes 2 locations)
        };

        out block {
            layout(location=0) S x[2];
            layout(location=10) int y;
        } outBlock;

        void main() {}
    )glsl";

    const char* fsSource = R"glsl(
        #version 450
        struct S {
            vec4 a[2];
            float b;
            vec4 c; // difference
            vec2 d;
        };

        in block {
            layout(location=0) S x[2];
            layout(location=10) int y;
        } inBlock;

        layout(location=0) out vec4 color;
        void main(){}
    )glsl";

    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-07754");
}

TEST_F(NegativeShaderInterface, VsFsTypeMismatchBlockArrayOfStruct) {
    TEST_DESCRIPTION("Have an array of struct inside a block between shaders");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* vsSource = R"glsl(
        #version 450
        struct S {
            vec4 a[2];
            float b;
            int c; // difference
        };

        out block {
            layout(location=0) float x;
            layout(location=6) S[2] y; // each array is 4 locations slots
            layout(location=14) int[4] z;
        } outBlock;

        void main() {
            outBlock.y[1].a[1] = vec4(1);
            gl_Position = vec4(1);
        }
    )glsl";

    const char* fsSource = R"glsl(
        #version 450
        struct S {
            vec4 a[2];
            float b;
            float c; // difference
        };

        in block {
            layout(location=0) float x;
            layout(location=6) S[2] y;
            layout(location=14) int[4] z;
        } inBlock;

        layout(location=0) out vec4 color;
        void main(){
            color = inBlock.y[1].a[1];
        }
    )glsl";

    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-07754");
}

TEST_F(NegativeShaderInterface, VsFsTypeMismatchBlockStructInnerArraySize) {
    TEST_DESCRIPTION("Have an struct inside a block between shaders, array size is difference");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();
    if (m_device->Physical().limits_.maxVertexOutputComponents <= 64) {
        GTEST_SKIP() << "maxVertexOutputComponents is too low";
    }

    const char* vsSource = R"glsl(
        #version 450
        struct S {
            vec4 a[2];
            float b;
            int[2] c; // difference
        };

        out block {
            layout(location=0) float x;
            layout(location=6) S[2] y;
            layout(location=18) int[4] z;
        } outBlock;

        void main() {
            outBlock.y[1].a[1] = vec4(1);
            gl_Position = vec4(1);
        }
    )glsl";

    const char* fsSource = R"glsl(
        #version 450
        struct S {
            vec4 a[2];
            float b;
            int[3] c; // difference
        };

        in block {
            layout(location=0) float x;
            layout(location=6) S[2] y;
            layout(location=18) int[4] z;
        } inBlock;

        layout(location=0) out vec4 color;
        void main(){
            color = inBlock.y[1].a[1];
        }
    )glsl";

    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    // Both are errors, depending on compiler, the order of variables listed will hit one before the other
    m_errorMonitor->SetUnexpectedError("VUID-RuntimeSpirv-OpEntryPoint-07754");
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-08743");
}

TEST_F(NegativeShaderInterface, VsFsTypeMismatchBlockStructOuterArraySize) {
    TEST_DESCRIPTION("Have an struct inside a block between shaders, array size is difference");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();
    if (m_device->Physical().limits_.maxVertexOutputComponents <= 64) {
        GTEST_SKIP() << "maxVertexOutputComponents is too low";
    }

    const char* vsSource = R"glsl(
        #version 450
        struct S {
            vec4 a[2];
            float b;
            float c;
        };

        out block {
            layout(location=0) float x;
            layout(location=6) S[2] y; // difference
            layout(location=20) int[4] z;
        } outBlock;

        void main() {
            outBlock.y[1].a[1] = vec4(1);
            gl_Position = vec4(1);
        }
    )glsl";

    const char* fsSource = R"glsl(
        #version 450
        struct S {
            vec4 a[2];
            float b;
            float c;
        };

        in block {
            layout(location=0) float x;
            layout(location=6) S[3] y; // difference
            layout(location=20) int[4] z;
        } inBlock;

        layout(location=0) out vec4 color;
        void main(){
            color = inBlock.y[1].a[1];
        }
    )glsl";

    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-08743");
}

TEST_F(NegativeShaderInterface, VsFsTypeMismatchBlockStructArraySizeVertex) {
    TEST_DESCRIPTION(
        "Have an struct inside a block between shaders, array size is difference, but from the vertex shader being too large");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();
    if (m_device->Physical().limits_.maxVertexOutputComponents <= 64) {
        GTEST_SKIP() << "maxVertexOutputComponents is too low";
    }

    const char* vsSource = R"glsl(
        #version 450
        struct S {
            vec4 a[2];
            float b;
            int[3] c; // difference
        };

        out block {
            layout(location=0) float x;
            layout(location=6) S[2] y;
            layout(location=18) int[4] z;
        } outBlock;

        void main() {
            outBlock.y[1].a[1] = vec4(1);
            gl_Position = vec4(1);
        }
    )glsl";

    const char* fsSource = R"glsl(
        #version 450
        struct S {
            vec4 a[2];
            float b;
            int[2] c; // difference
        };

        in block {
            layout(location=0) float x;
            layout(location=6) S[2] y;
            layout(location=18) int[4] z;
        } inBlock;

        layout(location=0) out vec4 color;
        void main(){
            color = inBlock.y[1].a[1];
        }
    )glsl";

    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    // Both are errors, depending on compiler, the order of variables listed will hit one before the other
    m_errorMonitor->SetUnexpectedError("VUID-RuntimeSpirv-OpEntryPoint-08743");
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-07754");
}

TEST_F(NegativeShaderInterface, VsFsTypeMismatchBlockStructOuter2DArraySize) {
    TEST_DESCRIPTION("Have an struct inside a block between shaders, array size is difference");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();
    if (m_device->Physical().limits_.maxVertexOutputComponents <= 64) {
        GTEST_SKIP() << "maxVertexOutputComponents is too low";
    }

    const char* vsSource = R"glsl(
        #version 450
        struct S {
            vec4 a[2];
            float b;
        };

        out block {
            layout(location=0) float x;
            layout(location=2) S[2][2] y; // difference
            layout(location=21) int[2] z;
        } outBlock;

        void main() {}
    )glsl";

    const char* fsSource = R"glsl(
        #version 450
        struct S {
            vec4 a[2];
            float b;
        };

        in block {
            layout(location=0) float x;
            layout(location=2) S[2][3] y; // difference
            layout(location=21) int[2] z;
        } inBlock;

        layout(location=0) out vec4 color;
        void main(){}
    )glsl";

    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-08743");
}

TEST_F(NegativeShaderInterface, VsFsTypeMismatchBlockNestedStructType64bit) {
    TEST_DESCRIPTION("Have nested struct inside a block between shaders");

    AddRequiredFeature(vkt::Feature::shaderFloat64);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* vsSource = R"glsl(
        #version 450
        #extension GL_EXT_shader_explicit_arithmetic_types_float64 : enable

        struct A {
            float a0_;
        };
        struct B {
            f64vec3 b0_;
            A b1_;
        };
        struct C {
            A c1_;
            B c2_;
        };

        out block {
            layout(location=0) float x;
            layout(location=1) C y;
        } outBlock;

        void main() {}
    )glsl";

    const char* fsSource = R"glsl(
        #version 450
        struct A {
            float a0_;
        };
        struct B {
            vec3 b0_;
            A b1_;
        };
        struct C {
            A c1_;
            B c2_;
        };

        in block {
            layout(location=0) float x;
            layout(location=1) C y;
        } inBlock;

        layout(location=0) out vec4 color;
        void main(){}
    )glsl";

    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-07754");
}

TEST_F(NegativeShaderInterface, VsFsTypeMismatchBlockNestedStructArray) {
    TEST_DESCRIPTION("Have nested struct inside a block between shaders");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* vsSource = R"glsl(
        #version 450
        struct A {
            float a0_;
        };
        struct B {
            int b0_;
            A b1_; // difference
        };
        struct C {
            vec4 c0_[2];
            A c1_;
            B c2_;
        };

        out block {
            layout(location=0) float x;
            layout(location=1) C y;
        } outBlock;

        void main() {}
    )glsl";

    const char* fsSource = R"glsl(
        #version 450
        struct A {
            float a0_;
        };
        struct B {
            int b0_;
            A b1_[2];  // difference
        };
        struct C {
            vec4 c0_[2];
            A c1_;
            B c2_;
        };

        in block {
            layout(location=0) float x;
            layout(location=1) C y;
        } inBlock;

        layout(location=0) out vec4 color;
        void main(){}
    )glsl";

    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-08743");
}

TEST_F(NegativeShaderInterface, VsFsMismatchByLocation) {
    TEST_DESCRIPTION(
        "Test that an error is produced for location mismatches across the vertex->fragment shader interface; This should manifest "
        "as a not-written/not-consumed pair, but flushes out broken walking of the interfaces");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* vsSource = R"glsl(
        #version 450
        out block { layout(location=1) float x; } outs;
        void main(){
           outs.x = 0;
           gl_Position = vec4(1);
        }
    )glsl";
    const char* fsSource = R"glsl(
        #version 450
        in block { layout(location=0) float x; } ins;
        layout(location=0) out vec4 color;
        void main(){
           color = vec4(ins.x);
        }
    )glsl";

    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-08743");
}

TEST_F(NegativeShaderInterface, VsFsMismatchByComponent) {
    TEST_DESCRIPTION(
        "Test that an error is produced for component mismatches across the vertex->fragment shader interface. It's not enough to "
        "have the same set of locations in use; matching is defined in terms of spirv variables.");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* vsSource = R"glsl(
        #version 450
        out block { layout(location=0, component=0) float x; } outs;
        void main(){
           outs.x = 0;
           gl_Position = vec4(1);
        }
    )glsl";
    const char* fsSource = R"glsl(
        #version 450
        in block { layout(location=0, component=1) float x; } ins;
        layout(location=0) out vec4 color;
        void main(){
           color = vec4(ins.x);
        }
    )glsl";

    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-08743");
}

TEST_F(NegativeShaderInterface, VsFsTypeMismatchShaderObject) {
    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::dynamicRendering);
    AddRequiredFeature(vkt::Feature::shaderObject);
    RETURN_IF_SKIP(Init());
    InitDynamicRenderTarget();

    const char* vsSource = R"glsl(
        #version 450
        layout(location=0) out int x;
        void main(){
           x = 0;
           gl_Position = vec4(1);
        }
    )glsl";
    const char* fsSource = R"glsl(
        #version 450
        layout(location=0) in float x; /* VS writes int */
        layout(location=0) out vec4 color;
        void main(){
           color = vec4(x);
        }
    )glsl";

    const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, vsSource));
    const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, fsSource));

    m_command_buffer.Begin();
    m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea());
    SetDefaultDynamicStatesExclude();
    m_command_buffer.BindShaders(vertShader, fragShader);
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpEntryPoint-07754");
    vk::CmdDraw(m_command_buffer, 4, 1, 0, 0);
    m_errorMonitor->VerifyFound();
    m_command_buffer.EndRendering();
    m_command_buffer.End();
}

TEST_F(NegativeShaderInterface, VsFsTypeMismatchVectorSizeShaderObject) {
    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::dynamicRendering);
    AddRequiredFeature(vkt::Feature::shaderObject);
    RETURN_IF_SKIP(Init());
    InitDynamicRenderTarget();

    const char* vsSource = R"glsl(
        #version 450
        layout(location=0) out vec4 x;
        void main(){
           gl_Position = vec4(1.0);
        }
    )glsl";
    const char* fsSource = R"glsl(
        #version 450
        layout(location=0) in vec3 x;
        layout(location=0) out vec4 color;
        void main(){
           color = vec4(1.0);
        }
    )glsl";

    const vkt::Shader vertShader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, vsSource));
    const vkt::Shader fragShader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, fsSource));

    m_command_buffer.Begin();
    m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea());
    SetDefaultDynamicStatesExclude();
    m_command_buffer.BindShaders(vertShader, fragShader);
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-maintenance4-06817");
    vk::CmdDraw(m_command_buffer, 4, 1, 0, 0);
    m_errorMonitor->VerifyFound();
    m_command_buffer.EndRendering();
    m_command_buffer.End();
}

TEST_F(NegativeShaderInterface, InputOutputMismatch) {
    TEST_DESCRIPTION("Test mismatch between vertex shader output and fragment shader input.");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char vsSource[] = R"glsl(
        #version 450
        layout(location = 1) out int v;
        void main() {
            v = 1;
        }
    )glsl";

    const char fsSource[] = R"glsl(
        #version 450
        layout(location = 0) out vec4 color;
        layout(location = 1) in float v;
        void main() {
           color = vec4(v);
        }
    )glsl";
    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    CreatePipelineHelper pipe(*this);
    pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};

    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpEntryPoint-07754");
    pipe.CreateGraphicsPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeShaderInterface, VertexOutputNotConsumed) {
    TEST_DESCRIPTION("Test that a warning is produced for a vertex output that is not consumed by the fragment stage");

    SetTargetApiVersion(VK_API_VERSION_1_0);

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* vsSource = R"glsl(
        #version 450
        layout(location=0) out float x;
        void main(){
           gl_Position = vec4(1);
           x = 0;
        }
    )glsl";
    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {vs.GetStageCreateInfo(), helper.fs_->GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kPerformanceWarningBit, "WARNING-Shader-OutputNotConsumed");
}

// Spec doesn't clarify if this is valid or not
// https://gitlab.khronos.org/vulkan/vulkan/-/issues/3293
TEST_F(NegativeShaderInterface, DISABLED_InputAndOutputComponents) {
    TEST_DESCRIPTION("Test invalid shader layout in and out with different components.");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    {
        const char* vsSource = R"glsl(
                #version 450

                layout(location = 0, component = 0) out float r;
                layout(location = 0, component = 2) out float b;

                void main() {
                    r = 0.25f;
                    b = 0.75f;
                }
            )glsl";
        VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);

        const char* fsSource = R"glsl(
                #version 450

                layout(location = 0) in vec3 rgb;

                layout (location = 0) out vec4 color;

                void main() {
                    color = vec4(rgb, 1.0f);
                }
            )glsl";
        VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

        const auto set_info = [&](CreatePipelineHelper& helper) {
            helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
        };
        CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-08743");
    }

    {
        const char* vsSource = R"glsl(
                #version 450

                layout(location = 0) out vec3 v;

                void main() {
                }
            )glsl";
        VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);

        const char* fsSource = R"glsl(
                #version 450

                layout(location = 0, component = 0) in float a;
                layout(location = 0, component = 2) in float b;

                layout (location = 0) out vec4 color;

                void main() {
                    color = vec4(1.0f);
                }
            )glsl";
        VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

        const auto set_info = [&](CreatePipelineHelper& helper) {
            helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
        };
        CreatePipelineHelper::OneshotTest(*this, set_info, kPerformanceWarningBit, "WARNING-Shader-OutputNotConsumed");
    }

    {
        const char* vsSource = R"glsl(
                #version 450

                layout(location = 0) out vec3 v;

                void main() {
                    v = vec3(1.0);
                }
            )glsl";
        VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);

        const char* fsSource = R"glsl(
                #version 450

                layout(location = 0) in vec4 v;

                layout (location = 0) out vec4 color;

                void main() {
                    color = v;
                }
            )glsl";
        VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

        const auto set_info = [&](CreatePipelineHelper& helper) {
            helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
        };
        CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-08743");
    }

    {
        const char* vsSource = R"glsl(
                #version 450

                layout(location = 0) out vec3 v;

                void main() {
                    v = vec3(1.0);
                }
            )glsl";
        VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);

        const char* fsSource = R"glsl(
                #version 450

                layout (location = 0) out vec4 color;

                void main() {
                    color = vec4(1.0);
                }
            )glsl";
        VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

        const auto set_info = [&](CreatePipelineHelper& helper) {
            helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
        };
        CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit);
    }

    {
        const char* vsSource = R"glsl(
                #version 450

                layout(location = 0) out vec3 v1;
                layout(location = 1) out vec3 v2;
                layout(location = 2) out vec3 v3;

                void main() {
                    v1 = vec3(1.0);
                    v2 = vec3(2.0);
                    v3 = vec3(3.0);
                }
            )glsl";
        VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);

        const char* fsSource = R"glsl(
                #version 450

                layout (location = 0) in vec3 v1;
                layout (location = 2) in vec3 v3;

                layout (location = 0) out vec4 color;

                void main() {
                    color = vec4(v1 * v3, 1.0);
                }
            )glsl";
        VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

        const auto set_info = [&](CreatePipelineHelper& helper) {
            helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
        };
        CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit);
    }
}

TEST_F(NegativeShaderInterface, AlphaToCoverageOutputLocation0) {
    TEST_DESCRIPTION("Test that an error is produced when alpha to coverage is enabled but no output at location 0 is declared.");

    RETURN_IF_SKIP(Init());
    InitRenderTarget(0u);

    VkShaderObj fs(*m_device, kMinimalShaderGlsl, VK_SHADER_STAGE_FRAGMENT_BIT);

    VkPipelineMultisampleStateCreateInfo ms_state_ci = vku::InitStructHelper();
    ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
    ms_state_ci.alphaToCoverageEnable = VK_TRUE;

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
        helper.ms_ci_ = ms_state_ci;
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-alphaToCoverageEnable-08891");
}

TEST_F(NegativeShaderInterface, AlphaToCoverageOutputIndex1) {
    TEST_DESCRIPTION("DualSource blend has two outputs at location zero, so Index 0 is the one that's required");
    AddRequiredFeature(vkt::Feature::dualSrcBlend);
    RETURN_IF_SKIP(Init());
    InitRenderTarget(0u);

    const char* fs_src = R"glsl(
        #version 460
        layout(location = 0, index = 1) out vec4 c0;
        void main() {
            c0 = vec4(0.0f);
        }
    )glsl";
    VkShaderObj fs(*m_device, fs_src, VK_SHADER_STAGE_FRAGMENT_BIT);

    VkPipelineMultisampleStateCreateInfo ms_state_ci = vku::InitStructHelper();
    ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
    ms_state_ci.alphaToCoverageEnable = VK_TRUE;

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
        helper.ms_ci_ = ms_state_ci;
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-alphaToCoverageEnable-08891");
}

TEST_F(NegativeShaderInterface, AlphaToCoverageOutputNoAlpha) {
    TEST_DESCRIPTION(
        "Test that an error is produced when alpha to coverage is enabled but output at location 0 doesn't have alpha component.");

    RETURN_IF_SKIP(Init());
    InitRenderTarget(0u);

    const char* fsSource = R"glsl(
        #version 450
        layout(location=0) out vec3 x;
        void main(){
           x = vec3(1);
        }
    )glsl";
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    VkPipelineMultisampleStateCreateInfo ms_state_ci = vku::InitStructHelper();
    ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
    ms_state_ci.alphaToCoverageEnable = VK_TRUE;

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
        helper.ms_ci_ = ms_state_ci;
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-alphaToCoverageEnable-08891");
}

TEST_F(NegativeShaderInterface, AlphaToCoverageArrayIndex) {
    TEST_DESCRIPTION("Have array out outputs, but start at index 1");

    RETURN_IF_SKIP(Init());
    InitRenderTarget(0u);

    const char* fsSource = R"glsl(
        #version 450
        layout(location=1) out vec4 fragData[3];
        void main() {
            fragData[0] = vec4(1.0);
        }
    )glsl";
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    VkPipelineMultisampleStateCreateInfo ms_state_ci = vku::InitStructHelper();
    ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
    ms_state_ci.alphaToCoverageEnable = VK_TRUE;

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
        helper.ms_ci_ = ms_state_ci;
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-alphaToCoverageEnable-08891");
}

TEST_F(NegativeShaderInterface, AlphaToCoverageArrayVec3) {
    TEST_DESCRIPTION("Have array out outputs, but not contain the alpha component");

    RETURN_IF_SKIP(Init());
    InitRenderTarget(0u);

    const char* fsSource = R"glsl(
        #version 450
        layout(location=0) out vec3 fragData[4];
        void main() {
            fragData[0] = vec3(1.0);
        }
    )glsl";
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    VkPipelineMultisampleStateCreateInfo ms_state_ci = vku::InitStructHelper();
    ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
    ms_state_ci.alphaToCoverageEnable = VK_TRUE;

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
        helper.ms_ci_ = ms_state_ci;
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-alphaToCoverageEnable-08891");
}

TEST_F(NegativeShaderInterface, MultidimensionalArray) {
    TEST_DESCRIPTION("Make sure multidimensional arrays are handled");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();
    if (m_device->Physical().limits_.maxVertexOutputComponents <= 64) {
        GTEST_SKIP() << "maxVertexOutputComponents is too low";
    }

    const char* vsSource = R"glsl(
        #version 450
        layout(location=0) out float[4][2][2] x;
        void main() {}
    )glsl";

    const char* fsSource = R"glsl(
        #version 450
        layout(location=0) in float[4][3][2] x; // 2 extra Locations
        layout(location=0) out float color;
        void main(){}
    )glsl";

    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-08743");
}

TEST_F(NegativeShaderInterface, MultidimensionalArrayDim) {
    TEST_DESCRIPTION("Make sure multidimensional arrays are handled");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();
    if (m_device->Physical().limits_.maxVertexOutputComponents <= 64) {
        GTEST_SKIP() << "maxVertexOutputComponents is too low";
    }

    const char* vsSource = R"glsl(
        #version 450
        layout(location=0) out float[4][2][2] x;
        void main() {}
    )glsl";

    const char* fsSource = R"glsl(
        #version 450
        layout(location=0) in float[17] x; // 1 extra Locations
        layout(location=0) out float color;
        void main(){}
    )glsl";

    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-08743");
}

TEST_F(NegativeShaderInterface, MultidimensionalArray64bit) {
    TEST_DESCRIPTION("Make sure multidimensional arrays are handled for 64bits");

    AddRequiredFeature(vkt::Feature::shaderFloat64);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    if (m_device->Physical().limits_.maxFragmentOutputAttachments < 25) {
        GTEST_SKIP() << "maxFragmentOutputAttachments is too low";
    }

    const char* vsSource = R"glsl(
        #version 450
        #extension GL_EXT_shader_explicit_arithmetic_types_float64 : enable
        layout(location=0) out f64vec3[2][2][2] x; // take 2 locations each (total 16)
        layout(location=24) out float y;
        void main() {}
    )glsl";

    const char* fsSource = R"glsl(
        #version 450
        #extension GL_EXT_shader_explicit_arithmetic_types_float64 : enable
        layout(location=0) flat in f64vec3[2][3][2] x;
        layout(location=24) out float color;
        void main(){}
    )glsl";

    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-08743");
}

TEST_F(NegativeShaderInterface, PackingInsideArray) {
    TEST_DESCRIPTION("From https://gitlab.khronos.org/vulkan/vulkan/-/issues/3558");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* vsSource = R"glsl(
        #version 450
        layout(location = 0, component = 1) out float[2] x;
        void main() {}
    )glsl";

    const char* fsSource = R"glsl(
        #version 450
        layout(location = 0, component = 1) in float x;
        layout(location = 1, component = 0) in float y;
        layout(location=0) out float color;
        void main(){}
    )glsl";

    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-08743");
}

TEST_F(NegativeShaderInterface, FragmentOutputNotWritten) {
    TEST_DESCRIPTION(
        "Test that an error is produced for a fragment shader which does not provide an output for one of the pipeline's color "
        "attachments");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* fs_source = R"glsl(
        #version 450
        layout(location = 0) out vec4 uFragColor; // not written to
        void main() {}
    )glsl";
    VkShaderObj fs(*m_device, fs_source, VK_SHADER_STAGE_FRAGMENT_BIT);

    CreatePipelineHelper pipe(*this);
    pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
    pipe.cb_attachments_.colorWriteMask = 0xf;  // all components
    m_errorMonitor->SetDesiredWarning("Undefined-Value-OutputNotWritten");
    pipe.CreateGraphicsPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeShaderInterface, FragmentOutputNotWrittenDynamicRendering) {
    AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::dynamicRendering);
    RETURN_IF_SKIP(Init());
    InitDynamicRenderTarget();

    const char* fs_source = R"glsl(
        #version 450
        layout(location = 0) out vec4 uFragColor; // not written to
        void main() {}
    )glsl";
    VkShaderObj fs(*m_device, fs_source, VK_SHADER_STAGE_FRAGMENT_BIT);

    VkFormat color_formats = VK_FORMAT_B8G8R8A8_UNORM;
    VkPipelineRenderingCreateInfo pipeline_rendering_info = vku::InitStructHelper();
    pipeline_rendering_info.colorAttachmentCount = 1;
    pipeline_rendering_info.pColorAttachmentFormats = &color_formats;

    CreatePipelineHelper pipe(*this, &pipeline_rendering_info);
    pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
    pipe.cb_attachments_.colorWriteMask = 0xf;  // all components
    pipe.CreateGraphicsPipeline();

    m_command_buffer.Begin();
    m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea());
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
    m_errorMonitor->SetDesiredWarning("Undefined-Value-OutputNotWritten-DynamicRendering");
    vk::CmdDraw(m_command_buffer, 3, 1, 0, 0);
    m_errorMonitor->VerifyFound();
    m_command_buffer.EndRendering();
    m_command_buffer.End();
}

TEST_F(NegativeShaderInterface, FragmentOutputNotWrittenDynamicRenderingShaderObject) {
    AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::dynamicRendering);
    AddRequiredFeature(vkt::Feature::shaderObject);
    RETURN_IF_SKIP(Init());
    InitDynamicRenderTarget();

    const char* fs_source = R"glsl(
        #version 450
        layout(location = 0) out vec4 uFragColor; // not written to
        void main() {}
    )glsl";

    const vkt::Shader vert_shader(*m_device, VK_SHADER_STAGE_VERTEX_BIT, GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl));
    const vkt::Shader frag_shader(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, fs_source));

    m_command_buffer.Begin();
    m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea());
    SetDefaultDynamicStatesExclude();
    m_command_buffer.BindShaders(vert_shader, frag_shader);
    VkColorComponentFlags color_write_mask = 0xf;  // all
    vk::CmdSetColorWriteMaskEXT(m_command_buffer, 0, 1, &color_write_mask);
    m_errorMonitor->SetDesiredWarning("Undefined-Value-OutputNotWritten-DynamicRendering");
    vk::CmdDraw(m_command_buffer, 4, 1, 0, 0);
    m_errorMonitor->VerifyFound();
    m_command_buffer.EndRendering();
    m_command_buffer.End();
}

// TODO - https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/7923
// also https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/9616
TEST_F(NegativeShaderInterface, DISABLED_FragmentOutputNotWrittenArray) {
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* fs_source = R"glsl(
        #version 460
        layout(location = 0) out vec4 uFragColor[2];
        void main(){
            uFragColor[0] = vec4(0);
        }
    )glsl";
    VkShaderObj fs(*m_device, fs_source, VK_SHADER_STAGE_FRAGMENT_BIT);

    RenderPassSingleSubpass rp(*this);
    rp.AddAttachmentDescription(VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
                                VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
    rp.AddAttachmentDescription(VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
                                VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
    rp.AddColorAttachment(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
    rp.AddColorAttachment(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
    rp.CreateRenderPass();

    VkPipelineColorBlendAttachmentState color_blends[2];
    color_blends[0] = DefaultColorBlendAttachmentState();
    color_blends[0].colorWriteMask = 0xf;
    color_blends[1] = DefaultColorBlendAttachmentState();
    color_blends[1].colorWriteMask = 0xf;

    CreatePipelineHelper pipe(*this);
    pipe.shader_stages_[1] = fs.GetStageCreateInfo();
    pipe.cb_ci_.attachmentCount = 2;
    pipe.cb_ci_.pAttachments = color_blends;
    pipe.gp_ci_.renderPass = rp;
    m_errorMonitor->SetDesiredWarning("Undefined-Value-OutputNotWritten");
    pipe.CreateGraphicsPipeline();
    m_errorMonitor->VerifyFound();
}

// TODO - https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/7923
// also https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/9616
TEST_F(NegativeShaderInterface, DISABLED_FragmentOutputNotWrittenArrayDynamicRendering) {
    AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::dynamicRendering);
    RETURN_IF_SKIP(Init());
    InitDynamicRenderTarget();

    const char* fs_source = R"glsl(
        #version 460
        layout(location = 0) out vec4 uFragColor[2];
        void main(){
            uFragColor[0] = vec4(0);
        }
    )glsl";
    VkShaderObj fs(*m_device, fs_source, VK_SHADER_STAGE_FRAGMENT_BIT);

    VkFormat color_formats[2] = {VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM};
    VkPipelineRenderingCreateInfo pipeline_rendering_info = vku::InitStructHelper();
    pipeline_rendering_info.colorAttachmentCount = 2;
    pipeline_rendering_info.pColorAttachmentFormats = color_formats;

    VkPipelineColorBlendAttachmentState color_blends[2];
    color_blends[0] = DefaultColorBlendAttachmentState();
    color_blends[0].colorWriteMask = 0xf;
    color_blends[1] = DefaultColorBlendAttachmentState();
    color_blends[1].colorWriteMask = 0xf;

    CreatePipelineHelper pipe(*this, &pipeline_rendering_info);
    pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
    pipe.cb_ci_.attachmentCount = 2;
    pipe.cb_ci_.pAttachments = color_blends;
    pipe.CreateGraphicsPipeline();

    VkRenderingAttachmentInfo color_attachments[2];
    color_attachments[0] = vku::InitStructHelper();
    color_attachments[0].imageView = GetDynamicRenderTarget();
    color_attachments[0].imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
    color_attachments[1] = color_attachments[0];

    VkRenderingInfo rendering_info = vku::InitStructHelper();
    rendering_info.colorAttachmentCount = 2;
    rendering_info.pColorAttachments = color_attachments;
    rendering_info.layerCount = 1;
    rendering_info.renderArea = GetRenderTargetArea();

    m_command_buffer.Begin();
    m_command_buffer.BeginRendering(rendering_info);
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
    m_errorMonitor->SetDesiredWarning("Undefined-Value-OutputNotWritten-DynamicRendering");
    vk::CmdDraw(m_command_buffer, 3, 1, 0, 0);
    m_errorMonitor->VerifyFound();
    m_command_buffer.EndRendering();
    m_command_buffer.End();
}

TEST_F(NegativeShaderInterface, CreatePipelineFragmentOutputTypeMismatch) {
    TEST_DESCRIPTION(
        "Test that an error is produced for a mismatch between the fundamental type of an fragment shader output variable, and the "
        "format of the corresponding attachment");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* fsSource = R"glsl(
        #version 450
        layout(location=0) out ivec4 x; /* not UNORM */
        void main(){
           x = ivec4(1);
        }
    )glsl";

    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    const auto set_info = [&](CreatePipelineHelper& helper) {
        helper.shader_stages_ = {helper.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
    };
    CreatePipelineHelper::OneshotTest(*this, set_info, kWarningBit, "Undefined-Value-ShaderFragmentOutputMismatch");
}

TEST_F(NegativeShaderInterface, FragmentOutputTypeMismatchDynamicRendering) {
    AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::dynamicRendering);
    RETURN_IF_SKIP(Init());
    InitDynamicRenderTarget();

    const char* fs_source = R"glsl(
        #version 450
        layout(location=0) out ivec4 x; /* not UNORM */
        void main(){
           x = ivec4(1);
        }
    )glsl";

    VkShaderObj fs(*m_device, fs_source, VK_SHADER_STAGE_FRAGMENT_BIT);

    VkFormat color_formats = VK_FORMAT_B8G8R8A8_UNORM;
    VkPipelineRenderingCreateInfo pipeline_rendering_info = vku::InitStructHelper();
    pipeline_rendering_info.colorAttachmentCount = 1;
    pipeline_rendering_info.pColorAttachmentFormats = &color_formats;

    CreatePipelineHelper pipe(*this, &pipeline_rendering_info);
    pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
    pipe.cb_attachments_.colorWriteMask = 0xf;  // all components
    pipe.CreateGraphicsPipeline();

    m_command_buffer.Begin();
    m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea());
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
    m_errorMonitor->SetDesiredWarning("Undefined-Value-ShaderFragmentOutputMismatch-DynamicRendering");
    vk::CmdDraw(m_command_buffer, 3, 1, 0, 0);
    m_errorMonitor->VerifyFound();
    m_command_buffer.EndRendering();
    m_command_buffer.End();
}

TEST_F(NegativeShaderInterface, FragmentOutputTypeMismatchDynamicRenderingLocalRead) {
    AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_LOCAL_READ_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::dynamicRendering);
    AddRequiredFeature(vkt::Feature::dynamicRenderingLocalRead);
    RETURN_IF_SKIP(Init());
    InitDynamicRenderTarget(VK_FORMAT_R8G8B8A8_SINT);
    InitDynamicRenderTarget(VK_FORMAT_R8G8B8A8_UNORM);

    const char* fs_source = R"glsl(
        #version 450
        layout(location=0) out ivec4 x; /* not UNORM */
        void main(){
           x = ivec4(1);
        }
    )glsl";

    VkShaderObj fs(*m_device, fs_source, VK_SHADER_STAGE_FRAGMENT_BIT);

    static constexpr uint32_t locations[] = {VK_ATTACHMENT_UNUSED, 0};
    VkRenderingAttachmentLocationInfo locations_info = vku::InitStructHelper();
    locations_info.colorAttachmentCount = std::size(locations);
    locations_info.pColorAttachmentLocations = locations;

    static constexpr VkFormat color_formats[] = {VK_FORMAT_R8G8B8A8_SINT, VK_FORMAT_R8G8B8A8_UNORM};
    VkPipelineRenderingCreateInfo pipeline_rendering_info = vku::InitStructHelper(&locations_info);
    pipeline_rendering_info.colorAttachmentCount = std::size(color_formats);
    pipeline_rendering_info.pColorAttachmentFormats = color_formats;

    VkPipelineColorBlendAttachmentState color_blend_attachments[2] = {};
    VkPipelineColorBlendStateCreateInfo cbi = vku::InitStructHelper();
    cbi.attachmentCount = 2u;
    cbi.pAttachments = color_blend_attachments;

    CreatePipelineHelper pipe(*this, &pipeline_rendering_info);
    pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
    pipe.cb_attachments_.colorWriteMask = 0xf;  // all components
    pipe.gp_ci_.pColorBlendState = &cbi;
    pipe.CreateGraphicsPipeline();

    VkRenderingAttachmentInfo color_attachment[] = {vku::InitStructHelper(), vku::InitStructHelper()};
    color_attachment[0].imageView = GetDynamicRenderTarget(0);
    color_attachment[0].imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
    color_attachment[1].imageView = GetDynamicRenderTarget(1);
    color_attachment[1].imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

    VkRenderingInfo rendering_info = vku::InitStructHelper();
    rendering_info.colorAttachmentCount = std::size(color_attachment);
    rendering_info.pColorAttachments = color_attachment;
    rendering_info.layerCount = 1;
    rendering_info.renderArea = GetRenderTargetArea();

    m_command_buffer.Begin();
    m_command_buffer.BeginRendering(rendering_info);
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
    vk::CmdSetRenderingAttachmentLocationsKHR(m_command_buffer, &locations_info);
    m_errorMonitor->SetDesiredWarning("Undefined-Value-ShaderFragmentOutputMismatch-DynamicRendering");
    vk::CmdDraw(m_command_buffer, 3, 1, 0, 0);
    m_errorMonitor->VerifyFound();
    m_command_buffer.EndRendering();
    m_command_buffer.End();
}

TEST_F(NegativeShaderInterface, FragmentOutputDynamicRenderingUnusedAttachments) {
    SetTargetApiVersion(VK_API_VERSION_1_2);
    AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::dynamicRendering);
    AddRequiredFeature(vkt::Feature::dynamicRenderingUnusedAttachments);
    RETURN_IF_SKIP(Init());

    VkPipelineRenderingCreateInfo pipeline_rendering_info = vku::InitStructHelper();

    VkFormat color_formats[] = {VK_FORMAT_R8G8B8A8_UNORM};
    pipeline_rendering_info.colorAttachmentCount = 1;
    pipeline_rendering_info.pColorAttachmentFormats = color_formats;

    CreatePipelineHelper pipe(*this, &pipeline_rendering_info);
    pipe.CreateGraphicsPipeline();

    VkFormat ds_format = FindSupportedDepthStencilFormat(Gpu());

    vkt::Image color_image(*m_device, 32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
    vkt::ImageView color_image_view = color_image.CreateView();

    vkt::Image ds_image(*m_device, 32, 32, ds_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
    const vkt::ImageView depth_view(*m_device, ds_image.BasicViewCreatInfo(VK_IMAGE_ASPECT_DEPTH_BIT));

    VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper();
    color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
    color_attachment.imageView = VK_NULL_HANDLE;  // null and causes warning

    VkRenderingAttachmentInfo depth_stencil_attachment = vku::InitStructHelper();
    depth_stencil_attachment.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
    depth_stencil_attachment.imageView = depth_view;

    m_command_buffer.Begin();
    VkRenderingInfo begin_rendering_info = vku::InitStructHelper();
    begin_rendering_info.layerCount = 1;
    begin_rendering_info.colorAttachmentCount = 1;
    begin_rendering_info.pColorAttachments = &color_attachment;
    begin_rendering_info.pDepthAttachment = &depth_stencil_attachment;
    begin_rendering_info.renderArea = {{0, 0}, {1, 1}};
    m_command_buffer.BeginRendering(begin_rendering_info);
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
    m_errorMonitor->SetDesiredWarning("Undefined-Value-ShaderOutputNotConsumed-DynamicRendering");
    vk::CmdDraw(m_command_buffer, 3, 1, 0, 0);
    m_errorMonitor->VerifyFound();
    m_command_buffer.EndRendering();
    m_command_buffer.End();
}

TEST_F(NegativeShaderInterface, CreatePipelineFragmentOutputNotConsumed) {
    TEST_DESCRIPTION(
        "Test that a warning is produced for a fragment shader which provides a spurious output with no matching attachment");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* fsSource = R"glsl(
        #version 450
        layout(location=0) out vec4 x;
        layout(location=1) out vec4 y; /* no matching attachment for this */
        void main(){
           x = vec4(1);
           y = vec4(1);
        }
    )glsl";
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    CreatePipelineHelper pipe(*this);
    pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
    m_errorMonitor->SetDesiredWarning("Undefined-Value-ShaderOutputNotConsumed");
    pipe.CreateGraphicsPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeShaderInterface, FragmentOutputNotConsumedDynamicRendering) {
    AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::dynamicRendering);
    RETURN_IF_SKIP(Init());
    InitDynamicRenderTarget();

    const char* fs_source = R"glsl(
        #version 450
        layout(location=0) out vec4 x;
        layout(location=1) out vec4 y; /* no matching attachment for this */
        void main(){
           x = vec4(1);
           y = vec4(1);
        }
    )glsl";
    VkShaderObj fs(*m_device, fs_source, VK_SHADER_STAGE_FRAGMENT_BIT);

    VkFormat color_formats = VK_FORMAT_B8G8R8A8_UNORM;
    VkPipelineRenderingCreateInfo pipeline_rendering_info = vku::InitStructHelper();
    pipeline_rendering_info.colorAttachmentCount = 1;
    pipeline_rendering_info.pColorAttachmentFormats = &color_formats;

    CreatePipelineHelper pipe(*this, &pipeline_rendering_info);
    pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
    pipe.cb_attachments_.colorWriteMask = 0xf;  // all components
    pipe.CreateGraphicsPipeline();

    m_command_buffer.Begin();
    m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea());
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
    m_errorMonitor->SetDesiredWarning("Undefined-Value-ShaderOutputNotConsumed-DynamicRendering");
    vk::CmdDraw(m_command_buffer, 3, 1, 0, 0);
    m_errorMonitor->VerifyFound();
    m_command_buffer.EndRendering();
    m_command_buffer.End();
}

TEST_F(NegativeShaderInterface, InvalidStaticSpirv) {
    TEST_DESCRIPTION(
        "Test that a warning is produced for a fragment shader which provides a spurious output with no matching attachment");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* spv_source = R"(
               OpCapability Shader
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %main "main" %fragCoord %block_var
               OpExecutionMode %main OriginUpperLeft
               OpSource GLSL 450
               OpDecorate %fragCoord Location 0
               OpDecorate %block Block
               OpMemberDecorate %block 0 Location 1
       %void = OpTypeVoid
      %voidfn = OpTypeFunction %void
      %float = OpTypeFloat 32
    %v4float = OpTypeVector %float 4
%ptr_v4float = OpTypePointer Output %v4float
  %fragCoord = OpVariable %ptr_v4float Output
      %block = OpTypeStruct %v4float %v4float
  %block_ptr = OpTypePointer Output %block
  %block_var = OpVariable %block_ptr Output
       %main = OpFunction %void None %voidfn
       %label = OpLabel
               OpReturn
               OpFunctionEnd
        )";

    m_errorMonitor->SetDesiredError("VUID-StandaloneSpirv-Location-04919");
    auto fs = VkShaderObj::CreateFromASM(this, spv_source, VK_SHADER_STAGE_FRAGMENT_BIT);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeShaderInterface, InvalidStaticSpirvMaintenance5) {
    TEST_DESCRIPTION("Test SPIRV is still checked if using new pNext in VkPipelineShaderStageCreateInfo");
    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_KHR_MAINTENANCE_5_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::maintenance5);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* spv_source = R"(
               OpCapability Shader
               OpMemoryModel Logical GLSL450
               OpEntryPoint Vertex %main "main"
               OpSource GLSL 460
               OpMemberDecorate %gl_PerVertex 2 BuiltIn Position
               OpDecorate %gl_PerVertex Location 1
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
       %main = OpFunction %void None %3
          %5 = OpLabel
               OpReturn
               OpFunctionEnd
        )";
    std::vector<uint32_t> shader;
    ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, spv_source, shader);

    VkShaderModuleCreateInfo module_create_info = vku::InitStructHelper();
    module_create_info.pCode = shader.data();
    module_create_info.codeSize = shader.size() * sizeof(uint32_t);

    VkPipelineShaderStageCreateInfo stage_ci = vku::InitStructHelper(&module_create_info);
    stage_ci.stage = VK_SHADER_STAGE_VERTEX_BIT;
    stage_ci.module = VK_NULL_HANDLE;
    stage_ci.pName = "main";

    CreatePipelineHelper pipe(*this);
    pipe.gp_ci_.stageCount = 1;
    pipe.gp_ci_.pStages = &stage_ci;
    m_errorMonitor->SetDesiredError("VUID-VkShaderModuleCreateInfo-pCode-08737");
    pipe.CreateGraphicsPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeShaderInterface, InvalidStaticSpirvMaintenance5Compute) {
    TEST_DESCRIPTION("Test SPIRV is still checked if using new pNext in VkPipelineShaderStageCreateInfo");
    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_KHR_MAINTENANCE_5_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::maintenance5);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* spv_source = R"(
               OpCapability Shader
               OpMemoryModel Logical GLSL450
               OpEntryPoint GLCompute %main "main"
               OpSource GLSL 460
               OpMemberDecorate %gl_PerVertex 2 BuiltIn Position
               OpDecorate %gl_PerVertex Location 1
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
       %main = OpFunction %void None %3
          %5 = OpLabel
               OpReturn
               OpFunctionEnd
        )";
    std::vector<uint32_t> shader;
    ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, spv_source, shader);

    VkShaderModuleCreateInfo module_create_info = vku::InitStructHelper();
    module_create_info.pCode = shader.data();
    module_create_info.codeSize = shader.size() * sizeof(uint32_t);

    VkPipelineShaderStageCreateInfo stage_ci = vku::InitStructHelper(&module_create_info);
    stage_ci.stage = VK_SHADER_STAGE_COMPUTE_BIT;
    stage_ci.module = VK_NULL_HANDLE;
    stage_ci.pName = "main";

    vkt::PipelineLayout layout(*m_device, {});
    CreateComputePipelineHelper pipe(*this);
    pipe.cp_ci_.stage = stage_ci;
    pipe.cp_ci_.layout = layout;

    m_errorMonitor->SetDesiredError("VUID-VkShaderModuleCreateInfo-pCode-08737");
    pipe.CreateComputePipeline(false);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeShaderInterface, PhysicalStorageBuffer) {
    TEST_DESCRIPTION("Details found in https://gitlab.khronos.org/spirv/SPIR-V/-/issues/779");
    SetTargetApiVersion(VK_API_VERSION_1_2);
    AddRequiredExtensions(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* vs_source = R"(
               OpCapability Shader
               OpCapability PhysicalStorageBufferAddresses
               OpExtension "SPV_KHR_physical_storage_buffer"
               OpMemoryModel PhysicalStorageBuffer64 GLSL450
               OpEntryPoint Vertex %main "main" %outgoingPtr
               OpDecorate %dataBuffer Block
               OpMemberDecorate %dataBuffer 0 Offset 0
               OpMemberDecorate %dataBuffer 1 Offset 4
               OpDecorate %outgoingPtr Location 0
               OpDecorate %outgoingPtr AliasedPointer
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
               OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_dataBuffer PhysicalStorageBuffer
        %int = OpTypeInt 32 1
 %dataBuffer = OpTypeStruct %int %int
%_ptr_PhysicalStorageBuffer_dataBuffer = OpTypePointer PhysicalStorageBuffer %dataBuffer
%_ptr_Output__ptr_PhysicalStorageBuffer_dataBuffer = OpTypePointer Output %_ptr_PhysicalStorageBuffer_dataBuffer
%outgoingPtr = OpVariable %_ptr_Output__ptr_PhysicalStorageBuffer_dataBuffer Output
       %uint = OpTypeInt 32 0
     %v2uint = OpTypeVector %uint 2
     %uint_2 = OpConstant %uint 2
         %14 = OpConstantComposite %v2uint %uint_2 %uint_2
       %main = OpFunction %void None %3
          %5 = OpLabel
         %15 = OpBitcast %_ptr_PhysicalStorageBuffer_dataBuffer %14
               OpStore %outgoingPtr %15
               OpReturn
               OpFunctionEnd
    )";

    m_errorMonitor->SetDesiredWarning("VUID-StandaloneSpirv-Input-09557");
    VkShaderObj vs(*m_device, vs_source, VK_SHADER_STAGE_VERTEX_BIT, SPV_ENV_VULKAN_1_0, SPV_SOURCE_ASM);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeShaderInterface, MultipleFragmentAttachment) {
    TEST_DESCRIPTION("https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/7923");
    RETURN_IF_SKIP(Init());

    const char* fsSource = R"glsl(
        #version 450
        layout(location=0) out vec4 color0;
        layout(location=1) out vec4 color1;
        layout(location=2) out vec4 color2;
        void main() {
           color0 = vec4(1.0);
           color1 = vec4(1.0);
        }
    )glsl";
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    RenderPassSingleSubpass rp(*this);
    rp.AddAttachmentDescription(VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
                                VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
    rp.AddAttachmentDescription(VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
                                VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
    rp.AddAttachmentDescription(VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
                                VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
    rp.AddColorAttachment(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
    rp.AddColorAttachment(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
    rp.AddColorAttachment(2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
    rp.CreateRenderPass();

    VkPipelineColorBlendAttachmentState color_blends[3];
    color_blends[0] = DefaultColorBlendAttachmentState();
    color_blends[0].colorWriteMask = 0xf;
    color_blends[1] = DefaultColorBlendAttachmentState();
    color_blends[1].colorWriteMask = 0xf;
    color_blends[2] = DefaultColorBlendAttachmentState();
    color_blends[2].colorWriteMask = 0xf;

    CreatePipelineHelper pipe(*this);
    pipe.shader_stages_[1] = fs.GetStageCreateInfo();
    pipe.cb_ci_.attachmentCount = 3;
    pipe.cb_ci_.pAttachments = color_blends;
    pipe.gp_ci_.renderPass = rp;
    m_errorMonitor->SetDesiredWarning("Undefined-Value-OutputNotWritten");
    pipe.CreateGraphicsPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeShaderInterface, MultipleFragmentAttachmentDynamicRendering) {
    AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::dynamicRendering);
    RETURN_IF_SKIP(Init());
    InitDynamicRenderTarget();

    const char* fsSource = R"glsl(
        #version 450
        layout(location=0) out vec4 color0;
        layout(location=1) out vec4 color1;
        layout(location=2) out vec4 color2;
        void main() {
           color0 = vec4(1.0);
           color1 = vec4(1.0);
        }
    )glsl";
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    VkFormat color_formats[3] = {VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM};
    VkPipelineRenderingCreateInfo pipeline_rendering_info = vku::InitStructHelper();
    pipeline_rendering_info.colorAttachmentCount = 3;
    pipeline_rendering_info.pColorAttachmentFormats = color_formats;

    VkPipelineColorBlendAttachmentState color_blends[3];
    color_blends[0] = DefaultColorBlendAttachmentState();
    color_blends[0].colorWriteMask = 0xf;
    color_blends[1] = DefaultColorBlendAttachmentState();
    color_blends[1].colorWriteMask = 0xf;
    color_blends[2] = DefaultColorBlendAttachmentState();
    color_blends[2].colorWriteMask = 0xf;

    CreatePipelineHelper pipe(*this, &pipeline_rendering_info);
    pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
    pipe.cb_ci_.attachmentCount = 3;
    pipe.cb_ci_.pAttachments = color_blends;
    pipe.CreateGraphicsPipeline();

    VkRenderingAttachmentInfo color_attachments[3];
    color_attachments[0] = vku::InitStructHelper();
    color_attachments[0].imageView = GetDynamicRenderTarget();
    color_attachments[0].imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
    color_attachments[1] = color_attachments[0];
    color_attachments[2] = color_attachments[0];

    VkRenderingInfo rendering_info = vku::InitStructHelper();
    rendering_info.colorAttachmentCount = 3;
    rendering_info.pColorAttachments = color_attachments;
    rendering_info.layerCount = 1;
    rendering_info.renderArea = GetRenderTargetArea();

    m_command_buffer.Begin();
    m_command_buffer.BeginRendering(rendering_info);
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
    m_errorMonitor->SetDesiredWarning("Undefined-Value-OutputNotWritten-DynamicRendering");
    vk::CmdDraw(m_command_buffer, 3, 1, 0, 0);
    m_errorMonitor->VerifyFound();
    m_command_buffer.EndRendering();
    m_command_buffer.End();
}

TEST_F(NegativeShaderInterface, MissingInputAttachmentIndex) {
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    // layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput xs;
    // layout(location=0) out vec4 color;
    // void main() {
    //     color = subpassLoad(xs);
    // }
    //
    // missing OpDecorate %xs InputAttachmentIndex 0
    const char* fsSource = R"(
               OpCapability Shader
               OpCapability InputAttachment
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %main "main" %color
               OpExecutionMode %main OriginUpperLeft
               OpDecorate %color Location 0
               OpDecorate %xs DescriptorSet 0
               OpDecorate %xs Binding 0
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
      %float = OpTypeFloat 32
    %v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float
      %color = OpVariable %_ptr_Output_v4float Output
         %10 = OpTypeImage %float SubpassData 0 0 0 2 Unknown
%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
         %xs = OpVariable %_ptr_UniformConstant_10 UniformConstant
        %int = OpTypeInt 32 1
      %int_0 = OpConstant %int 0
      %v2int = OpTypeVector %int 2
         %17 = OpConstantComposite %v2int %int_0 %int_0
       %main = OpFunction %void None %3
          %5 = OpLabel
         %13 = OpLoad %10 %xs
         %18 = OpImageRead %v4float %13 %17
               OpStore %color %18
               OpReturn
               OpFunctionEnd
    )";
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, SPV_ENV_VULKAN_1_0, SPV_SOURCE_ASM);

    RenderPassSingleSubpass rp(*this);
    rp.AddAttachmentDescription(VK_FORMAT_R8G8B8A8_UNORM);
    rp.AddInputAttachment(0, VK_IMAGE_LAYOUT_GENERAL);
    rp.AddColorAttachment(0, VK_IMAGE_LAYOUT_GENERAL);
    rp.CreateRenderPass();

    CreatePipelineHelper pipe(*this);
    pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
    pipe.dsl_bindings_[0] = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
    pipe.gp_ci_.renderPass = rp;
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-None-09558");
    pipe.CreateGraphicsPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeShaderInterface, MissingInputAttachmentIndexArray) {
    SetTargetApiVersion(VK_API_VERSION_1_2);
    AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_LOCAL_READ_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::dynamicRendering);
    AddRequiredFeature(vkt::Feature::dynamicRenderingLocalRead);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    // layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput xs[1];
    // layout(location=0) out vec4 color;
    // void main() {
    //     color = subpassLoad(xs[0]);
    // }
    //
    // missing OpDecorate %xs InputAttachmentIndex 0
    const char* fsSource = R"(
               OpCapability Shader
               OpCapability InputAttachment
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %main "main" %color
               OpExecutionMode %main OriginUpperLeft
               OpDecorate %color Location 0
               OpDecorate %xs DescriptorSet 0
               OpDecorate %xs Binding 0
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
      %float = OpTypeFloat 32
    %v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float
      %color = OpVariable %_ptr_Output_v4float Output
         %10 = OpTypeImage %float SubpassData 0 0 0 2 Unknown
       %uint = OpTypeInt 32 0
     %uint_1 = OpConstant %uint 1
%_arr_10_uint_1 = OpTypeArray %10 %uint_1
%_ptr_UniformConstant__arr_10_uint_1 = OpTypePointer UniformConstant %_arr_10_uint_1
         %xs = OpVariable %_ptr_UniformConstant__arr_10_uint_1 UniformConstant
        %int = OpTypeInt 32 1
      %int_0 = OpConstant %int 0
%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
      %v2int = OpTypeVector %int 2
         %22 = OpConstantComposite %v2int %int_0 %int_0
       %main = OpFunction %void None %3
          %5 = OpLabel
         %19 = OpAccessChain %_ptr_UniformConstant_10 %xs %int_0
         %20 = OpLoad %10 %19
         %23 = OpImageRead %v4float %20 %22
               OpStore %color %23
               OpReturn
               OpFunctionEnd
    )";

    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, SPV_ENV_VULKAN_1_0, SPV_SOURCE_ASM);

    CreatePipelineHelper pipe(*this);
    pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
    pipe.dsl_bindings_[0] = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-OpTypeImage-09644");
    pipe.CreateGraphicsPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeShaderInterface, MissingInputAttachmentIndexShaderObject) {
    AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::shaderObject);
    RETURN_IF_SKIP(Init());

    // layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput xs;
    // layout(location=0) out vec4 color;
    // void main() {
    //     color = subpassLoad(xs);
    // }
    //
    // missing OpDecorate %xs InputAttachmentIndex 0
    const char* fsSource = R"(
               OpCapability Shader
               OpCapability InputAttachment
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %main "main" %color
               OpExecutionMode %main OriginUpperLeft
               OpDecorate %color Location 0
               OpDecorate %xs DescriptorSet 0
               OpDecorate %xs Binding 0
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
      %float = OpTypeFloat 32
    %v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float
      %color = OpVariable %_ptr_Output_v4float Output
         %10 = OpTypeImage %float SubpassData 0 0 0 2 Unknown
%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
         %xs = OpVariable %_ptr_UniformConstant_10 UniformConstant
        %int = OpTypeInt 32 1
      %int_0 = OpConstant %int 0
      %v2int = OpTypeVector %int 2
         %17 = OpConstantComposite %v2int %int_0 %int_0
       %main = OpFunction %void None %3
          %5 = OpLabel
         %13 = OpLoad %10 %xs
         %18 = OpImageRead %v4float %13 %17
               OpStore %color %18
               OpReturn
               OpFunctionEnd
    )";
    std::vector<uint32_t> spv;
    ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, fsSource, spv);

    OneOffDescriptorSet descriptor_set(m_device,
                                       {
                                           {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
                                       });

    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-None-09558");
    const vkt::Shader frag_shader(*m_device,
                                  ShaderCreateInfo(spv, VK_SHADER_STAGE_FRAGMENT_BIT, 1, &descriptor_set.layout_.handle()));
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeShaderInterface, PhysicalStorageBufferArray) {
    TEST_DESCRIPTION("Details found in https://gitlab.khronos.org/spirv/SPIR-V/-/issues/779");
    SetTargetApiVersion(VK_API_VERSION_1_2);
    AddRequiredExtensions(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init())
    InitRenderTarget();

    const char* vs_source = R"(
               OpCapability Shader
               OpCapability PhysicalStorageBufferAddresses
               OpExtension "SPV_KHR_physical_storage_buffer"
               OpMemoryModel PhysicalStorageBuffer64 GLSL450
               OpEntryPoint Vertex %main "main" %outgoingPtr
               OpDecorate %dataBuffer Block
               OpMemberDecorate %dataBuffer 0 Offset 0
               OpMemberDecorate %dataBuffer 1 Offset 4
               OpDecorate %outgoingPtr Location 0
               OpDecorate %outgoingPtr AliasedPointer
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
               OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_dataBuffer PhysicalStorageBuffer
        %int = OpTypeInt 32 1
 %dataBuffer = OpTypeStruct %int %int
%_ptr_PhysicalStorageBuffer_dataBuffer = OpTypePointer PhysicalStorageBuffer %dataBuffer
       %uint = OpTypeInt 32 0
     %uint_3 = OpConstant %uint 3
%_arr__ptr_PhysicalStorageBuffer_dataBuffer_uint_3 = OpTypeArray %_ptr_PhysicalStorageBuffer_dataBuffer %uint_3
%_ptr_Output__arr__ptr_PhysicalStorageBuffer_dataBuffer_uint_3 = OpTypePointer Output %_arr__ptr_PhysicalStorageBuffer_dataBuffer_uint_3
%outgoingPtr = OpVariable %_ptr_Output__arr__ptr_PhysicalStorageBuffer_dataBuffer_uint_3 Output
      %int_2 = OpConstant %int 2
     %v2uint = OpTypeVector %uint 2
     %uint_2 = OpConstant %uint 2
         %17 = OpConstantComposite %v2uint %uint_2 %uint_2
%_ptr_Output__ptr_PhysicalStorageBuffer_dataBuffer = OpTypePointer Output %_ptr_PhysicalStorageBuffer_dataBuffer
       %main = OpFunction %void None %3
          %5 = OpLabel
         %18 = OpBitcast %_ptr_PhysicalStorageBuffer_dataBuffer %17
         %20 = OpAccessChain %_ptr_Output__ptr_PhysicalStorageBuffer_dataBuffer %outgoingPtr %int_2
               OpStore %20 %18
               OpReturn
               OpFunctionEnd
    )";

    m_errorMonitor->SetDesiredWarning("VUID-StandaloneSpirv-Input-09557");
    VkShaderObj vs(*m_device, vs_source, VK_SHADER_STAGE_VERTEX_BIT, SPV_ENV_VULKAN_1_0, SPV_SOURCE_ASM);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeShaderInterface, PhysicalStorageBufferLinkedList) {
    TEST_DESCRIPTION("Details found in https://gitlab.khronos.org/spirv/SPIR-V/-/issues/779");
    SetTargetApiVersion(VK_API_VERSION_1_2);
    AddRequiredExtensions(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init())
    InitRenderTarget();

    const char* fs_source = R"(
               OpCapability Shader
               OpCapability PhysicalStorageBufferAddresses
               OpExtension "SPV_KHR_physical_storage_buffer"
               OpMemoryModel PhysicalStorageBuffer64 GLSL450
               OpEntryPoint Fragment %main "main" %fragColor %incomingPtr
               OpExecutionMode %main OriginUpperLeft
               OpDecorate %fragColor Location 0
               OpDecorate %dataBuffer Block
               OpMemberDecorate %dataBuffer 0 Offset 0
               OpMemberDecorate %dataBuffer 1 Offset 16
               OpDecorate %incomingPtr Location 0
               OpDecorate %incomingPtr AliasedPointer
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
      %float = OpTypeFloat 32
    %v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float
  %fragColor = OpVariable %_ptr_Output_v4float Output
               OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_dataBuffer PhysicalStorageBuffer
 %dataBuffer = OpTypeStruct %v4float %_ptr_PhysicalStorageBuffer_dataBuffer
%_ptr_PhysicalStorageBuffer_dataBuffer = OpTypePointer PhysicalStorageBuffer %dataBuffer
%_ptr_Input__ptr_PhysicalStorageBuffer_dataBuffer = OpTypePointer Input %_ptr_PhysicalStorageBuffer_dataBuffer
%incomingPtr = OpVariable %_ptr_Input__ptr_PhysicalStorageBuffer_dataBuffer Input
        %int = OpTypeInt 32 1
      %int_0 = OpConstant %int 0
%_ptr_PhysicalStorageBuffer_v4float = OpTypePointer PhysicalStorageBuffer %v4float
       %main = OpFunction %void None %3
          %5 = OpLabel
         %14 = OpLoad %_ptr_PhysicalStorageBuffer_dataBuffer %incomingPtr
         %18 = OpAccessChain %_ptr_PhysicalStorageBuffer_v4float %14 %int_0
         %19 = OpLoad %v4float %18 Aligned 16
               OpStore %fragColor %19
               OpReturn
               OpFunctionEnd
    )";

    m_errorMonitor->SetDesiredWarning("VUID-StandaloneSpirv-Input-09557");
    VkShaderObj fs(*m_device, fs_source, VK_SHADER_STAGE_FRAGMENT_BIT, SPV_ENV_VULKAN_1_0, SPV_SOURCE_ASM);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeShaderInterface, PhysicalStorageBufferNested) {
    TEST_DESCRIPTION("Details found in https://gitlab.khronos.org/spirv/SPIR-V/-/issues/779");
    SetTargetApiVersion(VK_API_VERSION_1_2);
    AddRequiredExtensions(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init())
    InitRenderTarget();

    const char* fs_source = R"(
               OpCapability Shader
               OpCapability PhysicalStorageBufferAddresses
               OpExtension "SPV_KHR_physical_storage_buffer"
               OpMemoryModel PhysicalStorageBuffer64 GLSL450
               OpEntryPoint Fragment %main "main" %fragColor %incomingPtr
               OpExecutionMode %main OriginUpperLeft
               OpDecorate %fragColor Location 0
               OpDecorate %dataBuffer Block
               OpMemberDecorate %dataBuffer 0 Offset 0
               OpDecorate %t1 Block
               OpMemberDecorate %t1 0 NonWritable
               OpMemberDecorate %t1 0 Offset 0
               OpDecorate %_runtimearr_v4float ArrayStride 16
               OpDecorate %t2 Block
               OpMemberDecorate %t2 0 NonWritable
               OpMemberDecorate %t2 0 Offset 0
               OpDecorate %incomingPtr Location 0
               OpDecorate %incomingPtr AliasedPointer
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
      %float = OpTypeFloat 32
    %v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float
  %fragColor = OpVariable %_ptr_Output_v4float Output
               OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_dataBuffer PhysicalStorageBuffer
               OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_t1 PhysicalStorageBuffer
 %dataBuffer = OpTypeStruct %_ptr_PhysicalStorageBuffer_t1
               OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_t2 PhysicalStorageBuffer
         %t1 = OpTypeStruct %_ptr_PhysicalStorageBuffer_t2
%_runtimearr_v4float = OpTypeRuntimeArray %v4float
         %t2 = OpTypeStruct %_runtimearr_v4float
%_ptr_PhysicalStorageBuffer_t2 = OpTypePointer PhysicalStorageBuffer %t2
%_ptr_PhysicalStorageBuffer_t1 = OpTypePointer PhysicalStorageBuffer %t1
%_ptr_PhysicalStorageBuffer_dataBuffer = OpTypePointer PhysicalStorageBuffer %dataBuffer
%_ptr_Input__ptr_PhysicalStorageBuffer_dataBuffer = OpTypePointer Input %_ptr_PhysicalStorageBuffer_dataBuffer
%incomingPtr = OpVariable %_ptr_Input__ptr_PhysicalStorageBuffer_dataBuffer Input
        %int = OpTypeInt 32 1
      %int_0 = OpConstant %int 0
%_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_t1 = OpTypePointer PhysicalStorageBuffer %_ptr_PhysicalStorageBuffer_t1
%_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_t2 = OpTypePointer PhysicalStorageBuffer %_ptr_PhysicalStorageBuffer_t2
      %int_2 = OpConstant %int 2
%_ptr_PhysicalStorageBuffer_v4float = OpTypePointer PhysicalStorageBuffer %v4float
       %main = OpFunction %void None %3
          %5 = OpLabel
         %19 = OpLoad %_ptr_PhysicalStorageBuffer_dataBuffer %incomingPtr
         %23 = OpAccessChain %_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_t1 %19 %int_0
         %24 = OpLoad %_ptr_PhysicalStorageBuffer_t1 %23 Aligned 4
         %26 = OpAccessChain %_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_t2 %24 %int_0
         %27 = OpLoad %_ptr_PhysicalStorageBuffer_t2 %26 Aligned 4
         %30 = OpAccessChain %_ptr_PhysicalStorageBuffer_v4float %27 %int_0 %int_2
         %31 = OpLoad %v4float %30 Aligned 4
               OpStore %fragColor %31
               OpReturn
               OpFunctionEnd
    )";

    m_errorMonitor->SetDesiredWarning("VUID-StandaloneSpirv-PhysicalStorageBuffer64-06314");
    VkShaderObj fs(*m_device, fs_source, VK_SHADER_STAGE_FRAGMENT_BIT, SPV_ENV_VULKAN_1_0, SPV_SOURCE_ASM);
    m_errorMonitor->VerifyFound();
}

// More interface checks that require deeping spirv matching
// https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/11267
TEST_F(NegativeShaderInterface, DISABLED_NestedStructInBlock) {
    ASSERT_NO_FATAL_FAILURE(Init());
    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());

    const char vsSource[] = R"glsl(
        #version 450
        struct Foo {
            vec2 a;
        };
        layout(location = 0) out block {
            Foo foo;
        } testBlock;
        void main(void) {
            testBlock.foo.a = vec2(0);
        }
    )glsl";

    const char fsSource[] = R"glsl(
        #version 450
        layout(location = 0) out vec4 color;
        struct Foo {
            int a[8];
            vec4 b;
        };
        layout(location = 0) in block {
            Foo foo;
        } testBlock;
        void main(void) {
            color = testBlock.foo.b;
        }
    )glsl";
    VkShaderObj vs(*m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
    VkShaderObj fs(*m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);

    auto set_info = [&](CreatePipelineHelper& info) { info.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()}; };
    CreatePipelineHelper::OneshotTest(*this, set_info, kErrorBit, "VUID-RuntimeSpirv-OpEntryPoint-07754");
}

TEST_F(NegativeShaderInterface, MeshFragmentPerPrimitive) {
    SetTargetApiVersion(VK_API_VERSION_1_2);
    AddRequiredExtensions(VK_EXT_MESH_SHADER_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::meshShader);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* ms_source = R"glsl(
        #version 460
        #extension GL_EXT_mesh_shader : require
        layout(max_vertices = 12) out;
        layout(max_primitives = 4) out;
        layout(triangles) out;

        layout(location = 0) out uint out_0[12];
        layout(location = 1) perprimitiveEXT out uint out_1[4];
        layout(location = 2) out float out_2[12];
        layout(location = 3) perprimitiveEXT out float out_3[4];

        void main() {
            SetMeshOutputsEXT(12,4);
            out_0[0] = 0;
            out_1[0] = 0;
            out_2[0] = 0.0;
            out_3[0] = 0.0;
            gl_PrimitiveTriangleIndicesEXT[1] = uvec3(0,1,2);
        }
    )glsl";

    const char* fs_source = R"glsl(
        #version 460
        #extension GL_EXT_mesh_shader : require

        layout(location = 0) in flat uint in_0;
        layout(location = 1) flat in uint in_1; // missing perprimitiveEXT
        layout(location = 2) in float in_2;
        layout(location = 3) perprimitiveEXT in float in_3;
        layout(location = 0) out vec4 c;
        void main(){
            c = vec4(1);
            if (in_0 == 0 && in_1 == 0 && in_2 == 1.0 && in_3 == 1.0) {
                c = vec4(0);
            }
        }
    )glsl";

    VkShaderObj ms(*m_device, ms_source, VK_SHADER_STAGE_MESH_BIT_EXT, SPV_ENV_VULKAN_1_2);
    VkShaderObj fs(*m_device, fs_source, VK_SHADER_STAGE_FRAGMENT_BIT, SPV_ENV_VULKAN_1_2);

    CreatePipelineHelper pipe(*this);
    pipe.shader_stages_ = {ms.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    m_errorMonitor->SetDesiredWarning("VUID-RuntimeSpirv-OpVariable-08746");
    pipe.CreateGraphicsPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeShaderInterface, MeshFragmentPerPrimitive2) {
    SetTargetApiVersion(VK_API_VERSION_1_2);
    AddRequiredExtensions(VK_EXT_MESH_SHADER_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::meshShader);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    const char* ms_source = R"glsl(
        #version 460
        #extension GL_EXT_mesh_shader : require
        layout(max_vertices = 12) out;
        layout(max_primitives = 4) out;
        layout(triangles) out;

        layout(location = 0) out float out_0[12];
        layout(location = 1) out float out_1[12]; // missing perprimitiveEXT

        void main() {
            SetMeshOutputsEXT(12,4);
            out_0[0] = 0.0;
            out_1[0] = 0.0;
            gl_PrimitiveTriangleIndicesEXT[1] = uvec3(0,1,2);
        }
    )glsl";

    const char* fs_source = R"glsl(
        #version 460
        #extension GL_EXT_mesh_shader : require

        layout(location = 0) in float in_0;
        layout(location = 1) in perprimitiveEXT float in_1;
        layout(location = 0) out vec4 c;
        void main(){
            c = vec4(1);
            if (in_0 == 1.0 && in_1 == 1.0) {
                c = vec4(0);
            }
        }
    )glsl";

    VkShaderObj ms(*m_device, ms_source, VK_SHADER_STAGE_MESH_BIT_EXT, SPV_ENV_VULKAN_1_2);
    VkShaderObj fs(*m_device, fs_source, VK_SHADER_STAGE_FRAGMENT_BIT, SPV_ENV_VULKAN_1_2);

    CreatePipelineHelper pipe(*this);
    pipe.shader_stages_ = {ms.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    m_errorMonitor->SetDesiredWarning("VUID-RuntimeSpirv-OpVariable-08746");
    pipe.CreateGraphicsPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeShaderInterface, MeshFragmentPerPrimitiveSlang) {
    SetTargetApiVersion(VK_API_VERSION_1_2);
    AddRequiredExtensions(VK_EXT_MESH_SHADER_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::meshShader);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    // https://godbolt.org/z/ov4G4K19a
    // Known issue in slang https://github.com/shader-slang/slang/issues/7019
    const char* spirv_source = R"(
               OpCapability MeshShadingEXT
               OpCapability Shader
               OpExtension "SPV_KHR_non_semantic_info"
               OpExtension "SPV_EXT_mesh_shader"
          %2 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
               OpMemoryModel Logical GLSL450
               OpEntryPoint MeshEXT %main "main" %38 %gl_Position %verts_normal %prims_color %75
               OpEntryPoint Fragment %main_0 "main" %entryPointParam_main %gl_FragCoord %input_normal %prim_color
               OpExecutionMode %main OutputPrimitivesEXT 3
               OpExecutionMode %main OutputVertices 9
               OpExecutionMode %main LocalSize 1 1 1
               OpExecutionMode %main OutputTrianglesEXT
               OpExecutionMode %main_0 OriginUpperLeft
               OpSource Slang 1
               OpDecorate %38 BuiltIn PrimitiveTriangleIndicesEXT
               OpDecorate %gl_Position BuiltIn Position
               OpDecorate %verts_normal Location 0
               OpDecorate %prims_color Location 1
               OpDecorate %prims_color PerPrimitiveEXT
               OpDecorate %75 BuiltIn CullPrimitiveEXT
               OpDecorate %75 PerPrimitiveEXT
               OpDecorate %gl_FragCoord BuiltIn FragCoord
               OpDecorate %input_normal Location 0
               OpDecorate %prim_color Location 1
               OpDecorate %prim_color Flat
               OpDecorate %entryPointParam_main Location 0
       %void = OpTypeVoid
       %uint = OpTypeInt 32 0
     %uint_5 = OpConstant %uint 5
         %12 = OpTypeFunction %void
     %uint_0 = OpConstant %uint 0
     %uint_6 = OpConstant %uint 6
     %uint_2 = OpConstant %uint 2
     %v3uint = OpTypeVector %uint 3
        %int = OpTypeInt 32 1
      %int_3 = OpConstant %int 3
%_arr_v3uint_int_3 = OpTypeArray %v3uint %int_3
%_ptr_Output__arr_v3uint_int_3 = OpTypePointer Output %_arr_v3uint_int_3
%_ptr_Output_v3uint = OpTypePointer Output %v3uint
         %41 = OpConstantComposite %v3uint %uint_0 %uint_0 %uint_0
    %uint_18 = OpConstant %uint 18
      %float = OpTypeFloat 32
    %v4float = OpTypeVector %float 4
      %int_9 = OpConstant %int 9
%_arr_v4float_int_9 = OpTypeArray %v4float %int_9
%_ptr_Output__arr_v4float_int_9 = OpTypePointer Output %_arr_v4float_int_9
%_ptr_Output_v4float = OpTypePointer Output %v4float
    %uint_19 = OpConstant %uint 19
    %uint_20 = OpConstant %uint 20
%_arr_v4float_int_3 = OpTypeArray %v4float %int_3
%_ptr_Output__arr_v4float_int_3 = OpTypePointer Output %_arr_v4float_int_3
    %uint_21 = OpConstant %uint 21
       %bool = OpTypeBool
%_arr_bool_int_3 = OpTypeArray %bool %int_3
%_ptr_Output__arr_bool_int_3 = OpTypePointer Output %_arr_bool_int_3
%_ptr_Output_bool = OpTypePointer Output %bool
       %true = OpConstantTrue %bool
    %uint_25 = OpConstant %uint 25
     %uint_8 = OpConstant %uint 8
%_ptr_Input_v4float = OpTypePointer Input %v4float
    %uint_27 = OpConstant %uint 27
         %38 = OpVariable %_ptr_Output__arr_v3uint_int_3 Output
%gl_Position = OpVariable %_ptr_Output__arr_v4float_int_9 Output
%verts_normal = OpVariable %_ptr_Output__arr_v4float_int_9 Output
%prims_color = OpVariable %_ptr_Output__arr_v4float_int_3 Output
         %75 = OpVariable %_ptr_Output__arr_bool_int_3 Output
%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
%input_normal = OpVariable %_ptr_Input_v4float Input
 %prim_color = OpVariable %_ptr_Input_v4float Input
%entryPointParam_main = OpVariable %_ptr_Output_v4float Output
    %float_0 = OpConstant %float 0
        %123 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
       %main = OpFunction %void None %12
         %13 = OpLabel
               OpSetMeshOutputsEXT %uint_6 %uint_2
         %40 = OpAccessChain %_ptr_Output_v3uint %38 %uint_0
               OpStore %40 %41
         %52 = OpAccessChain %_ptr_Output_v4float %gl_Position %uint_0
               OpStore %52 %123
         %61 = OpAccessChain %_ptr_Output_v4float %verts_normal %uint_0
               OpStore %61 %123
         %68 = OpAccessChain %_ptr_Output_v4float %prims_color %uint_0
               OpStore %68 %123
         %77 = OpAccessChain %_ptr_Output_bool %75 %uint_0
               OpStore %77 %true
               OpReturn
               OpFunctionEnd
     %main_0 = OpFunction %void None %12
         %82 = OpLabel
         %90 = OpLoad %v4float %gl_FragCoord
         %93 = OpLoad %v4float %input_normal
         %95 = OpLoad %v4float %prim_color
        %100 = OpFAdd %v4float %95 %90
        %101 = OpFAdd %v4float %100 %93
               OpStore %entryPointParam_main %101
               OpReturn
               OpFunctionEnd
    )";

    VkShaderObj ms(*m_device, spirv_source, VK_SHADER_STAGE_MESH_BIT_EXT, SPV_ENV_VULKAN_1_2, SPV_SOURCE_ASM);
    VkShaderObj fs(*m_device, spirv_source, VK_SHADER_STAGE_FRAGMENT_BIT, SPV_ENV_VULKAN_1_2, SPV_SOURCE_ASM);

    CreatePipelineHelper pipe(*this);
    pipe.shader_stages_ = {ms.GetStageCreateInfo(), fs.GetStageCreateInfo()};
    m_errorMonitor->SetDesiredWarning("VUID-RuntimeSpirv-OpVariable-08746");
    pipe.CreateGraphicsPipeline();
    m_errorMonitor->VerifyFound();
}
