Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (c) 2015-2017 The Khronos Group Inc.
      3  * Copyright (c) 2015-2017 Valve Corporation
      4  * Copyright (c) 2015-2017 LunarG, Inc.
      5  * Copyright (c) 2015-2017 Google, Inc.
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *     http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Author: Chia-I Wu <olvaffe (at) gmail.com>
     14  * Author: Chris Forbes <chrisf (at) ijw.co.nz>
     15  * Author: Courtney Goeltzenleuchter <courtney (at) LunarG.com>
     16  * Author: Mark Lobodzinski <mark (at) lunarg.com>
     17  * Author: Mike Stroyan <mike (at) LunarG.com>
     18  * Author: Tobin Ehlis <tobine (at) google.com>
     19  * Author: Tony Barbour <tony (at) LunarG.com>
     20  * Author: Cody Northrop <cnorthrop (at) google.com>
     21  * Author: Dave Houlton <daveh (at) lunarg.com>
     22  * Author: Jeremy Kniager <jeremyk (at) lunarg.com>
     23  */
     24 
     25 #ifdef ANDROID
     26 #include "vulkan_wrapper.h"
     27 #else
     28 #define NOMINMAX
     29 #include <vulkan/vulkan.h>
     30 #endif
     31 
     32 #include "layers/vk_device_profile_api_layer.h"
     33 
     34 #if defined(ANDROID) && defined(VALIDATION_APK)
     35 #include <android/log.h>
     36 #include <android_native_app_glue.h>
     37 #endif
     38 
     39 #include "icd-spv.h"
     40 #include "test_common.h"
     41 #include "vk_layer_config.h"
     42 #include "vk_format_utils.h"
     43 #include "vk_validation_error_messages.h"
     44 #include "vkrenderframework.h"
     45 #include "vk_typemap_helper.h"
     46 
     47 #include <limits.h>
     48 
     49 #include <algorithm>
     50 #include <functional>
     51 #include <memory>
     52 #include <unordered_set>
     53 
     54 //--------------------------------------------------------------------------------------
     55 // Mesh and VertexFormat Data
     56 //--------------------------------------------------------------------------------------
     57 
     58 enum BsoFailSelect {
     59     BsoFailNone,
     60     BsoFailLineWidth,
     61     BsoFailDepthBias,
     62     BsoFailViewport,
     63     BsoFailScissor,
     64     BsoFailBlend,
     65     BsoFailDepthBounds,
     66     BsoFailStencilReadMask,
     67     BsoFailStencilWriteMask,
     68     BsoFailStencilReference,
     69     BsoFailCmdClearAttachments,
     70     BsoFailIndexBuffer
     71 };
     72 
     73 static const char bindStateVertShaderText[] =
     74     "#version 450\n"
     75     "vec2 vertices[3];\n"
     76     "void main() {\n"
     77     "      vertices[0] = vec2(-1.0, -1.0);\n"
     78     "      vertices[1] = vec2( 1.0, -1.0);\n"
     79     "      vertices[2] = vec2( 0.0,  1.0);\n"
     80     "   gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0);\n"
     81     "}\n";
     82 
     83 static const char bindStateFragShaderText[] =
     84     "#version 450\n"
     85     "\n"
     86     "layout(location = 0) out vec4 uFragColor;\n"
     87     "void main(){\n"
     88     "   uFragColor = vec4(0,1,0,1);\n"
     89     "}\n";
     90 
     91 // Static arrays helper
     92 template <class ElementT, size_t array_size>
     93 size_t size(ElementT (&)[array_size]) {
     94     return array_size;
     95 }
     96 
     97 // Format search helper
     98 VkFormat FindSupportedDepthStencilFormat(VkPhysicalDevice phy) {
     99     VkFormat ds_formats[] = {VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT};
    100     for (uint32_t i = 0; i < sizeof(ds_formats); i++) {
    101         VkFormatProperties format_props;
    102         vkGetPhysicalDeviceFormatProperties(phy, ds_formats[i], &format_props);
    103 
    104         if (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
    105             return ds_formats[i];
    106         }
    107     }
    108     return VK_FORMAT_UNDEFINED;
    109 }
    110 
    111 // Returns true if *any* requested features are available.
    112 // Assumption is that the framework can successfully create an image as
    113 // long as at least one of the feature bits is present (excepting VTX_BUF).
    114 bool ImageFormatIsSupported(VkPhysicalDevice phy, VkFormat format, VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL,
    115                             VkFormatFeatureFlags features = ~VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) {
    116     VkFormatProperties format_props;
    117     vkGetPhysicalDeviceFormatProperties(phy, format, &format_props);
    118     VkFormatFeatureFlags phy_features =
    119         (VK_IMAGE_TILING_OPTIMAL == tiling ? format_props.optimalTilingFeatures : format_props.linearTilingFeatures);
    120     return (0 != (phy_features & features));
    121 }
    122 
    123 // Returns true if format and *all* requested features are available.
    124 bool ImageFormatAndFeaturesSupported(VkPhysicalDevice phy, VkFormat format, VkImageTiling tiling, VkFormatFeatureFlags features) {
    125     VkFormatProperties format_props;
    126     vkGetPhysicalDeviceFormatProperties(phy, format, &format_props);
    127     VkFormatFeatureFlags phy_features =
    128         (VK_IMAGE_TILING_OPTIMAL == tiling ? format_props.optimalTilingFeatures : format_props.linearTilingFeatures);
    129     return (features == (phy_features & features));
    130 }
    131 
    132 // Validation report callback prototype
    133 static VKAPI_ATTR VkBool32 VKAPI_CALL myDbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject,
    134                                                 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg,
    135                                                 void *pUserData);
    136 
    137 // Simple sane SamplerCreateInfo boilerplate
    138 static VkSamplerCreateInfo SafeSaneSamplerCreateInfo() {
    139     VkSamplerCreateInfo sampler_create_info = {};
    140     sampler_create_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
    141     sampler_create_info.pNext = nullptr;
    142     sampler_create_info.magFilter = VK_FILTER_NEAREST;
    143     sampler_create_info.minFilter = VK_FILTER_NEAREST;
    144     sampler_create_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
    145     sampler_create_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
    146     sampler_create_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
    147     sampler_create_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
    148     sampler_create_info.mipLodBias = 1.0;
    149     sampler_create_info.anisotropyEnable = VK_FALSE;
    150     sampler_create_info.maxAnisotropy = 1.0;
    151     sampler_create_info.compareEnable = VK_FALSE;
    152     sampler_create_info.compareOp = VK_COMPARE_OP_NEVER;
    153     sampler_create_info.minLod = 1.0;
    154     sampler_create_info.maxLod = 1.0;
    155     sampler_create_info.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
    156     sampler_create_info.unnormalizedCoordinates = VK_FALSE;
    157 
    158     return sampler_create_info;
    159 }
    160 
    161 // Dependent "false" type for the static assert, as GCC will evaluate
    162 // non-dependent static_asserts even for non-instantiated templates
    163 template <typename T>
    164 struct AlwaysFalse : std::false_type {};
    165 
    166 // Template wrapper of cmath.h versions to avoid portability issues with std::nextafter
    167 template <typename T>
    168 T NextAfter(T from, T to) {
    169     static_assert(AlwaysFalse<T>::value, "must specialize for each supported type");
    170 }
    171 template <>
    172 float NextAfter(float from, float to) {
    173     return nextafterf(from, to);
    174 }
    175 // lowest <= value <= max non intuitive, thus the named wrapper
    176 template <typename T>
    177 T NextAfterGreater(const T from) {
    178     return NextAfter<T>(from, std::numeric_limits<T>::max());
    179 }
    180 template <typename T>
    181 T NextAfterLess(const T from) {
    182     return NextAfter<T>(from, std::numeric_limits<T>::lowest());
    183 }
    184 
    185 // ErrorMonitor Usage:
    186 //
    187 // Call SetDesiredFailureMsg with a string to be compared against all
    188 // encountered log messages, or a validation error enum identifying
    189 // desired error message. Passing NULL or VALIDATION_ERROR_MAX_ENUM
    190 // will match all log messages. logMsg will return true for skipCall
    191 // only if msg is matched or NULL.
    192 //
    193 // Call VerifyFound to determine if all desired failure messages
    194 // were encountered. Call VerifyNotFound to determine if any unexpected
    195 // failure was encountered.
    196 class ErrorMonitor {
    197    public:
    198     ErrorMonitor() {
    199         test_platform_thread_create_mutex(&mutex_);
    200         test_platform_thread_lock_mutex(&mutex_);
    201         Reset();
    202         test_platform_thread_unlock_mutex(&mutex_);
    203     }
    204 
    205     ~ErrorMonitor() { test_platform_thread_delete_mutex(&mutex_); }
    206 
    207     // Set monitor to pristine state
    208     void Reset() {
    209         message_flags_ = VK_DEBUG_REPORT_ERROR_BIT_EXT;
    210         bailout_ = NULL;
    211         message_found_ = VK_FALSE;
    212         failure_message_strings_.clear();
    213         desired_message_strings_.clear();
    214         desired_message_ids_.clear();
    215         ignore_message_strings_.clear();
    216         other_messages_.clear();
    217         message_outstanding_count_ = 0;
    218     }
    219 
    220     // ErrorMonitor will look for an error message containing the specified string(s)
    221     void SetDesiredFailureMsg(const VkFlags msgFlags, const char *const msgString) {
    222         test_platform_thread_lock_mutex(&mutex_);
    223         desired_message_strings_.insert(msgString);
    224         message_flags_ |= msgFlags;
    225         message_outstanding_count_++;
    226         test_platform_thread_unlock_mutex(&mutex_);
    227     }
    228 
    229     // ErrorMonitor will look for an error message containing the specified string(s)
    230     template <typename Iter>
    231     void SetDesiredFailureMsg(const VkFlags msgFlags, Iter iter, const Iter end) {
    232         for (; iter != end; ++iter) {
    233             SetDesiredFailureMsg(msgFlags, *iter);
    234         }
    235     }
    236 
    237     // ErrorMonitor will look for a message ID matching the specified one(s)
    238     void SetDesiredFailureMsg(const VkFlags msgFlags, const UNIQUE_VALIDATION_ERROR_CODE msg_id) {
    239         test_platform_thread_lock_mutex(&mutex_);
    240         desired_message_ids_.insert(msg_id);
    241         message_flags_ |= msgFlags;
    242         message_outstanding_count_++;
    243         test_platform_thread_unlock_mutex(&mutex_);
    244     }
    245 
    246     // Set an error that the error monitor will ignore. Do not use this function if you are creating a new test.
    247     // TODO: This is stopgap to block new unexpected errors from being introduced. The long-term goal is to remove the use of this
    248     // function and its definition.
    249     void SetUnexpectedError(const char *const msg) {
    250         test_platform_thread_lock_mutex(&mutex_);
    251 
    252         ignore_message_strings_.emplace_back(msg);
    253 
    254         test_platform_thread_unlock_mutex(&mutex_);
    255     }
    256 
    257     VkBool32 CheckForDesiredMsg(const uint32_t message_code, const char *const msgString) {
    258         VkBool32 result = VK_FALSE;
    259         test_platform_thread_lock_mutex(&mutex_);
    260         if (bailout_ != nullptr) {
    261             *bailout_ = true;
    262         }
    263         string errorString(msgString);
    264         bool found_expected = false;
    265 
    266         if (!IgnoreMessage(errorString)) {
    267             for (auto desired_msg : desired_message_strings_) {
    268                 if (desired_msg.length() == 0) {
    269                     // An empty desired_msg string "" indicates a positive test - not expecting an error.
    270                     // Return true to avoid calling layers/driver with this error.
    271                     // And don't erase the "" string, so it remains if another error is found.
    272                     result = VK_TRUE;
    273                     found_expected = true;
    274                     message_found_ = true;
    275                     failure_message_strings_.insert(errorString);
    276                 } else if (errorString.find(desired_msg) != string::npos) {
    277                     found_expected = true;
    278                     message_outstanding_count_--;
    279                     failure_message_strings_.insert(errorString);
    280                     message_found_ = true;
    281                     result = VK_TRUE;
    282                     // We only want one match for each expected error so remove from set here
    283                     // Since we're about the break the loop it's ok to remove from set we're iterating over
    284                     desired_message_strings_.erase(desired_msg);
    285                     break;
    286                 }
    287             }
    288             for (auto desired_id : desired_message_ids_) {
    289                 if (desired_id == VALIDATION_ERROR_MAX_ENUM) {
    290                     // A message ID set to MAX_ENUM indicates a positive test - not expecting an error.
    291                     // Return true to avoid calling layers/driver with this error.
    292                     result = VK_TRUE;
    293                 } else if (desired_id == message_code) {
    294                     // Double-check that the string matches the error enum
    295                     if (errorString.find(validation_error_map[desired_id]) != string::npos) {
    296                         found_expected = true;
    297                         message_outstanding_count_--;
    298                         result = VK_TRUE;
    299                         message_found_ = true;
    300                         desired_message_ids_.erase(desired_id);
    301                         break;
    302                     } else {
    303                         // Treat this message as a regular unexpected error, but print a warning jic
    304                         printf("Message (%s) from MessageID %d does not correspond to expected message from error Database (%s)\n",
    305                                errorString.c_str(), desired_id, validation_error_map[desired_id]);
    306                     }
    307                 }
    308             }
    309 
    310             if (!found_expected) {
    311                 printf("Unexpected: %s\n", msgString);
    312                 other_messages_.push_back(errorString);
    313             }
    314         }
    315 
    316         test_platform_thread_unlock_mutex(&mutex_);
    317         return result;
    318     }
    319 
    320     vector<string> GetOtherFailureMsgs() const { return other_messages_; }
    321 
    322     VkDebugReportFlagsEXT GetMessageFlags() const { return message_flags_; }
    323 
    324     bool AnyDesiredMsgFound() const { return message_found_; }
    325 
    326     bool AllDesiredMsgsFound() const { return (0 == message_outstanding_count_); }
    327 
    328     void SetBailout(bool *bailout) { bailout_ = bailout; }
    329 
    330     void DumpFailureMsgs() const {
    331         vector<string> otherMsgs = GetOtherFailureMsgs();
    332         if (otherMsgs.size()) {
    333             cout << "Other error messages logged for this test were:" << endl;
    334             for (auto iter = otherMsgs.begin(); iter != otherMsgs.end(); iter++) {
    335                 cout << "     " << *iter << endl;
    336             }
    337         }
    338     }
    339 
    340     // Helpers
    341 
    342     // ExpectSuccess now takes an optional argument allowing a custom combination of debug flags
    343     void ExpectSuccess(VkDebugReportFlagsEXT const message_flag_mask = VK_DEBUG_REPORT_ERROR_BIT_EXT) {
    344         // Match ANY message matching specified type
    345         SetDesiredFailureMsg(message_flag_mask, "");
    346         message_flags_ = message_flag_mask;  // override mask handling in SetDesired...
    347     }
    348 
    349     void VerifyFound() {
    350         // Not seeing the desired message is a failure. /Before/ throwing, dump any other messages.
    351         if (!AllDesiredMsgsFound()) {
    352             DumpFailureMsgs();
    353             for (auto desired_msg : desired_message_strings_) {
    354                 ADD_FAILURE() << "Did not receive expected error '" << desired_msg << "'";
    355             }
    356             for (auto desired_id : desired_message_ids_) {
    357                 ADD_FAILURE() << "Did not receive expected error ENUM '0x" << std::hex << desired_id << "'";
    358             }
    359         }
    360         Reset();
    361     }
    362 
    363     void VerifyNotFound() {
    364         // ExpectSuccess() configured us to match anything. Any error is a failure.
    365         if (AnyDesiredMsgFound()) {
    366             DumpFailureMsgs();
    367             for (auto msg : failure_message_strings_) {
    368                 ADD_FAILURE() << "Expected to succeed but got error: " << msg;
    369             }
    370         }
    371         Reset();
    372     }
    373 
    374    private:
    375     // TODO: This is stopgap to block new unexpected errors from being introduced. The long-term goal is to remove the use of this
    376     // function and its definition.
    377     bool IgnoreMessage(std::string const &msg) const {
    378         if (ignore_message_strings_.empty()) {
    379             return false;
    380         }
    381 
    382         return std::find_if(ignore_message_strings_.begin(), ignore_message_strings_.end(), [&msg](std::string const &str) {
    383                    return msg.find(str) != std::string::npos;
    384                }) != ignore_message_strings_.end();
    385     }
    386 
    387     VkFlags message_flags_;
    388     std::unordered_set<uint32_t> desired_message_ids_;
    389     std::unordered_set<string> desired_message_strings_;
    390     std::unordered_set<string> failure_message_strings_;
    391     std::vector<std::string> ignore_message_strings_;
    392     vector<string> other_messages_;
    393     test_platform_thread_mutex mutex_;
    394     bool *bailout_;
    395     bool message_found_;
    396     int message_outstanding_count_;
    397 };
    398 
    399 static VKAPI_ATTR VkBool32 VKAPI_CALL myDbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject,
    400                                                 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg,
    401                                                 void *pUserData) {
    402     ErrorMonitor *errMonitor = (ErrorMonitor *)pUserData;
    403     if (msgFlags & errMonitor->GetMessageFlags()) {
    404 #ifdef _DEBUG
    405         char embedded_code_string[2048];
    406         snprintf(embedded_code_string, 2048, "%s [%08x]", pMsg, msgCode);
    407         return errMonitor->CheckForDesiredMsg(msgCode, embedded_code_string);
    408 #else
    409         return errMonitor->CheckForDesiredMsg(msgCode, pMsg);
    410 #endif
    411     }
    412     return VK_FALSE;
    413 }
    414 
    415 class VkLayerTest : public VkRenderFramework {
    416    public:
    417     void VKTriangleTest(BsoFailSelect failCase);
    418     void GenericDrawPreparation(VkCommandBufferObj *commandBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet,
    419                                 BsoFailSelect failCase);
    420 
    421     void Init(VkPhysicalDeviceFeatures *features = nullptr, const VkCommandPoolCreateFlags flags = 0) {
    422         InitFramework(myDbgFunc, m_errorMonitor);
    423         InitState(features, flags);
    424     }
    425 
    426    protected:
    427     ErrorMonitor *m_errorMonitor;
    428 
    429    public:
    430     ErrorMonitor *Monitor() { return m_errorMonitor; }
    431     VkCommandBufferObj *CommandBuffer() { return m_commandBuffer; }
    432 
    433    protected:
    434     bool m_enableWSI;
    435 
    436     virtual void SetUp() {
    437         m_instance_layer_names.clear();
    438         m_instance_extension_names.clear();
    439         m_device_extension_names.clear();
    440 
    441         // Add default instance extensions to the list
    442         m_instance_extension_names.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
    443 #ifdef _WIN32
    444         m_instance_extension_names.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
    445 #endif
    446 #ifdef VK_USE_PLATFORM_XCB_KHR
    447         m_instance_extension_names.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
    448 #endif
    449 
    450         // Use Threading layer first to protect others from
    451         // ThreadCommandBufferCollision test
    452         m_instance_layer_names.push_back("VK_LAYER_GOOGLE_threading");
    453         m_instance_layer_names.push_back("VK_LAYER_LUNARG_parameter_validation");
    454         m_instance_layer_names.push_back("VK_LAYER_LUNARG_object_tracker");
    455         m_instance_layer_names.push_back("VK_LAYER_LUNARG_core_validation");
    456         m_instance_layer_names.push_back("VK_LAYER_GOOGLE_unique_objects");
    457         if (VkTestFramework::m_devsim_layer) {
    458             if (InstanceLayerSupported("VK_LAYER_LUNARG_device_simulation")) {
    459                 m_instance_layer_names.push_back("VK_LAYER_LUNARG_device_simulation");
    460             } else {
    461                 VkTestFramework::m_devsim_layer = false;
    462                 printf("             Did not find VK_LAYER_LUNARG_device_simulation layer so it will not be enabled.\n");
    463             }
    464         }
    465         if (m_enableWSI) {
    466             m_instance_extension_names.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
    467             m_device_extension_names.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
    468 #ifdef NEED_TO_TEST_THIS_ON_PLATFORM
    469 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
    470             m_instance_extension_names.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
    471 #endif  // VK_USE_PLATFORM_ANDROID_KHR
    472 #if defined(VK_USE_PLATFORM_MIR_KHR)
    473             m_instance_extension_names.push_back(VK_KHR_MIR_SURFACE_EXTENSION_NAME);
    474 #endif  // VK_USE_PLATFORM_MIR_KHR
    475 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
    476             m_instance_extension_names.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
    477 #endif  // VK_USE_PLATFORM_WAYLAND_KHR
    478 #if defined(VK_USE_PLATFORM_WIN32_KHR)
    479             m_instance_extension_names.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
    480 #endif  // VK_USE_PLATFORM_WIN32_KHR
    481 #endif  // NEED_TO_TEST_THIS_ON_PLATFORM
    482 #if defined(VK_USE_PLATFORM_XCB_KHR)
    483             m_instance_extension_names.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
    484 #elif defined(VK_USE_PLATFORM_XLIB_KHR)
    485             m_instance_extension_names.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
    486 #endif  // VK_USE_PLATFORM_XLIB_KHR
    487         }
    488 
    489         this->app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    490         this->app_info.pNext = NULL;
    491         this->app_info.pApplicationName = "layer_tests";
    492         this->app_info.applicationVersion = 1;
    493         this->app_info.pEngineName = "unittest";
    494         this->app_info.engineVersion = 1;
    495         this->app_info.apiVersion = VK_API_VERSION_1_0;
    496 
    497         m_errorMonitor = new ErrorMonitor;
    498     }
    499 
    500     bool LoadDeviceProfileLayer(
    501         PFN_vkSetPhysicalDeviceFormatPropertiesEXT &fpvkSetPhysicalDeviceFormatPropertiesEXT,
    502         PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT &fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT) {
    503         // Load required functions
    504         fpvkSetPhysicalDeviceFormatPropertiesEXT =
    505             (PFN_vkSetPhysicalDeviceFormatPropertiesEXT)vkGetInstanceProcAddr(instance(), "vkSetPhysicalDeviceFormatPropertiesEXT");
    506         fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT =
    507             (PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT)vkGetInstanceProcAddr(
    508                 instance(), "vkGetOriginalPhysicalDeviceFormatPropertiesEXT");
    509 
    510         if (!(fpvkSetPhysicalDeviceFormatPropertiesEXT) || !(fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) {
    511             printf("             Can't find device_profile_api functions; skipped.\n");
    512             return 0;
    513         }
    514 
    515         return 1;
    516     }
    517 
    518     virtual void TearDown() {
    519         // Clean up resources before we reset
    520         ShutdownFramework();
    521         delete m_errorMonitor;
    522     }
    523 
    524     VkLayerTest() { m_enableWSI = false; }
    525 };
    526 
    527 void VkLayerTest::VKTriangleTest(BsoFailSelect failCase) {
    528     ASSERT_TRUE(m_device && m_device->initialized());  // VKTriangleTest assumes Init() has finished
    529 
    530     ASSERT_NO_FATAL_FAILURE(InitViewport());
    531 
    532     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
    533     VkShaderObj ps(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
    534 
    535     VkPipelineObj pipelineobj(m_device);
    536     pipelineobj.AddDefaultColorAttachment();
    537     pipelineobj.AddShader(&vs);
    538     pipelineobj.AddShader(&ps);
    539 
    540     bool failcase_needs_depth = false;  // to mark cases that need depth attachment
    541 
    542     switch (failCase) {
    543         case BsoFailLineWidth: {
    544             pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_LINE_WIDTH);
    545             VkPipelineInputAssemblyStateCreateInfo ia_state = {};
    546             ia_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
    547             ia_state.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
    548             pipelineobj.SetInputAssembly(&ia_state);
    549             break;
    550         }
    551         case BsoFailDepthBias: {
    552             pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_DEPTH_BIAS);
    553             VkPipelineRasterizationStateCreateInfo rs_state = {};
    554             rs_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
    555             rs_state.depthBiasEnable = VK_TRUE;
    556             rs_state.lineWidth = 1.0f;
    557             pipelineobj.SetRasterization(&rs_state);
    558             break;
    559         }
    560         case BsoFailViewport: {
    561             pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_VIEWPORT);
    562             break;
    563         }
    564         case BsoFailScissor: {
    565             pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_SCISSOR);
    566             break;
    567         }
    568         case BsoFailBlend: {
    569             pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_BLEND_CONSTANTS);
    570             VkPipelineColorBlendAttachmentState att_state = {};
    571             att_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
    572             att_state.blendEnable = VK_TRUE;
    573             pipelineobj.AddColorAttachment(0, att_state);
    574             break;
    575         }
    576         case BsoFailDepthBounds: {
    577             failcase_needs_depth = true;
    578             pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_DEPTH_BOUNDS);
    579             break;
    580         }
    581         case BsoFailStencilReadMask: {
    582             failcase_needs_depth = true;
    583             pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK);
    584             break;
    585         }
    586         case BsoFailStencilWriteMask: {
    587             failcase_needs_depth = true;
    588             pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK);
    589             break;
    590         }
    591         case BsoFailStencilReference: {
    592             failcase_needs_depth = true;
    593             pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
    594             break;
    595         }
    596 
    597         case BsoFailIndexBuffer:
    598             break;
    599         case BsoFailCmdClearAttachments:
    600             break;
    601         case BsoFailNone:
    602             break;
    603         default:
    604             break;
    605     }
    606 
    607     VkDescriptorSetObj descriptorSet(m_device);
    608 
    609     VkImageView *depth_attachment = nullptr;
    610     if (failcase_needs_depth) {
    611         m_depth_stencil_fmt = FindSupportedDepthStencilFormat(gpu());
    612         ASSERT_TRUE(m_depth_stencil_fmt != VK_FORMAT_UNDEFINED);
    613 
    614         m_depthStencil->Init(m_device, static_cast<uint32_t>(m_width), static_cast<uint32_t>(m_height), m_depth_stencil_fmt,
    615                              VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
    616         depth_attachment = m_depthStencil->BindInfo();
    617     }
    618 
    619     ASSERT_NO_FATAL_FAILURE(InitRenderTarget(1, depth_attachment));
    620     m_commandBuffer->begin();
    621 
    622     GenericDrawPreparation(m_commandBuffer, pipelineobj, descriptorSet, failCase);
    623 
    624     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
    625 
    626     // render triangle
    627     if (failCase == BsoFailIndexBuffer) {
    628         // Use DrawIndexed w/o an index buffer bound
    629         m_commandBuffer->DrawIndexed(3, 1, 0, 0, 0);
    630     } else {
    631         m_commandBuffer->Draw(3, 1, 0, 0);
    632     }
    633 
    634     if (failCase == BsoFailCmdClearAttachments) {
    635         VkClearAttachment color_attachment = {};
    636         color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
    637         color_attachment.colorAttachment = 1;  // Someone who knew what they were doing would use 0 for the index;
    638         VkClearRect clear_rect = {{{0, 0}, {static_cast<uint32_t>(m_width), static_cast<uint32_t>(m_height)}}, 0, 0};
    639 
    640         vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
    641     }
    642 
    643     // finalize recording of the command buffer
    644     m_commandBuffer->EndRenderPass();
    645     m_commandBuffer->end();
    646     m_commandBuffer->QueueCommandBuffer(true);
    647 }
    648 
    649 void VkLayerTest::GenericDrawPreparation(VkCommandBufferObj *commandBuffer, VkPipelineObj &pipelineobj,
    650                                          VkDescriptorSetObj &descriptorSet, BsoFailSelect failCase) {
    651     commandBuffer->ClearAllBuffers(m_renderTargets, m_clear_color, m_depthStencil, m_depth_clear_color, m_stencil_clear_color);
    652 
    653     commandBuffer->PrepareAttachments(m_renderTargets, m_depthStencil);
    654     // Make sure depthWriteEnable is set so that Depth fail test will work
    655     // correctly
    656     // Make sure stencilTestEnable is set so that Stencil fail test will work
    657     // correctly
    658     VkStencilOpState stencil = {};
    659     stencil.failOp = VK_STENCIL_OP_KEEP;
    660     stencil.passOp = VK_STENCIL_OP_KEEP;
    661     stencil.depthFailOp = VK_STENCIL_OP_KEEP;
    662     stencil.compareOp = VK_COMPARE_OP_NEVER;
    663 
    664     VkPipelineDepthStencilStateCreateInfo ds_ci = {};
    665     ds_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
    666     ds_ci.pNext = NULL;
    667     ds_ci.depthTestEnable = VK_FALSE;
    668     ds_ci.depthWriteEnable = VK_TRUE;
    669     ds_ci.depthCompareOp = VK_COMPARE_OP_NEVER;
    670     ds_ci.depthBoundsTestEnable = VK_FALSE;
    671     if (failCase == BsoFailDepthBounds) {
    672         ds_ci.depthBoundsTestEnable = VK_TRUE;
    673         ds_ci.maxDepthBounds = 0.0f;
    674         ds_ci.minDepthBounds = 0.0f;
    675     }
    676     ds_ci.stencilTestEnable = VK_TRUE;
    677     ds_ci.front = stencil;
    678     ds_ci.back = stencil;
    679 
    680     pipelineobj.SetDepthStencil(&ds_ci);
    681     pipelineobj.SetViewport(m_viewports);
    682     pipelineobj.SetScissor(m_scissors);
    683     descriptorSet.CreateVKDescriptorSet(commandBuffer);
    684     VkResult err = pipelineobj.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
    685     ASSERT_VK_SUCCESS(err);
    686     vkCmdBindPipeline(commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineobj.handle());
    687     commandBuffer->BindDescriptorSet(descriptorSet);
    688 }
    689 
    690 class VkPositiveLayerTest : public VkLayerTest {
    691    public:
    692    protected:
    693 };
    694 
    695 class VkWsiEnabledLayerTest : public VkLayerTest {
    696    public:
    697    protected:
    698     VkWsiEnabledLayerTest() { m_enableWSI = true; }
    699 };
    700 
    701 class VkBufferTest {
    702    public:
    703     enum eTestEnFlags {
    704         eDoubleDelete,
    705         eInvalidDeviceOffset,
    706         eInvalidMemoryOffset,
    707         eBindNullBuffer,
    708         eBindFakeBuffer,
    709         eFreeInvalidHandle,
    710         eNone,
    711     };
    712 
    713     enum eTestConditions { eOffsetAlignment = 1 };
    714 
    715     static bool GetTestConditionValid(VkDeviceObj *aVulkanDevice, eTestEnFlags aTestFlag, VkBufferUsageFlags aBufferUsage = 0) {
    716         if (eInvalidDeviceOffset != aTestFlag && eInvalidMemoryOffset != aTestFlag) {
    717             return true;
    718         }
    719         VkDeviceSize offset_limit = 0;
    720         if (eInvalidMemoryOffset == aTestFlag) {
    721             VkBuffer vulkanBuffer;
    722             VkBufferCreateInfo buffer_create_info = {};
    723             buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
    724             buffer_create_info.size = 32;
    725             buffer_create_info.usage = aBufferUsage;
    726 
    727             vkCreateBuffer(aVulkanDevice->device(), &buffer_create_info, nullptr, &vulkanBuffer);
    728             VkMemoryRequirements memory_reqs = {};
    729 
    730             vkGetBufferMemoryRequirements(aVulkanDevice->device(), vulkanBuffer, &memory_reqs);
    731             vkDestroyBuffer(aVulkanDevice->device(), vulkanBuffer, nullptr);
    732             offset_limit = memory_reqs.alignment;
    733         } else if ((VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) & aBufferUsage) {
    734             offset_limit = aVulkanDevice->props.limits.minTexelBufferOffsetAlignment;
    735         } else if (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT & aBufferUsage) {
    736             offset_limit = aVulkanDevice->props.limits.minUniformBufferOffsetAlignment;
    737         } else if (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT & aBufferUsage) {
    738             offset_limit = aVulkanDevice->props.limits.minStorageBufferOffsetAlignment;
    739         }
    740         return eOffsetAlignment < offset_limit;
    741     }
    742 
    743     // A constructor which performs validation tests within construction.
    744     VkBufferTest(VkDeviceObj *aVulkanDevice, VkBufferUsageFlags aBufferUsage, eTestEnFlags aTestFlag = eNone)
    745         : AllocateCurrent(true),
    746           BoundCurrent(false),
    747           CreateCurrent(false),
    748           InvalidDeleteEn(false),
    749           VulkanDevice(aVulkanDevice->device()) {
    750         if (eBindNullBuffer == aTestFlag || eBindFakeBuffer == aTestFlag) {
    751             VkMemoryAllocateInfo memory_allocate_info = {};
    752             memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
    753             memory_allocate_info.allocationSize = 1;   // fake size -- shouldn't matter for the test
    754             memory_allocate_info.memoryTypeIndex = 0;  // fake type -- shouldn't matter for the test
    755             vkAllocateMemory(VulkanDevice, &memory_allocate_info, nullptr, &VulkanMemory);
    756 
    757             VulkanBuffer = (aTestFlag == eBindNullBuffer) ? VK_NULL_HANDLE : (VkBuffer)0xCDCDCDCDCDCDCDCD;
    758 
    759             vkBindBufferMemory(VulkanDevice, VulkanBuffer, VulkanMemory, 0);
    760         } else {
    761             VkBufferCreateInfo buffer_create_info = {};
    762             buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
    763             buffer_create_info.size = 32;
    764             buffer_create_info.usage = aBufferUsage;
    765 
    766             vkCreateBuffer(VulkanDevice, &buffer_create_info, nullptr, &VulkanBuffer);
    767 
    768             CreateCurrent = true;
    769 
    770             VkMemoryRequirements memory_requirements;
    771             vkGetBufferMemoryRequirements(VulkanDevice, VulkanBuffer, &memory_requirements);
    772 
    773             VkMemoryAllocateInfo memory_allocate_info = {};
    774             memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
    775             memory_allocate_info.allocationSize = memory_requirements.size + eOffsetAlignment;
    776             bool pass = aVulkanDevice->phy().set_memory_type(memory_requirements.memoryTypeBits, &memory_allocate_info,
    777                                                              VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
    778             if (!pass) {
    779                 CreateCurrent = false;
    780                 vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr);
    781                 return;
    782             }
    783 
    784             vkAllocateMemory(VulkanDevice, &memory_allocate_info, NULL, &VulkanMemory);
    785             // NB: 1 is intentionally an invalid offset value
    786             const bool offset_en = eInvalidDeviceOffset == aTestFlag || eInvalidMemoryOffset == aTestFlag;
    787             vkBindBufferMemory(VulkanDevice, VulkanBuffer, VulkanMemory, offset_en ? eOffsetAlignment : 0);
    788             BoundCurrent = true;
    789 
    790             InvalidDeleteEn = (eFreeInvalidHandle == aTestFlag);
    791         }
    792     }
    793 
    794     ~VkBufferTest() {
    795         if (CreateCurrent) {
    796             vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr);
    797         }
    798         if (AllocateCurrent) {
    799             if (InvalidDeleteEn) {
    800                 union {
    801                     VkDeviceMemory device_memory;
    802                     unsigned long long index_access;
    803                 } bad_index;
    804 
    805                 bad_index.device_memory = VulkanMemory;
    806                 bad_index.index_access++;
    807 
    808                 vkFreeMemory(VulkanDevice, bad_index.device_memory, nullptr);
    809             }
    810             vkFreeMemory(VulkanDevice, VulkanMemory, nullptr);
    811         }
    812     }
    813 
    814     bool GetBufferCurrent() { return AllocateCurrent && BoundCurrent && CreateCurrent; }
    815 
    816     const VkBuffer &GetBuffer() { return VulkanBuffer; }
    817 
    818     void TestDoubleDestroy() {
    819         // Destroy the buffer but leave the flag set, which will cause
    820         // the buffer to be destroyed again in the destructor.
    821         vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr);
    822     }
    823 
    824    protected:
    825     bool AllocateCurrent;
    826     bool BoundCurrent;
    827     bool CreateCurrent;
    828     bool InvalidDeleteEn;
    829 
    830     VkBuffer VulkanBuffer;
    831     VkDevice VulkanDevice;
    832     VkDeviceMemory VulkanMemory;
    833 };
    834 
    835 class VkVerticesObj {
    836    public:
    837     VkVerticesObj(VkDeviceObj *aVulkanDevice, unsigned aAttributeCount, unsigned aBindingCount, unsigned aByteStride,
    838                   VkDeviceSize aVertexCount, const float *aVerticies)
    839         : BoundCurrent(false),
    840           AttributeCount(aAttributeCount),
    841           BindingCount(aBindingCount),
    842           BindId(BindIdGenerator),
    843           PipelineVertexInputStateCreateInfo(),
    844           VulkanMemoryBuffer(aVulkanDevice, static_cast<int>(aByteStride * aVertexCount),
    845                              reinterpret_cast<const void *>(aVerticies), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) {
    846         BindIdGenerator++;  // NB: This can wrap w/misuse
    847 
    848         VertexInputAttributeDescription = new VkVertexInputAttributeDescription[AttributeCount];
    849         VertexInputBindingDescription = new VkVertexInputBindingDescription[BindingCount];
    850 
    851         PipelineVertexInputStateCreateInfo.pVertexAttributeDescriptions = VertexInputAttributeDescription;
    852         PipelineVertexInputStateCreateInfo.vertexAttributeDescriptionCount = AttributeCount;
    853         PipelineVertexInputStateCreateInfo.pVertexBindingDescriptions = VertexInputBindingDescription;
    854         PipelineVertexInputStateCreateInfo.vertexBindingDescriptionCount = BindingCount;
    855         PipelineVertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
    856 
    857         unsigned i = 0;
    858         do {
    859             VertexInputAttributeDescription[i].binding = BindId;
    860             VertexInputAttributeDescription[i].location = i;
    861             VertexInputAttributeDescription[i].format = VK_FORMAT_R32G32B32_SFLOAT;
    862             VertexInputAttributeDescription[i].offset = sizeof(float) * aByteStride;
    863             i++;
    864         } while (AttributeCount < i);
    865 
    866         i = 0;
    867         do {
    868             VertexInputBindingDescription[i].binding = BindId;
    869             VertexInputBindingDescription[i].stride = aByteStride;
    870             VertexInputBindingDescription[i].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
    871             i++;
    872         } while (BindingCount < i);
    873     }
    874 
    875     ~VkVerticesObj() {
    876         if (VertexInputAttributeDescription) {
    877             delete[] VertexInputAttributeDescription;
    878         }
    879         if (VertexInputBindingDescription) {
    880             delete[] VertexInputBindingDescription;
    881         }
    882     }
    883 
    884     bool AddVertexInputToPipe(VkPipelineObj &aPipelineObj) {
    885         aPipelineObj.AddVertexInputAttribs(VertexInputAttributeDescription, AttributeCount);
    886         aPipelineObj.AddVertexInputBindings(VertexInputBindingDescription, BindingCount);
    887         return true;
    888     }
    889 
    890     void BindVertexBuffers(VkCommandBuffer aCommandBuffer, unsigned aOffsetCount = 0, VkDeviceSize *aOffsetList = nullptr) {
    891         VkDeviceSize *offsetList;
    892         unsigned offsetCount;
    893 
    894         if (aOffsetCount) {
    895             offsetList = aOffsetList;
    896             offsetCount = aOffsetCount;
    897         } else {
    898             offsetList = new VkDeviceSize[1]();
    899             offsetCount = 1;
    900         }
    901 
    902         vkCmdBindVertexBuffers(aCommandBuffer, BindId, offsetCount, &VulkanMemoryBuffer.handle(), offsetList);
    903         BoundCurrent = true;
    904 
    905         if (!aOffsetCount) {
    906             delete[] offsetList;
    907         }
    908     }
    909 
    910    protected:
    911     static uint32_t BindIdGenerator;
    912 
    913     bool BoundCurrent;
    914     unsigned AttributeCount;
    915     unsigned BindingCount;
    916     uint32_t BindId;
    917 
    918     VkPipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo;
    919     VkVertexInputAttributeDescription *VertexInputAttributeDescription;
    920     VkVertexInputBindingDescription *VertexInputBindingDescription;
    921     VkConstantBufferObj VulkanMemoryBuffer;
    922 };
    923 
    924 uint32_t VkVerticesObj::BindIdGenerator;
    925 
    926 struct OneOffDescriptorSet {
    927     VkDeviceObj *device_;
    928     VkDescriptorPool pool_;
    929     VkDescriptorSetLayoutObj layout_;
    930     VkDescriptorSet set_;
    931     typedef std::vector<VkDescriptorSetLayoutBinding> Bindings;
    932 
    933     OneOffDescriptorSet(VkDeviceObj *device, const Bindings &bindings)
    934         : device_{device}, pool_{}, layout_(device, bindings), set_{} {
    935         VkResult err;
    936 
    937         std::vector<VkDescriptorPoolSize> sizes;
    938         for (const auto &b : bindings) sizes.push_back({b.descriptorType, std::max(1u, b.descriptorCount)});
    939 
    940         VkDescriptorPoolCreateInfo dspci = {
    941             VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, nullptr, 0, 1, uint32_t(sizes.size()), sizes.data()};
    942         err = vkCreateDescriptorPool(device_->handle(), &dspci, nullptr, &pool_);
    943         if (err != VK_SUCCESS) return;
    944 
    945         VkDescriptorSetAllocateInfo alloc_info = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, nullptr, pool_, 1,
    946                                                   &layout_.handle()};
    947         err = vkAllocateDescriptorSets(device_->handle(), &alloc_info, &set_);
    948     }
    949 
    950     ~OneOffDescriptorSet() {
    951         // No need to destroy set-- it's going away with the pool.
    952         vkDestroyDescriptorPool(device_->handle(), pool_, nullptr);
    953     }
    954 
    955     bool Initialized() { return pool_ != VK_NULL_HANDLE && layout_.initialized() && set_ != VK_NULL_HANDLE; }
    956 };
    957 
    958 template <typename T>
    959 bool IsValidVkStruct(const T &s) {
    960     return LvlTypeMap<T>::kSType == s.sType;
    961 }
    962 
    963 // Helper class for tersely creating create pipeline tests
    964 //
    965 // Designed with minimal error checking to ensure easy error state creation
    966 // See OneshotTest for typical usage
    967 struct CreatePipelineHelper {
    968    public:
    969     std::vector<VkDescriptorSetLayoutBinding> dsl_bindings_;
    970     std::unique_ptr<OneOffDescriptorSet> descriptor_set_;
    971     std::vector<VkPipelineShaderStageCreateInfo> shader_stages_;
    972     VkPipelineVertexInputStateCreateInfo vi_ci_ = {};
    973     VkPipelineInputAssemblyStateCreateInfo ia_ci_ = {};
    974     VkPipelineTessellationStateCreateInfo tess_ci_ = {};
    975     VkViewport viewport_ = {};
    976     VkRect2D scissor_ = {};
    977     VkPipelineViewportStateCreateInfo vp_state_ci_ = {};
    978     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci_ = {};
    979     VkPipelineLayoutCreateInfo pipeline_layout_ci_ = {};
    980     VkPipelineLayoutObj pipeline_layout_;
    981     VkPipelineDynamicStateCreateInfo dyn_state_ci_ = {};
    982     VkPipelineRasterizationStateCreateInfo rs_state_ci_ = {};
    983     VkPipelineColorBlendAttachmentState cb_attachments_ = {};
    984     VkPipelineColorBlendStateCreateInfo cb_ci_ = {};
    985     VkGraphicsPipelineCreateInfo gp_ci_ = {};
    986     VkPipelineCacheCreateInfo pc_ci_ = {};
    987     VkPipeline pipeline_ = VK_NULL_HANDLE;
    988     VkPipelineCache pipeline_cache_ = VK_NULL_HANDLE;
    989     std::unique_ptr<VkShaderObj> vs_;
    990     std::unique_ptr<VkShaderObj> fs_;
    991     VkLayerTest &layer_test_;
    992     CreatePipelineHelper(VkLayerTest &test) : layer_test_(test) {}
    993     ~CreatePipelineHelper() {
    994         VkDevice device = layer_test_.device();
    995         vkDestroyPipelineCache(device, pipeline_cache_, nullptr);
    996         vkDestroyPipeline(device, pipeline_, nullptr);
    997     }
    998 
    999     void InitDescriptorSetInfo() { dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}}; }
   1000 
   1001     void InitInputAndVertexInfo() {
   1002         vi_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
   1003 
   1004         ia_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
   1005         ia_ci_.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
   1006     }
   1007 
   1008     void InitMultisampleInfo() {
   1009         pipe_ms_state_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
   1010         pipe_ms_state_ci_.pNext = nullptr;
   1011         pipe_ms_state_ci_.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
   1012         pipe_ms_state_ci_.sampleShadingEnable = VK_FALSE;
   1013         pipe_ms_state_ci_.minSampleShading = 1.0;
   1014         pipe_ms_state_ci_.pSampleMask = NULL;
   1015     }
   1016 
   1017     void InitPipelineLayoutInfo() {
   1018         pipeline_layout_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
   1019         pipeline_layout_ci_.setLayoutCount = 1;     // Not really changeable because InitState() sets exactly one pSetLayout
   1020         pipeline_layout_ci_.pSetLayouts = nullptr;  // must bound after it is created
   1021     }
   1022 
   1023     void InitViewportInfo() {
   1024         viewport_ = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
   1025         scissor_ = {{0, 0}, {64, 64}};
   1026 
   1027         vp_state_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
   1028         vp_state_ci_.pNext = nullptr;
   1029         vp_state_ci_.viewportCount = 1;
   1030         vp_state_ci_.pViewports = &viewport_;  // ignored if dynamic
   1031         vp_state_ci_.scissorCount = 1;
   1032         vp_state_ci_.pScissors = &scissor_;  // ignored if dynamic
   1033     }
   1034 
   1035     void InitDynamicStateInfo() {
   1036         // Use a "validity" check on the {} initialized structure to detect initialization
   1037         // during late bind
   1038     }
   1039 
   1040     void InitShaderInfo() {
   1041         vs_.reset(new VkShaderObj(layer_test_.DeviceObj(), bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, &layer_test_));
   1042         fs_.reset(new VkShaderObj(layer_test_.DeviceObj(), bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, &layer_test_));
   1043         // We shouldn't need a fragment shader but add it to be able to run on more devices
   1044         shader_stages_ = {vs_->GetStageCreateInfo(), fs_->GetStageCreateInfo()};
   1045     }
   1046 
   1047     void InitRasterizationInfo() {
   1048         rs_state_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
   1049         rs_state_ci_.pNext = nullptr;
   1050         rs_state_ci_.flags = 0;
   1051         rs_state_ci_.depthClampEnable = VK_FALSE;
   1052         rs_state_ci_.rasterizerDiscardEnable = VK_FALSE;
   1053         rs_state_ci_.polygonMode = VK_POLYGON_MODE_FILL;
   1054         rs_state_ci_.cullMode = VK_CULL_MODE_BACK_BIT;
   1055         rs_state_ci_.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
   1056         rs_state_ci_.depthBiasEnable = VK_FALSE;
   1057         rs_state_ci_.lineWidth = 1.0F;
   1058     }
   1059 
   1060     void InitBlendStateInfo() {
   1061         cb_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
   1062         cb_ci_.logicOpEnable = VK_FALSE;
   1063         cb_ci_.logicOp = VK_LOGIC_OP_COPY;  // ignored if enable is VK_FALSE above
   1064         cb_ci_.attachmentCount = layer_test_.RenderPassInfo().subpassCount;
   1065         ASSERT_TRUE(IsValidVkStruct(layer_test_.RenderPassInfo()));
   1066         cb_ci_.pAttachments = &cb_attachments_;
   1067         for (int i = 0; i < 4; i++) {
   1068             cb_ci_.blendConstants[0] = 1.0F;
   1069         }
   1070     }
   1071 
   1072     void InitGraphicsPipelineInfo() {
   1073         // Color-only rendering in a subpass with no depth/stencil attachment
   1074         // Active Pipeline Shader Stages
   1075         //    Vertex Shader
   1076         //    Fragment Shader
   1077         // Required: Fixed-Function Pipeline Stages
   1078         //    VkPipelineVertexInputStateCreateInfo
   1079         //    VkPipelineInputAssemblyStateCreateInfo
   1080         //    VkPipelineViewportStateCreateInfo
   1081         //    VkPipelineRasterizationStateCreateInfo
   1082         //    VkPipelineMultisampleStateCreateInfo
   1083         //    VkPipelineColorBlendStateCreateInfo
   1084         gp_ci_.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
   1085         gp_ci_.pNext = nullptr;
   1086         gp_ci_.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
   1087         gp_ci_.pVertexInputState = &vi_ci_;
   1088         gp_ci_.pInputAssemblyState = &ia_ci_;
   1089         gp_ci_.pTessellationState = nullptr;
   1090         gp_ci_.pViewportState = &vp_state_ci_;
   1091         gp_ci_.pRasterizationState = &rs_state_ci_;
   1092         gp_ci_.pMultisampleState = &pipe_ms_state_ci_;
   1093         gp_ci_.pDepthStencilState = nullptr;
   1094         gp_ci_.pColorBlendState = &cb_ci_;
   1095         gp_ci_.pDynamicState = nullptr;
   1096         gp_ci_.renderPass = layer_test_.renderPass();
   1097     }
   1098 
   1099     void InitPipelineCacheInfo() {
   1100         pc_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
   1101         pc_ci_.pNext = nullptr;
   1102         pc_ci_.flags = 0;
   1103         pc_ci_.initialDataSize = 0;
   1104         pc_ci_.pInitialData = nullptr;
   1105     }
   1106 
   1107     // Not called by default during init_info
   1108     void InitTesselationState() {
   1109         // TBD -- add shaders and create_info
   1110     }
   1111 
   1112     // TDB -- add control for optional and/or additional initialization
   1113     void InitInfo() {
   1114         InitDescriptorSetInfo();
   1115         InitInputAndVertexInfo();
   1116         InitMultisampleInfo();
   1117         InitPipelineLayoutInfo();
   1118         InitViewportInfo();
   1119         InitDynamicStateInfo();
   1120         InitShaderInfo();
   1121         InitRasterizationInfo();
   1122         InitBlendStateInfo();
   1123         InitGraphicsPipelineInfo();
   1124         InitPipelineCacheInfo();
   1125     }
   1126 
   1127     void InitState() {
   1128         VkResult err;
   1129         descriptor_set_.reset(new OneOffDescriptorSet(layer_test_.DeviceObj(), dsl_bindings_));
   1130         ASSERT_TRUE(descriptor_set_->Initialized());
   1131 
   1132         const std::vector<VkPushConstantRange> push_ranges(
   1133             pipeline_layout_ci_.pPushConstantRanges,
   1134             pipeline_layout_ci_.pPushConstantRanges + pipeline_layout_ci_.pushConstantRangeCount);
   1135         pipeline_layout_ = VkPipelineLayoutObj(layer_test_.DeviceObj(), {&descriptor_set_->layout_}, push_ranges);
   1136 
   1137         err = vkCreatePipelineCache(layer_test_.device(), &pc_ci_, NULL, &pipeline_cache_);
   1138         ASSERT_VK_SUCCESS(err);
   1139     }
   1140 
   1141     void LateBindPipelineInfo() {
   1142         // By value or dynamically located items must be late bound
   1143         gp_ci_.layout = pipeline_layout_.handle();
   1144         gp_ci_.stageCount = shader_stages_.size();
   1145         gp_ci_.pStages = shader_stages_.data();
   1146         if ((gp_ci_.pTessellationState == nullptr) && IsValidVkStruct(tess_ci_)) {
   1147             gp_ci_.pTessellationState = &tess_ci_;
   1148         }
   1149         if ((gp_ci_.pDynamicState == nullptr) && IsValidVkStruct(dyn_state_ci_)) {
   1150             gp_ci_.pDynamicState = &dyn_state_ci_;
   1151         }
   1152     }
   1153 
   1154     VkResult CreateGraphicsPipeline(bool implicit_destroy = true, bool do_late_bind = true) {
   1155         VkResult err;
   1156         if (do_late_bind) {
   1157             LateBindPipelineInfo();
   1158         }
   1159         if (implicit_destroy && (pipeline_ != VK_NULL_HANDLE)) {
   1160             vkDestroyPipeline(layer_test_.device(), pipeline_, nullptr);
   1161             pipeline_ = VK_NULL_HANDLE;
   1162         }
   1163         err = vkCreateGraphicsPipelines(layer_test_.device(), pipeline_cache_, 1, &gp_ci_, NULL, &pipeline_);
   1164         return err;
   1165     }
   1166 
   1167     // Helper function to create a simple test case (postive or negative)
   1168     //
   1169     // info_override can be any callable that takes a CreatePipelineHeper &
   1170     // flags, error can be any args accepted by "SetDesiredFailure".
   1171     template <typename Test, typename OverrideFunc, typename Error>
   1172     static void OneshotTest(Test &test, OverrideFunc &info_override, const VkFlags flags, const std::vector<Error> &errors,
   1173                             bool positive_test = false) {
   1174         CreatePipelineHelper helper(test);
   1175         helper.InitInfo();
   1176         info_override(helper);
   1177         helper.InitState();
   1178 
   1179         for (const auto &error : errors) test.Monitor()->SetDesiredFailureMsg(flags, error);
   1180         helper.CreateGraphicsPipeline();
   1181 
   1182         if (positive_test) {
   1183             test.Monitor()->VerifyNotFound();
   1184         } else {
   1185             test.Monitor()->VerifyFound();
   1186         }
   1187     }
   1188 
   1189     template <typename Test, typename OverrideFunc, typename Error>
   1190     static void OneshotTest(Test &test, OverrideFunc &info_override, const VkFlags flags, Error error, bool positive_test = false) {
   1191         OneshotTest(test, info_override, flags, std::vector<Error>(1, error), positive_test);
   1192     }
   1193 };
   1194 namespace chain_util {
   1195 template <typename T>
   1196 T Init(const void *pnext_in = nullptr) {
   1197     T pnext_obj = {};
   1198     pnext_obj.sType = LvlTypeMap<T>::kSType;
   1199     pnext_obj.pNext = pnext_in;
   1200     return pnext_obj;
   1201 }
   1202 class ExtensionChain {
   1203     const void *head_ = nullptr;
   1204     typedef std::function<bool(const char *)> AddIfFunction;
   1205     AddIfFunction add_if_;
   1206     typedef std::vector<const char *> List;
   1207     List *list_;
   1208 
   1209    public:
   1210     template <typename F>
   1211     ExtensionChain(F &add_if, List *list) : add_if_(add_if), list_(list) {}
   1212     template <typename T>
   1213     void Add(const char *name, T &obj) {
   1214         if (add_if_(name)) {
   1215             if (list_) {
   1216                 list_->push_back(name);
   1217             }
   1218             obj.pNext = head_;
   1219             head_ = &obj;
   1220         }
   1221     }
   1222     const void *Head() const { return head_; }
   1223 };
   1224 }  // namespace chain_util
   1225 
   1226 // ********************************************************************************************************************
   1227 // ********************************************************************************************************************
   1228 // ********************************************************************************************************************
   1229 // ********************************************************************************************************************
   1230 TEST_F(VkLayerTest, RequiredParameter) {
   1231     TEST_DESCRIPTION("Specify VK_NULL_HANDLE, NULL, and 0 for required handle, pointer, array, and array count parameters");
   1232 
   1233     ASSERT_NO_FATAL_FAILURE(Init());
   1234 
   1235     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pFeatures specified as NULL");
   1236     // Specify NULL for a pointer to a handle
   1237     // Expected to trigger an error with
   1238     // parameter_validation::validate_required_pointer
   1239     vkGetPhysicalDeviceFeatures(gpu(), NULL);
   1240     m_errorMonitor->VerifyFound();
   1241 
   1242     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   1243                                          "required parameter pQueueFamilyPropertyCount specified as NULL");
   1244     // Specify NULL for pointer to array count
   1245     // Expected to trigger an error with parameter_validation::validate_array
   1246     vkGetPhysicalDeviceQueueFamilyProperties(gpu(), NULL, NULL);
   1247     m_errorMonitor->VerifyFound();
   1248 
   1249     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1e030a1b);
   1250     // Specify 0 for a required array count
   1251     // Expected to trigger an error with parameter_validation::validate_array
   1252     VkViewport view_port = {};
   1253     m_commandBuffer->SetViewport(0, 0, &view_port);
   1254     m_errorMonitor->VerifyFound();
   1255 
   1256     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1e03fa01);
   1257     // Specify NULL for a required array
   1258     // Expected to trigger an error with parameter_validation::validate_array
   1259     m_commandBuffer->SetViewport(0, 1, NULL);
   1260     m_errorMonitor->VerifyFound();
   1261 
   1262     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter memory specified as VK_NULL_HANDLE");
   1263     // Specify VK_NULL_HANDLE for a required handle
   1264     // Expected to trigger an error with
   1265     // parameter_validation::validate_required_handle
   1266     vkUnmapMemory(device(), VK_NULL_HANDLE);
   1267     m_errorMonitor->VerifyFound();
   1268 
   1269     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   1270                                          "required parameter pFences[0] specified as VK_NULL_HANDLE");
   1271     // Specify VK_NULL_HANDLE for a required handle array entry
   1272     // Expected to trigger an error with
   1273     // parameter_validation::validate_required_handle_array
   1274     VkFence fence = VK_NULL_HANDLE;
   1275     vkResetFences(device(), 1, &fence);
   1276     m_errorMonitor->VerifyFound();
   1277 
   1278     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pAllocateInfo specified as NULL");
   1279     // Specify NULL for a required struct pointer
   1280     // Expected to trigger an error with
   1281     // parameter_validation::validate_struct_type
   1282     VkDeviceMemory memory = VK_NULL_HANDLE;
   1283     vkAllocateMemory(device(), NULL, NULL, &memory);
   1284     m_errorMonitor->VerifyFound();
   1285 
   1286     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "value of faceMask must not be 0");
   1287     // Specify 0 for a required VkFlags parameter
   1288     // Expected to trigger an error with parameter_validation::validate_flags
   1289     m_commandBuffer->SetStencilReference(0, 0);
   1290     m_errorMonitor->VerifyFound();
   1291 
   1292     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "value of pSubmits[0].pWaitDstStageMask[0] must not be 0");
   1293     // Specify 0 for a required VkFlags array entry
   1294     // Expected to trigger an error with
   1295     // parameter_validation::validate_flags_array
   1296     VkSemaphore semaphore = VK_NULL_HANDLE;
   1297     VkPipelineStageFlags stageFlags = 0;
   1298     VkSubmitInfo submitInfo = {};
   1299     submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   1300     submitInfo.waitSemaphoreCount = 1;
   1301     submitInfo.pWaitSemaphores = &semaphore;
   1302     submitInfo.pWaitDstStageMask = &stageFlags;
   1303     vkQueueSubmit(m_device->m_queue, 1, &submitInfo, VK_NULL_HANDLE);
   1304     m_errorMonitor->VerifyFound();
   1305 }
   1306 
   1307 TEST_F(VkLayerTest, ReservedParameter) {
   1308     TEST_DESCRIPTION("Specify a non-zero value for a reserved parameter");
   1309 
   1310     ASSERT_NO_FATAL_FAILURE(Init());
   1311 
   1312     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " must be 0");
   1313     // Specify 0 for a reserved VkFlags parameter
   1314     // Expected to trigger an error with
   1315     // parameter_validation::validate_reserved_flags
   1316     VkEvent event_handle = VK_NULL_HANDLE;
   1317     VkEventCreateInfo event_info = {};
   1318     event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
   1319     event_info.flags = 1;
   1320     vkCreateEvent(device(), &event_info, NULL, &event_handle);
   1321     m_errorMonitor->VerifyFound();
   1322 }
   1323 
   1324 TEST_F(VkLayerTest, DebugMarkerNameTest) {
   1325     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   1326     if (DeviceExtensionSupported(gpu(), "VK_LAYER_LUNARG_core_validation", VK_EXT_DEBUG_MARKER_EXTENSION_NAME)) {
   1327         m_device_extension_names.push_back(VK_EXT_DEBUG_MARKER_EXTENSION_NAME);
   1328     } else {
   1329         printf("             Debug Marker Extension not supported, skipping test\n");
   1330         return;
   1331     }
   1332     ASSERT_NO_FATAL_FAILURE(InitState());
   1333 
   1334     PFN_vkDebugMarkerSetObjectNameEXT fpvkDebugMarkerSetObjectNameEXT =
   1335         (PFN_vkDebugMarkerSetObjectNameEXT)vkGetInstanceProcAddr(instance(), "vkDebugMarkerSetObjectNameEXT");
   1336     if (!(fpvkDebugMarkerSetObjectNameEXT)) {
   1337         printf("             Can't find fpvkDebugMarkerSetObjectNameEXT; skipped.\n");
   1338         return;
   1339     }
   1340 
   1341     VkEvent event_handle = VK_NULL_HANDLE;
   1342     VkEventCreateInfo event_info = {};
   1343     event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
   1344     vkCreateEvent(device(), &event_info, NULL, &event_handle);
   1345     VkDebugMarkerObjectNameInfoEXT name_info = {};
   1346     name_info.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT;
   1347     name_info.pNext = nullptr;
   1348     name_info.object = (uint64_t)event_handle;
   1349     name_info.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT;
   1350     name_info.pObjectName = "UnimaginablyImprobableString";
   1351     fpvkDebugMarkerSetObjectNameEXT(device(), &name_info);
   1352 
   1353     m_commandBuffer->begin();
   1354     vkCmdSetEvent(m_commandBuffer->handle(), event_handle, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
   1355     m_commandBuffer->end();
   1356     VkSubmitInfo submit_info = {};
   1357     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   1358     submit_info.commandBufferCount = 1;
   1359     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   1360     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   1361     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "UnimaginablyImprobableString");
   1362     vkDestroyEvent(m_device->device(), event_handle, NULL);
   1363     m_errorMonitor->VerifyFound();
   1364     vkQueueWaitIdle(m_device->m_queue);
   1365 }
   1366 
   1367 TEST_F(VkLayerTest, InvalidStructSType) {
   1368     TEST_DESCRIPTION("Specify an invalid VkStructureType for a Vulkan structure's sType field");
   1369 
   1370     ASSERT_NO_FATAL_FAILURE(Init());
   1371 
   1372     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pAllocateInfo->sType must be");
   1373     // Zero struct memory, effectively setting sType to
   1374     // VK_STRUCTURE_TYPE_APPLICATION_INFO
   1375     // Expected to trigger an error with
   1376     // parameter_validation::validate_struct_type
   1377     VkMemoryAllocateInfo alloc_info = {};
   1378     VkDeviceMemory memory = VK_NULL_HANDLE;
   1379     vkAllocateMemory(device(), &alloc_info, NULL, &memory);
   1380     m_errorMonitor->VerifyFound();
   1381 
   1382     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pSubmits[0].sType must be");
   1383     // Zero struct memory, effectively setting sType to
   1384     // VK_STRUCTURE_TYPE_APPLICATION_INFO
   1385     // Expected to trigger an error with
   1386     // parameter_validation::validate_struct_type_array
   1387     VkSubmitInfo submit_info = {};
   1388     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   1389     m_errorMonitor->VerifyFound();
   1390 }
   1391 
   1392 TEST_F(VkLayerTest, InvalidStructPNext) {
   1393     TEST_DESCRIPTION("Specify an invalid value for a Vulkan structure's pNext field");
   1394 
   1395     ASSERT_NO_FATAL_FAILURE(Init());
   1396 
   1397     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "value of pCreateInfo->pNext must be NULL");
   1398     // Set VkMemoryAllocateInfo::pNext to a non-NULL value, when pNext must be NULL.
   1399     // Need to pick a function that has no allowed pNext structure types.
   1400     // Expected to trigger an error with parameter_validation::validate_struct_pnext
   1401     VkEvent event = VK_NULL_HANDLE;
   1402     VkEventCreateInfo event_alloc_info = {};
   1403     // Zero-initialization will provide the correct sType
   1404     VkApplicationInfo app_info = {};
   1405     event_alloc_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
   1406     event_alloc_info.pNext = &app_info;
   1407     vkCreateEvent(device(), &event_alloc_info, NULL, &event);
   1408     m_errorMonitor->VerifyFound();
   1409 
   1410     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
   1411                                          " chain includes a structure with unexpected VkStructureType ");
   1412     // Set VkMemoryAllocateInfo::pNext to a non-NULL value, but use
   1413     // a function that has allowed pNext structure types and specify
   1414     // a structure type that is not allowed.
   1415     // Expected to trigger an error with parameter_validation::validate_struct_pnext
   1416     VkDeviceMemory memory = VK_NULL_HANDLE;
   1417     VkMemoryAllocateInfo memory_alloc_info = {};
   1418     memory_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   1419     memory_alloc_info.pNext = &app_info;
   1420     vkAllocateMemory(device(), &memory_alloc_info, NULL, &memory);
   1421     m_errorMonitor->VerifyFound();
   1422 }
   1423 
   1424 TEST_F(VkLayerTest, UnrecognizedValueOutOfRange) {
   1425     ASSERT_NO_FATAL_FAILURE(Init());
   1426 
   1427     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   1428                                          "does not fall within the begin..end range of the core VkFormat enumeration tokens");
   1429     // Specify an invalid VkFormat value
   1430     // Expected to trigger an error with
   1431     // parameter_validation::validate_ranged_enum
   1432     VkFormatProperties format_properties;
   1433     vkGetPhysicalDeviceFormatProperties(gpu(), static_cast<VkFormat>(8000), &format_properties);
   1434     m_errorMonitor->VerifyFound();
   1435 }
   1436 
   1437 TEST_F(VkLayerTest, UnrecognizedValueBadMask) {
   1438     ASSERT_NO_FATAL_FAILURE(Init());
   1439 
   1440     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "contains flag bits that are not recognized members of");
   1441     // Specify an invalid VkFlags bitmask value
   1442     // Expected to trigger an error with parameter_validation::validate_flags
   1443     VkImageFormatProperties image_format_properties;
   1444     vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
   1445                                              static_cast<VkImageUsageFlags>(1 << 25), 0, &image_format_properties);
   1446     m_errorMonitor->VerifyFound();
   1447 }
   1448 
   1449 TEST_F(VkLayerTest, UnrecognizedValueBadFlag) {
   1450     ASSERT_NO_FATAL_FAILURE(Init());
   1451 
   1452     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "contains flag bits that are not recognized members of");
   1453     // Specify an invalid VkFlags array entry
   1454     // Expected to trigger an error with
   1455     // parameter_validation::validate_flags_array
   1456     VkSemaphore semaphore = VK_NULL_HANDLE;
   1457     VkPipelineStageFlags stage_flags = static_cast<VkPipelineStageFlags>(1 << 25);
   1458     VkSubmitInfo submit_info = {};
   1459     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   1460     submit_info.waitSemaphoreCount = 1;
   1461     submit_info.pWaitSemaphores = &semaphore;
   1462     submit_info.pWaitDstStageMask = &stage_flags;
   1463     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   1464     m_errorMonitor->VerifyFound();
   1465 }
   1466 
   1467 TEST_F(VkLayerTest, UnrecognizedValueBadBool) {
   1468     // Make sure using VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE doesn't trigger a false positive.
   1469     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   1470     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME)) {
   1471         m_device_extension_names.push_back(VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME);
   1472     } else {
   1473         printf("             VK_KHR_sampler_mirror_clamp_to_edge extension not supported, skipping test\n");
   1474         return;
   1475     }
   1476     ASSERT_NO_FATAL_FAILURE(InitState());
   1477 
   1478     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "is neither VK_TRUE nor VK_FALSE");
   1479     // Specify an invalid VkBool32 value, expecting a warning with parameter_validation::validate_bool32
   1480     VkSampler sampler = VK_NULL_HANDLE;
   1481     VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
   1482     sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
   1483     sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
   1484     sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
   1485 
   1486     // Not VK_TRUE or VK_FALSE
   1487     sampler_info.anisotropyEnable = 3;
   1488     vkCreateSampler(m_device->device(), &sampler_info, NULL, &sampler);
   1489     m_errorMonitor->VerifyFound();
   1490 }
   1491 
   1492 TEST_F(VkLayerTest, MirrorClampToEdgeNotEnabled) {
   1493     TEST_DESCRIPTION("Validation should catch using CLAMP_TO_EDGE addressing mode if the extension is not enabled.");
   1494 
   1495     ASSERT_NO_FATAL_FAILURE(Init());
   1496 
   1497     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1260086e);
   1498     VkSampler sampler = VK_NULL_HANDLE;
   1499     VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
   1500     // Set the modes to cause the error
   1501     sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
   1502     sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
   1503     sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
   1504 
   1505     vkCreateSampler(m_device->device(), &sampler_info, NULL, &sampler);
   1506     m_errorMonitor->VerifyFound();
   1507 }
   1508 
   1509 TEST_F(VkLayerTest, AnisotropyFeatureDisabled) {
   1510     TEST_DESCRIPTION("Validation should check anisotropy parameters are correct with samplerAnisotropy disabled.");
   1511 
   1512     // Determine if required device features are available
   1513     VkPhysicalDeviceFeatures device_features = {};
   1514     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   1515     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
   1516     device_features.samplerAnisotropy = VK_FALSE;  // force anisotropy off
   1517     ASSERT_NO_FATAL_FAILURE(InitState(&device_features));
   1518 
   1519     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1260085c);
   1520     VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
   1521     // With the samplerAnisotropy disable, the sampler must not enable it.
   1522     sampler_info.anisotropyEnable = VK_TRUE;
   1523     VkSampler sampler = VK_NULL_HANDLE;
   1524 
   1525     VkResult err;
   1526     err = vkCreateSampler(m_device->device(), &sampler_info, NULL, &sampler);
   1527     m_errorMonitor->VerifyFound();
   1528     if (VK_SUCCESS == err) {
   1529         vkDestroySampler(m_device->device(), sampler, NULL);
   1530     }
   1531     sampler = VK_NULL_HANDLE;
   1532 }
   1533 
   1534 TEST_F(VkLayerTest, AnisotropyFeatureEnabled) {
   1535     TEST_DESCRIPTION("Validation must check several conditons that apply only when Anisotropy is enabled.");
   1536 
   1537     // Determine if required device features are available
   1538     VkPhysicalDeviceFeatures device_features = {};
   1539     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   1540     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
   1541 
   1542     // These tests require that the device support sparse residency for 2D images
   1543     if (VK_TRUE != device_features.samplerAnisotropy) {
   1544         printf("             Test requires unsupported samplerAnisotropy feature. Skipped.\n");
   1545         return;
   1546     }
   1547 
   1548     bool cubic_support = false;
   1549     if (DeviceExtensionSupported(gpu(), nullptr, "VK_IMG_filter_cubic")) {
   1550         m_device_extension_names.push_back("VK_IMG_filter_cubic");
   1551         cubic_support = true;
   1552     }
   1553 
   1554     VkSamplerCreateInfo sampler_info_ref = SafeSaneSamplerCreateInfo();
   1555     sampler_info_ref.anisotropyEnable = VK_TRUE;
   1556     VkSamplerCreateInfo sampler_info = sampler_info_ref;
   1557     ASSERT_NO_FATAL_FAILURE(InitState());
   1558 
   1559     auto do_test = [this](UNIQUE_VALIDATION_ERROR_CODE code, const VkSamplerCreateInfo *pCreateInfo) -> void {
   1560         VkResult err;
   1561         VkSampler sampler = VK_NULL_HANDLE;
   1562         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, code);
   1563         err = vkCreateSampler(m_device->device(), pCreateInfo, NULL, &sampler);
   1564         m_errorMonitor->VerifyFound();
   1565         if (VK_SUCCESS == err) {
   1566             vkDestroySampler(m_device->device(), sampler, NULL);
   1567         }
   1568     };
   1569 
   1570     // maxAnisotropy out-of-bounds low.
   1571     sampler_info.maxAnisotropy = NextAfterLess(1.0F);
   1572     do_test(VALIDATION_ERROR_1260085e, &sampler_info);
   1573     sampler_info.maxAnisotropy = sampler_info_ref.maxAnisotropy;
   1574 
   1575     // maxAnisotropy out-of-bounds high.
   1576     sampler_info.maxAnisotropy = NextAfterGreater(m_device->phy().properties().limits.maxSamplerAnisotropy);
   1577     do_test(VALIDATION_ERROR_1260085e, &sampler_info);
   1578     sampler_info.maxAnisotropy = sampler_info_ref.maxAnisotropy;
   1579 
   1580     // Both anisotropy and unnormalized coords enabled
   1581     sampler_info.unnormalizedCoordinates = VK_TRUE;
   1582     do_test(VALIDATION_ERROR_12600868, &sampler_info);
   1583     sampler_info.unnormalizedCoordinates = sampler_info_ref.unnormalizedCoordinates;
   1584 
   1585     // Both anisotropy and cubic filtering enabled
   1586     if (cubic_support) {
   1587         sampler_info.minFilter = VK_FILTER_CUBIC_IMG;
   1588         do_test(VALIDATION_ERROR_12600872, &sampler_info);
   1589         sampler_info.minFilter = sampler_info_ref.minFilter;
   1590 
   1591         sampler_info.magFilter = VK_FILTER_CUBIC_IMG;
   1592         do_test(VALIDATION_ERROR_12600872, &sampler_info);
   1593         sampler_info.magFilter = sampler_info_ref.magFilter;
   1594     } else {
   1595         printf("             Test requires unsupported extension \"VK_IMG_filter_cubic\". Skipped.\n");
   1596     }
   1597 }
   1598 
   1599 TEST_F(VkLayerTest, UnrecognizedValueMaxEnum) {
   1600     ASSERT_NO_FATAL_FAILURE(Init());
   1601 
   1602     // Specify MAX_ENUM
   1603     VkFormatProperties format_properties;
   1604     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "does not fall within the begin..end range");
   1605     vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_MAX_ENUM, &format_properties);
   1606     m_errorMonitor->VerifyFound();
   1607 }
   1608 
   1609 TEST_F(VkLayerTest, UpdateBufferAlignment) {
   1610     TEST_DESCRIPTION("Check alignment parameters for vkCmdUpdateBuffer");
   1611     uint32_t updateData[] = {1, 2, 3, 4, 5, 6, 7, 8};
   1612 
   1613     ASSERT_NO_FATAL_FAILURE(Init());
   1614 
   1615     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
   1616     vk_testing::Buffer buffer;
   1617     buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs);
   1618 
   1619     m_commandBuffer->begin();
   1620     // Introduce failure by using dstOffset that is not multiple of 4
   1621     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4");
   1622     m_commandBuffer->UpdateBuffer(buffer.handle(), 1, 4, updateData);
   1623     m_errorMonitor->VerifyFound();
   1624 
   1625     // Introduce failure by using dataSize that is not multiple of 4
   1626     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4");
   1627     m_commandBuffer->UpdateBuffer(buffer.handle(), 0, 6, updateData);
   1628     m_errorMonitor->VerifyFound();
   1629 
   1630     // Introduce failure by using dataSize that is < 0
   1631     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   1632                                          "must be greater than zero and less than or equal to 65536");
   1633     m_commandBuffer->UpdateBuffer(buffer.handle(), 0, (VkDeviceSize)-44, updateData);
   1634     m_errorMonitor->VerifyFound();
   1635 
   1636     // Introduce failure by using dataSize that is > 65536
   1637     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   1638                                          "must be greater than zero and less than or equal to 65536");
   1639     m_commandBuffer->UpdateBuffer(buffer.handle(), 0, (VkDeviceSize)80000, updateData);
   1640     m_errorMonitor->VerifyFound();
   1641 
   1642     m_commandBuffer->end();
   1643 }
   1644 
   1645 TEST_F(VkLayerTest, FillBufferAlignment) {
   1646     TEST_DESCRIPTION("Check alignment parameters for vkCmdFillBuffer");
   1647 
   1648     ASSERT_NO_FATAL_FAILURE(Init());
   1649 
   1650     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
   1651     vk_testing::Buffer buffer;
   1652     buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs);
   1653 
   1654     m_commandBuffer->begin();
   1655 
   1656     // Introduce failure by using dstOffset that is not multiple of 4
   1657     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4");
   1658     m_commandBuffer->FillBuffer(buffer.handle(), 1, 4, 0x11111111);
   1659     m_errorMonitor->VerifyFound();
   1660 
   1661     // Introduce failure by using size that is not multiple of 4
   1662     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4");
   1663     m_commandBuffer->FillBuffer(buffer.handle(), 0, 6, 0x11111111);
   1664     m_errorMonitor->VerifyFound();
   1665 
   1666     // Introduce failure by using size that is zero
   1667     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must be greater than zero");
   1668     m_commandBuffer->FillBuffer(buffer.handle(), 0, 0, 0x11111111);
   1669     m_errorMonitor->VerifyFound();
   1670 
   1671     m_commandBuffer->end();
   1672 }
   1673 
   1674 TEST_F(VkLayerTest, PSOPolygonModeInvalid) {
   1675     TEST_DESCRIPTION("Attempt to use a non-solid polygon fill mode in a pipeline when this feature is not enabled.");
   1676 
   1677     ASSERT_NO_FATAL_FAILURE(Init());
   1678     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   1679 
   1680     std::vector<const char *> device_extension_names;
   1681     auto features = m_device->phy().features();
   1682     // Artificially disable support for non-solid fill modes
   1683     features.fillModeNonSolid = VK_FALSE;
   1684     // The sacrificial device object
   1685     VkDeviceObj test_device(0, gpu(), device_extension_names, &features);
   1686 
   1687     VkRenderpassObj render_pass(&test_device);
   1688 
   1689     const VkPipelineLayoutObj pipeline_layout(&test_device);
   1690 
   1691     VkPipelineRasterizationStateCreateInfo rs_ci = {};
   1692     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
   1693     rs_ci.pNext = nullptr;
   1694     rs_ci.lineWidth = 1.0f;
   1695     rs_ci.rasterizerDiscardEnable = VK_TRUE;
   1696 
   1697     VkShaderObj vs(&test_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   1698     VkShaderObj fs(&test_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   1699 
   1700     // Set polygonMode to unsupported value POINT, should fail
   1701     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   1702                                          "polygonMode cannot be VK_POLYGON_MODE_POINT or VK_POLYGON_MODE_LINE");
   1703     {
   1704         VkPipelineObj pipe(&test_device);
   1705         pipe.AddShader(&vs);
   1706         pipe.AddShader(&fs);
   1707         pipe.AddDefaultColorAttachment();
   1708         // Introduce failure by setting unsupported polygon mode
   1709         rs_ci.polygonMode = VK_POLYGON_MODE_POINT;
   1710         pipe.SetRasterization(&rs_ci);
   1711         pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle());
   1712     }
   1713     m_errorMonitor->VerifyFound();
   1714 
   1715     // Try again with polygonMode=LINE, should fail
   1716     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   1717                                          "polygonMode cannot be VK_POLYGON_MODE_POINT or VK_POLYGON_MODE_LINE");
   1718     {
   1719         VkPipelineObj pipe(&test_device);
   1720         pipe.AddShader(&vs);
   1721         pipe.AddShader(&fs);
   1722         pipe.AddDefaultColorAttachment();
   1723         // Introduce failure by setting unsupported polygon mode
   1724         rs_ci.polygonMode = VK_POLYGON_MODE_LINE;
   1725         pipe.SetRasterization(&rs_ci);
   1726         pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle());
   1727     }
   1728     m_errorMonitor->VerifyFound();
   1729 }
   1730 
   1731 TEST_F(VkLayerTest, SparseBindingImageBufferCreate) {
   1732     TEST_DESCRIPTION("Create buffer/image with sparse attributes but without the sparse_binding bit set");
   1733 
   1734     ASSERT_NO_FATAL_FAILURE(Init());
   1735 
   1736     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0140072c);
   1737     VkBuffer buffer;
   1738     VkBufferCreateInfo buf_info = {};
   1739     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   1740     buf_info.pNext = NULL;
   1741     buf_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
   1742     buf_info.size = 2048;
   1743     buf_info.queueFamilyIndexCount = 0;
   1744     buf_info.pQueueFamilyIndices = NULL;
   1745     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   1746     buf_info.flags = VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT;
   1747     vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
   1748     m_errorMonitor->VerifyFound();
   1749 
   1750     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e007b6);
   1751     VkImage image;
   1752     VkImageCreateInfo image_create_info = {};
   1753     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   1754     image_create_info.pNext = NULL;
   1755     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   1756     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
   1757     image_create_info.extent.width = 512;
   1758     image_create_info.extent.height = 64;
   1759     image_create_info.extent.depth = 1;
   1760     image_create_info.mipLevels = 1;
   1761     image_create_info.arrayLayers = 1;
   1762     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   1763     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   1764     image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
   1765     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   1766     image_create_info.queueFamilyIndexCount = 0;
   1767     image_create_info.pQueueFamilyIndices = NULL;
   1768     image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   1769     image_create_info.flags = VK_BUFFER_CREATE_SPARSE_ALIASED_BIT;
   1770     vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
   1771     m_errorMonitor->VerifyFound();
   1772 }
   1773 
   1774 TEST_F(VkLayerTest, SparseResidencyImageCreateUnsupportedTypes) {
   1775     TEST_DESCRIPTION("Create images with sparse residency with unsupported types");
   1776 
   1777     // Determine which device feature are available
   1778     VkPhysicalDeviceFeatures device_features = {};
   1779     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   1780     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
   1781 
   1782     // Mask out device features we don't want and initialize device state
   1783     device_features.sparseResidencyImage2D = VK_FALSE;
   1784     device_features.sparseResidencyImage3D = VK_FALSE;
   1785     ASSERT_NO_FATAL_FAILURE(InitState(&device_features));
   1786 
   1787     VkImage image = VK_NULL_HANDLE;
   1788     VkResult result = VK_RESULT_MAX_ENUM;
   1789     VkImageCreateInfo image_create_info = {};
   1790     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   1791     image_create_info.pNext = NULL;
   1792     image_create_info.imageType = VK_IMAGE_TYPE_1D;
   1793     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
   1794     image_create_info.extent.width = 512;
   1795     image_create_info.extent.height = 1;
   1796     image_create_info.extent.depth = 1;
   1797     image_create_info.mipLevels = 1;
   1798     image_create_info.arrayLayers = 1;
   1799     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   1800     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   1801     image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
   1802     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   1803     image_create_info.queueFamilyIndexCount = 0;
   1804     image_create_info.pQueueFamilyIndices = NULL;
   1805     image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   1806     image_create_info.flags = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_BUFFER_CREATE_SPARSE_BINDING_BIT;
   1807 
   1808     // 1D image w/ sparse residency is an error
   1809     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00794);
   1810     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
   1811     m_errorMonitor->VerifyFound();
   1812     if (VK_SUCCESS == result) {
   1813         vkDestroyImage(m_device->device(), image, NULL);
   1814         image = VK_NULL_HANDLE;
   1815     }
   1816 
   1817     // 2D image w/ sparse residency when feature isn't available
   1818     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   1819     image_create_info.extent.height = 64;
   1820     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00796);
   1821     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
   1822     m_errorMonitor->VerifyFound();
   1823     if (VK_SUCCESS == result) {
   1824         vkDestroyImage(m_device->device(), image, NULL);
   1825         image = VK_NULL_HANDLE;
   1826     }
   1827 
   1828     // 3D image w/ sparse residency when feature isn't available
   1829     image_create_info.imageType = VK_IMAGE_TYPE_3D;
   1830     image_create_info.extent.depth = 8;
   1831     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00798);
   1832     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
   1833     m_errorMonitor->VerifyFound();
   1834     if (VK_SUCCESS == result) {
   1835         vkDestroyImage(m_device->device(), image, NULL);
   1836         image = VK_NULL_HANDLE;
   1837     }
   1838 }
   1839 
   1840 TEST_F(VkLayerTest, SparseResidencyImageCreateUnsupportedSamples) {
   1841     TEST_DESCRIPTION("Create images with sparse residency with unsupported tiling or sample counts");
   1842 
   1843     // Determine which device feature are available
   1844     VkPhysicalDeviceFeatures device_features = {};
   1845     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   1846     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
   1847 
   1848     // These tests require that the device support sparse residency for 2D images
   1849     if (VK_TRUE != device_features.sparseResidencyImage2D) {
   1850         printf("             Test requires unsupported SparseResidencyImage2D feature. Skipped.\n");
   1851         return;
   1852     }
   1853 
   1854     // Mask out device features we don't want and initialize device state
   1855     device_features.sparseResidency2Samples = VK_FALSE;
   1856     device_features.sparseResidency4Samples = VK_FALSE;
   1857     device_features.sparseResidency8Samples = VK_FALSE;
   1858     device_features.sparseResidency16Samples = VK_FALSE;
   1859     ASSERT_NO_FATAL_FAILURE(InitState(&device_features));
   1860 
   1861     VkImage image = VK_NULL_HANDLE;
   1862     VkResult result = VK_RESULT_MAX_ENUM;
   1863     VkImageCreateInfo image_create_info = {};
   1864     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   1865     image_create_info.pNext = NULL;
   1866     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   1867     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
   1868     image_create_info.extent.width = 64;
   1869     image_create_info.extent.height = 64;
   1870     image_create_info.extent.depth = 1;
   1871     image_create_info.mipLevels = 1;
   1872     image_create_info.arrayLayers = 1;
   1873     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   1874     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
   1875     image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
   1876     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   1877     image_create_info.queueFamilyIndexCount = 0;
   1878     image_create_info.pQueueFamilyIndices = NULL;
   1879     image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   1880     image_create_info.flags = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_BUFFER_CREATE_SPARSE_BINDING_BIT;
   1881 
   1882     // 2D image w/ sparse residency and linear tiling is an error
   1883     m_errorMonitor->SetDesiredFailureMsg(
   1884         VK_DEBUG_REPORT_ERROR_BIT_EXT,
   1885         "VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT then image tiling of VK_IMAGE_TILING_LINEAR is not supported");
   1886     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
   1887     m_errorMonitor->VerifyFound();
   1888     if (VK_SUCCESS == result) {
   1889         vkDestroyImage(m_device->device(), image, NULL);
   1890         image = VK_NULL_HANDLE;
   1891     }
   1892     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   1893 
   1894     // Multi-sample image w/ sparse residency when feature isn't available (4 flavors)
   1895     image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
   1896     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e0079a);
   1897     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
   1898     m_errorMonitor->VerifyFound();
   1899     if (VK_SUCCESS == result) {
   1900         vkDestroyImage(m_device->device(), image, NULL);
   1901         image = VK_NULL_HANDLE;
   1902     }
   1903 
   1904     image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
   1905     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e0079c);
   1906     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
   1907     m_errorMonitor->VerifyFound();
   1908     if (VK_SUCCESS == result) {
   1909         vkDestroyImage(m_device->device(), image, NULL);
   1910         image = VK_NULL_HANDLE;
   1911     }
   1912 
   1913     image_create_info.samples = VK_SAMPLE_COUNT_8_BIT;
   1914     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e0079e);
   1915     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
   1916     m_errorMonitor->VerifyFound();
   1917     if (VK_SUCCESS == result) {
   1918         vkDestroyImage(m_device->device(), image, NULL);
   1919         image = VK_NULL_HANDLE;
   1920     }
   1921 
   1922     image_create_info.samples = VK_SAMPLE_COUNT_16_BIT;
   1923     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e007a0);
   1924     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
   1925     m_errorMonitor->VerifyFound();
   1926     if (VK_SUCCESS == result) {
   1927         vkDestroyImage(m_device->device(), image, NULL);
   1928         image = VK_NULL_HANDLE;
   1929     }
   1930 }
   1931 
   1932 TEST_F(VkLayerTest, InvalidMemoryAliasing) {
   1933     TEST_DESCRIPTION(
   1934         "Create a buffer and image, allocate memory, and bind the buffer and image to memory such that they will alias.");
   1935     VkResult err;
   1936     bool pass;
   1937     ASSERT_NO_FATAL_FAILURE(Init());
   1938 
   1939     VkBuffer buffer, buffer2;
   1940     VkImage image;
   1941     VkImage image2;
   1942     VkDeviceMemory mem;      // buffer will be bound first
   1943     VkDeviceMemory mem_img;  // image bound first
   1944     VkMemoryRequirements buff_mem_reqs, img_mem_reqs;
   1945     VkMemoryRequirements buff_mem_reqs2, img_mem_reqs2;
   1946 
   1947     VkBufferCreateInfo buf_info = {};
   1948     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   1949     buf_info.pNext = NULL;
   1950     buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
   1951     buf_info.size = 256;
   1952     buf_info.queueFamilyIndexCount = 0;
   1953     buf_info.pQueueFamilyIndices = NULL;
   1954     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   1955     buf_info.flags = 0;
   1956     err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
   1957     ASSERT_VK_SUCCESS(err);
   1958 
   1959     vkGetBufferMemoryRequirements(m_device->device(), buffer, &buff_mem_reqs);
   1960 
   1961     VkImageCreateInfo image_create_info = {};
   1962     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   1963     image_create_info.pNext = NULL;
   1964     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   1965     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
   1966     image_create_info.extent.width = 64;
   1967     image_create_info.extent.height = 64;
   1968     image_create_info.extent.depth = 1;
   1969     image_create_info.mipLevels = 1;
   1970     image_create_info.arrayLayers = 1;
   1971     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   1972     // Image tiling must be optimal to trigger error when aliasing linear buffer
   1973     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   1974     image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
   1975     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   1976     image_create_info.queueFamilyIndexCount = 0;
   1977     image_create_info.pQueueFamilyIndices = NULL;
   1978     image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   1979     image_create_info.flags = 0;
   1980 
   1981     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
   1982     ASSERT_VK_SUCCESS(err);
   1983     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image2);
   1984     ASSERT_VK_SUCCESS(err);
   1985 
   1986     vkGetImageMemoryRequirements(m_device->device(), image, &img_mem_reqs);
   1987 
   1988     VkMemoryAllocateInfo alloc_info = {};
   1989     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   1990     alloc_info.pNext = NULL;
   1991     alloc_info.memoryTypeIndex = 0;
   1992     // Ensure memory is big enough for both bindings
   1993     alloc_info.allocationSize = buff_mem_reqs.size + img_mem_reqs.size;
   1994     pass = m_device->phy().set_memory_type(buff_mem_reqs.memoryTypeBits & img_mem_reqs.memoryTypeBits, &alloc_info,
   1995                                            VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
   1996     if (!pass) {
   1997         vkDestroyBuffer(m_device->device(), buffer, NULL);
   1998         vkDestroyImage(m_device->device(), image, NULL);
   1999         vkDestroyImage(m_device->device(), image2, NULL);
   2000         return;
   2001     }
   2002     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
   2003     ASSERT_VK_SUCCESS(err);
   2004     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
   2005     ASSERT_VK_SUCCESS(err);
   2006 
   2007     vkGetImageMemoryRequirements(m_device->device(), image2, &img_mem_reqs2);
   2008 
   2009     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, " is aliased with linear buffer 0x");
   2010     // VALIDATION FAILURE due to image mapping overlapping buffer mapping
   2011     err = vkBindImageMemory(m_device->device(), image, mem, 0);
   2012     m_errorMonitor->VerifyFound();
   2013 
   2014     // Now correctly bind image2 to second mem allocation before incorrectly
   2015     // aliasing buffer2
   2016     err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer2);
   2017     ASSERT_VK_SUCCESS(err);
   2018     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem_img);
   2019     ASSERT_VK_SUCCESS(err);
   2020     err = vkBindImageMemory(m_device->device(), image2, mem_img, 0);
   2021     ASSERT_VK_SUCCESS(err);
   2022     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "is aliased with non-linear image 0x");
   2023     vkGetBufferMemoryRequirements(m_device->device(), buffer2, &buff_mem_reqs2);
   2024     err = vkBindBufferMemory(m_device->device(), buffer2, mem_img, 0);
   2025     m_errorMonitor->VerifyFound();
   2026 
   2027     vkDestroyBuffer(m_device->device(), buffer, NULL);
   2028     vkDestroyBuffer(m_device->device(), buffer2, NULL);
   2029     vkDestroyImage(m_device->device(), image, NULL);
   2030     vkDestroyImage(m_device->device(), image2, NULL);
   2031     vkFreeMemory(m_device->device(), mem, NULL);
   2032     vkFreeMemory(m_device->device(), mem_img, NULL);
   2033 }
   2034 
   2035 TEST_F(VkLayerTest, InvalidMemoryMapping) {
   2036     TEST_DESCRIPTION("Attempt to map memory in a number of incorrect ways");
   2037     VkResult err;
   2038     bool pass;
   2039     ASSERT_NO_FATAL_FAILURE(Init());
   2040 
   2041     VkBuffer buffer;
   2042     VkDeviceMemory mem;
   2043     VkMemoryRequirements mem_reqs;
   2044 
   2045     const VkDeviceSize atom_size = m_device->props.limits.nonCoherentAtomSize;
   2046 
   2047     VkBufferCreateInfo buf_info = {};
   2048     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   2049     buf_info.pNext = NULL;
   2050     buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
   2051     buf_info.size = 256;
   2052     buf_info.queueFamilyIndexCount = 0;
   2053     buf_info.pQueueFamilyIndices = NULL;
   2054     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   2055     buf_info.flags = 0;
   2056     err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
   2057     ASSERT_VK_SUCCESS(err);
   2058 
   2059     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
   2060     VkMemoryAllocateInfo alloc_info = {};
   2061     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   2062     alloc_info.pNext = NULL;
   2063     alloc_info.memoryTypeIndex = 0;
   2064 
   2065     // Ensure memory is big enough for both bindings
   2066     static const VkDeviceSize allocation_size = 0x10000;
   2067     alloc_info.allocationSize = allocation_size;
   2068     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
   2069     if (!pass) {
   2070         vkDestroyBuffer(m_device->device(), buffer, NULL);
   2071         return;
   2072     }
   2073     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
   2074     ASSERT_VK_SUCCESS(err);
   2075 
   2076     uint8_t *pData;
   2077     // Attempt to map memory size 0 is invalid
   2078     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VkMapMemory: Attempting to map memory range of size zero");
   2079     err = vkMapMemory(m_device->device(), mem, 0, 0, 0, (void **)&pData);
   2080     m_errorMonitor->VerifyFound();
   2081     // Map memory twice
   2082     err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData);
   2083     ASSERT_VK_SUCCESS(err);
   2084     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   2085                                          "VkMapMemory: Attempting to map memory on an already-mapped object ");
   2086     err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData);
   2087     m_errorMonitor->VerifyFound();
   2088 
   2089     // Unmap the memory to avoid re-map error
   2090     vkUnmapMemory(m_device->device(), mem);
   2091     // overstep allocation with VK_WHOLE_SIZE
   2092     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   2093                                          " with size of VK_WHOLE_SIZE oversteps total array size 0x");
   2094     err = vkMapMemory(m_device->device(), mem, allocation_size + 1, VK_WHOLE_SIZE, 0, (void **)&pData);
   2095     m_errorMonitor->VerifyFound();
   2096     // overstep allocation w/o VK_WHOLE_SIZE
   2097     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " oversteps total array size 0x");
   2098     err = vkMapMemory(m_device->device(), mem, 1, allocation_size, 0, (void **)&pData);
   2099     m_errorMonitor->VerifyFound();
   2100     // Now error due to unmapping memory that's not mapped
   2101     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Unmapping Memory without memory being mapped: ");
   2102     vkUnmapMemory(m_device->device(), mem);
   2103     m_errorMonitor->VerifyFound();
   2104 
   2105     // Now map memory and cause errors due to flushing invalid ranges
   2106     err = vkMapMemory(m_device->device(), mem, 4 * atom_size, VK_WHOLE_SIZE, 0, (void **)&pData);
   2107     ASSERT_VK_SUCCESS(err);
   2108     VkMappedMemoryRange mmr = {};
   2109     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
   2110     mmr.memory = mem;
   2111     mmr.offset = atom_size;  // Error b/c offset less than offset of mapped mem
   2112     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0c20055a);
   2113     vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
   2114     m_errorMonitor->VerifyFound();
   2115 
   2116     // Now flush range that oversteps mapped range
   2117     vkUnmapMemory(m_device->device(), mem);
   2118     err = vkMapMemory(m_device->device(), mem, 0, 4 * atom_size, 0, (void **)&pData);
   2119     ASSERT_VK_SUCCESS(err);
   2120     mmr.offset = atom_size;
   2121     mmr.size = 4 * atom_size;  // Flushing bounds exceed mapped bounds
   2122     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0c20055a);
   2123     vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
   2124     m_errorMonitor->VerifyFound();
   2125 
   2126     // Now flush range with VK_WHOLE_SIZE that oversteps offset
   2127     vkUnmapMemory(m_device->device(), mem);
   2128     err = vkMapMemory(m_device->device(), mem, 2 * atom_size, 4 * atom_size, 0, (void **)&pData);
   2129     ASSERT_VK_SUCCESS(err);
   2130     mmr.offset = atom_size;
   2131     mmr.size = VK_WHOLE_SIZE;
   2132     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0c20055c);
   2133     vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
   2134     m_errorMonitor->VerifyFound();
   2135 
   2136     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
   2137                                            VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
   2138     if (!pass) {
   2139         vkFreeMemory(m_device->device(), mem, NULL);
   2140         vkDestroyBuffer(m_device->device(), buffer, NULL);
   2141         return;
   2142     }
   2143     // TODO : If we can get HOST_VISIBLE w/o HOST_COHERENT we can test cases of
   2144     //  MEMTRACK_INVALID_MAP in validateAndCopyNoncoherentMemoryToDriver()
   2145 
   2146     vkDestroyBuffer(m_device->device(), buffer, NULL);
   2147     vkFreeMemory(m_device->device(), mem, NULL);
   2148 }
   2149 
   2150 TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit) {
   2151     VkResult err;
   2152     bool pass;
   2153 
   2154     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   2155                                          "Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT");
   2156 
   2157     ASSERT_NO_FATAL_FAILURE(Init());
   2158 
   2159     // Create an image, allocate memory, free it, and then try to bind it
   2160     VkImage image;
   2161     VkDeviceMemory mem;
   2162     VkMemoryRequirements mem_reqs;
   2163 
   2164     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
   2165     const int32_t tex_width = 32;
   2166     const int32_t tex_height = 32;
   2167 
   2168     VkImageCreateInfo image_create_info = {};
   2169     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   2170     image_create_info.pNext = NULL;
   2171     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   2172     image_create_info.format = tex_format;
   2173     image_create_info.extent.width = tex_width;
   2174     image_create_info.extent.height = tex_height;
   2175     image_create_info.extent.depth = 1;
   2176     image_create_info.mipLevels = 1;
   2177     image_create_info.arrayLayers = 1;
   2178     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   2179     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
   2180     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
   2181     image_create_info.flags = 0;
   2182     image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
   2183 
   2184     VkMemoryAllocateInfo mem_alloc = {};
   2185     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   2186     mem_alloc.pNext = NULL;
   2187     mem_alloc.allocationSize = 0;
   2188 
   2189     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
   2190     ASSERT_VK_SUCCESS(err);
   2191 
   2192     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
   2193 
   2194     mem_alloc.allocationSize = mem_reqs.size;
   2195 
   2196     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
   2197     if (!pass) {  // If we can't find any unmappable memory this test doesn't
   2198                   // make sense
   2199         vkDestroyImage(m_device->device(), image, NULL);
   2200         return;
   2201     }
   2202 
   2203     // allocate memory
   2204     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
   2205     ASSERT_VK_SUCCESS(err);
   2206 
   2207     // Try to bind free memory that has been freed
   2208     err = vkBindImageMemory(m_device->device(), image, mem, 0);
   2209     ASSERT_VK_SUCCESS(err);
   2210 
   2211     // Map memory as if to initialize the image
   2212     void *mappedAddress = NULL;
   2213     err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, &mappedAddress);
   2214 
   2215     m_errorMonitor->VerifyFound();
   2216 
   2217     vkDestroyImage(m_device->device(), image, NULL);
   2218     vkFreeMemory(m_device->device(), mem, NULL);
   2219 }
   2220 
   2221 TEST_F(VkLayerTest, RebindMemory) {
   2222     VkResult err;
   2223     bool pass;
   2224 
   2225     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "which has already been bound to mem object");
   2226 
   2227     ASSERT_NO_FATAL_FAILURE(Init());
   2228 
   2229     // Create an image, allocate memory, free it, and then try to bind it
   2230     VkImage image;
   2231     VkDeviceMemory mem1;
   2232     VkDeviceMemory mem2;
   2233     VkMemoryRequirements mem_reqs;
   2234 
   2235     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
   2236     const int32_t tex_width = 32;
   2237     const int32_t tex_height = 32;
   2238 
   2239     VkImageCreateInfo image_create_info = {};
   2240     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   2241     image_create_info.pNext = NULL;
   2242     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   2243     image_create_info.format = tex_format;
   2244     image_create_info.extent.width = tex_width;
   2245     image_create_info.extent.height = tex_height;
   2246     image_create_info.extent.depth = 1;
   2247     image_create_info.mipLevels = 1;
   2248     image_create_info.arrayLayers = 1;
   2249     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   2250     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
   2251     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
   2252     image_create_info.flags = 0;
   2253 
   2254     VkMemoryAllocateInfo mem_alloc = {};
   2255     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   2256     mem_alloc.pNext = NULL;
   2257     mem_alloc.allocationSize = 0;
   2258     mem_alloc.memoryTypeIndex = 0;
   2259 
   2260     // Introduce failure, do NOT set memProps to
   2261     // VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
   2262     mem_alloc.memoryTypeIndex = 1;
   2263     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
   2264     ASSERT_VK_SUCCESS(err);
   2265 
   2266     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
   2267 
   2268     mem_alloc.allocationSize = mem_reqs.size;
   2269     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
   2270     ASSERT_TRUE(pass);
   2271 
   2272     // allocate 2 memory objects
   2273     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem1);
   2274     ASSERT_VK_SUCCESS(err);
   2275     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem2);
   2276     ASSERT_VK_SUCCESS(err);
   2277 
   2278     // Bind first memory object to Image object
   2279     err = vkBindImageMemory(m_device->device(), image, mem1, 0);
   2280     ASSERT_VK_SUCCESS(err);
   2281 
   2282     // Introduce validation failure, try to bind a different memory object to
   2283     // the same image object
   2284     err = vkBindImageMemory(m_device->device(), image, mem2, 0);
   2285 
   2286     m_errorMonitor->VerifyFound();
   2287 
   2288     vkDestroyImage(m_device->device(), image, NULL);
   2289     vkFreeMemory(m_device->device(), mem1, NULL);
   2290     vkFreeMemory(m_device->device(), mem2, NULL);
   2291 }
   2292 
   2293 TEST_F(VkLayerTest, SubmitSignaledFence) {
   2294     vk_testing::Fence testFence;
   2295 
   2296     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   2297                                          "submitted in SIGNALED state.  Fences must be reset before being submitted");
   2298 
   2299     VkFenceCreateInfo fenceInfo = {};
   2300     fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
   2301     fenceInfo.pNext = NULL;
   2302     fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
   2303 
   2304     ASSERT_NO_FATAL_FAILURE(Init());
   2305     ASSERT_NO_FATAL_FAILURE(InitViewport());
   2306     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   2307 
   2308     m_commandBuffer->begin();
   2309     m_commandBuffer->ClearAllBuffers(m_renderTargets, m_clear_color, nullptr, m_depth_clear_color, m_stencil_clear_color);
   2310     m_commandBuffer->end();
   2311 
   2312     testFence.init(*m_device, fenceInfo);
   2313 
   2314     VkSubmitInfo submit_info;
   2315     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   2316     submit_info.pNext = NULL;
   2317     submit_info.waitSemaphoreCount = 0;
   2318     submit_info.pWaitSemaphores = NULL;
   2319     submit_info.pWaitDstStageMask = NULL;
   2320     submit_info.commandBufferCount = 1;
   2321     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   2322     submit_info.signalSemaphoreCount = 0;
   2323     submit_info.pSignalSemaphores = NULL;
   2324 
   2325     vkQueueSubmit(m_device->m_queue, 1, &submit_info, testFence.handle());
   2326     vkQueueWaitIdle(m_device->m_queue);
   2327 
   2328     m_errorMonitor->VerifyFound();
   2329 }
   2330 
   2331 TEST_F(VkLayerTest, InvalidUsageBits) {
   2332     TEST_DESCRIPTION(
   2333         "Specify wrong usage for image then create conflicting view of image Initialize buffer with wrong usage then perform copy "
   2334         "expecting errors from both the image and the buffer (2 calls)");
   2335 
   2336     ASSERT_NO_FATAL_FAILURE(Init());
   2337     auto format = FindSupportedDepthStencilFormat(gpu());
   2338     if (!format) {
   2339         printf("             No Depth + Stencil format found. Skipped.\n");
   2340         return;
   2341     }
   2342 
   2343     VkImageObj image(m_device);
   2344     // Initialize image with transfer source usage
   2345     image.Init(128, 128, 1, format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   2346     ASSERT_TRUE(image.initialized());
   2347 
   2348     VkImageView dsv;
   2349     VkImageViewCreateInfo dsvci = {};
   2350     dsvci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   2351     dsvci.image = image.handle();
   2352     dsvci.viewType = VK_IMAGE_VIEW_TYPE_2D;
   2353     dsvci.format = format;
   2354     dsvci.subresourceRange.layerCount = 1;
   2355     dsvci.subresourceRange.baseMipLevel = 0;
   2356     dsvci.subresourceRange.levelCount = 1;
   2357     dsvci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
   2358 
   2359     // Create a view with depth / stencil aspect for image with different usage
   2360     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid usage flag for Image ");
   2361     vkCreateImageView(m_device->device(), &dsvci, NULL, &dsv);
   2362     m_errorMonitor->VerifyFound();
   2363 
   2364     // Initialize buffer with TRANSFER_DST usage
   2365     vk_testing::Buffer buffer;
   2366     VkMemoryPropertyFlags reqs = 0;
   2367     buffer.init_as_dst(*m_device, 128 * 128, reqs);
   2368     VkBufferImageCopy region = {};
   2369     region.bufferRowLength = 128;
   2370     region.bufferImageHeight = 128;
   2371     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
   2372     region.imageSubresource.layerCount = 1;
   2373     region.imageExtent.height = 16;
   2374     region.imageExtent.width = 16;
   2375     region.imageExtent.depth = 1;
   2376 
   2377     // Buffer usage not set to TRANSFER_SRC and image usage not set to TRANSFER_DST
   2378     m_commandBuffer->begin();
   2379 
   2380     // two separate errors from this call:
   2381     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18e00162);
   2382     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18e0015c);
   2383 
   2384     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
   2385                            &region);
   2386     m_errorMonitor->VerifyFound();
   2387 }
   2388 
   2389 TEST_F(VkLayerTest, LeakAnObject) {
   2390     VkResult err;
   2391 
   2392     TEST_DESCRIPTION("Create a fence and destroy its device without first destroying the fence.");
   2393 
   2394     // Note that we have to create a new device since destroying the
   2395     // framework's device causes Teardown() to fail and just calling Teardown
   2396     // will destroy the errorMonitor.
   2397 
   2398     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "has not been destroyed.");
   2399 
   2400     ASSERT_NO_FATAL_FAILURE(Init());
   2401 
   2402     vk_testing::QueueCreateInfoArray queue_info(m_device->queue_props);
   2403 
   2404     // The sacrificial device object
   2405     VkDevice testDevice;
   2406     VkDeviceCreateInfo device_create_info = {};
   2407     auto features = m_device->phy().features();
   2408     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
   2409     device_create_info.pNext = NULL;
   2410     device_create_info.queueCreateInfoCount = queue_info.size();
   2411     device_create_info.pQueueCreateInfos = queue_info.data();
   2412     device_create_info.enabledLayerCount = 0;
   2413     device_create_info.ppEnabledLayerNames = NULL;
   2414     device_create_info.pEnabledFeatures = &features;
   2415     err = vkCreateDevice(gpu(), &device_create_info, NULL, &testDevice);
   2416     ASSERT_VK_SUCCESS(err);
   2417 
   2418     VkFence fence;
   2419     VkFenceCreateInfo fence_create_info = {};
   2420     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
   2421     fence_create_info.pNext = NULL;
   2422     fence_create_info.flags = 0;
   2423     err = vkCreateFence(testDevice, &fence_create_info, NULL, &fence);
   2424     ASSERT_VK_SUCCESS(err);
   2425 
   2426     // Induce failure by not calling vkDestroyFence
   2427     vkDestroyDevice(testDevice, NULL);
   2428     m_errorMonitor->VerifyFound();
   2429 }
   2430 
   2431 TEST_F(VkLayerTest, InvalidCommandPoolConsistency) {
   2432     TEST_DESCRIPTION("Allocate command buffers from one command pool and attempt to delete them from another.");
   2433 
   2434     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "FreeCommandBuffers is attempting to free Command Buffer");
   2435 
   2436     ASSERT_NO_FATAL_FAILURE(Init());
   2437     VkCommandPool command_pool_one;
   2438     VkCommandPool command_pool_two;
   2439 
   2440     VkCommandPoolCreateInfo pool_create_info{};
   2441     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
   2442     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
   2443     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
   2444 
   2445     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_one);
   2446 
   2447     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_two);
   2448 
   2449     VkCommandBuffer cb;
   2450     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
   2451     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
   2452     command_buffer_allocate_info.commandPool = command_pool_one;
   2453     command_buffer_allocate_info.commandBufferCount = 1;
   2454     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
   2455     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &cb);
   2456 
   2457     vkFreeCommandBuffers(m_device->device(), command_pool_two, 1, &cb);
   2458 
   2459     m_errorMonitor->VerifyFound();
   2460 
   2461     vkDestroyCommandPool(m_device->device(), command_pool_one, NULL);
   2462     vkDestroyCommandPool(m_device->device(), command_pool_two, NULL);
   2463 }
   2464 
   2465 TEST_F(VkLayerTest, InvalidDescriptorPoolConsistency) {
   2466     VkResult err;
   2467 
   2468     TEST_DESCRIPTION("Allocate descriptor sets from one DS pool and attempt to delete them from another.");
   2469 
   2470     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "FreeDescriptorSets is attempting to free descriptorSet");
   2471 
   2472     ASSERT_NO_FATAL_FAILURE(Init());
   2473     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   2474 
   2475     VkDescriptorPoolSize ds_type_count = {};
   2476     ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
   2477     ds_type_count.descriptorCount = 1;
   2478 
   2479     VkDescriptorPoolCreateInfo ds_pool_ci = {};
   2480     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
   2481     ds_pool_ci.pNext = NULL;
   2482     ds_pool_ci.flags = 0;
   2483     ds_pool_ci.maxSets = 1;
   2484     ds_pool_ci.poolSizeCount = 1;
   2485     ds_pool_ci.pPoolSizes = &ds_type_count;
   2486 
   2487     VkDescriptorPool bad_pool;
   2488     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &bad_pool);
   2489     ASSERT_VK_SUCCESS(err);
   2490 
   2491     OneOffDescriptorSet ds(m_device, {
   2492                                          {0, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
   2493                                      });
   2494 
   2495     err = vkFreeDescriptorSets(m_device->device(), bad_pool, 1, &ds.set_);
   2496 
   2497     m_errorMonitor->VerifyFound();
   2498 
   2499     vkDestroyDescriptorPool(m_device->device(), bad_pool, NULL);
   2500 }
   2501 
   2502 TEST_F(VkLayerTest, CreateUnknownObject) {
   2503     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_2a20a001);
   2504 
   2505     TEST_DESCRIPTION("Pass an invalid image object handle into a Vulkan API call.");
   2506 
   2507     ASSERT_NO_FATAL_FAILURE(Init());
   2508 
   2509     // Pass bogus handle into GetImageMemoryRequirements
   2510     VkMemoryRequirements mem_reqs;
   2511     uint64_t fakeImageHandle = 0xCADECADE;
   2512     VkImage fauxImage = reinterpret_cast<VkImage &>(fakeImageHandle);
   2513 
   2514     vkGetImageMemoryRequirements(m_device->device(), fauxImage, &mem_reqs);
   2515 
   2516     m_errorMonitor->VerifyFound();
   2517 }
   2518 
   2519 TEST_F(VkLayerTest, UseObjectWithWrongDevice) {
   2520     TEST_DESCRIPTION(
   2521         "Try to destroy a render pass object using a device other than the one it was created on. This should generate a distinct "
   2522         "error from the invalid handle error.");
   2523     // Create first device and renderpass
   2524     ASSERT_NO_FATAL_FAILURE(Init());
   2525     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   2526 
   2527     // Create second device
   2528     float priorities[] = {1.0f};
   2529     VkDeviceQueueCreateInfo queue_info{};
   2530     queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
   2531     queue_info.pNext = NULL;
   2532     queue_info.flags = 0;
   2533     queue_info.queueFamilyIndex = 0;
   2534     queue_info.queueCount = 1;
   2535     queue_info.pQueuePriorities = &priorities[0];
   2536 
   2537     VkDeviceCreateInfo device_create_info = {};
   2538     auto features = m_device->phy().features();
   2539     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
   2540     device_create_info.pNext = NULL;
   2541     device_create_info.queueCreateInfoCount = 1;
   2542     device_create_info.pQueueCreateInfos = &queue_info;
   2543     device_create_info.enabledLayerCount = 0;
   2544     device_create_info.ppEnabledLayerNames = NULL;
   2545     device_create_info.pEnabledFeatures = &features;
   2546 
   2547     VkDevice second_device;
   2548     ASSERT_VK_SUCCESS(vkCreateDevice(gpu(), &device_create_info, NULL, &second_device));
   2549 
   2550     // Try to destroy the renderpass from the first device using the second device
   2551     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_2642ae07);
   2552     vkDestroyRenderPass(second_device, m_renderPass, NULL);
   2553     m_errorMonitor->VerifyFound();
   2554 
   2555     vkDestroyDevice(second_device, NULL);
   2556 }
   2557 
   2558 TEST_F(VkLayerTest, PipelineNotBound) {
   2559     TEST_DESCRIPTION("Pass in an invalid pipeline object handle into a Vulkan API call.");
   2560 
   2561     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18027c01);
   2562 
   2563     ASSERT_NO_FATAL_FAILURE(Init());
   2564     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   2565 
   2566     VkPipeline badPipeline = (VkPipeline)((size_t)0xbaadb1be);
   2567 
   2568     m_commandBuffer->begin();
   2569     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
   2570 
   2571     m_errorMonitor->VerifyFound();
   2572 }
   2573 
   2574 TEST_F(VkLayerTest, BindImageInvalidMemoryType) {
   2575     VkResult err;
   2576 
   2577     TEST_DESCRIPTION("Test validation check for an invalid memory type index during bind[Buffer|Image]Memory time");
   2578 
   2579     ASSERT_NO_FATAL_FAILURE(Init());
   2580 
   2581     // Create an image, allocate memory, set a bad typeIndex and then try to
   2582     // bind it
   2583     VkImage image;
   2584     VkDeviceMemory mem;
   2585     VkMemoryRequirements mem_reqs;
   2586     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
   2587     const int32_t tex_width = 32;
   2588     const int32_t tex_height = 32;
   2589 
   2590     VkImageCreateInfo image_create_info = {};
   2591     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   2592     image_create_info.pNext = NULL;
   2593     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   2594     image_create_info.format = tex_format;
   2595     image_create_info.extent.width = tex_width;
   2596     image_create_info.extent.height = tex_height;
   2597     image_create_info.extent.depth = 1;
   2598     image_create_info.mipLevels = 1;
   2599     image_create_info.arrayLayers = 1;
   2600     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   2601     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   2602     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
   2603     image_create_info.flags = 0;
   2604 
   2605     VkMemoryAllocateInfo mem_alloc = {};
   2606     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   2607     mem_alloc.pNext = NULL;
   2608     mem_alloc.allocationSize = 0;
   2609     mem_alloc.memoryTypeIndex = 0;
   2610 
   2611     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
   2612     ASSERT_VK_SUCCESS(err);
   2613 
   2614     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
   2615     mem_alloc.allocationSize = mem_reqs.size;
   2616 
   2617     // Introduce Failure, select invalid TypeIndex
   2618     VkPhysicalDeviceMemoryProperties memory_info;
   2619 
   2620     vkGetPhysicalDeviceMemoryProperties(gpu(), &memory_info);
   2621     unsigned int i;
   2622     for (i = 0; i < memory_info.memoryTypeCount; i++) {
   2623         if ((mem_reqs.memoryTypeBits & (1 << i)) == 0) {
   2624             mem_alloc.memoryTypeIndex = i;
   2625             break;
   2626         }
   2627     }
   2628     if (i >= memory_info.memoryTypeCount) {
   2629         printf("             No invalid memory type index could be found; skipped.\n");
   2630         vkDestroyImage(m_device->device(), image, NULL);
   2631         return;
   2632     }
   2633 
   2634     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "for this object type are not compatible with the memory");
   2635 
   2636     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
   2637     ASSERT_VK_SUCCESS(err);
   2638 
   2639     err = vkBindImageMemory(m_device->device(), image, mem, 0);
   2640     (void)err;
   2641 
   2642     m_errorMonitor->VerifyFound();
   2643 
   2644     vkDestroyImage(m_device->device(), image, NULL);
   2645     vkFreeMemory(m_device->device(), mem, NULL);
   2646 }
   2647 
   2648 TEST_F(VkLayerTest, BindInvalidMemory) {
   2649     VkResult err;
   2650     bool pass;
   2651 
   2652     ASSERT_NO_FATAL_FAILURE(Init());
   2653 
   2654     const VkFormat tex_format = VK_FORMAT_R8G8B8A8_UNORM;
   2655     const int32_t tex_width = 256;
   2656     const int32_t tex_height = 256;
   2657 
   2658     VkImageCreateInfo image_create_info = {};
   2659     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   2660     image_create_info.pNext = NULL;
   2661     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   2662     image_create_info.format = tex_format;
   2663     image_create_info.extent.width = tex_width;
   2664     image_create_info.extent.height = tex_height;
   2665     image_create_info.extent.depth = 1;
   2666     image_create_info.mipLevels = 1;
   2667     image_create_info.arrayLayers = 1;
   2668     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   2669     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   2670     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
   2671     image_create_info.flags = 0;
   2672 
   2673     VkBufferCreateInfo buffer_create_info = {};
   2674     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   2675     buffer_create_info.pNext = NULL;
   2676     buffer_create_info.flags = 0;
   2677     buffer_create_info.size = 4 * 1024 * 1024;
   2678     buffer_create_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
   2679     buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   2680 
   2681     // Create an image/buffer, allocate memory, free it, and then try to bind it
   2682     {
   2683         VkImage image = VK_NULL_HANDLE;
   2684         VkBuffer buffer = VK_NULL_HANDLE;
   2685         err = vkCreateImage(device(), &image_create_info, NULL, &image);
   2686         ASSERT_VK_SUCCESS(err);
   2687         err = vkCreateBuffer(device(), &buffer_create_info, NULL, &buffer);
   2688         ASSERT_VK_SUCCESS(err);
   2689         VkMemoryRequirements image_mem_reqs = {}, buffer_mem_reqs = {};
   2690         vkGetImageMemoryRequirements(device(), image, &image_mem_reqs);
   2691         vkGetBufferMemoryRequirements(device(), buffer, &buffer_mem_reqs);
   2692 
   2693         VkMemoryAllocateInfo image_mem_alloc = {}, buffer_mem_alloc = {};
   2694         image_mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   2695         image_mem_alloc.allocationSize = image_mem_reqs.size;
   2696         pass = m_device->phy().set_memory_type(image_mem_reqs.memoryTypeBits, &image_mem_alloc, 0);
   2697         ASSERT_TRUE(pass);
   2698         buffer_mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   2699         buffer_mem_alloc.allocationSize = buffer_mem_reqs.size;
   2700         pass = m_device->phy().set_memory_type(buffer_mem_reqs.memoryTypeBits, &buffer_mem_alloc, 0);
   2701         ASSERT_TRUE(pass);
   2702 
   2703         VkDeviceMemory image_mem = VK_NULL_HANDLE, buffer_mem = VK_NULL_HANDLE;
   2704         err = vkAllocateMemory(device(), &image_mem_alloc, NULL, &image_mem);
   2705         ASSERT_VK_SUCCESS(err);
   2706         err = vkAllocateMemory(device(), &buffer_mem_alloc, NULL, &buffer_mem);
   2707         ASSERT_VK_SUCCESS(err);
   2708 
   2709         vkFreeMemory(device(), image_mem, NULL);
   2710         vkFreeMemory(device(), buffer_mem, NULL);
   2711 
   2712         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1740c601);
   2713         err = vkBindImageMemory(device(), image, image_mem, 0);
   2714         (void)err;  // This may very well return an error.
   2715         m_errorMonitor->VerifyFound();
   2716 
   2717         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1700c601);
   2718         err = vkBindBufferMemory(device(), buffer, buffer_mem, 0);
   2719         (void)err;  // This may very well return an error.
   2720         m_errorMonitor->VerifyFound();
   2721 
   2722         vkDestroyImage(m_device->device(), image, NULL);
   2723         vkDestroyBuffer(m_device->device(), buffer, NULL);
   2724     }
   2725 
   2726     // Try to bind memory to an object that already has a memory binding
   2727     {
   2728         VkImage image = VK_NULL_HANDLE;
   2729         err = vkCreateImage(device(), &image_create_info, NULL, &image);
   2730         ASSERT_VK_SUCCESS(err);
   2731         VkBuffer buffer = VK_NULL_HANDLE;
   2732         err = vkCreateBuffer(device(), &buffer_create_info, NULL, &buffer);
   2733         ASSERT_VK_SUCCESS(err);
   2734         VkMemoryRequirements image_mem_reqs = {}, buffer_mem_reqs = {};
   2735         vkGetImageMemoryRequirements(device(), image, &image_mem_reqs);
   2736         vkGetBufferMemoryRequirements(device(), buffer, &buffer_mem_reqs);
   2737         VkMemoryAllocateInfo image_alloc_info = {}, buffer_alloc_info = {};
   2738         image_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   2739         image_alloc_info.allocationSize = image_mem_reqs.size;
   2740         buffer_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   2741         buffer_alloc_info.allocationSize = buffer_mem_reqs.size;
   2742         pass = m_device->phy().set_memory_type(image_mem_reqs.memoryTypeBits, &image_alloc_info, 0);
   2743         ASSERT_TRUE(pass);
   2744         pass = m_device->phy().set_memory_type(buffer_mem_reqs.memoryTypeBits, &buffer_alloc_info, 0);
   2745         ASSERT_TRUE(pass);
   2746         VkDeviceMemory image_mem, buffer_mem;
   2747         err = vkAllocateMemory(device(), &image_alloc_info, NULL, &image_mem);
   2748         ASSERT_VK_SUCCESS(err);
   2749         err = vkAllocateMemory(device(), &buffer_alloc_info, NULL, &buffer_mem);
   2750         ASSERT_VK_SUCCESS(err);
   2751 
   2752         err = vkBindImageMemory(device(), image, image_mem, 0);
   2753         ASSERT_VK_SUCCESS(err);
   2754         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_17400828);
   2755         err = vkBindImageMemory(device(), image, image_mem, 0);
   2756         (void)err;  // This may very well return an error.
   2757         m_errorMonitor->VerifyFound();
   2758 
   2759         err = vkBindBufferMemory(device(), buffer, buffer_mem, 0);
   2760         ASSERT_VK_SUCCESS(err);
   2761         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1700080a);
   2762         err = vkBindBufferMemory(device(), buffer, buffer_mem, 0);
   2763         (void)err;  // This may very well return an error.
   2764         m_errorMonitor->VerifyFound();
   2765 
   2766         vkFreeMemory(device(), image_mem, NULL);
   2767         vkFreeMemory(device(), buffer_mem, NULL);
   2768         vkDestroyImage(device(), image, NULL);
   2769         vkDestroyBuffer(device(), buffer, NULL);
   2770     }
   2771 
   2772     // Try to bind memory to an object with an invalid memoryOffset
   2773     {
   2774         VkImage image = VK_NULL_HANDLE;
   2775         err = vkCreateImage(device(), &image_create_info, NULL, &image);
   2776         ASSERT_VK_SUCCESS(err);
   2777         VkBuffer buffer = VK_NULL_HANDLE;
   2778         err = vkCreateBuffer(device(), &buffer_create_info, NULL, &buffer);
   2779         ASSERT_VK_SUCCESS(err);
   2780         VkMemoryRequirements image_mem_reqs = {}, buffer_mem_reqs = {};
   2781         vkGetImageMemoryRequirements(device(), image, &image_mem_reqs);
   2782         vkGetBufferMemoryRequirements(device(), buffer, &buffer_mem_reqs);
   2783         VkMemoryAllocateInfo image_alloc_info = {}, buffer_alloc_info = {};
   2784         image_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   2785         // Leave some extra space for alignment wiggle room
   2786         image_alloc_info.allocationSize = image_mem_reqs.size + image_mem_reqs.alignment;
   2787         buffer_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   2788         buffer_alloc_info.allocationSize = buffer_mem_reqs.size + buffer_mem_reqs.alignment;
   2789         pass = m_device->phy().set_memory_type(image_mem_reqs.memoryTypeBits, &image_alloc_info, 0);
   2790         ASSERT_TRUE(pass);
   2791         pass = m_device->phy().set_memory_type(buffer_mem_reqs.memoryTypeBits, &buffer_alloc_info, 0);
   2792         ASSERT_TRUE(pass);
   2793         VkDeviceMemory image_mem, buffer_mem;
   2794         err = vkAllocateMemory(device(), &image_alloc_info, NULL, &image_mem);
   2795         ASSERT_VK_SUCCESS(err);
   2796         err = vkAllocateMemory(device(), &buffer_alloc_info, NULL, &buffer_mem);
   2797         ASSERT_VK_SUCCESS(err);
   2798 
   2799         // Test unaligned memory offset
   2800         {
   2801             if (image_mem_reqs.alignment > 1) {
   2802                 VkDeviceSize image_offset = 1;
   2803                 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_17400830);
   2804                 err = vkBindImageMemory(device(), image, image_mem, image_offset);
   2805                 (void)err;  // This may very well return an error.
   2806                 m_errorMonitor->VerifyFound();
   2807             }
   2808 
   2809             if (buffer_mem_reqs.alignment > 1) {
   2810                 VkDeviceSize buffer_offset = 1;
   2811                 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_17000818);
   2812                 err = vkBindBufferMemory(device(), buffer, buffer_mem, buffer_offset);
   2813                 (void)err;  // This may very well return an error.
   2814                 m_errorMonitor->VerifyFound();
   2815             }
   2816         }
   2817 
   2818         // Test memory offsets outside the memory allocation
   2819         {
   2820             VkDeviceSize image_offset =
   2821                 (image_alloc_info.allocationSize + image_mem_reqs.alignment) & ~(image_mem_reqs.alignment - 1);
   2822             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1740082c);
   2823             err = vkBindImageMemory(device(), image, image_mem, image_offset);
   2824             (void)err;  // This may very well return an error.
   2825             m_errorMonitor->VerifyFound();
   2826 
   2827             VkDeviceSize buffer_offset =
   2828                 (buffer_alloc_info.allocationSize + buffer_mem_reqs.alignment) & ~(buffer_mem_reqs.alignment - 1);
   2829             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1700080e);
   2830             err = vkBindBufferMemory(device(), buffer, buffer_mem, buffer_offset);
   2831             (void)err;  // This may very well return an error.
   2832             m_errorMonitor->VerifyFound();
   2833         }
   2834 
   2835         // Test memory offsets within the memory allocation, but which leave too little memory for
   2836         // the resource.
   2837         {
   2838             VkDeviceSize image_offset = (image_mem_reqs.size - 1) & ~(image_mem_reqs.alignment - 1);
   2839             if ((image_offset > 0) && (image_mem_reqs.size < (image_alloc_info.allocationSize - image_mem_reqs.alignment))) {
   2840                 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_17400832);
   2841                 err = vkBindImageMemory(device(), image, image_mem, image_offset);
   2842                 (void)err;  // This may very well return an error.
   2843                 m_errorMonitor->VerifyFound();
   2844             }
   2845 
   2846             VkDeviceSize buffer_offset = (buffer_mem_reqs.size - 1) & ~(buffer_mem_reqs.alignment - 1);
   2847             if (buffer_offset > 0) {
   2848                 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1700081a);
   2849                 err = vkBindBufferMemory(device(), buffer, buffer_mem, buffer_offset);
   2850                 (void)err;  // This may very well return an error.
   2851                 m_errorMonitor->VerifyFound();
   2852             }
   2853         }
   2854 
   2855         vkFreeMemory(device(), image_mem, NULL);
   2856         vkFreeMemory(device(), buffer_mem, NULL);
   2857         vkDestroyImage(device(), image, NULL);
   2858         vkDestroyBuffer(device(), buffer, NULL);
   2859     }
   2860 
   2861     // Try to bind memory to an object with an invalid memory type
   2862     {
   2863         VkImage image = VK_NULL_HANDLE;
   2864         err = vkCreateImage(device(), &image_create_info, NULL, &image);
   2865         ASSERT_VK_SUCCESS(err);
   2866         VkBuffer buffer = VK_NULL_HANDLE;
   2867         err = vkCreateBuffer(device(), &buffer_create_info, NULL, &buffer);
   2868         ASSERT_VK_SUCCESS(err);
   2869         VkMemoryRequirements image_mem_reqs = {}, buffer_mem_reqs = {};
   2870         vkGetImageMemoryRequirements(device(), image, &image_mem_reqs);
   2871         vkGetBufferMemoryRequirements(device(), buffer, &buffer_mem_reqs);
   2872         VkMemoryAllocateInfo image_alloc_info = {}, buffer_alloc_info = {};
   2873         image_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   2874         image_alloc_info.allocationSize = image_mem_reqs.size;
   2875         buffer_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   2876         buffer_alloc_info.allocationSize = buffer_mem_reqs.size;
   2877         // Create a mask of available memory types *not* supported by these resources,
   2878         // and try to use one of them.
   2879         VkPhysicalDeviceMemoryProperties memory_properties = {};
   2880         vkGetPhysicalDeviceMemoryProperties(m_device->phy().handle(), &memory_properties);
   2881         VkDeviceMemory image_mem, buffer_mem;
   2882 
   2883         uint32_t image_unsupported_mem_type_bits = ((1 << memory_properties.memoryTypeCount) - 1) & ~image_mem_reqs.memoryTypeBits;
   2884         if (image_unsupported_mem_type_bits != 0) {
   2885             pass = m_device->phy().set_memory_type(image_unsupported_mem_type_bits, &image_alloc_info, 0);
   2886             ASSERT_TRUE(pass);
   2887             err = vkAllocateMemory(device(), &image_alloc_info, NULL, &image_mem);
   2888             ASSERT_VK_SUCCESS(err);
   2889             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1740082e);
   2890             err = vkBindImageMemory(device(), image, image_mem, 0);
   2891             (void)err;  // This may very well return an error.
   2892             m_errorMonitor->VerifyFound();
   2893             vkFreeMemory(device(), image_mem, NULL);
   2894         }
   2895 
   2896         uint32_t buffer_unsupported_mem_type_bits =
   2897             ((1 << memory_properties.memoryTypeCount) - 1) & ~buffer_mem_reqs.memoryTypeBits;
   2898         if (buffer_unsupported_mem_type_bits != 0) {
   2899             pass = m_device->phy().set_memory_type(buffer_unsupported_mem_type_bits, &buffer_alloc_info, 0);
   2900             ASSERT_TRUE(pass);
   2901             err = vkAllocateMemory(device(), &buffer_alloc_info, NULL, &buffer_mem);
   2902             ASSERT_VK_SUCCESS(err);
   2903             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_17000816);
   2904             err = vkBindBufferMemory(device(), buffer, buffer_mem, 0);
   2905             (void)err;  // This may very well return an error.
   2906             m_errorMonitor->VerifyFound();
   2907             vkFreeMemory(device(), buffer_mem, NULL);
   2908         }
   2909 
   2910         vkDestroyImage(device(), image, NULL);
   2911         vkDestroyBuffer(device(), buffer, NULL);
   2912     }
   2913 
   2914     // Try to bind memory to an image created with sparse memory flags
   2915     {
   2916         VkImageCreateInfo sparse_image_create_info = image_create_info;
   2917         sparse_image_create_info.flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
   2918         VkImageFormatProperties image_format_properties = {};
   2919         err = vkGetPhysicalDeviceImageFormatProperties(m_device->phy().handle(), sparse_image_create_info.format,
   2920                                                        sparse_image_create_info.imageType, sparse_image_create_info.tiling,
   2921                                                        sparse_image_create_info.usage, sparse_image_create_info.flags,
   2922                                                        &image_format_properties);
   2923         if (!m_device->phy().features().sparseResidencyImage2D || err == VK_ERROR_FORMAT_NOT_SUPPORTED) {
   2924             // most likely means sparse formats aren't supported here; skip this test.
   2925         } else {
   2926             ASSERT_VK_SUCCESS(err);
   2927             if (image_format_properties.maxExtent.width == 0) {
   2928                 printf("             Sparse image format not supported; skipped.\n");
   2929                 return;
   2930             } else {
   2931                 VkImage sparse_image = VK_NULL_HANDLE;
   2932                 err = vkCreateImage(m_device->device(), &sparse_image_create_info, NULL, &sparse_image);
   2933                 ASSERT_VK_SUCCESS(err);
   2934                 VkMemoryRequirements sparse_mem_reqs = {};
   2935                 vkGetImageMemoryRequirements(m_device->device(), sparse_image, &sparse_mem_reqs);
   2936                 if (sparse_mem_reqs.memoryTypeBits != 0) {
   2937                     VkMemoryAllocateInfo sparse_mem_alloc = {};
   2938                     sparse_mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   2939                     sparse_mem_alloc.pNext = NULL;
   2940                     sparse_mem_alloc.allocationSize = sparse_mem_reqs.size;
   2941                     sparse_mem_alloc.memoryTypeIndex = 0;
   2942                     pass = m_device->phy().set_memory_type(sparse_mem_reqs.memoryTypeBits, &sparse_mem_alloc, 0);
   2943                     ASSERT_TRUE(pass);
   2944                     VkDeviceMemory sparse_mem = VK_NULL_HANDLE;
   2945                     err = vkAllocateMemory(m_device->device(), &sparse_mem_alloc, NULL, &sparse_mem);
   2946                     ASSERT_VK_SUCCESS(err);
   2947                     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1740082a);
   2948                     err = vkBindImageMemory(m_device->device(), sparse_image, sparse_mem, 0);
   2949                     // This may very well return an error.
   2950                     (void)err;
   2951                     m_errorMonitor->VerifyFound();
   2952                     vkFreeMemory(m_device->device(), sparse_mem, NULL);
   2953                 }
   2954                 vkDestroyImage(m_device->device(), sparse_image, NULL);
   2955             }
   2956         }
   2957     }
   2958 
   2959     // Try to bind memory to a buffer created with sparse memory flags
   2960     {
   2961         VkBufferCreateInfo sparse_buffer_create_info = buffer_create_info;
   2962         sparse_buffer_create_info.flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
   2963         if (!m_device->phy().features().sparseResidencyBuffer) {
   2964             // most likely means sparse formats aren't supported here; skip this test.
   2965         } else {
   2966             VkBuffer sparse_buffer = VK_NULL_HANDLE;
   2967             err = vkCreateBuffer(m_device->device(), &sparse_buffer_create_info, NULL, &sparse_buffer);
   2968             ASSERT_VK_SUCCESS(err);
   2969             VkMemoryRequirements sparse_mem_reqs = {};
   2970             vkGetBufferMemoryRequirements(m_device->device(), sparse_buffer, &sparse_mem_reqs);
   2971             if (sparse_mem_reqs.memoryTypeBits != 0) {
   2972                 VkMemoryAllocateInfo sparse_mem_alloc = {};
   2973                 sparse_mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   2974                 sparse_mem_alloc.pNext = NULL;
   2975                 sparse_mem_alloc.allocationSize = sparse_mem_reqs.size;
   2976                 sparse_mem_alloc.memoryTypeIndex = 0;
   2977                 pass = m_device->phy().set_memory_type(sparse_mem_reqs.memoryTypeBits, &sparse_mem_alloc, 0);
   2978                 ASSERT_TRUE(pass);
   2979                 VkDeviceMemory sparse_mem = VK_NULL_HANDLE;
   2980                 err = vkAllocateMemory(m_device->device(), &sparse_mem_alloc, NULL, &sparse_mem);
   2981                 ASSERT_VK_SUCCESS(err);
   2982                 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1700080c);
   2983                 err = vkBindBufferMemory(m_device->device(), sparse_buffer, sparse_mem, 0);
   2984                 // This may very well return an error.
   2985                 (void)err;
   2986                 m_errorMonitor->VerifyFound();
   2987                 vkFreeMemory(m_device->device(), sparse_mem, NULL);
   2988             }
   2989             vkDestroyBuffer(m_device->device(), sparse_buffer, NULL);
   2990         }
   2991     }
   2992 }
   2993 
   2994 TEST_F(VkLayerTest, BindMemoryToDestroyedObject) {
   2995     VkResult err;
   2996     bool pass;
   2997 
   2998     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1740a001);
   2999 
   3000     ASSERT_NO_FATAL_FAILURE(Init());
   3001 
   3002     // Create an image object, allocate memory, destroy the object and then try
   3003     // to bind it
   3004     VkImage image;
   3005     VkDeviceMemory mem;
   3006     VkMemoryRequirements mem_reqs;
   3007 
   3008     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
   3009     const int32_t tex_width = 32;
   3010     const int32_t tex_height = 32;
   3011 
   3012     VkImageCreateInfo image_create_info = {};
   3013     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   3014     image_create_info.pNext = NULL;
   3015     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   3016     image_create_info.format = tex_format;
   3017     image_create_info.extent.width = tex_width;
   3018     image_create_info.extent.height = tex_height;
   3019     image_create_info.extent.depth = 1;
   3020     image_create_info.mipLevels = 1;
   3021     image_create_info.arrayLayers = 1;
   3022     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   3023     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
   3024     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
   3025     image_create_info.flags = 0;
   3026 
   3027     VkMemoryAllocateInfo mem_alloc = {};
   3028     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   3029     mem_alloc.pNext = NULL;
   3030     mem_alloc.allocationSize = 0;
   3031     mem_alloc.memoryTypeIndex = 0;
   3032 
   3033     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
   3034     ASSERT_VK_SUCCESS(err);
   3035 
   3036     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
   3037 
   3038     mem_alloc.allocationSize = mem_reqs.size;
   3039     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
   3040     ASSERT_TRUE(pass);
   3041 
   3042     // Allocate memory
   3043     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
   3044     ASSERT_VK_SUCCESS(err);
   3045 
   3046     // Introduce validation failure, destroy Image object before binding
   3047     vkDestroyImage(m_device->device(), image, NULL);
   3048     ASSERT_VK_SUCCESS(err);
   3049 
   3050     // Now Try to bind memory to this destroyed object
   3051     err = vkBindImageMemory(m_device->device(), image, mem, 0);
   3052     // This may very well return an error.
   3053     (void)err;
   3054 
   3055     m_errorMonitor->VerifyFound();
   3056 
   3057     vkFreeMemory(m_device->device(), mem, NULL);
   3058 }
   3059 
   3060 TEST_F(VkLayerTest, ExceedMemoryAllocationCount) {
   3061     VkResult err = VK_SUCCESS;
   3062     const int max_mems = 32;
   3063     VkDeviceMemory mems[max_mems + 1];
   3064 
   3065     if (!EnableDeviceProfileLayer()) return;
   3066 
   3067     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   3068 
   3069     PFN_vkSetPhysicalDeviceLimitsEXT fpvkSetPhysicalDeviceLimitsEXT =
   3070         (PFN_vkSetPhysicalDeviceLimitsEXT)vkGetInstanceProcAddr(instance(), "vkSetPhysicalDeviceLimitsEXT");
   3071     PFN_vkGetOriginalPhysicalDeviceLimitsEXT fpvkGetOriginalPhysicalDeviceLimitsEXT =
   3072         (PFN_vkGetOriginalPhysicalDeviceLimitsEXT)vkGetInstanceProcAddr(instance(), "vkGetOriginalPhysicalDeviceLimitsEXT");
   3073 
   3074     if (!(fpvkSetPhysicalDeviceLimitsEXT) || !(fpvkGetOriginalPhysicalDeviceLimitsEXT)) {
   3075         printf("             Can't find device_profile_api functions; skipped.\n");
   3076         return;
   3077     }
   3078     VkPhysicalDeviceProperties props;
   3079     fpvkGetOriginalPhysicalDeviceLimitsEXT(gpu(), &props.limits);
   3080     if (props.limits.maxMemoryAllocationCount > max_mems) {
   3081         props.limits.maxMemoryAllocationCount = max_mems;
   3082         fpvkSetPhysicalDeviceLimitsEXT(gpu(), &props.limits);
   3083     }
   3084     ASSERT_NO_FATAL_FAILURE(InitState());
   3085     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_16c004f8);
   3086 
   3087     VkMemoryAllocateInfo mem_alloc = {};
   3088     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   3089     mem_alloc.pNext = NULL;
   3090     mem_alloc.memoryTypeIndex = 0;
   3091     mem_alloc.allocationSize = 4;
   3092 
   3093     int i;
   3094     for (i = 0; i <= max_mems; i++) {
   3095         err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mems[i]);
   3096         if (err != VK_SUCCESS) {
   3097             break;
   3098         }
   3099     }
   3100     m_errorMonitor->VerifyFound();
   3101 
   3102     for (int j = 0; j < i; j++) {
   3103         vkFreeMemory(m_device->device(), mems[j], NULL);
   3104     }
   3105 }
   3106 
   3107 TEST_F(VkLayerTest, CreatePipelineBadVertexAttributeFormat) {
   3108     TEST_DESCRIPTION("Test that pipeline validation catches invalid vertex attribute formats");
   3109 
   3110     ASSERT_NO_FATAL_FAILURE(Init());
   3111     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   3112 
   3113     VkVertexInputBindingDescription input_binding;
   3114     memset(&input_binding, 0, sizeof(input_binding));
   3115 
   3116     VkVertexInputAttributeDescription input_attribs;
   3117     memset(&input_attribs, 0, sizeof(input_attribs));
   3118 
   3119     // Pick a really bad format for this purpose and make sure it should fail
   3120     input_attribs.format = VK_FORMAT_BC2_UNORM_BLOCK;
   3121     VkFormatProperties format_props = m_device->format_properties(input_attribs.format);
   3122     if ((format_props.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) != 0) {
   3123         printf("             Format unsuitable for test; skipped.\n");
   3124         return;
   3125     }
   3126 
   3127     input_attribs.location = 0;
   3128     char const *vsSource =
   3129         "#version 450\n"
   3130         "\n"
   3131         "void main(){\n"
   3132         "   gl_Position = vec4(1);\n"
   3133         "}\n";
   3134     char const *fsSource =
   3135         "#version 450\n"
   3136         "\n"
   3137         "layout(location=0) out vec4 color;\n"
   3138         "void main(){\n"
   3139         "   color = vec4(1);\n"
   3140         "}\n";
   3141 
   3142     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_14a004de);
   3143     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   3144     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   3145 
   3146     VkPipelineObj pipe(m_device);
   3147     pipe.AddDefaultColorAttachment();
   3148     pipe.AddShader(&vs);
   3149     pipe.AddShader(&fs);
   3150 
   3151     pipe.AddVertexInputBindings(&input_binding, 1);
   3152     pipe.AddVertexInputAttribs(&input_attribs, 1);
   3153 
   3154     VkDescriptorSetObj descriptorSet(m_device);
   3155     descriptorSet.AppendDummy();
   3156     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   3157 
   3158     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   3159 
   3160     m_errorMonitor->VerifyFound();
   3161 }
   3162 
   3163 TEST_F(VkLayerTest, ImageSampleCounts) {
   3164     TEST_DESCRIPTION("Use bad sample counts in image transfer calls to trigger validation errors.");
   3165     ASSERT_NO_FATAL_FAILURE(Init(nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
   3166 
   3167     VkMemoryPropertyFlags reqs = 0;
   3168     VkImageCreateInfo image_create_info = {};
   3169     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   3170     image_create_info.pNext = NULL;
   3171     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   3172     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
   3173     image_create_info.extent.width = 256;
   3174     image_create_info.extent.height = 256;
   3175     image_create_info.extent.depth = 1;
   3176     image_create_info.mipLevels = 1;
   3177     image_create_info.arrayLayers = 1;
   3178     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   3179     image_create_info.flags = 0;
   3180 
   3181     VkImageBlit blit_region = {};
   3182     blit_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   3183     blit_region.srcSubresource.baseArrayLayer = 0;
   3184     blit_region.srcSubresource.layerCount = 1;
   3185     blit_region.srcSubresource.mipLevel = 0;
   3186     blit_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   3187     blit_region.dstSubresource.baseArrayLayer = 0;
   3188     blit_region.dstSubresource.layerCount = 1;
   3189     blit_region.dstSubresource.mipLevel = 0;
   3190     blit_region.srcOffsets[0] = {0, 0, 0};
   3191     blit_region.srcOffsets[1] = {256, 256, 1};
   3192     blit_region.dstOffsets[0] = {0, 0, 0};
   3193     blit_region.dstOffsets[1] = {128, 128, 1};
   3194 
   3195     // Create two images, the source with sampleCount = 4, and attempt to blit
   3196     // between them
   3197     {
   3198         image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
   3199         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   3200         VkImageObj src_image(m_device);
   3201         src_image.init(&image_create_info);
   3202         src_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
   3203         image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   3204         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   3205         VkImageObj dst_image(m_device);
   3206         dst_image.init(&image_create_info);
   3207         dst_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
   3208         m_commandBuffer->begin();
   3209         // TODO: These 2 VUs are redundant - expect one of them to go away
   3210         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001d2);
   3211         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001c8);
   3212         vkCmdBlitImage(m_commandBuffer->handle(), src_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_image.handle(),
   3213                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit_region, VK_FILTER_NEAREST);
   3214         m_errorMonitor->VerifyFound();
   3215         m_commandBuffer->end();
   3216     }
   3217 
   3218     // Create two images, the dest with sampleCount = 4, and attempt to blit
   3219     // between them
   3220     {
   3221         image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   3222         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   3223         VkImageObj src_image(m_device);
   3224         src_image.init(&image_create_info);
   3225         src_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
   3226         image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
   3227         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   3228         VkImageObj dst_image(m_device);
   3229         dst_image.init(&image_create_info);
   3230         dst_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
   3231         m_commandBuffer->begin();
   3232         // TODO: These 2 VUs are redundant - expect one of them to go away
   3233         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001d4);
   3234         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001c8);
   3235         vkCmdBlitImage(m_commandBuffer->handle(), src_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_image.handle(),
   3236                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit_region, VK_FILTER_NEAREST);
   3237         m_errorMonitor->VerifyFound();
   3238         m_commandBuffer->end();
   3239     }
   3240 
   3241     VkBufferImageCopy copy_region = {};
   3242     copy_region.bufferRowLength = 128;
   3243     copy_region.bufferImageHeight = 128;
   3244     copy_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   3245     copy_region.imageSubresource.layerCount = 1;
   3246     copy_region.imageExtent.height = 64;
   3247     copy_region.imageExtent.width = 64;
   3248     copy_region.imageExtent.depth = 1;
   3249 
   3250     // Create src buffer and dst image with sampleCount = 4 and attempt to copy
   3251     // buffer to image
   3252     {
   3253         vk_testing::Buffer src_buffer;
   3254         src_buffer.init_as_src(*m_device, 128 * 128 * 4, reqs);
   3255         image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
   3256         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   3257         VkImageObj dst_image(m_device);
   3258         dst_image.init(&image_create_info);
   3259         dst_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
   3260         m_commandBuffer->begin();
   3261         m_errorMonitor->SetDesiredFailureMsg(
   3262             VK_DEBUG_REPORT_ERROR_BIT_EXT,
   3263             "was created with a sample count of VK_SAMPLE_COUNT_4_BIT but must be VK_SAMPLE_COUNT_1_BIT");
   3264         vkCmdCopyBufferToImage(m_commandBuffer->handle(), src_buffer.handle(), dst_image.handle(),
   3265                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copy_region);
   3266         m_errorMonitor->VerifyFound();
   3267         m_commandBuffer->end();
   3268     }
   3269 
   3270     // Create dst buffer and src image with sampleCount = 4 and attempt to copy
   3271     // image to buffer
   3272     {
   3273         vk_testing::Buffer dst_buffer;
   3274         dst_buffer.init_as_dst(*m_device, 128 * 128 * 4, reqs);
   3275         image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
   3276         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   3277         vk_testing::Image src_image;
   3278         src_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
   3279         m_commandBuffer->begin();
   3280         m_errorMonitor->SetDesiredFailureMsg(
   3281             VK_DEBUG_REPORT_ERROR_BIT_EXT,
   3282             "was created with a sample count of VK_SAMPLE_COUNT_4_BIT but must be VK_SAMPLE_COUNT_1_BIT");
   3283         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), src_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   3284                                dst_buffer.handle(), 1, &copy_region);
   3285         m_errorMonitor->VerifyFound();
   3286         m_commandBuffer->end();
   3287     }
   3288 }
   3289 
   3290 TEST_F(VkLayerTest, BlitImageFormatTypes) {
   3291     ASSERT_NO_FATAL_FAILURE(Init());
   3292 
   3293     VkFormat f_unsigned = VK_FORMAT_R8G8B8A8_UINT;
   3294     VkFormat f_signed = VK_FORMAT_R8G8B8A8_SINT;
   3295     VkFormat f_float = VK_FORMAT_R32_SFLOAT;
   3296     VkFormat f_depth = VK_FORMAT_D32_SFLOAT_S8_UINT;
   3297     VkFormat f_depth2 = VK_FORMAT_D32_SFLOAT;
   3298 
   3299     if (!ImageFormatIsSupported(gpu(), f_unsigned, VK_IMAGE_TILING_OPTIMAL) ||
   3300         !ImageFormatIsSupported(gpu(), f_signed, VK_IMAGE_TILING_OPTIMAL) ||
   3301         !ImageFormatIsSupported(gpu(), f_float, VK_IMAGE_TILING_OPTIMAL) ||
   3302         !ImageFormatIsSupported(gpu(), f_depth, VK_IMAGE_TILING_OPTIMAL) ||
   3303         !ImageFormatIsSupported(gpu(), f_depth2, VK_IMAGE_TILING_OPTIMAL)) {
   3304         printf("             Requested formats not supported - BlitImageFormatTypes skipped.\n");
   3305         return;
   3306     }
   3307 
   3308     // Note any missing feature bits
   3309     bool usrc = !ImageFormatAndFeaturesSupported(gpu(), f_unsigned, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_SRC_BIT);
   3310     bool udst = !ImageFormatAndFeaturesSupported(gpu(), f_unsigned, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_DST_BIT);
   3311     bool ssrc = !ImageFormatAndFeaturesSupported(gpu(), f_signed, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_SRC_BIT);
   3312     bool sdst = !ImageFormatAndFeaturesSupported(gpu(), f_signed, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_DST_BIT);
   3313     bool fsrc = !ImageFormatAndFeaturesSupported(gpu(), f_float, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_SRC_BIT);
   3314     bool fdst = !ImageFormatAndFeaturesSupported(gpu(), f_float, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_DST_BIT);
   3315     bool d1dst = !ImageFormatAndFeaturesSupported(gpu(), f_depth, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_DST_BIT);
   3316     bool d2src = !ImageFormatAndFeaturesSupported(gpu(), f_depth2, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_SRC_BIT);
   3317 
   3318     VkImageObj unsigned_image(m_device);
   3319     unsigned_image.Init(64, 64, 1, f_unsigned, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
   3320                         VK_IMAGE_TILING_OPTIMAL, 0);
   3321     ASSERT_TRUE(unsigned_image.initialized());
   3322     unsigned_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
   3323 
   3324     VkImageObj signed_image(m_device);
   3325     signed_image.Init(64, 64, 1, f_signed, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
   3326                       VK_IMAGE_TILING_OPTIMAL, 0);
   3327     ASSERT_TRUE(signed_image.initialized());
   3328     signed_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
   3329 
   3330     VkImageObj float_image(m_device);
   3331     float_image.Init(64, 64, 1, f_float, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL,
   3332                      0);
   3333     ASSERT_TRUE(float_image.initialized());
   3334     float_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
   3335 
   3336     VkImageObj depth_image(m_device);
   3337     depth_image.Init(64, 64, 1, f_depth, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL,
   3338                      0);
   3339     ASSERT_TRUE(depth_image.initialized());
   3340     depth_image.SetLayout(VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_LAYOUT_GENERAL);
   3341 
   3342     VkImageObj depth_image2(m_device);
   3343     depth_image2.Init(64, 64, 1, f_depth2, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
   3344                       VK_IMAGE_TILING_OPTIMAL, 0);
   3345     ASSERT_TRUE(depth_image2.initialized());
   3346     depth_image2.SetLayout(VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_LAYOUT_GENERAL);
   3347 
   3348     VkImageBlit blitRegion = {};
   3349     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   3350     blitRegion.srcSubresource.baseArrayLayer = 0;
   3351     blitRegion.srcSubresource.layerCount = 1;
   3352     blitRegion.srcSubresource.mipLevel = 0;
   3353     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   3354     blitRegion.dstSubresource.baseArrayLayer = 0;
   3355     blitRegion.dstSubresource.layerCount = 1;
   3356     blitRegion.dstSubresource.mipLevel = 0;
   3357     blitRegion.srcOffsets[0] = {0, 0, 0};
   3358     blitRegion.srcOffsets[1] = {64, 64, 1};
   3359     blitRegion.dstOffsets[0] = {0, 0, 0};
   3360     blitRegion.dstOffsets[1] = {32, 32, 1};
   3361 
   3362     m_commandBuffer->begin();
   3363 
   3364     // Unsigned int vs not an int
   3365     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001cc);
   3366     if (usrc) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001b4);
   3367     if (fdst) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001be);
   3368     vkCmdBlitImage(m_commandBuffer->handle(), unsigned_image.image(), unsigned_image.Layout(), float_image.image(),
   3369                    float_image.Layout(), 1, &blitRegion, VK_FILTER_NEAREST);
   3370     m_errorMonitor->VerifyFound();
   3371     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001cc);
   3372     if (fsrc) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001b4);
   3373     if (udst) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001be);
   3374     vkCmdBlitImage(m_commandBuffer->handle(), float_image.image(), float_image.Layout(), unsigned_image.image(),
   3375                    unsigned_image.Layout(), 1, &blitRegion, VK_FILTER_NEAREST);
   3376     m_errorMonitor->VerifyFound();
   3377 
   3378     // Signed int vs not an int,
   3379     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001ca);
   3380     if (ssrc) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001b4);
   3381     if (fdst) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001be);
   3382     vkCmdBlitImage(m_commandBuffer->handle(), signed_image.image(), signed_image.Layout(), float_image.image(),
   3383                    float_image.Layout(), 1, &blitRegion, VK_FILTER_NEAREST);
   3384     m_errorMonitor->VerifyFound();
   3385     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001ca);
   3386     if (fsrc) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001b4);
   3387     if (sdst) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001be);
   3388     vkCmdBlitImage(m_commandBuffer->handle(), float_image.image(), float_image.Layout(), signed_image.image(),
   3389                    signed_image.Layout(), 1, &blitRegion, VK_FILTER_NEAREST);
   3390     m_errorMonitor->VerifyFound();
   3391 
   3392     // Signed vs Unsigned int - generates both VUs
   3393     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001ca);
   3394     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001cc);
   3395     if (ssrc) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001b4);
   3396     if (udst) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001be);
   3397     vkCmdBlitImage(m_commandBuffer->handle(), signed_image.image(), signed_image.Layout(), unsigned_image.image(),
   3398                    unsigned_image.Layout(), 1, &blitRegion, VK_FILTER_NEAREST);
   3399     m_errorMonitor->VerifyFound();
   3400     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001ca);
   3401     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001cc);
   3402     if (usrc) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001b4);
   3403     if (sdst) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001be);
   3404     vkCmdBlitImage(m_commandBuffer->handle(), unsigned_image.image(), unsigned_image.Layout(), signed_image.image(),
   3405                    signed_image.Layout(), 1, &blitRegion, VK_FILTER_NEAREST);
   3406     m_errorMonitor->VerifyFound();
   3407 
   3408     // Depth vs any non-identical depth format
   3409     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001ce);
   3410     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
   3411     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
   3412     if (d2src) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001b4);
   3413     if (d1dst) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001be);
   3414     vkCmdBlitImage(m_commandBuffer->handle(), depth_image2.image(), depth_image2.Layout(), depth_image.image(),
   3415                    depth_image.Layout(), 1, &blitRegion, VK_FILTER_NEAREST);
   3416     m_errorMonitor->VerifyFound();
   3417 
   3418     m_commandBuffer->end();
   3419 }
   3420 
   3421 TEST_F(VkLayerTest, BlitImageFilters) {
   3422     bool cubic_support = false;
   3423     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   3424     if (DeviceExtensionSupported(gpu(), nullptr, "VK_IMG_filter_cubic")) {
   3425         m_device_extension_names.push_back("VK_IMG_filter_cubic");
   3426         cubic_support = true;
   3427     }
   3428     ASSERT_NO_FATAL_FAILURE(InitState());
   3429 
   3430     VkFormat fmt = VK_FORMAT_R8_UINT;
   3431     if (!ImageFormatIsSupported(gpu(), fmt, VK_IMAGE_TILING_OPTIMAL)) {
   3432         printf("             No R8_UINT format support - BlitImageFilters skipped.\n");
   3433         return;
   3434     }
   3435 
   3436     // Create 2D images
   3437     VkImageObj src2D(m_device);
   3438     VkImageObj dst2D(m_device);
   3439     src2D.Init(64, 64, 1, fmt, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   3440     dst2D.Init(64, 64, 1, fmt, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   3441     ASSERT_TRUE(src2D.initialized());
   3442     ASSERT_TRUE(dst2D.initialized());
   3443     src2D.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
   3444     dst2D.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
   3445 
   3446     // Create 3D image
   3447     VkImageCreateInfo ci;
   3448     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   3449     ci.pNext = NULL;
   3450     ci.flags = 0;
   3451     ci.imageType = VK_IMAGE_TYPE_3D;
   3452     ci.format = fmt;
   3453     ci.extent = {64, 64, 4};
   3454     ci.mipLevels = 1;
   3455     ci.arrayLayers = 1;
   3456     ci.samples = VK_SAMPLE_COUNT_1_BIT;
   3457     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
   3458     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   3459     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   3460     ci.queueFamilyIndexCount = 0;
   3461     ci.pQueueFamilyIndices = NULL;
   3462     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   3463 
   3464     VkImageObj src3D(m_device);
   3465     src3D.init(&ci);
   3466     ASSERT_TRUE(src3D.initialized());
   3467 
   3468     VkImageBlit blitRegion = {};
   3469     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   3470     blitRegion.srcSubresource.baseArrayLayer = 0;
   3471     blitRegion.srcSubresource.layerCount = 1;
   3472     blitRegion.srcSubresource.mipLevel = 0;
   3473     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   3474     blitRegion.dstSubresource.baseArrayLayer = 0;
   3475     blitRegion.dstSubresource.layerCount = 1;
   3476     blitRegion.dstSubresource.mipLevel = 0;
   3477     blitRegion.srcOffsets[0] = {0, 0, 0};
   3478     blitRegion.srcOffsets[1] = {48, 48, 1};
   3479     blitRegion.dstOffsets[0] = {0, 0, 0};
   3480     blitRegion.dstOffsets[1] = {64, 64, 1};
   3481 
   3482     m_commandBuffer->begin();
   3483 
   3484     // UINT format should not support linear filtering, but check to be sure
   3485     if (!ImageFormatAndFeaturesSupported(gpu(), fmt, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)) {
   3486         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001d6);
   3487         vkCmdBlitImage(m_commandBuffer->handle(), src2D.image(), src2D.Layout(), dst2D.image(), dst2D.Layout(), 1, &blitRegion,
   3488                        VK_FILTER_LINEAR);
   3489         m_errorMonitor->VerifyFound();
   3490     }
   3491 
   3492     if (cubic_support && !ImageFormatAndFeaturesSupported(gpu(), fmt, VK_IMAGE_TILING_OPTIMAL,
   3493                                                           VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG)) {
   3494         // Invalid filter CUBIC_IMG
   3495         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001d8);
   3496         vkCmdBlitImage(m_commandBuffer->handle(), src3D.image(), src3D.Layout(), dst2D.image(), dst2D.Layout(), 1, &blitRegion,
   3497                        VK_FILTER_CUBIC_IMG);
   3498         m_errorMonitor->VerifyFound();
   3499 
   3500         // Invalid filter CUBIC_IMG + invalid 2D source image
   3501         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001d8);
   3502         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001da);
   3503         vkCmdBlitImage(m_commandBuffer->handle(), src2D.image(), src2D.Layout(), dst2D.image(), dst2D.Layout(), 1, &blitRegion,
   3504                        VK_FILTER_CUBIC_IMG);
   3505         m_errorMonitor->VerifyFound();
   3506     }
   3507 
   3508     m_commandBuffer->end();
   3509 }
   3510 
   3511 TEST_F(VkLayerTest, BlitImageLayout) {
   3512     TEST_DESCRIPTION("Incorrect vkCmdBlitImage layouts");
   3513 
   3514     ASSERT_NO_FATAL_FAILURE(Init(nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
   3515 
   3516     VkResult err;
   3517     VkFormat fmt = VK_FORMAT_R8G8B8A8_UNORM;
   3518 
   3519     VkSubmitInfo submit_info = {};
   3520     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   3521     submit_info.commandBufferCount = 1;
   3522     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   3523 
   3524     // Create images
   3525     VkImageObj img_src_transfer(m_device);
   3526     VkImageObj img_dst_transfer(m_device);
   3527     VkImageObj img_general(m_device);
   3528     VkImageObj img_color(m_device);
   3529 
   3530     img_src_transfer.InitNoLayout(64, 64, 1, fmt, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
   3531                                   VK_IMAGE_TILING_OPTIMAL, 0);
   3532     img_dst_transfer.InitNoLayout(64, 64, 1, fmt, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
   3533                                   VK_IMAGE_TILING_OPTIMAL, 0);
   3534     img_general.InitNoLayout(64, 64, 1, fmt, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
   3535                              VK_IMAGE_TILING_OPTIMAL, 0);
   3536     img_color.InitNoLayout(64, 64, 1, fmt,
   3537                            VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
   3538                            VK_IMAGE_TILING_OPTIMAL, 0);
   3539 
   3540     ASSERT_TRUE(img_src_transfer.initialized());
   3541     ASSERT_TRUE(img_dst_transfer.initialized());
   3542     ASSERT_TRUE(img_general.initialized());
   3543     ASSERT_TRUE(img_color.initialized());
   3544 
   3545     img_src_transfer.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
   3546     img_dst_transfer.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
   3547     img_general.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
   3548     img_color.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
   3549 
   3550     VkImageBlit blit_region = {};
   3551     blit_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   3552     blit_region.srcSubresource.baseArrayLayer = 0;
   3553     blit_region.srcSubresource.layerCount = 1;
   3554     blit_region.srcSubresource.mipLevel = 0;
   3555     blit_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   3556     blit_region.dstSubresource.baseArrayLayer = 0;
   3557     blit_region.dstSubresource.layerCount = 1;
   3558     blit_region.dstSubresource.mipLevel = 0;
   3559     blit_region.srcOffsets[0] = {0, 0, 0};
   3560     blit_region.srcOffsets[1] = {48, 48, 1};
   3561     blit_region.dstOffsets[0] = {0, 0, 0};
   3562     blit_region.dstOffsets[1] = {64, 64, 1};
   3563 
   3564     m_commandBuffer->begin();
   3565 
   3566     // Illegal srcImageLayout
   3567     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001bc);
   3568     vkCmdBlitImage(m_commandBuffer->handle(), img_src_transfer.image(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   3569                    img_dst_transfer.image(), img_dst_transfer.Layout(), 1, &blit_region, VK_FILTER_LINEAR);
   3570     m_errorMonitor->VerifyFound();
   3571 
   3572     // Illegal destImageLayout
   3573     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001c6);
   3574     vkCmdBlitImage(m_commandBuffer->handle(), img_src_transfer.image(), img_src_transfer.Layout(), img_dst_transfer.image(),
   3575                    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, &blit_region, VK_FILTER_LINEAR);
   3576 
   3577     m_commandBuffer->end();
   3578     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   3579     m_errorMonitor->VerifyFound();
   3580 
   3581     err = vkQueueWaitIdle(m_device->m_queue);
   3582     ASSERT_VK_SUCCESS(err);
   3583 
   3584     m_commandBuffer->reset(0);
   3585     m_commandBuffer->begin();
   3586 
   3587     // Source image in invalid layout at start of the CB
   3588     m_errorMonitor->SetDesiredFailureMsg(
   3589         VK_DEBUG_REPORT_ERROR_BIT_EXT, "layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL when first use is VK_IMAGE_LAYOUT_GENERAL");
   3590     vkCmdBlitImage(m_commandBuffer->handle(), img_src_transfer.image(), img_src_transfer.Layout(), img_color.image(),
   3591                    VK_IMAGE_LAYOUT_GENERAL, 1, &blit_region, VK_FILTER_LINEAR);
   3592 
   3593     m_commandBuffer->end();
   3594     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   3595     m_errorMonitor->VerifyFound();
   3596     err = vkQueueWaitIdle(m_device->m_queue);
   3597     ASSERT_VK_SUCCESS(err);
   3598 
   3599     m_commandBuffer->reset(0);
   3600     m_commandBuffer->begin();
   3601 
   3602     // Destination image in invalid layout at start of the CB
   3603     m_errorMonitor->SetDesiredFailureMsg(
   3604         VK_DEBUG_REPORT_ERROR_BIT_EXT, "layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL when first use is VK_IMAGE_LAYOUT_GENERAL");
   3605     vkCmdBlitImage(m_commandBuffer->handle(), img_color.image(), VK_IMAGE_LAYOUT_GENERAL, img_dst_transfer.image(),
   3606                    img_dst_transfer.Layout(), 1, &blit_region, VK_FILTER_LINEAR);
   3607 
   3608     m_commandBuffer->end();
   3609     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   3610     m_errorMonitor->VerifyFound();
   3611     err = vkQueueWaitIdle(m_device->m_queue);
   3612     ASSERT_VK_SUCCESS(err);
   3613 
   3614     // Source image in invalid layout in the middle of CB
   3615     m_commandBuffer->reset(0);
   3616     m_commandBuffer->begin();
   3617 
   3618     VkImageMemoryBarrier img_barrier = {};
   3619     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
   3620     img_barrier.pNext = nullptr;
   3621     img_barrier.srcAccessMask = 0;
   3622     img_barrier.dstAccessMask = 0;
   3623     img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
   3624     img_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   3625     img_barrier.image = img_general.handle();
   3626     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   3627     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   3628     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   3629     img_barrier.subresourceRange.baseArrayLayer = 0;
   3630     img_barrier.subresourceRange.baseMipLevel = 0;
   3631     img_barrier.subresourceRange.layerCount = 1;
   3632     img_barrier.subresourceRange.levelCount = 1;
   3633 
   3634     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0,
   3635                          nullptr, 0, nullptr, 1, &img_barrier);
   3636 
   3637     m_errorMonitor->SetDesiredFailureMsg(
   3638         VK_DEBUG_REPORT_ERROR_BIT_EXT,
   3639         "layout VK_IMAGE_LAYOUT_GENERAL that doesn't match the actual current layout VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL");
   3640     vkCmdBlitImage(m_commandBuffer->handle(), img_general.image(), VK_IMAGE_LAYOUT_GENERAL, img_dst_transfer.image(),
   3641                    img_dst_transfer.Layout(), 1, &blit_region, VK_FILTER_LINEAR);
   3642 
   3643     m_commandBuffer->end();
   3644     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   3645     m_errorMonitor->VerifyFound();
   3646     err = vkQueueWaitIdle(m_device->m_queue);
   3647     ASSERT_VK_SUCCESS(err);
   3648 
   3649     // Destination image in invalid layout in the middle of CB
   3650     m_commandBuffer->reset(0);
   3651     m_commandBuffer->begin();
   3652 
   3653     img_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   3654     img_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   3655     img_barrier.image = img_dst_transfer.handle();
   3656 
   3657     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0,
   3658                          nullptr, 0, nullptr, 1, &img_barrier);
   3659 
   3660     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   3661                                          "layout VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL that doesn't match the actual current layout "
   3662                                          "VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL");
   3663     vkCmdBlitImage(m_commandBuffer->handle(), img_src_transfer.image(), img_src_transfer.Layout(), img_dst_transfer.image(),
   3664                    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit_region, VK_FILTER_LINEAR);
   3665 
   3666     m_commandBuffer->end();
   3667     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   3668     m_errorMonitor->VerifyFound();
   3669     err = vkQueueWaitIdle(m_device->m_queue);
   3670     ASSERT_VK_SUCCESS(err);
   3671 }
   3672 
   3673 TEST_F(VkLayerTest, BlitImageOffsets) {
   3674     ASSERT_NO_FATAL_FAILURE(Init());
   3675 
   3676     VkFormat fmt = VK_FORMAT_R8G8B8A8_UNORM;
   3677     if (!ImageFormatAndFeaturesSupported(gpu(), fmt, VK_IMAGE_TILING_OPTIMAL,
   3678                                          VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT)) {
   3679         printf("             No blit feature bits - BlitImageOffsets skipped.\n");
   3680         return;
   3681     }
   3682 
   3683     VkImageCreateInfo ci;
   3684     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   3685     ci.pNext = NULL;
   3686     ci.flags = 0;
   3687     ci.imageType = VK_IMAGE_TYPE_1D;
   3688     ci.format = fmt;
   3689     ci.extent = {64, 1, 1};
   3690     ci.mipLevels = 1;
   3691     ci.arrayLayers = 1;
   3692     ci.samples = VK_SAMPLE_COUNT_1_BIT;
   3693     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
   3694     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   3695     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   3696     ci.queueFamilyIndexCount = 0;
   3697     ci.pQueueFamilyIndices = NULL;
   3698     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   3699 
   3700     VkImageObj image_1D(m_device);
   3701     image_1D.init(&ci);
   3702     ASSERT_TRUE(image_1D.initialized());
   3703 
   3704     ci.imageType = VK_IMAGE_TYPE_2D;
   3705     ci.extent = {64, 64, 1};
   3706     VkImageObj image_2D(m_device);
   3707     image_2D.init(&ci);
   3708     ASSERT_TRUE(image_2D.initialized());
   3709 
   3710     ci.imageType = VK_IMAGE_TYPE_3D;
   3711     ci.extent = {64, 64, 64};
   3712     VkImageObj image_3D(m_device);
   3713     image_3D.init(&ci);
   3714     ASSERT_TRUE(image_3D.initialized());
   3715 
   3716     VkImageBlit blit_region = {};
   3717     blit_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   3718     blit_region.srcSubresource.baseArrayLayer = 0;
   3719     blit_region.srcSubresource.layerCount = 1;
   3720     blit_region.srcSubresource.mipLevel = 0;
   3721     blit_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   3722     blit_region.dstSubresource.baseArrayLayer = 0;
   3723     blit_region.dstSubresource.layerCount = 1;
   3724     blit_region.dstSubresource.mipLevel = 0;
   3725 
   3726     m_commandBuffer->begin();
   3727 
   3728     // 1D, with src/dest y offsets other than (0,1)
   3729     blit_region.srcOffsets[0] = {0, 1, 0};
   3730     blit_region.srcOffsets[1] = {30, 1, 1};
   3731     blit_region.dstOffsets[0] = {32, 0, 0};
   3732     blit_region.dstOffsets[1] = {64, 1, 1};
   3733     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001ea);
   3734     vkCmdBlitImage(m_commandBuffer->handle(), image_1D.image(), image_1D.Layout(), image_1D.image(), image_1D.Layout(), 1,
   3735                    &blit_region, VK_FILTER_NEAREST);
   3736     m_errorMonitor->VerifyFound();
   3737 
   3738     blit_region.srcOffsets[0] = {0, 0, 0};
   3739     blit_region.dstOffsets[0] = {32, 1, 0};
   3740     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001f4);
   3741     vkCmdBlitImage(m_commandBuffer->handle(), image_1D.image(), image_1D.Layout(), image_1D.image(), image_1D.Layout(), 1,
   3742                    &blit_region, VK_FILTER_NEAREST);
   3743     m_errorMonitor->VerifyFound();
   3744 
   3745     // 2D, with src/dest z offsets other than (0,1)
   3746     blit_region.srcOffsets[0] = {0, 0, 1};
   3747     blit_region.srcOffsets[1] = {24, 31, 1};
   3748     blit_region.dstOffsets[0] = {32, 32, 0};
   3749     blit_region.dstOffsets[1] = {64, 64, 1};
   3750     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001ee);
   3751     vkCmdBlitImage(m_commandBuffer->handle(), image_2D.image(), image_2D.Layout(), image_2D.image(), image_2D.Layout(), 1,
   3752                    &blit_region, VK_FILTER_NEAREST);
   3753     m_errorMonitor->VerifyFound();
   3754 
   3755     blit_region.srcOffsets[0] = {0, 0, 0};
   3756     blit_region.dstOffsets[0] = {32, 32, 1};
   3757     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001f8);
   3758     vkCmdBlitImage(m_commandBuffer->handle(), image_2D.image(), image_2D.Layout(), image_2D.image(), image_2D.Layout(), 1,
   3759                    &blit_region, VK_FILTER_NEAREST);
   3760     m_errorMonitor->VerifyFound();
   3761 
   3762     // Source offsets exceeding source image dimensions
   3763     blit_region.srcOffsets[0] = {0, 0, 0};
   3764     blit_region.srcOffsets[1] = {65, 64, 1};  // src x
   3765     blit_region.dstOffsets[0] = {0, 0, 0};
   3766     blit_region.dstOffsets[1] = {64, 64, 1};
   3767     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001e6);  // x
   3768     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001ae);  // src region
   3769     vkCmdBlitImage(m_commandBuffer->handle(), image_3D.image(), image_3D.Layout(), image_2D.image(), image_2D.Layout(), 1,
   3770                    &blit_region, VK_FILTER_NEAREST);
   3771     m_errorMonitor->VerifyFound();
   3772 
   3773     blit_region.srcOffsets[1] = {64, 65, 1};                                                         // src y
   3774     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001e8);  // y
   3775     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001ae);  // src region
   3776     vkCmdBlitImage(m_commandBuffer->handle(), image_3D.image(), image_3D.Layout(), image_2D.image(), image_2D.Layout(), 1,
   3777                    &blit_region, VK_FILTER_NEAREST);
   3778     m_errorMonitor->VerifyFound();
   3779 
   3780     blit_region.srcOffsets[0] = {0, 0, 65};  // src z
   3781     blit_region.srcOffsets[1] = {64, 64, 64};
   3782     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001ec);  // z
   3783     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001ae);  // src region
   3784     vkCmdBlitImage(m_commandBuffer->handle(), image_3D.image(), image_3D.Layout(), image_2D.image(), image_2D.Layout(), 1,
   3785                    &blit_region, VK_FILTER_NEAREST);
   3786     m_errorMonitor->VerifyFound();
   3787 
   3788     // Dest offsets exceeding source image dimensions
   3789     blit_region.srcOffsets[0] = {0, 0, 0};
   3790     blit_region.srcOffsets[1] = {64, 64, 1};
   3791     blit_region.dstOffsets[0] = {96, 64, 32};  // dst x
   3792     blit_region.dstOffsets[1] = {64, 0, 33};
   3793     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001f0);  // x
   3794     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001b0);  // dst region
   3795     vkCmdBlitImage(m_commandBuffer->handle(), image_2D.image(), image_2D.Layout(), image_3D.image(), image_3D.Layout(), 1,
   3796                    &blit_region, VK_FILTER_NEAREST);
   3797     m_errorMonitor->VerifyFound();
   3798 
   3799     blit_region.dstOffsets[0] = {0, 65, 32};                                                         // dst y
   3800     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001f2);  // y
   3801     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001b0);  // dst region
   3802     vkCmdBlitImage(m_commandBuffer->handle(), image_2D.image(), image_2D.Layout(), image_3D.image(), image_3D.Layout(), 1,
   3803                    &blit_region, VK_FILTER_NEAREST);
   3804     m_errorMonitor->VerifyFound();
   3805 
   3806     blit_region.dstOffsets[0] = {0, 64, 65};  // dst z
   3807     blit_region.dstOffsets[1] = {64, 0, 64};
   3808     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001f6);  // z
   3809     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001b0);  // dst region
   3810     vkCmdBlitImage(m_commandBuffer->handle(), image_2D.image(), image_2D.Layout(), image_3D.image(), image_3D.Layout(), 1,
   3811                    &blit_region, VK_FILTER_NEAREST);
   3812     m_errorMonitor->VerifyFound();
   3813 
   3814     m_commandBuffer->end();
   3815 }
   3816 
   3817 TEST_F(VkLayerTest, MiscBlitImageTests) {
   3818     ASSERT_NO_FATAL_FAILURE(Init());
   3819 
   3820     VkFormat f_color = VK_FORMAT_R32_SFLOAT;  // Need features ..BLIT_SRC_BIT & ..BLIT_DST_BIT
   3821     VkFormat f_depth = VK_FORMAT_D32_SFLOAT;  // Need feature ..BLIT_SRC_BIT but not ..BLIT_DST_BIT
   3822 
   3823     if (!ImageFormatAndFeaturesSupported(gpu(), f_color, VK_IMAGE_TILING_OPTIMAL,
   3824                                          VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT) ||
   3825         !ImageFormatAndFeaturesSupported(gpu(), f_depth, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_SRC_BIT) ||
   3826         ImageFormatAndFeaturesSupported(gpu(), f_depth, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_DST_BIT)) {
   3827         printf("             Requested format features unavailable - MiscBlitImageTests skipped.\n");
   3828         return;
   3829     }
   3830 
   3831     VkImageCreateInfo ci;
   3832     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   3833     ci.pNext = NULL;
   3834     ci.flags = 0;
   3835     ci.imageType = VK_IMAGE_TYPE_2D;
   3836     ci.format = f_color;
   3837     ci.extent = {64, 64, 1};
   3838     ci.mipLevels = 1;
   3839     ci.arrayLayers = 1;
   3840     ci.samples = VK_SAMPLE_COUNT_1_BIT;
   3841     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
   3842     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   3843     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   3844     ci.queueFamilyIndexCount = 0;
   3845     ci.pQueueFamilyIndices = NULL;
   3846     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   3847 
   3848     // 2D color image
   3849     VkImageObj color_img(m_device);
   3850     color_img.init(&ci);
   3851     ASSERT_TRUE(color_img.initialized());
   3852 
   3853     // 2D multi-sample image
   3854     ci.samples = VK_SAMPLE_COUNT_4_BIT;
   3855     VkImageObj ms_img(m_device);
   3856     ms_img.init(&ci);
   3857     ASSERT_TRUE(ms_img.initialized());
   3858 
   3859     // 2D depth image
   3860     ci.format = f_depth;
   3861     ci.samples = VK_SAMPLE_COUNT_1_BIT;
   3862     VkImageObj depth_img(m_device);
   3863     depth_img.init(&ci);
   3864     ASSERT_TRUE(depth_img.initialized());
   3865 
   3866     // 3D color image
   3867     ci.format = f_color;
   3868     ci.imageType = VK_IMAGE_TYPE_3D;
   3869     ci.extent = {64, 64, 8};
   3870     VkImageObj color_3D_img(m_device);
   3871     color_3D_img.init(&ci);
   3872     ASSERT_TRUE(color_3D_img.initialized());
   3873 
   3874     VkImageBlit blitRegion = {};
   3875     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   3876     blitRegion.srcSubresource.baseArrayLayer = 0;
   3877     blitRegion.srcSubresource.layerCount = 1;
   3878     blitRegion.srcSubresource.mipLevel = 0;
   3879     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   3880     blitRegion.dstSubresource.baseArrayLayer = 0;
   3881     blitRegion.dstSubresource.layerCount = 1;
   3882     blitRegion.dstSubresource.mipLevel = 0;
   3883     blitRegion.srcOffsets[0] = {0, 0, 0};
   3884     blitRegion.srcOffsets[1] = {16, 16, 1};
   3885     blitRegion.dstOffsets[0] = {32, 32, 0};
   3886     blitRegion.dstOffsets[1] = {64, 64, 1};
   3887 
   3888     m_commandBuffer->begin();
   3889 
   3890     // Blit depth image - has SRC_BIT but not DST_BIT
   3891     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
   3892     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
   3893     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001be);
   3894     vkCmdBlitImage(m_commandBuffer->handle(), depth_img.image(), depth_img.Layout(), depth_img.image(), depth_img.Layout(), 1,
   3895                    &blitRegion, VK_FILTER_NEAREST);
   3896     m_errorMonitor->VerifyFound();
   3897 
   3898     // Blit with aspectMask errors
   3899     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
   3900     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
   3901     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001e2);
   3902     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001e4);
   3903     vkCmdBlitImage(m_commandBuffer->handle(), color_img.image(), color_img.Layout(), color_img.image(), color_img.Layout(), 1,
   3904                    &blitRegion, VK_FILTER_NEAREST);
   3905     m_errorMonitor->VerifyFound();
   3906 
   3907     // Blit multi-sample image
   3908     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   3909     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   3910     // TODO: redundant VUs, one (1c8) or two (1d2 & 1d4) should be eliminated.
   3911     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001c8);
   3912     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001d2);
   3913     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001d4);
   3914     vkCmdBlitImage(m_commandBuffer->handle(), ms_img.image(), ms_img.Layout(), ms_img.image(), ms_img.Layout(), 1, &blitRegion,
   3915                    VK_FILTER_NEAREST);
   3916     m_errorMonitor->VerifyFound();
   3917 
   3918     // Blit 3D with baseArrayLayer != 0 or layerCount != 1
   3919     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   3920     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   3921     blitRegion.srcSubresource.baseArrayLayer = 1;
   3922     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001e0);
   3923     vkCmdBlitImage(m_commandBuffer->handle(), color_3D_img.image(), color_3D_img.Layout(), color_3D_img.image(),
   3924                    color_3D_img.Layout(), 1, &blitRegion, VK_FILTER_NEAREST);
   3925     m_errorMonitor->VerifyFound();
   3926     blitRegion.srcSubresource.baseArrayLayer = 0;
   3927     blitRegion.srcSubresource.layerCount = 0;
   3928     blitRegion.dstSubresource.layerCount = 0;
   3929     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001e0);
   3930     vkCmdBlitImage(m_commandBuffer->handle(), color_3D_img.image(), color_3D_img.Layout(), color_3D_img.image(),
   3931                    color_3D_img.Layout(), 1, &blitRegion, VK_FILTER_NEAREST);
   3932     m_errorMonitor->VerifyFound();
   3933 
   3934     m_commandBuffer->end();
   3935 }
   3936 
   3937 TEST_F(VkLayerTest, DSImageTransferGranularityTests) {
   3938     VkResult err;
   3939     bool pass;
   3940 
   3941     TEST_DESCRIPTION("Tests for validaiton of Queue Family property minImageTransferGranularity.");
   3942     ASSERT_NO_FATAL_FAILURE(Init());
   3943 
   3944     // If w/d/h granularity is 1, test is not meaningful
   3945     // TODO: When virtual device limits are available, create a set of limits for this test that
   3946     // will always have a granularity of > 1 for w, h, and d
   3947     auto index = m_device->graphics_queue_node_index_;
   3948     auto queue_family_properties = m_device->phy().queue_properties();
   3949 
   3950     if ((queue_family_properties[index].minImageTransferGranularity.depth < 4) ||
   3951         (queue_family_properties[index].minImageTransferGranularity.width < 4) ||
   3952         (queue_family_properties[index].minImageTransferGranularity.height < 4)) {
   3953         return;
   3954     }
   3955 
   3956     // Create two images of different types and try to copy between them
   3957     VkImage srcImage;
   3958     VkImage dstImage;
   3959     VkDeviceMemory srcMem;
   3960     VkDeviceMemory destMem;
   3961     VkMemoryRequirements memReqs;
   3962 
   3963     VkImageCreateInfo image_create_info = {};
   3964     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   3965     image_create_info.pNext = NULL;
   3966     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   3967     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
   3968     image_create_info.extent.width = 32;
   3969     image_create_info.extent.height = 32;
   3970     image_create_info.extent.depth = 1;
   3971     image_create_info.mipLevels = 1;
   3972     image_create_info.arrayLayers = 4;
   3973     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   3974     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   3975     image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   3976     image_create_info.flags = 0;
   3977 
   3978     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
   3979     ASSERT_VK_SUCCESS(err);
   3980 
   3981     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
   3982     ASSERT_VK_SUCCESS(err);
   3983 
   3984     // Allocate memory
   3985     VkMemoryAllocateInfo memAlloc = {};
   3986     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   3987     memAlloc.pNext = NULL;
   3988     memAlloc.allocationSize = 0;
   3989     memAlloc.memoryTypeIndex = 0;
   3990 
   3991     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
   3992     memAlloc.allocationSize = memReqs.size;
   3993     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
   3994     ASSERT_TRUE(pass);
   3995     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
   3996     ASSERT_VK_SUCCESS(err);
   3997 
   3998     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
   3999     memAlloc.allocationSize = memReqs.size;
   4000     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
   4001     ASSERT_VK_SUCCESS(err);
   4002     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
   4003     ASSERT_VK_SUCCESS(err);
   4004 
   4005     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
   4006     ASSERT_VK_SUCCESS(err);
   4007     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
   4008     ASSERT_VK_SUCCESS(err);
   4009 
   4010     m_commandBuffer->begin();
   4011     VkImageCopy copyRegion;
   4012     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   4013     copyRegion.srcSubresource.mipLevel = 0;
   4014     copyRegion.srcSubresource.baseArrayLayer = 0;
   4015     copyRegion.srcSubresource.layerCount = 1;
   4016     copyRegion.srcOffset.x = 0;
   4017     copyRegion.srcOffset.y = 0;
   4018     copyRegion.srcOffset.z = 0;
   4019     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   4020     copyRegion.dstSubresource.mipLevel = 0;
   4021     copyRegion.dstSubresource.baseArrayLayer = 0;
   4022     copyRegion.dstSubresource.layerCount = 1;
   4023     copyRegion.dstOffset.x = 0;
   4024     copyRegion.dstOffset.y = 0;
   4025     copyRegion.dstOffset.z = 0;
   4026     copyRegion.extent.width = 1;
   4027     copyRegion.extent.height = 1;
   4028     copyRegion.extent.depth = 1;
   4029 
   4030     // Introduce failure by setting srcOffset to a bad granularity value
   4031     copyRegion.srcOffset.y = 3;
   4032     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
   4033     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
   4034     m_errorMonitor->VerifyFound();
   4035 
   4036     // Introduce failure by setting extent to a bad granularity value
   4037     copyRegion.srcOffset.y = 0;
   4038     copyRegion.extent.width = 3;
   4039     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
   4040     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
   4041     m_errorMonitor->VerifyFound();
   4042 
   4043     // Now do some buffer/image copies
   4044     vk_testing::Buffer buffer;
   4045     VkMemoryPropertyFlags reqs = 0;
   4046     buffer.init_as_dst(*m_device, 128 * 128, reqs);
   4047     VkBufferImageCopy region = {};
   4048     region.bufferOffset = 0;
   4049     region.bufferRowLength = 3;
   4050     region.bufferImageHeight = 128;
   4051     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   4052     region.imageSubresource.layerCount = 1;
   4053     region.imageExtent.height = 16;
   4054     region.imageExtent.width = 16;
   4055     region.imageExtent.depth = 1;
   4056     region.imageOffset.x = 0;
   4057     region.imageOffset.y = 0;
   4058     region.imageOffset.z = 0;
   4059 
   4060     // Introduce failure by setting bufferRowLength to a bad granularity value
   4061     region.bufferRowLength = 3;
   4062     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
   4063     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
   4064     m_errorMonitor->VerifyFound();
   4065     region.bufferRowLength = 128;
   4066 
   4067     // Introduce failure by setting bufferOffset to a bad granularity value
   4068     region.bufferOffset = 3;
   4069     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
   4070     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1, &region);
   4071     m_errorMonitor->VerifyFound();
   4072     region.bufferOffset = 0;
   4073 
   4074     // Introduce failure by setting bufferImageHeight to a bad granularity value
   4075     region.bufferImageHeight = 3;
   4076     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
   4077     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1, &region);
   4078     m_errorMonitor->VerifyFound();
   4079     region.bufferImageHeight = 128;
   4080 
   4081     // Introduce failure by setting imageExtent to a bad granularity value
   4082     region.imageExtent.width = 3;
   4083     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
   4084     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1, &region);
   4085     m_errorMonitor->VerifyFound();
   4086     region.imageExtent.width = 16;
   4087 
   4088     // Introduce failure by setting imageOffset to a bad granularity value
   4089     region.imageOffset.z = 3;
   4090     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
   4091     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
   4092     m_errorMonitor->VerifyFound();
   4093 
   4094     m_commandBuffer->end();
   4095 
   4096     vkDestroyImage(m_device->device(), srcImage, NULL);
   4097     vkDestroyImage(m_device->device(), dstImage, NULL);
   4098     vkFreeMemory(m_device->device(), srcMem, NULL);
   4099     vkFreeMemory(m_device->device(), destMem, NULL);
   4100 }
   4101 
   4102 TEST_F(VkLayerTest, MismatchedQueueFamiliesOnSubmit) {
   4103     TEST_DESCRIPTION(
   4104         "Submit command buffer created using one queue family and attempt to submit them on a queue created in a different queue "
   4105         "family.");
   4106 
   4107     ASSERT_NO_FATAL_FAILURE(Init());  // assumes it initializes all queue families on vkCreateDevice
   4108 
   4109     // This test is meaningless unless we have multiple queue families
   4110     auto queue_family_properties = m_device->phy().queue_properties();
   4111     std::vector<uint32_t> queue_families;
   4112     for (uint32_t i = 0; i < queue_family_properties.size(); ++i)
   4113         if (queue_family_properties[i].queueCount > 0) queue_families.push_back(i);
   4114 
   4115     if (queue_families.size() < 2) {
   4116         printf("             Device only has one queue family; skipped.\n");
   4117         return;
   4118     }
   4119 
   4120     const uint32_t queue_family = queue_families[0];
   4121 
   4122     const uint32_t other_queue_family = queue_families[1];
   4123     VkQueue other_queue;
   4124     vkGetDeviceQueue(m_device->device(), other_queue_family, 0, &other_queue);
   4125 
   4126     VkCommandPoolObj cmd_pool(m_device, queue_family);
   4127     VkCommandBufferObj cmd_buff(m_device, &cmd_pool);
   4128 
   4129     cmd_buff.begin();
   4130     cmd_buff.end();
   4131 
   4132     // Submit on the wrong queue
   4133     VkSubmitInfo submit_info = {};
   4134     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   4135     submit_info.commandBufferCount = 1;
   4136     submit_info.pCommandBuffers = &cmd_buff.handle();
   4137 
   4138     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_31a00094);
   4139     vkQueueSubmit(other_queue, 1, &submit_info, VK_NULL_HANDLE);
   4140     m_errorMonitor->VerifyFound();
   4141 }
   4142 
   4143 TEST_F(VkLayerTest, RenderPassAttachmentIndexOutOfRange) {
   4144     ASSERT_NO_FATAL_FAILURE(Init());
   4145 
   4146     // There are no attachments, but refer to attachment 0.
   4147     VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
   4148     VkSubpassDescription subpasses[] = {
   4149         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr},
   4150     };
   4151 
   4152     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, subpasses, 0, nullptr};
   4153     VkRenderPass rp;
   4154 
   4155     // "... must be less than the total number of attachments ..."
   4156     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_12200684);
   4157     vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   4158     m_errorMonitor->VerifyFound();
   4159 }
   4160 
   4161 TEST_F(VkLayerTest, RenderPassPipelineSubpassMismatch) {
   4162     TEST_DESCRIPTION("Use a pipeline for the wrong subpass in a render pass instance");
   4163     ASSERT_NO_FATAL_FAILURE(Init());
   4164 
   4165     // A renderpass with two subpasses, both writing the same attachment.
   4166     VkAttachmentDescription attach[] = {
   4167         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
   4168          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
   4169          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
   4170     };
   4171     VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
   4172     VkSubpassDescription subpasses[] = {
   4173         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr},
   4174         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr},
   4175     };
   4176     VkSubpassDependency dep = {0,
   4177                                1,
   4178                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   4179                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   4180                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   4181                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   4182                                VK_DEPENDENCY_BY_REGION_BIT};
   4183     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 2, subpasses, 1, &dep};
   4184     VkRenderPass rp;
   4185     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   4186     ASSERT_VK_SUCCESS(err);
   4187 
   4188     VkImageObj image(m_device);
   4189     image.InitNoLayout(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   4190     VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
   4191 
   4192     VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &imageView, 32, 32, 1};
   4193     VkFramebuffer fb;
   4194     err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
   4195     ASSERT_VK_SUCCESS(err);
   4196 
   4197     char const *vsSource =
   4198         "#version 450\n"
   4199         "void main() { gl_Position = vec4(1); }\n";
   4200     char const *fsSource =
   4201         "#version 450\n"
   4202         "layout(location=0) out vec4 color;\n"
   4203         "void main() { color = vec4(1); }\n";
   4204 
   4205     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   4206     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   4207     VkPipelineObj pipe(m_device);
   4208     pipe.AddDefaultColorAttachment();
   4209     pipe.AddShader(&vs);
   4210     pipe.AddShader(&fs);
   4211     VkViewport view_port = {};
   4212     m_viewports.push_back(view_port);
   4213     pipe.SetViewport(m_viewports);
   4214     VkRect2D rect = {};
   4215     m_scissors.push_back(rect);
   4216     pipe.SetScissor(m_scissors);
   4217 
   4218     const VkPipelineLayoutObj pl(m_device);
   4219     pipe.CreateVKPipeline(pl.handle(), rp);
   4220 
   4221     m_commandBuffer->begin();
   4222 
   4223     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
   4224                                   nullptr,
   4225                                   rp,
   4226                                   fb,
   4227                                   {{
   4228                                        0,
   4229                                        0,
   4230                                    },
   4231                                    {32, 32}},
   4232                                   0,
   4233                                   nullptr};
   4234 
   4235     // subtest 1: bind in the wrong subpass
   4236     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
   4237     vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
   4238     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "built for subpass 0 but used in subpass 1");
   4239     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   4240     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
   4241     m_errorMonitor->VerifyFound();
   4242 
   4243     vkCmdEndRenderPass(m_commandBuffer->handle());
   4244 
   4245     // subtest 2: bind in correct subpass, then transition to next subpass
   4246     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
   4247     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   4248     vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
   4249     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "built for subpass 0 but used in subpass 1");
   4250     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
   4251     m_errorMonitor->VerifyFound();
   4252 
   4253     vkCmdEndRenderPass(m_commandBuffer->handle());
   4254 
   4255     m_commandBuffer->end();
   4256 
   4257     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
   4258     vkDestroyRenderPass(m_device->device(), rp, nullptr);
   4259 }
   4260 
   4261 TEST_F(VkLayerTest, RenderPassBarrierConflicts) {
   4262     TEST_DESCRIPTION("Add a pipeline barrier within a subpass that has conflicting state");
   4263     ASSERT_NO_FATAL_FAILURE(Init());
   4264 
   4265     // A renderpass with a single subpass that declared a self-dependency
   4266     VkAttachmentDescription attach[] = {
   4267         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
   4268          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
   4269          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
   4270     };
   4271     VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
   4272     VkSubpassDescription subpasses[] = {
   4273         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr},
   4274     };
   4275     VkSubpassDependency dep = {0,
   4276                                0,
   4277                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   4278                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   4279                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   4280                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   4281                                VK_DEPENDENCY_BY_REGION_BIT};
   4282     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 1, &dep};
   4283     VkRenderPass rp;
   4284     VkRenderPass rp_noselfdep;
   4285 
   4286     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   4287     ASSERT_VK_SUCCESS(err);
   4288     rpci.dependencyCount = 0;
   4289     rpci.pDependencies = nullptr;
   4290     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp_noselfdep);
   4291     ASSERT_VK_SUCCESS(err);
   4292 
   4293     VkImageObj image(m_device);
   4294     image.InitNoLayout(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   4295     VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
   4296 
   4297     VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &imageView, 32, 32, 1};
   4298     VkFramebuffer fb;
   4299     err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
   4300     ASSERT_VK_SUCCESS(err);
   4301 
   4302     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800928);
   4303     m_commandBuffer->begin();
   4304     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
   4305                                   nullptr,
   4306                                   rp_noselfdep,
   4307                                   fb,
   4308                                   {{
   4309                                        0,
   4310                                        0,
   4311                                    },
   4312                                    {32, 32}},
   4313                                   0,
   4314                                   nullptr};
   4315 
   4316     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
   4317     VkMemoryBarrier mem_barrier = {};
   4318     mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
   4319     mem_barrier.pNext = NULL;
   4320     mem_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
   4321     mem_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
   4322     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 1,
   4323                          &mem_barrier, 0, nullptr, 0, nullptr);
   4324     m_errorMonitor->VerifyFound();
   4325     vkCmdEndRenderPass(m_commandBuffer->handle());
   4326 
   4327     rpbi.renderPass = rp;
   4328     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
   4329     VkImageMemoryBarrier img_barrier = {};
   4330     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
   4331     img_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
   4332     img_barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
   4333     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   4334     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   4335     img_barrier.image = image.handle();
   4336     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   4337     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   4338     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   4339     img_barrier.subresourceRange.baseArrayLayer = 0;
   4340     img_barrier.subresourceRange.baseMipLevel = 0;
   4341     img_barrier.subresourceRange.layerCount = 1;
   4342     img_barrier.subresourceRange.levelCount = 1;
   4343     // Mis-match src stage mask
   4344     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b80092a);
   4345     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   4346                          VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
   4347     m_errorMonitor->VerifyFound();
   4348     // Now mis-match dst stage mask
   4349     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b80092c);
   4350     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_HOST_BIT,
   4351                          VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
   4352     m_errorMonitor->VerifyFound();
   4353     // Set srcQueueFamilyIndex to something other than IGNORED
   4354     img_barrier.srcQueueFamilyIndex = 0;
   4355     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b80093c);
   4356     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   4357                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
   4358                          &img_barrier);
   4359     m_errorMonitor->VerifyFound();
   4360     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   4361     // Mis-match mem barrier src access mask
   4362     mem_barrier = {};
   4363     mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
   4364     mem_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
   4365     mem_barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
   4366     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b80092e);
   4367     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   4368                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 1, &mem_barrier, 0, nullptr, 0,
   4369                          nullptr);
   4370     m_errorMonitor->VerifyFound();
   4371     // Mis-match mem barrier dst access mask. Also set srcAccessMask to 0 which should not cause an error
   4372     mem_barrier.srcAccessMask = 0;
   4373     mem_barrier.dstAccessMask = VK_ACCESS_HOST_WRITE_BIT;
   4374     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800930);
   4375     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   4376                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 1, &mem_barrier, 0, nullptr, 0,
   4377                          nullptr);
   4378     m_errorMonitor->VerifyFound();
   4379     // Mis-match image barrier src access mask
   4380     img_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
   4381     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b80092e);
   4382     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   4383                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
   4384                          &img_barrier);
   4385     m_errorMonitor->VerifyFound();
   4386     // Mis-match image barrier dst access mask
   4387     img_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
   4388     img_barrier.dstAccessMask = VK_ACCESS_HOST_WRITE_BIT;
   4389     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800930);
   4390     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   4391                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
   4392                          &img_barrier);
   4393     m_errorMonitor->VerifyFound();
   4394     // Mis-match dependencyFlags
   4395     img_barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
   4396     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800932);
   4397     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   4398                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0 /* wrong */, 0, nullptr, 0, nullptr, 1, &img_barrier);
   4399     m_errorMonitor->VerifyFound();
   4400     // Send non-zero bufferMemoryBarrierCount
   4401     // Construct a valid BufferMemoryBarrier to avoid any parameter errors
   4402     // First we need a valid buffer to reference
   4403     vk_testing::Buffer buffer;
   4404     VkMemoryPropertyFlags mem_reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
   4405     buffer.init_as_src_and_dst(*m_device, 256, mem_reqs);
   4406     VkBufferMemoryBarrier bmb = {};
   4407     bmb.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
   4408     bmb.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
   4409     bmb.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
   4410     bmb.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   4411     bmb.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   4412     bmb.buffer = buffer.handle();
   4413     bmb.offset = 0;
   4414     bmb.size = VK_WHOLE_SIZE;
   4415     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800934);
   4416     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   4417                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1, &bmb, 0,
   4418                          nullptr);
   4419     m_errorMonitor->VerifyFound();
   4420     // Add image barrier w/ image handle that's not in framebuffer
   4421     VkImageObj lone_image(m_device);
   4422     lone_image.InitNoLayout(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   4423     img_barrier.image = lone_image.handle();
   4424     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800936);
   4425     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   4426                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
   4427                          &img_barrier);
   4428     m_errorMonitor->VerifyFound();
   4429     // Have image barrier with mis-matched layouts
   4430     img_barrier.image = image.handle();
   4431     img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   4432     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b80093a);
   4433     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   4434                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
   4435                          &img_barrier);
   4436     m_errorMonitor->VerifyFound();
   4437 
   4438     img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
   4439     img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
   4440     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800938);
   4441     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   4442                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
   4443                          &img_barrier);
   4444     m_errorMonitor->VerifyFound();
   4445     vkCmdEndRenderPass(m_commandBuffer->handle());
   4446 
   4447     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
   4448     vkDestroyRenderPass(m_device->device(), rp, nullptr);
   4449     vkDestroyRenderPass(m_device->device(), rp_noselfdep, nullptr);
   4450 }
   4451 
   4452 TEST_F(VkLayerTest, InvalidSecondaryCommandBufferBarrier) {
   4453     TEST_DESCRIPTION("Add an invalid image barrier in a secondary command buffer");
   4454     ASSERT_NO_FATAL_FAILURE(Init());
   4455 
   4456     // A renderpass with a single subpass that declared a self-dependency
   4457     VkAttachmentDescription attach[] = {
   4458         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
   4459          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
   4460          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
   4461     };
   4462     VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
   4463     VkSubpassDescription subpasses[] = {
   4464         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr},
   4465     };
   4466     VkSubpassDependency dep = {0,
   4467                                0,
   4468                                VK_PIPELINE_STAGE_HOST_BIT,
   4469                                VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   4470                                VK_ACCESS_HOST_WRITE_BIT,
   4471                                VK_ACCESS_SHADER_WRITE_BIT,
   4472                                VK_DEPENDENCY_BY_REGION_BIT};
   4473     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 1, &dep};
   4474     VkRenderPass rp;
   4475 
   4476     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   4477     ASSERT_VK_SUCCESS(err);
   4478 
   4479     VkImageObj image(m_device);
   4480     image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   4481     VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
   4482     // Second image that img_barrier will incorrectly use
   4483     VkImageObj image2(m_device);
   4484     image2.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   4485 
   4486     VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &imageView, 32, 32, 1};
   4487     VkFramebuffer fb;
   4488     err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
   4489     ASSERT_VK_SUCCESS(err);
   4490 
   4491     m_commandBuffer->begin();
   4492 
   4493     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
   4494                                   nullptr,
   4495                                   rp,
   4496                                   fb,
   4497                                   {{
   4498                                        0,
   4499                                        0,
   4500                                    },
   4501                                    {32, 32}},
   4502                                   0,
   4503                                   nullptr};
   4504 
   4505     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
   4506 
   4507     VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
   4508     VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
   4509 
   4510     VkCommandBufferInheritanceInfo cbii = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
   4511                                            nullptr,
   4512                                            rp,
   4513                                            0,
   4514                                            VK_NULL_HANDLE,  // Set to NULL FB handle intentionally to flesh out any errors
   4515                                            VK_FALSE,
   4516                                            0,
   4517                                            0};
   4518     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
   4519                                      VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,
   4520                                      &cbii};
   4521     vkBeginCommandBuffer(secondary.handle(), &cbbi);
   4522     VkImageMemoryBarrier img_barrier = {};
   4523     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
   4524     img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
   4525     img_barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
   4526     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   4527     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   4528     img_barrier.image = image2.handle();  // Image mis-matches with FB image
   4529     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   4530     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   4531     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   4532     img_barrier.subresourceRange.baseArrayLayer = 0;
   4533     img_barrier.subresourceRange.baseMipLevel = 0;
   4534     img_barrier.subresourceRange.layerCount = 1;
   4535     img_barrier.subresourceRange.levelCount = 1;
   4536     vkCmdPipelineBarrier(secondary.handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   4537                          VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
   4538     secondary.end();
   4539 
   4540     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800936);
   4541     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
   4542     m_errorMonitor->VerifyFound();
   4543 
   4544     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
   4545     vkDestroyRenderPass(m_device->device(), rp, nullptr);
   4546 }
   4547 
   4548 TEST_F(VkLayerTest, ImageBarrierSubpassConflict) {
   4549     TEST_DESCRIPTION("Check case where subpass index references different image from image barrier");
   4550     ASSERT_NO_FATAL_FAILURE(Init());
   4551 
   4552     // Create RP/FB combo where subpass has incorrect index attachment, this is 2nd half of VALIDATION_ERROR_1b800936
   4553     VkAttachmentDescription attach[] = {
   4554         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
   4555          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
   4556          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
   4557         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
   4558          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
   4559          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
   4560     };
   4561     // ref attachment points to wrong attachment index compared to img_barrier below
   4562     VkAttachmentReference ref = {1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
   4563     VkSubpassDescription subpasses[] = {
   4564         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr},
   4565     };
   4566     VkSubpassDependency dep = {0,
   4567                                0,
   4568                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   4569                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   4570                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   4571                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   4572                                VK_DEPENDENCY_BY_REGION_BIT};
   4573 
   4574     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attach, 1, subpasses, 1, &dep};
   4575     VkRenderPass rp;
   4576 
   4577     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   4578     ASSERT_VK_SUCCESS(err);
   4579 
   4580     VkImageObj image(m_device);
   4581     image.InitNoLayout(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   4582     VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
   4583     VkImageObj image2(m_device);
   4584     image2.InitNoLayout(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   4585     VkImageView imageView2 = image2.targetView(VK_FORMAT_R8G8B8A8_UNORM);
   4586     // re-use imageView from start of test
   4587     VkImageView iv_array[2] = {imageView, imageView2};
   4588 
   4589     VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 2, iv_array, 32, 32, 1};
   4590     VkFramebuffer fb;
   4591     err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
   4592     ASSERT_VK_SUCCESS(err);
   4593 
   4594     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
   4595                                   nullptr,
   4596                                   rp,
   4597                                   fb,
   4598                                   {{
   4599                                        0,
   4600                                        0,
   4601                                    },
   4602                                    {32, 32}},
   4603                                   0,
   4604                                   nullptr};
   4605 
   4606     VkImageMemoryBarrier img_barrier = {};
   4607     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
   4608     img_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
   4609     img_barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
   4610     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   4611     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   4612     img_barrier.image = image.handle(); /* barrier references image from attachment index 0 */
   4613     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   4614     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   4615     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   4616     img_barrier.subresourceRange.baseArrayLayer = 0;
   4617     img_barrier.subresourceRange.baseMipLevel = 0;
   4618     img_barrier.subresourceRange.layerCount = 1;
   4619     img_barrier.subresourceRange.levelCount = 1;
   4620     m_commandBuffer->begin();
   4621     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
   4622     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800936);
   4623     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   4624                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
   4625                          &img_barrier);
   4626     m_errorMonitor->VerifyFound();
   4627 
   4628     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
   4629     vkDestroyRenderPass(m_device->device(), rp, nullptr);
   4630 }
   4631 
   4632 TEST_F(VkLayerTest, TemporaryExternalSemaphore) {
   4633 #ifdef _WIN32
   4634     const auto extension_name = VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME;
   4635     const auto handle_type = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR;
   4636 #else
   4637     const auto extension_name = VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME;
   4638     const auto handle_type = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
   4639 #endif
   4640     // Check for external semaphore instance extensions
   4641     if (InstanceExtensionSupported(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME)) {
   4642         m_instance_extension_names.push_back(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
   4643         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
   4644     } else {
   4645         printf("             External semaphore extension not supported, skipping test\n");
   4646         return;
   4647     }
   4648     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   4649 
   4650     // Check for external semaphore device extensions
   4651     if (DeviceExtensionSupported(gpu(), nullptr, extension_name)) {
   4652         m_device_extension_names.push_back(extension_name);
   4653         m_device_extension_names.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
   4654     } else {
   4655         printf("             External semaphore extension not supported, skipping test\n");
   4656         return;
   4657     }
   4658     ASSERT_NO_FATAL_FAILURE(InitState());
   4659 
   4660     // Check for external semaphore import and export capability
   4661     VkPhysicalDeviceExternalSemaphoreInfoKHR esi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR, nullptr,
   4662                                                     handle_type};
   4663     VkExternalSemaphorePropertiesKHR esp = {VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR, nullptr};
   4664     auto vkGetPhysicalDeviceExternalSemaphorePropertiesKHR =
   4665         (PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)vkGetInstanceProcAddr(
   4666             instance(), "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR");
   4667     vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(gpu(), &esi, &esp);
   4668 
   4669     if (!(esp.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR) ||
   4670         !(esp.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR)) {
   4671         printf("             External semaphore does not support importing and exporting, skipping test\n");
   4672         return;
   4673     }
   4674 
   4675     VkResult err;
   4676 
   4677     // Create a semaphore to export payload from
   4678     VkExportSemaphoreCreateInfoKHR esci = {VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR, nullptr, handle_type};
   4679     VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &esci, 0};
   4680 
   4681     VkSemaphore export_semaphore;
   4682     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &export_semaphore);
   4683     ASSERT_VK_SUCCESS(err);
   4684 
   4685     // Create a semaphore to import payload into
   4686     sci.pNext = nullptr;
   4687     VkSemaphore import_semaphore;
   4688     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &import_semaphore);
   4689     ASSERT_VK_SUCCESS(err);
   4690 
   4691 #ifdef _WIN32
   4692     // Export semaphore payload to an opaque handle
   4693     HANDLE handle = nullptr;
   4694     VkSemaphoreGetWin32HandleInfoKHR ghi = {VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR, nullptr, export_semaphore,
   4695                                             handle_type};
   4696     auto vkGetSemaphoreWin32HandleKHR =
   4697         (PFN_vkGetSemaphoreWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetSemaphoreWin32HandleKHR");
   4698     err = vkGetSemaphoreWin32HandleKHR(m_device->device(), &ghi, &handle);
   4699     ASSERT_VK_SUCCESS(err);
   4700 
   4701     // Import opaque handle exported above *temporarily*
   4702     VkImportSemaphoreWin32HandleInfoKHR ihi = {VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR,
   4703                                                nullptr,
   4704                                                import_semaphore,
   4705                                                VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR,
   4706                                                handle_type,
   4707                                                handle,
   4708                                                nullptr};
   4709     auto vkImportSemaphoreWin32HandleKHR =
   4710         (PFN_vkImportSemaphoreWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportSemaphoreWin32HandleKHR");
   4711     err = vkImportSemaphoreWin32HandleKHR(m_device->device(), &ihi);
   4712     ASSERT_VK_SUCCESS(err);
   4713 #else
   4714     // Export semaphore payload to an opaque handle
   4715     int fd = 0;
   4716     VkSemaphoreGetFdInfoKHR ghi = {VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR, nullptr, export_semaphore, handle_type};
   4717     auto vkGetSemaphoreFdKHR = (PFN_vkGetSemaphoreFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetSemaphoreFdKHR");
   4718     err = vkGetSemaphoreFdKHR(m_device->device(), &ghi, &fd);
   4719     ASSERT_VK_SUCCESS(err);
   4720 
   4721     // Import opaque handle exported above *temporarily*
   4722     VkImportSemaphoreFdInfoKHR ihi = {VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR, nullptr,     import_semaphore,
   4723                                       VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR,          handle_type, fd};
   4724     auto vkImportSemaphoreFdKHR = (PFN_vkImportSemaphoreFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportSemaphoreFdKHR");
   4725     err = vkImportSemaphoreFdKHR(m_device->device(), &ihi);
   4726     ASSERT_VK_SUCCESS(err);
   4727 #endif
   4728 
   4729     // Wait on the imported semaphore twice in vkQueueSubmit, the second wait should be an error
   4730     VkPipelineStageFlags flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
   4731     VkSubmitInfo si[] = {
   4732         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, &flags, 0, nullptr, 1, &export_semaphore},
   4733         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &import_semaphore, &flags, 0, nullptr, 0, nullptr},
   4734         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, &flags, 0, nullptr, 1, &export_semaphore},
   4735         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &import_semaphore, &flags, 0, nullptr, 0, nullptr},
   4736     };
   4737     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "has no way to be signaled");
   4738     vkQueueSubmit(m_device->m_queue, 4, si, VK_NULL_HANDLE);
   4739     m_errorMonitor->VerifyFound();
   4740 
   4741     // Wait on the imported semaphore twice in vkQueueBindSparse, the second wait should be an error
   4742     VkBindSparseInfo bi[] = {
   4743         {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 1, &export_semaphore},
   4744         {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 1, &import_semaphore, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr},
   4745         {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 1, &export_semaphore},
   4746         {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 1, &import_semaphore, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr},
   4747     };
   4748     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "has no way to be signaled");
   4749     vkQueueBindSparse(m_device->m_queue, 4, bi, VK_NULL_HANDLE);
   4750     m_errorMonitor->VerifyFound();
   4751 
   4752     // Cleanup
   4753     err = vkQueueWaitIdle(m_device->m_queue);
   4754     ASSERT_VK_SUCCESS(err);
   4755     vkDestroySemaphore(m_device->device(), export_semaphore, nullptr);
   4756     vkDestroySemaphore(m_device->device(), import_semaphore, nullptr);
   4757 }
   4758 
   4759 TEST_F(VkLayerTest, TemporaryExternalFence) {
   4760 #ifdef _WIN32
   4761     const auto extension_name = VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME;
   4762     const auto handle_type = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
   4763 #else
   4764     const auto extension_name = VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME;
   4765     const auto handle_type = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
   4766 #endif
   4767     // Check for external fence instance extensions
   4768     if (InstanceExtensionSupported(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME)) {
   4769         m_instance_extension_names.push_back(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME);
   4770         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
   4771     } else {
   4772         printf("             External fence extension not supported, skipping test\n");
   4773         return;
   4774     }
   4775     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   4776 
   4777     // Check for external fence device extensions
   4778     if (DeviceExtensionSupported(gpu(), nullptr, extension_name)) {
   4779         m_device_extension_names.push_back(extension_name);
   4780         m_device_extension_names.push_back(VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME);
   4781     } else {
   4782         printf("             External fence extension not supported, skipping test\n");
   4783         return;
   4784     }
   4785     ASSERT_NO_FATAL_FAILURE(InitState());
   4786 
   4787     // Check for external fence import and export capability
   4788     VkPhysicalDeviceExternalFenceInfoKHR efi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR, nullptr, handle_type};
   4789     VkExternalFencePropertiesKHR efp = {VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR, nullptr};
   4790     auto vkGetPhysicalDeviceExternalFencePropertiesKHR = (PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR)vkGetInstanceProcAddr(
   4791         instance(), "vkGetPhysicalDeviceExternalFencePropertiesKHR");
   4792     vkGetPhysicalDeviceExternalFencePropertiesKHR(gpu(), &efi, &efp);
   4793 
   4794     if (!(efp.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR) ||
   4795         !(efp.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR)) {
   4796         printf("             External fence does not support importing and exporting, skipping test\n");
   4797         return;
   4798     }
   4799 
   4800     VkResult err;
   4801 
   4802     // Create a fence to export payload from
   4803     VkFence export_fence;
   4804     {
   4805         VkExportFenceCreateInfoKHR efci = {VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR, nullptr, handle_type};
   4806         VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, &efci, 0};
   4807         err = vkCreateFence(m_device->device(), &fci, nullptr, &export_fence);
   4808         ASSERT_VK_SUCCESS(err);
   4809     }
   4810 
   4811     // Create a fence to import payload into
   4812     VkFence import_fence;
   4813     {
   4814         VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
   4815         err = vkCreateFence(m_device->device(), &fci, nullptr, &import_fence);
   4816         ASSERT_VK_SUCCESS(err);
   4817     }
   4818 
   4819 #ifdef _WIN32
   4820     // Export fence payload to an opaque handle
   4821     HANDLE handle = nullptr;
   4822     {
   4823         VkFenceGetWin32HandleInfoKHR ghi = {VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR, nullptr, export_fence, handle_type};
   4824         auto vkGetFenceWin32HandleKHR =
   4825             (PFN_vkGetFenceWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetFenceWin32HandleKHR");
   4826         err = vkGetFenceWin32HandleKHR(m_device->device(), &ghi, &handle);
   4827         ASSERT_VK_SUCCESS(err);
   4828     }
   4829 
   4830     // Import opaque handle exported above
   4831     {
   4832         VkImportFenceWin32HandleInfoKHR ifi = {VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR,
   4833                                                nullptr,
   4834                                                import_fence,
   4835                                                VK_FENCE_IMPORT_TEMPORARY_BIT_KHR,
   4836                                                handle_type,
   4837                                                handle,
   4838                                                nullptr};
   4839         auto vkImportFenceWin32HandleKHR =
   4840             (PFN_vkImportFenceWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportFenceWin32HandleKHR");
   4841         err = vkImportFenceWin32HandleKHR(m_device->device(), &ifi);
   4842         ASSERT_VK_SUCCESS(err);
   4843     }
   4844 #else
   4845     // Export fence payload to an opaque handle
   4846     int fd = 0;
   4847     {
   4848         VkFenceGetFdInfoKHR gfi = {VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR, nullptr, export_fence, handle_type};
   4849         auto vkGetFenceFdKHR = (PFN_vkGetFenceFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetFenceFdKHR");
   4850         err = vkGetFenceFdKHR(m_device->device(), &gfi, &fd);
   4851         ASSERT_VK_SUCCESS(err);
   4852     }
   4853 
   4854     // Import opaque handle exported above
   4855     {
   4856         VkImportFenceFdInfoKHR ifi = {VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR, nullptr,     import_fence,
   4857                                       VK_FENCE_IMPORT_TEMPORARY_BIT_KHR,          handle_type, fd};
   4858         auto vkImportFenceFdKHR = (PFN_vkImportFenceFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportFenceFdKHR");
   4859         err = vkImportFenceFdKHR(m_device->device(), &ifi);
   4860         ASSERT_VK_SUCCESS(err);
   4861     }
   4862 #endif
   4863 
   4864     // Undo the temporary import
   4865     vkResetFences(m_device->device(), 1, &import_fence);
   4866 
   4867     // Signal the previously imported fence twice, the second signal should produce a validation error
   4868     vkQueueSubmit(m_device->m_queue, 0, nullptr, import_fence);
   4869     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is already in use by another submission.");
   4870     vkQueueSubmit(m_device->m_queue, 0, nullptr, import_fence);
   4871     m_errorMonitor->VerifyFound();
   4872 
   4873     // Cleanup
   4874     err = vkQueueWaitIdle(m_device->m_queue);
   4875     ASSERT_VK_SUCCESS(err);
   4876     vkDestroyFence(m_device->device(), export_fence, nullptr);
   4877     vkDestroyFence(m_device->device(), import_fence, nullptr);
   4878 }
   4879 
   4880 TEST_F(VkPositiveLayerTest, SecondaryCommandBufferBarrier) {
   4881     TEST_DESCRIPTION("Add a pipeline barrier in a secondary command buffer");
   4882     ASSERT_NO_FATAL_FAILURE(Init());
   4883 
   4884     // A renderpass with a single subpass that declared a self-dependency
   4885     VkAttachmentDescription attach[] = {
   4886         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
   4887          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
   4888          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
   4889     };
   4890     VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
   4891     VkSubpassDescription subpasses[] = {
   4892         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr},
   4893     };
   4894     VkSubpassDependency dep = {0,
   4895                                0,
   4896                                VK_PIPELINE_STAGE_HOST_BIT,
   4897                                VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   4898                                VK_ACCESS_HOST_WRITE_BIT,
   4899                                VK_ACCESS_SHADER_WRITE_BIT,
   4900                                VK_DEPENDENCY_BY_REGION_BIT};
   4901     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 1, &dep};
   4902     VkRenderPass rp;
   4903 
   4904     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   4905     ASSERT_VK_SUCCESS(err);
   4906 
   4907     VkImageObj image(m_device);
   4908     image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   4909     VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
   4910 
   4911     VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &imageView, 32, 32, 1};
   4912     VkFramebuffer fb;
   4913     err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
   4914     ASSERT_VK_SUCCESS(err);
   4915 
   4916     m_commandBuffer->begin();
   4917 
   4918     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
   4919                                   nullptr,
   4920                                   rp,
   4921                                   fb,
   4922                                   {{
   4923                                        0,
   4924                                        0,
   4925                                    },
   4926                                    {32, 32}},
   4927                                   0,
   4928                                   nullptr};
   4929 
   4930     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
   4931 
   4932     VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
   4933     VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
   4934 
   4935     VkCommandBufferInheritanceInfo cbii = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
   4936                                            nullptr,
   4937                                            rp,
   4938                                            0,
   4939                                            VK_NULL_HANDLE,  // Set to NULL FB handle intentionally to flesh out any errors
   4940                                            VK_FALSE,
   4941                                            0,
   4942                                            0};
   4943     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
   4944                                      VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,
   4945                                      &cbii};
   4946     vkBeginCommandBuffer(secondary.handle(), &cbbi);
   4947     VkMemoryBarrier mem_barrier = {};
   4948     mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
   4949     mem_barrier.pNext = NULL;
   4950     mem_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
   4951     mem_barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
   4952     vkCmdPipelineBarrier(secondary.handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   4953                          VK_DEPENDENCY_BY_REGION_BIT, 1, &mem_barrier, 0, nullptr, 0, nullptr);
   4954     VkImageMemoryBarrier img_barrier = {};
   4955     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
   4956     img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
   4957     img_barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
   4958     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   4959     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   4960     img_barrier.image = image.handle();
   4961     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   4962     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   4963     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   4964     img_barrier.subresourceRange.baseArrayLayer = 0;
   4965     img_barrier.subresourceRange.baseMipLevel = 0;
   4966     img_barrier.subresourceRange.layerCount = 1;
   4967     img_barrier.subresourceRange.levelCount = 1;
   4968     vkCmdPipelineBarrier(secondary.handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   4969                          VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
   4970     secondary.end();
   4971 
   4972     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
   4973     vkCmdEndRenderPass(m_commandBuffer->handle());
   4974     m_commandBuffer->end();
   4975 
   4976     VkSubmitInfo submit_info = {};
   4977     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   4978     submit_info.commandBufferCount = 1;
   4979     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   4980     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   4981     vkQueueWaitIdle(m_device->m_queue);
   4982 
   4983     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
   4984     vkDestroyRenderPass(m_device->device(), rp, nullptr);
   4985 }
   4986 
   4987 TEST_F(VkLayerTest, RenderPassInvalidRenderArea) {
   4988     TEST_DESCRIPTION("Generate INVALID_RENDER_AREA error by beginning renderpass with extent outside of framebuffer");
   4989     ASSERT_NO_FATAL_FAILURE(Init());
   4990     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   4991 
   4992     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   4993                                          "Cannot execute a render pass with renderArea not within the bound of the framebuffer.");
   4994 
   4995     // Framebuffer for render target is 256x256, exceed that for INVALID_RENDER_AREA
   4996     m_renderPassBeginInfo.renderArea.extent.width = 257;
   4997     m_renderPassBeginInfo.renderArea.extent.height = 257;
   4998     m_commandBuffer->begin();
   4999     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   5000     m_errorMonitor->VerifyFound();
   5001 }
   5002 
   5003 TEST_F(VkLayerTest, DisabledIndependentBlend) {
   5004     TEST_DESCRIPTION(
   5005         "Generate INDEPENDENT_BLEND by disabling independent blend and then specifying different blend states for two "
   5006         "attachements");
   5007     VkPhysicalDeviceFeatures features = {};
   5008     features.independentBlend = VK_FALSE;
   5009     ASSERT_NO_FATAL_FAILURE(Init(&features));
   5010 
   5011     m_errorMonitor->SetDesiredFailureMsg(
   5012         VK_DEBUG_REPORT_ERROR_BIT_EXT,
   5013         "Invalid Pipeline CreateInfo: If independent blend feature not enabled, all elements of pAttachments must be identical");
   5014 
   5015     VkDescriptorSetObj descriptorSet(m_device);
   5016     descriptorSet.AppendDummy();
   5017     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   5018 
   5019     VkPipelineObj pipeline(m_device);
   5020     // Create a renderPass with two color attachments
   5021     VkAttachmentReference attachments[2] = {};
   5022     attachments[0].layout = VK_IMAGE_LAYOUT_GENERAL;
   5023     attachments[1].attachment = 1;
   5024     attachments[1].layout = VK_IMAGE_LAYOUT_GENERAL;
   5025 
   5026     VkSubpassDescription subpass = {};
   5027     subpass.pColorAttachments = attachments;
   5028     subpass.colorAttachmentCount = 2;
   5029 
   5030     VkRenderPassCreateInfo rpci = {};
   5031     rpci.subpassCount = 1;
   5032     rpci.pSubpasses = &subpass;
   5033     rpci.attachmentCount = 2;
   5034 
   5035     VkAttachmentDescription attach_desc[2] = {};
   5036     attach_desc[0].format = VK_FORMAT_B8G8R8A8_UNORM;
   5037     attach_desc[0].samples = VK_SAMPLE_COUNT_1_BIT;
   5038     attach_desc[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   5039     attach_desc[0].finalLayout = VK_IMAGE_LAYOUT_GENERAL;
   5040     attach_desc[1].format = VK_FORMAT_B8G8R8A8_UNORM;
   5041     attach_desc[1].samples = VK_SAMPLE_COUNT_1_BIT;
   5042     attach_desc[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   5043     attach_desc[1].finalLayout = VK_IMAGE_LAYOUT_GENERAL;
   5044 
   5045     rpci.pAttachments = attach_desc;
   5046     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
   5047 
   5048     VkRenderPass renderpass;
   5049     vkCreateRenderPass(m_device->device(), &rpci, NULL, &renderpass);
   5050     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   5051     pipeline.AddShader(&vs);
   5052 
   5053     VkPipelineColorBlendAttachmentState att_state1 = {}, att_state2 = {};
   5054     att_state1.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
   5055     att_state1.blendEnable = VK_TRUE;
   5056     att_state2.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
   5057     att_state2.blendEnable = VK_FALSE;
   5058     pipeline.AddColorAttachment(0, att_state1);
   5059     pipeline.AddColorAttachment(1, att_state2);
   5060     pipeline.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderpass);
   5061     m_errorMonitor->VerifyFound();
   5062     vkDestroyRenderPass(m_device->device(), renderpass, NULL);
   5063 }
   5064 
   5065 // Is the Pipeline compatible with the expectations of the Renderpass/subpasses?
   5066 TEST_F(VkLayerTest, PipelineRenderpassCompatibility) {
   5067     TEST_DESCRIPTION(
   5068         "Create a graphics pipeline that is incompatible with the requirements of its contained Renderpass/subpasses.");
   5069     ASSERT_NO_FATAL_FAILURE(Init());
   5070 
   5071     VkDescriptorSetObj ds_obj(m_device);
   5072     ds_obj.AppendDummy();
   5073     ds_obj.CreateVKDescriptorSet(m_commandBuffer);
   5074 
   5075     VkShaderObj vs_obj(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   5076 
   5077     VkPipelineColorBlendAttachmentState att_state1 = {};
   5078     att_state1.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
   5079     att_state1.blendEnable = VK_TRUE;
   5080 
   5081     VkRenderpassObj rp_obj(m_device);
   5082 
   5083     {
   5084         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_096005e2);
   5085         VkPipelineObj pipeline(m_device);
   5086         pipeline.AddShader(&vs_obj);
   5087         pipeline.AddColorAttachment(0, att_state1);
   5088 
   5089         VkGraphicsPipelineCreateInfo info = {};
   5090         pipeline.InitGraphicsPipelineCreateInfo(&info);
   5091         info.pColorBlendState = nullptr;
   5092 
   5093         pipeline.CreateVKPipeline(ds_obj.GetPipelineLayout(), rp_obj.handle(), &info);
   5094         m_errorMonitor->VerifyFound();
   5095     }
   5096 }
   5097 
   5098 TEST_F(VkLayerTest, CreateRenderPassAttachments) {
   5099     TEST_DESCRIPTION(
   5100         "Ensure that CreateRenderPass produces the expected validation errors when a subpass's attachments violate the valid usage "
   5101         "conditions.");
   5102 
   5103     ASSERT_NO_FATAL_FAILURE(Init());
   5104 
   5105     std::vector<VkAttachmentDescription> attachments = {
   5106         // input attachments
   5107         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5108          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
   5109         // color attachments
   5110         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5111          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5112          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
   5113         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5114          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5115          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
   5116         // depth attachment
   5117         {0, VK_FORMAT_D24_UNORM_S8_UINT, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5118          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   5119          VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL},
   5120         // resolve attachment
   5121         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5122          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5123          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
   5124         // preserve attachments
   5125         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
   5126          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   5127          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
   5128     };
   5129 
   5130     std::vector<VkAttachmentReference> input = {
   5131         {0, VK_IMAGE_LAYOUT_GENERAL},
   5132     };
   5133     std::vector<VkAttachmentReference> color = {
   5134         {1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
   5135         {2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
   5136     };
   5137     VkAttachmentReference depth = {3, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
   5138     std::vector<VkAttachmentReference> resolve = {
   5139         {4, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
   5140         {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
   5141     };
   5142     std::vector<uint32_t> preserve = {5};
   5143 
   5144     VkSubpassDescription subpass = {0,
   5145                                     VK_PIPELINE_BIND_POINT_GRAPHICS,
   5146                                     (uint32_t)input.size(),
   5147                                     input.data(),
   5148                                     (uint32_t)color.size(),
   5149                                     color.data(),
   5150                                     resolve.data(),
   5151                                     &depth,
   5152                                     (uint32_t)preserve.size(),
   5153                                     preserve.data()};
   5154 
   5155     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
   5156                                    nullptr,
   5157                                    0,
   5158                                    (uint32_t)attachments.size(),
   5159                                    attachments.data(),
   5160                                    1,
   5161                                    &subpass,
   5162                                    0,
   5163                                    nullptr};
   5164 
   5165     VkRenderPass rp;
   5166     VkResult err;
   5167     // Test too many color attachments
   5168     {
   5169         std::vector<VkAttachmentReference> too_many_colors(m_device->props.limits.maxColorAttachments + 1, color[0]);
   5170         subpass.colorAttachmentCount = (uint32_t)too_many_colors.size();
   5171         subpass.pColorAttachments = too_many_colors.data();
   5172         subpass.pResolveAttachments = NULL;
   5173         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1400069a);
   5174         err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   5175         m_errorMonitor->VerifyFound();
   5176         if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr);
   5177         subpass.colorAttachmentCount = (uint32_t)color.size();
   5178         subpass.pColorAttachments = color.data();
   5179         subpass.pResolveAttachments = resolve.data();
   5180     }
   5181     // Test sample count mismatch between color buffers
   5182     attachments[subpass.pColorAttachments[1].attachment].samples = VK_SAMPLE_COUNT_8_BIT;
   5183     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0082b401);
   5184     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   5185     m_errorMonitor->VerifyFound();
   5186     if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr);
   5187     attachments[subpass.pColorAttachments[1].attachment].samples = attachments[subpass.pColorAttachments[0].attachment].samples;
   5188     // Test sample count mismatch between color buffers and depth buffer
   5189     attachments[subpass.pDepthStencilAttachment->attachment].samples = VK_SAMPLE_COUNT_8_BIT;
   5190     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0082b401);
   5191     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   5192     m_errorMonitor->VerifyFound();
   5193     if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr);
   5194     attachments[subpass.pDepthStencilAttachment->attachment].samples = attachments[subpass.pColorAttachments[0].attachment].samples;
   5195     // Test resolve attachment with UNUSED color attachment
   5196     color[0].attachment = VK_ATTACHMENT_UNUSED;
   5197     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1400069e);
   5198     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   5199     m_errorMonitor->VerifyFound();
   5200     if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr);
   5201     color[0].attachment = 1;
   5202     // Test resolve from a single-sampled color attachment
   5203     attachments[subpass.pColorAttachments[0].attachment].samples = VK_SAMPLE_COUNT_1_BIT;
   5204     attachments[subpass.pColorAttachments[1].attachment].samples = VK_SAMPLE_COUNT_1_BIT;  // avoid mismatch (00337)
   5205     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_140006a0);
   5206     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   5207     m_errorMonitor->VerifyFound();
   5208     if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr);
   5209     attachments[subpass.pColorAttachments[0].attachment].samples = VK_SAMPLE_COUNT_4_BIT;
   5210     attachments[subpass.pColorAttachments[1].attachment].samples = VK_SAMPLE_COUNT_4_BIT;
   5211     // Test resolve to a multi-sampled resolve attachment
   5212     attachments[subpass.pResolveAttachments[0].attachment].samples = VK_SAMPLE_COUNT_4_BIT;
   5213     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_140006a2);
   5214     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   5215     m_errorMonitor->VerifyFound();
   5216     if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr);
   5217     attachments[subpass.pResolveAttachments[0].attachment].samples = VK_SAMPLE_COUNT_1_BIT;
   5218     // Test with color/resolve format mismatch
   5219     attachments[subpass.pColorAttachments[0].attachment].format = VK_FORMAT_R8G8B8A8_SRGB;
   5220     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_140006a4);
   5221     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   5222     m_errorMonitor->VerifyFound();
   5223     if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr);
   5224     attachments[subpass.pColorAttachments[0].attachment].format = attachments[subpass.pResolveAttachments[0].attachment].format;
   5225     // Test for UNUSED preserve attachments
   5226     preserve[0] = VK_ATTACHMENT_UNUSED;
   5227     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_140006aa);
   5228     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   5229     m_errorMonitor->VerifyFound();
   5230     if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr);
   5231     preserve[0] = 5;
   5232     // Test for preserve attachments used elsewhere in the subpass
   5233     color[0].attachment = preserve[0];
   5234     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_140006ac);
   5235     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   5236     m_errorMonitor->VerifyFound();
   5237     if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr);
   5238     color[0].attachment = 1;
   5239     // test for layout mismatch between input attachment and color attachment
   5240     input[0].attachment = color[0].attachment;
   5241     input[0].layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
   5242     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_140006ae);
   5243     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   5244     m_errorMonitor->VerifyFound();
   5245     if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr);
   5246     input[0].attachment = 0;
   5247     input[0].layout = VK_IMAGE_LAYOUT_GENERAL;
   5248     // test for layout mismatch between input attachment and depth attachment
   5249     input[0].attachment = depth.attachment;
   5250     input[0].layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
   5251     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_140006ae);
   5252     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   5253     m_errorMonitor->VerifyFound();
   5254     if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr);
   5255     input[0].attachment = 0;
   5256     input[0].layout = VK_IMAGE_LAYOUT_GENERAL;
   5257     // Test for attachment used first as input with loadOp=CLEAR
   5258     {
   5259         std::vector<VkSubpassDescription> subpasses = {subpass, subpass, subpass};
   5260         subpasses[0].inputAttachmentCount = 0;
   5261         subpasses[1].inputAttachmentCount = 0;
   5262         attachments[input[0].attachment].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
   5263         VkRenderPassCreateInfo rpci_multipass = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
   5264                                                  nullptr,
   5265                                                  0,
   5266                                                  (uint32_t)attachments.size(),
   5267                                                  attachments.data(),
   5268                                                  (uint32_t)subpasses.size(),
   5269                                                  subpasses.data(),
   5270                                                  0,
   5271                                                  nullptr};
   5272         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1400069c);
   5273         err = vkCreateRenderPass(m_device->device(), &rpci_multipass, nullptr, &rp);
   5274         m_errorMonitor->VerifyFound();
   5275         if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr);
   5276         attachments[input[0].attachment].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
   5277     }
   5278 }
   5279 
   5280 TEST_F(VkLayerTest, FramebufferCreateErrors) {
   5281     TEST_DESCRIPTION(
   5282         "Hit errors when attempting to create a framebuffer :\n"
   5283         " 1. Mismatch between framebuffer & renderPass attachmentCount\n"
   5284         " 2. Use a color image as depthStencil attachment\n"
   5285         " 3. Mismatch framebuffer & renderPass attachment formats\n"
   5286         " 4. Mismatch framebuffer & renderPass attachment #samples\n"
   5287         " 5. Framebuffer attachment w/ non-1 mip-levels\n"
   5288         " 6. Framebuffer attachment where dimensions don't match\n"
   5289         " 7. Framebuffer attachment where dimensions don't match\n"
   5290         " 8. Framebuffer attachment w/o identity swizzle\n"
   5291         " 9. framebuffer dimensions exceed physical device limits\n");
   5292 
   5293     ASSERT_NO_FATAL_FAILURE(Init());
   5294     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   5295 
   5296     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006d8);
   5297 
   5298     // Create a renderPass with a single color attachment
   5299     VkAttachmentReference attach = {};
   5300     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
   5301     VkSubpassDescription subpass = {};
   5302     subpass.pColorAttachments = &attach;
   5303     VkRenderPassCreateInfo rpci = {};
   5304     rpci.subpassCount = 1;
   5305     rpci.pSubpasses = &subpass;
   5306     rpci.attachmentCount = 1;
   5307     VkAttachmentDescription attach_desc = {};
   5308     attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
   5309     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
   5310     attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
   5311     rpci.pAttachments = &attach_desc;
   5312     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
   5313     VkRenderPass rp;
   5314     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
   5315     ASSERT_VK_SUCCESS(err);
   5316 
   5317     VkImageView ivs[2];
   5318     ivs[0] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM);
   5319     ivs[1] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM);
   5320     VkFramebufferCreateInfo fb_info = {};
   5321     fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
   5322     fb_info.pNext = NULL;
   5323     fb_info.renderPass = rp;
   5324     // Set mis-matching attachmentCount
   5325     fb_info.attachmentCount = 2;
   5326     fb_info.pAttachments = ivs;
   5327     fb_info.width = 100;
   5328     fb_info.height = 100;
   5329     fb_info.layers = 1;
   5330 
   5331     VkFramebuffer fb;
   5332     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
   5333 
   5334     m_errorMonitor->VerifyFound();
   5335     if (err == VK_SUCCESS) {
   5336         vkDestroyFramebuffer(m_device->device(), fb, NULL);
   5337     }
   5338     vkDestroyRenderPass(m_device->device(), rp, NULL);
   5339 
   5340     // Create a renderPass with a depth-stencil attachment created with
   5341     // IMAGE_USAGE_COLOR_ATTACHMENT
   5342     // Add our color attachment to pDepthStencilAttachment
   5343     subpass.pDepthStencilAttachment = &attach;
   5344     subpass.pColorAttachments = NULL;
   5345     VkRenderPass rp_ds;
   5346     err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_ds);
   5347     ASSERT_VK_SUCCESS(err);
   5348     // Set correct attachment count, but attachment has COLOR usage bit set
   5349     fb_info.attachmentCount = 1;
   5350     fb_info.renderPass = rp_ds;
   5351 
   5352     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006dc);
   5353     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
   5354 
   5355     m_errorMonitor->VerifyFound();
   5356     if (err == VK_SUCCESS) {
   5357         vkDestroyFramebuffer(m_device->device(), fb, NULL);
   5358     }
   5359     vkDestroyRenderPass(m_device->device(), rp_ds, NULL);
   5360 
   5361     // Create new renderpass with alternate attachment format from fb
   5362     attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM;
   5363     subpass.pDepthStencilAttachment = NULL;
   5364     subpass.pColorAttachments = &attach;
   5365     err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
   5366     ASSERT_VK_SUCCESS(err);
   5367 
   5368     // Cause error due to mis-matched formats between rp & fb
   5369     //  rp attachment 0 now has RGBA8 but corresponding fb attach is BGRA8
   5370     fb_info.renderPass = rp;
   5371     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006e0);
   5372     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
   5373 
   5374     m_errorMonitor->VerifyFound();
   5375     if (err == VK_SUCCESS) {
   5376         vkDestroyFramebuffer(m_device->device(), fb, NULL);
   5377     }
   5378     vkDestroyRenderPass(m_device->device(), rp, NULL);
   5379 
   5380     // Create new renderpass with alternate sample count from fb
   5381     attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
   5382     attach_desc.samples = VK_SAMPLE_COUNT_4_BIT;
   5383     err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
   5384     ASSERT_VK_SUCCESS(err);
   5385 
   5386     // Cause error due to mis-matched sample count between rp & fb
   5387     fb_info.renderPass = rp;
   5388     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006e2);
   5389     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
   5390 
   5391     m_errorMonitor->VerifyFound();
   5392     if (err == VK_SUCCESS) {
   5393         vkDestroyFramebuffer(m_device->device(), fb, NULL);
   5394     }
   5395 
   5396     vkDestroyRenderPass(m_device->device(), rp, NULL);
   5397 
   5398     {
   5399         // Create an image with 2 mip levels.
   5400         VkImageObj image(m_device);
   5401         image.Init(128, 128, 2, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   5402         ASSERT_TRUE(image.initialized());
   5403 
   5404         // Create a image view with two mip levels.
   5405         VkImageView view;
   5406         VkImageViewCreateInfo ivci = {};
   5407         ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   5408         ivci.image = image.handle();
   5409         ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
   5410         ivci.format = VK_FORMAT_B8G8R8A8_UNORM;
   5411         ivci.subresourceRange.layerCount = 1;
   5412         ivci.subresourceRange.baseMipLevel = 0;
   5413         // Set level count to 2 (only 1 is allowed for FB attachment)
   5414         ivci.subresourceRange.levelCount = 2;
   5415         ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   5416         err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
   5417         ASSERT_VK_SUCCESS(err);
   5418 
   5419         // Re-create renderpass to have matching sample count
   5420         attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
   5421         err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
   5422         ASSERT_VK_SUCCESS(err);
   5423 
   5424         fb_info.renderPass = rp;
   5425         fb_info.pAttachments = &view;
   5426         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006e6);
   5427         err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
   5428 
   5429         m_errorMonitor->VerifyFound();
   5430         if (err == VK_SUCCESS) {
   5431             vkDestroyFramebuffer(m_device->device(), fb, NULL);
   5432         }
   5433         vkDestroyImageView(m_device->device(), view, NULL);
   5434     }
   5435 
   5436     // Update view to original color buffer and grow FB dimensions too big
   5437     fb_info.pAttachments = ivs;
   5438     fb_info.height = 1024;
   5439     fb_info.width = 1024;
   5440     fb_info.layers = 2;
   5441     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006e4);
   5442     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
   5443 
   5444     m_errorMonitor->VerifyFound();
   5445     if (err == VK_SUCCESS) {
   5446         vkDestroyFramebuffer(m_device->device(), fb, NULL);
   5447     }
   5448 
   5449     {
   5450         // Create an image with one mip level.
   5451         VkImageObj image(m_device);
   5452         image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   5453         ASSERT_TRUE(image.initialized());
   5454 
   5455         // Create view attachment with non-identity swizzle
   5456         VkImageView view;
   5457         VkImageViewCreateInfo ivci = {};
   5458         ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   5459         ivci.image = image.handle();
   5460         ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
   5461         ivci.format = VK_FORMAT_B8G8R8A8_UNORM;
   5462         ivci.subresourceRange.layerCount = 1;
   5463         ivci.subresourceRange.baseMipLevel = 0;
   5464         ivci.subresourceRange.levelCount = 1;
   5465         ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   5466         ivci.components.r = VK_COMPONENT_SWIZZLE_G;
   5467         ivci.components.g = VK_COMPONENT_SWIZZLE_R;
   5468         ivci.components.b = VK_COMPONENT_SWIZZLE_A;
   5469         ivci.components.a = VK_COMPONENT_SWIZZLE_B;
   5470         err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
   5471         ASSERT_VK_SUCCESS(err);
   5472 
   5473         fb_info.pAttachments = &view;
   5474         fb_info.height = 100;
   5475         fb_info.width = 100;
   5476         fb_info.layers = 1;
   5477 
   5478         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006e8);
   5479         err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
   5480 
   5481         m_errorMonitor->VerifyFound();
   5482         if (err == VK_SUCCESS) {
   5483             vkDestroyFramebuffer(m_device->device(), fb, NULL);
   5484         }
   5485         vkDestroyImageView(m_device->device(), view, NULL);
   5486     }
   5487 
   5488     // reset attachment to color attachment
   5489     fb_info.pAttachments = ivs;
   5490 
   5491     // Request fb that exceeds max width
   5492     fb_info.width = m_device->props.limits.maxFramebufferWidth + 1;
   5493     fb_info.height = 100;
   5494     fb_info.layers = 1;
   5495     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006ec);
   5496     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006e4);
   5497     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
   5498     m_errorMonitor->VerifyFound();
   5499     if (err == VK_SUCCESS) {
   5500         vkDestroyFramebuffer(m_device->device(), fb, NULL);
   5501     }
   5502     // and width=0
   5503     fb_info.width = 0;
   5504     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006ea);
   5505     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
   5506     m_errorMonitor->VerifyFound();
   5507     if (err == VK_SUCCESS) {
   5508         vkDestroyFramebuffer(m_device->device(), fb, NULL);
   5509     }
   5510 
   5511     // Request fb that exceeds max height
   5512     fb_info.width = 100;
   5513     fb_info.height = m_device->props.limits.maxFramebufferHeight + 1;
   5514     fb_info.layers = 1;
   5515     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006f0);
   5516     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006e4);
   5517     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
   5518     m_errorMonitor->VerifyFound();
   5519     if (err == VK_SUCCESS) {
   5520         vkDestroyFramebuffer(m_device->device(), fb, NULL);
   5521     }
   5522     // and height=0
   5523     fb_info.height = 0;
   5524     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006ee);
   5525     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
   5526     m_errorMonitor->VerifyFound();
   5527     if (err == VK_SUCCESS) {
   5528         vkDestroyFramebuffer(m_device->device(), fb, NULL);
   5529     }
   5530 
   5531     // Request fb that exceeds max layers
   5532     fb_info.width = 100;
   5533     fb_info.height = 100;
   5534     fb_info.layers = m_device->props.limits.maxFramebufferLayers + 1;
   5535     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006f4);
   5536     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006e4);
   5537     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
   5538     m_errorMonitor->VerifyFound();
   5539     if (err == VK_SUCCESS) {
   5540         vkDestroyFramebuffer(m_device->device(), fb, NULL);
   5541     }
   5542     // and layers=0
   5543     fb_info.layers = 0;
   5544     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006f2);
   5545     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
   5546     m_errorMonitor->VerifyFound();
   5547     if (err == VK_SUCCESS) {
   5548         vkDestroyFramebuffer(m_device->device(), fb, NULL);
   5549     }
   5550 
   5551     vkDestroyRenderPass(m_device->device(), rp, NULL);
   5552 }
   5553 
   5554 TEST_F(VkLayerTest, DynamicDepthBiasNotBound) {
   5555     TEST_DESCRIPTION(
   5556         "Run a simple draw calls to validate failure when Depth Bias dynamic state is required but not correctly bound.");
   5557 
   5558     ASSERT_NO_FATAL_FAILURE(Init());
   5559     // Dynamic depth bias
   5560     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic depth bias state not set for this command buffer");
   5561     VKTriangleTest(BsoFailDepthBias);
   5562     m_errorMonitor->VerifyFound();
   5563 }
   5564 
   5565 TEST_F(VkLayerTest, DynamicLineWidthNotBound) {
   5566     TEST_DESCRIPTION(
   5567         "Run a simple draw calls to validate failure when Line Width dynamic state is required but not correctly bound.");
   5568 
   5569     ASSERT_NO_FATAL_FAILURE(Init());
   5570     // Dynamic line width
   5571     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic line width state not set for this command buffer");
   5572     VKTriangleTest(BsoFailLineWidth);
   5573     m_errorMonitor->VerifyFound();
   5574 }
   5575 
   5576 TEST_F(VkLayerTest, DynamicViewportNotBound) {
   5577     TEST_DESCRIPTION(
   5578         "Run a simple draw calls to validate failure when Viewport dynamic state is required but not correctly bound.");
   5579 
   5580     ASSERT_NO_FATAL_FAILURE(Init());
   5581     // Dynamic viewport state
   5582     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   5583                                          "Dynamic viewport(s) 0 are used by pipeline state object, but were not provided");
   5584     VKTriangleTest(BsoFailViewport);
   5585     m_errorMonitor->VerifyFound();
   5586 }
   5587 
   5588 TEST_F(VkLayerTest, DynamicScissorNotBound) {
   5589     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Scissor dynamic state is required but not correctly bound.");
   5590 
   5591     ASSERT_NO_FATAL_FAILURE(Init());
   5592     // Dynamic scissor state
   5593     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   5594                                          "Dynamic scissor(s) 0 are used by pipeline state object, but were not provided");
   5595     VKTriangleTest(BsoFailScissor);
   5596     m_errorMonitor->VerifyFound();
   5597 }
   5598 
   5599 TEST_F(VkLayerTest, DynamicBlendConstantsNotBound) {
   5600     TEST_DESCRIPTION(
   5601         "Run a simple draw calls to validate failure when Blend Constants dynamic state is required but not correctly bound.");
   5602 
   5603     ASSERT_NO_FATAL_FAILURE(Init());
   5604     // Dynamic blend constant state
   5605     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   5606                                          "Dynamic blend constants state not set for this command buffer");
   5607     VKTriangleTest(BsoFailBlend);
   5608     m_errorMonitor->VerifyFound();
   5609 }
   5610 
   5611 TEST_F(VkLayerTest, DynamicDepthBoundsNotBound) {
   5612     TEST_DESCRIPTION(
   5613         "Run a simple draw calls to validate failure when Depth Bounds dynamic state is required but not correctly bound.");
   5614 
   5615     ASSERT_NO_FATAL_FAILURE(Init());
   5616     if (!m_device->phy().features().depthBounds) {
   5617         printf("             Device does not support depthBounds test; skipped.\n");
   5618         return;
   5619     }
   5620     // Dynamic depth bounds
   5621     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   5622                                          "Dynamic depth bounds state not set for this command buffer");
   5623     VKTriangleTest(BsoFailDepthBounds);
   5624     m_errorMonitor->VerifyFound();
   5625 }
   5626 
   5627 TEST_F(VkLayerTest, DynamicStencilReadNotBound) {
   5628     TEST_DESCRIPTION(
   5629         "Run a simple draw calls to validate failure when Stencil Read dynamic state is required but not correctly bound.");
   5630 
   5631     ASSERT_NO_FATAL_FAILURE(Init());
   5632     // Dynamic stencil read mask
   5633     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   5634                                          "Dynamic stencil read mask state not set for this command buffer");
   5635     VKTriangleTest(BsoFailStencilReadMask);
   5636     m_errorMonitor->VerifyFound();
   5637 }
   5638 
   5639 TEST_F(VkLayerTest, DynamicStencilWriteNotBound) {
   5640     TEST_DESCRIPTION(
   5641         "Run a simple draw calls to validate failure when Stencil Write dynamic state is required but not correctly bound.");
   5642 
   5643     ASSERT_NO_FATAL_FAILURE(Init());
   5644     // Dynamic stencil write mask
   5645     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   5646                                          "Dynamic stencil write mask state not set for this command buffer");
   5647     VKTriangleTest(BsoFailStencilWriteMask);
   5648     m_errorMonitor->VerifyFound();
   5649 }
   5650 
   5651 TEST_F(VkLayerTest, DynamicStencilRefNotBound) {
   5652     TEST_DESCRIPTION(
   5653         "Run a simple draw calls to validate failure when Stencil Ref dynamic state is required but not correctly bound.");
   5654 
   5655     ASSERT_NO_FATAL_FAILURE(Init());
   5656     // Dynamic stencil reference
   5657     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   5658                                          "Dynamic stencil reference state not set for this command buffer");
   5659     VKTriangleTest(BsoFailStencilReference);
   5660     m_errorMonitor->VerifyFound();
   5661 }
   5662 
   5663 TEST_F(VkLayerTest, IndexBufferNotBound) {
   5664     TEST_DESCRIPTION("Run an indexed draw call without an index buffer bound.");
   5665 
   5666     ASSERT_NO_FATAL_FAILURE(Init());
   5667     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   5668                                          "Index buffer object not bound to this command buffer when Indexed ");
   5669     VKTriangleTest(BsoFailIndexBuffer);
   5670     m_errorMonitor->VerifyFound();
   5671 }
   5672 
   5673 TEST_F(VkLayerTest, CommandBufferTwoSubmits) {
   5674     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   5675                                          "was begun w/ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has been submitted");
   5676 
   5677     ASSERT_NO_FATAL_FAILURE(Init());
   5678     ASSERT_NO_FATAL_FAILURE(InitViewport());
   5679     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   5680 
   5681     // We luck out b/c by default the framework creates CB w/ the
   5682     // VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set
   5683     m_commandBuffer->begin();
   5684     m_commandBuffer->ClearAllBuffers(m_renderTargets, m_clear_color, nullptr, m_depth_clear_color, m_stencil_clear_color);
   5685     m_commandBuffer->end();
   5686 
   5687     // Bypass framework since it does the waits automatically
   5688     VkResult err = VK_SUCCESS;
   5689     VkSubmitInfo submit_info;
   5690     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   5691     submit_info.pNext = NULL;
   5692     submit_info.waitSemaphoreCount = 0;
   5693     submit_info.pWaitSemaphores = NULL;
   5694     submit_info.pWaitDstStageMask = NULL;
   5695     submit_info.commandBufferCount = 1;
   5696     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   5697     submit_info.signalSemaphoreCount = 0;
   5698     submit_info.pSignalSemaphores = NULL;
   5699 
   5700     err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   5701     ASSERT_VK_SUCCESS(err);
   5702     vkQueueWaitIdle(m_device->m_queue);
   5703 
   5704     // Cause validation error by re-submitting cmd buffer that should only be
   5705     // submitted once
   5706     err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   5707     vkQueueWaitIdle(m_device->m_queue);
   5708 
   5709     m_errorMonitor->VerifyFound();
   5710 }
   5711 
   5712 TEST_F(VkLayerTest, AllocDescriptorFromEmptyPool) {
   5713     TEST_DESCRIPTION("Attempt to allocate more sets and descriptors than descriptor pool has available.");
   5714     VkResult err;
   5715 
   5716     ASSERT_NO_FATAL_FAILURE(Init());
   5717     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   5718 
   5719     // Create Pool w/ 1 Sampler descriptor, but try to alloc Uniform Buffer
   5720     // descriptor from it
   5721     VkDescriptorPoolSize ds_type_count = {};
   5722     ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
   5723     ds_type_count.descriptorCount = 2;
   5724 
   5725     VkDescriptorPoolCreateInfo ds_pool_ci = {};
   5726     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
   5727     ds_pool_ci.pNext = NULL;
   5728     ds_pool_ci.flags = 0;
   5729     ds_pool_ci.maxSets = 1;
   5730     ds_pool_ci.poolSizeCount = 1;
   5731     ds_pool_ci.pPoolSizes = &ds_type_count;
   5732 
   5733     VkDescriptorPool ds_pool;
   5734     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
   5735     ASSERT_VK_SUCCESS(err);
   5736 
   5737     VkDescriptorSetLayoutBinding dsl_binding_samp = {};
   5738     dsl_binding_samp.binding = 0;
   5739     dsl_binding_samp.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
   5740     dsl_binding_samp.descriptorCount = 1;
   5741     dsl_binding_samp.stageFlags = VK_SHADER_STAGE_ALL;
   5742     dsl_binding_samp.pImmutableSamplers = NULL;
   5743 
   5744     const VkDescriptorSetLayoutObj ds_layout_samp(m_device, {dsl_binding_samp});
   5745 
   5746     // Try to allocate 2 sets when pool only has 1 set
   5747     VkDescriptorSet descriptor_sets[2];
   5748     VkDescriptorSetLayout set_layouts[2] = {ds_layout_samp.handle(), ds_layout_samp.handle()};
   5749     VkDescriptorSetAllocateInfo alloc_info = {};
   5750     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
   5751     alloc_info.descriptorSetCount = 2;
   5752     alloc_info.descriptorPool = ds_pool;
   5753     alloc_info.pSetLayouts = set_layouts;
   5754     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_04c00264);
   5755     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, descriptor_sets);
   5756     m_errorMonitor->VerifyFound();
   5757 
   5758     alloc_info.descriptorSetCount = 1;
   5759     // Create layout w/ descriptor type not available in pool
   5760     VkDescriptorSetLayoutBinding dsl_binding = {};
   5761     dsl_binding.binding = 0;
   5762     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   5763     dsl_binding.descriptorCount = 1;
   5764     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
   5765     dsl_binding.pImmutableSamplers = NULL;
   5766 
   5767     const VkDescriptorSetLayoutObj ds_layout_ub(m_device, {dsl_binding});
   5768 
   5769     VkDescriptorSet descriptor_set;
   5770     alloc_info.descriptorSetCount = 1;
   5771     alloc_info.pSetLayouts = &ds_layout_ub.handle();
   5772     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_04c00266);
   5773     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
   5774 
   5775     m_errorMonitor->VerifyFound();
   5776 
   5777     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
   5778 }
   5779 
   5780 TEST_F(VkLayerTest, FreeDescriptorFromOneShotPool) {
   5781     VkResult err;
   5782 
   5783     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_28600270);
   5784 
   5785     ASSERT_NO_FATAL_FAILURE(Init());
   5786     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   5787 
   5788     VkDescriptorPoolSize ds_type_count = {};
   5789     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   5790     ds_type_count.descriptorCount = 1;
   5791 
   5792     VkDescriptorPoolCreateInfo ds_pool_ci = {};
   5793     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
   5794     ds_pool_ci.pNext = NULL;
   5795     ds_pool_ci.maxSets = 1;
   5796     ds_pool_ci.poolSizeCount = 1;
   5797     ds_pool_ci.flags = 0;
   5798     // Not specifying VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT means
   5799     // app can only call vkResetDescriptorPool on this pool.;
   5800     ds_pool_ci.pPoolSizes = &ds_type_count;
   5801 
   5802     VkDescriptorPool ds_pool;
   5803     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
   5804     ASSERT_VK_SUCCESS(err);
   5805 
   5806     VkDescriptorSetLayoutBinding dsl_binding = {};
   5807     dsl_binding.binding = 0;
   5808     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   5809     dsl_binding.descriptorCount = 1;
   5810     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
   5811     dsl_binding.pImmutableSamplers = NULL;
   5812 
   5813     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
   5814 
   5815     VkDescriptorSet descriptorSet;
   5816     VkDescriptorSetAllocateInfo alloc_info = {};
   5817     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
   5818     alloc_info.descriptorSetCount = 1;
   5819     alloc_info.descriptorPool = ds_pool;
   5820     alloc_info.pSetLayouts = &ds_layout.handle();
   5821     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
   5822     ASSERT_VK_SUCCESS(err);
   5823 
   5824     err = vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptorSet);
   5825     m_errorMonitor->VerifyFound();
   5826 
   5827     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
   5828 }
   5829 
   5830 TEST_F(VkLayerTest, InvalidDescriptorPool) {
   5831     // Attempt to clear Descriptor Pool with bad object.
   5832     // ObjectTracker should catch this.
   5833 
   5834     ASSERT_NO_FATAL_FAILURE(Init());
   5835     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_32a04601);
   5836     uint64_t fake_pool_handle = 0xbaad6001;
   5837     VkDescriptorPool bad_pool = reinterpret_cast<VkDescriptorPool &>(fake_pool_handle);
   5838     vkResetDescriptorPool(device(), bad_pool, 0);
   5839     m_errorMonitor->VerifyFound();
   5840 }
   5841 
   5842 TEST_F(VkLayerTest, InvalidDescriptorSet) {
   5843     // Attempt to bind an invalid Descriptor Set to a valid Command Buffer
   5844     // ObjectTracker should catch this.
   5845     // Create a valid cmd buffer
   5846     // call vkCmdBindDescriptorSets w/ false Descriptor Set
   5847 
   5848     uint64_t fake_set_handle = 0xbaad6001;
   5849     VkDescriptorSet bad_set = reinterpret_cast<VkDescriptorSet &>(fake_set_handle);
   5850 
   5851     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_17c13001);
   5852 
   5853     ASSERT_NO_FATAL_FAILURE(Init());
   5854 
   5855     VkDescriptorSetLayoutBinding layout_binding = {};
   5856     layout_binding.binding = 0;
   5857     layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   5858     layout_binding.descriptorCount = 1;
   5859     layout_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
   5860     layout_binding.pImmutableSamplers = NULL;
   5861 
   5862     const VkDescriptorSetLayoutObj descriptor_set_layout(m_device, {layout_binding});
   5863 
   5864     const VkPipelineLayoutObj pipeline_layout(DeviceObj(), {&descriptor_set_layout});
   5865 
   5866     m_commandBuffer->begin();
   5867     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &bad_set, 0,
   5868                             NULL);
   5869     m_errorMonitor->VerifyFound();
   5870     m_commandBuffer->end();
   5871 }
   5872 
   5873 TEST_F(VkLayerTest, InvalidDescriptorSetLayout) {
   5874     // Attempt to create a Pipeline Layout with an invalid Descriptor Set Layout.
   5875     // ObjectTracker should catch this.
   5876     uint64_t fake_layout_handle = 0xbaad6001;
   5877     VkDescriptorSetLayout bad_layout = reinterpret_cast<VkDescriptorSetLayout &>(fake_layout_handle);
   5878     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe22c01);
   5879     ASSERT_NO_FATAL_FAILURE(Init());
   5880     VkPipelineLayout pipeline_layout;
   5881     VkPipelineLayoutCreateInfo plci = {};
   5882     plci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
   5883     plci.pNext = NULL;
   5884     plci.setLayoutCount = 1;
   5885     plci.pSetLayouts = &bad_layout;
   5886     vkCreatePipelineLayout(device(), &plci, NULL, &pipeline_layout);
   5887 
   5888     m_errorMonitor->VerifyFound();
   5889 }
   5890 
   5891 TEST_F(VkLayerTest, WriteDescriptorSetIntegrityCheck) {
   5892     TEST_DESCRIPTION(
   5893         "This test verifies some requirements of chapter 13.2.3 of the Vulkan Spec "
   5894         "1) A uniform buffer update must have a valid buffer index. "
   5895         "2) When using an array of descriptors in a single WriteDescriptor, the descriptor types and stageflags "
   5896         "must all be the same. "
   5897         "3) Immutable Sampler state must match across descriptors");
   5898 
   5899     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15c00288);
   5900 
   5901     ASSERT_NO_FATAL_FAILURE(Init());
   5902     VkDescriptorPoolSize ds_type_count[4] = {};
   5903     ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   5904     ds_type_count[0].descriptorCount = 1;
   5905     ds_type_count[1].type = VK_DESCRIPTOR_TYPE_SAMPLER;
   5906     ds_type_count[1].descriptorCount = 1;
   5907     ds_type_count[2].type = VK_DESCRIPTOR_TYPE_SAMPLER;
   5908     ds_type_count[2].descriptorCount = 1;
   5909     ds_type_count[3].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
   5910     ds_type_count[3].descriptorCount = 1;
   5911 
   5912     VkDescriptorPoolCreateInfo ds_pool_ci = {};
   5913     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
   5914     ds_pool_ci.maxSets = 1;
   5915     ds_pool_ci.poolSizeCount = sizeof(ds_type_count) / sizeof(VkDescriptorPoolSize);
   5916     ds_pool_ci.pPoolSizes = ds_type_count;
   5917 
   5918     VkDescriptorPool ds_pool;
   5919     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
   5920     ASSERT_VK_SUCCESS(err);
   5921 
   5922     VkDescriptorSetLayoutBinding dslb1 = {};
   5923     dslb1.binding = 0;
   5924     dslb1.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   5925     dslb1.descriptorCount = 1;
   5926     dslb1.stageFlags = VK_SHADER_STAGE_ALL;
   5927     dslb1.pImmutableSamplers = NULL;
   5928 
   5929     VkDescriptorSetLayoutBinding dslb2 = {};
   5930     dslb2.binding = 1;
   5931     dslb2.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
   5932     dslb2.descriptorCount = 1;
   5933     dslb2.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
   5934     dslb2.pImmutableSamplers = NULL;
   5935 
   5936     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
   5937     VkSampler sampler;
   5938 
   5939     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
   5940     ASSERT_VK_SUCCESS(err);
   5941 
   5942     VkDescriptorSetLayoutBinding dslb3 = {};
   5943     dslb3.binding = 2;
   5944     dslb3.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
   5945     dslb3.descriptorCount = 1;
   5946     dslb3.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
   5947     dslb3.pImmutableSamplers = static_cast<VkSampler *>(&sampler);
   5948 
   5949     const std::vector<VkDescriptorSetLayoutBinding> layout_bindings = {dslb1, dslb2, dslb3};
   5950     const VkDescriptorSetLayoutObj ds_layout(m_device, layout_bindings);
   5951 
   5952     VkDescriptorSetAllocateInfo alloc_info = {};
   5953     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
   5954     alloc_info.descriptorSetCount = 1;
   5955     alloc_info.descriptorPool = ds_pool;
   5956     alloc_info.pSetLayouts = &ds_layout.handle();
   5957     VkDescriptorSet descriptorSet;
   5958     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
   5959     ASSERT_VK_SUCCESS(err);
   5960 
   5961     VkWriteDescriptorSet descriptor_write = {};
   5962     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   5963     descriptor_write.dstSet = descriptorSet;
   5964     descriptor_write.dstBinding = 0;
   5965     descriptor_write.descriptorCount = 1;
   5966     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   5967 
   5968     // 1) The uniform buffer is intentionally invalid here
   5969     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   5970     m_errorMonitor->VerifyFound();
   5971 
   5972     // Create a buffer to update the descriptor with
   5973     uint32_t qfi = 0;
   5974     VkBufferCreateInfo buffCI = {};
   5975     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   5976     buffCI.size = 1024;
   5977     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
   5978     buffCI.queueFamilyIndexCount = 1;
   5979     buffCI.pQueueFamilyIndices = &qfi;
   5980 
   5981     VkBuffer dyub;
   5982     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
   5983     ASSERT_VK_SUCCESS(err);
   5984 
   5985     VkDeviceMemory mem;
   5986     VkMemoryRequirements mem_reqs;
   5987     vkGetBufferMemoryRequirements(m_device->device(), dyub, &mem_reqs);
   5988 
   5989     VkMemoryAllocateInfo mem_alloc_info = {};
   5990     mem_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   5991     mem_alloc_info.allocationSize = mem_reqs.size;
   5992     m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
   5993     err = vkAllocateMemory(m_device->device(), &mem_alloc_info, NULL, &mem);
   5994     ASSERT_VK_SUCCESS(err);
   5995 
   5996     err = vkBindBufferMemory(m_device->device(), dyub, mem, 0);
   5997     ASSERT_VK_SUCCESS(err);
   5998 
   5999     VkDescriptorBufferInfo buffInfo[2] = {};
   6000     buffInfo[0].buffer = dyub;
   6001     buffInfo[0].offset = 0;
   6002     buffInfo[0].range = 1024;
   6003     buffInfo[1].buffer = dyub;
   6004     buffInfo[1].offset = 0;
   6005     buffInfo[1].range = 1024;
   6006     descriptor_write.pBufferInfo = buffInfo;
   6007     descriptor_write.descriptorCount = 2;
   6008 
   6009     // 2) The stateFlags don't match between the first and second descriptor
   6010     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15c00282);
   6011     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   6012     m_errorMonitor->VerifyFound();
   6013 
   6014     // 3) The second descriptor has a null_ptr pImmutableSamplers and
   6015     // the third descriptor contains an immutable sampler
   6016     descriptor_write.dstBinding = 1;
   6017     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
   6018 
   6019     // Make pImageInfo index non-null to avoid complaints of it missing
   6020     VkDescriptorImageInfo imageInfo = {};
   6021     imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
   6022     descriptor_write.pImageInfo = &imageInfo;
   6023     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15c00282);
   6024     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   6025     m_errorMonitor->VerifyFound();
   6026 
   6027     vkDestroyBuffer(m_device->device(), dyub, NULL);
   6028     vkFreeMemory(m_device->device(), mem, NULL);
   6029     vkDestroySampler(m_device->device(), sampler, NULL);
   6030     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
   6031 }
   6032 
   6033 TEST_F(VkLayerTest, WriteDescriptorSetConsecutiveUpdates) {
   6034     TEST_DESCRIPTION(
   6035         "Verifies that updates rolling over to next descriptor work correctly by destroying buffer from consecutive update known "
   6036         "to be used in descriptor set and verifying that error is flagged.");
   6037 
   6038     ASSERT_NO_FATAL_FAILURE(Init());
   6039     ASSERT_NO_FATAL_FAILURE(InitViewport());
   6040     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   6041 
   6042     OneOffDescriptorSet ds(m_device, {
   6043                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2, VK_SHADER_STAGE_ALL, nullptr},
   6044                                          {1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
   6045                                      });
   6046 
   6047     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
   6048 
   6049     uint32_t qfi = 0;
   6050     VkBufferCreateInfo bci = {};
   6051     bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   6052     bci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
   6053     bci.size = 2048;
   6054     bci.queueFamilyIndexCount = 1;
   6055     bci.pQueueFamilyIndices = &qfi;
   6056     vk_testing::Buffer buffer0;
   6057     buffer0.init(*m_device, bci);
   6058     VkPipelineObj pipe(m_device);
   6059     {  // Scope 2nd buffer to cause early destruction
   6060         vk_testing::Buffer buffer1;
   6061         bci.size = 1024;
   6062         buffer1.init(*m_device, bci);
   6063 
   6064         VkDescriptorBufferInfo buffer_info[3] = {};
   6065         buffer_info[0].buffer = buffer0.handle();
   6066         buffer_info[0].offset = 0;
   6067         buffer_info[0].range = 1024;
   6068         buffer_info[1].buffer = buffer0.handle();
   6069         buffer_info[1].offset = 1024;
   6070         buffer_info[1].range = 1024;
   6071         buffer_info[2].buffer = buffer1.handle();
   6072         buffer_info[2].offset = 0;
   6073         buffer_info[2].range = 1024;
   6074 
   6075         VkWriteDescriptorSet descriptor_write = {};
   6076         descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   6077         descriptor_write.dstSet = ds.set_;  // descriptor_set;
   6078         descriptor_write.dstBinding = 0;
   6079         descriptor_write.descriptorCount = 3;
   6080         descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   6081         descriptor_write.pBufferInfo = buffer_info;
   6082 
   6083         // Update descriptor
   6084         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   6085 
   6086         // Create PSO that uses the uniform buffers
   6087         char const *vsSource =
   6088             "#version 450\n"
   6089             "\n"
   6090             "void main(){\n"
   6091             "   gl_Position = vec4(1);\n"
   6092             "}\n";
   6093         char const *fsSource =
   6094             "#version 450\n"
   6095             "\n"
   6096             "layout(location=0) out vec4 x;\n"
   6097             "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
   6098             "layout(set=0) layout(binding=1) uniform blah { int x; } duh;\n"
   6099             "void main(){\n"
   6100             "   x = vec4(duh.x, bar.y, bar.x, 1);\n"
   6101             "}\n";
   6102         VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   6103         VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   6104 
   6105         pipe.AddShader(&vs);
   6106         pipe.AddShader(&fs);
   6107         pipe.AddDefaultColorAttachment();
   6108 
   6109         VkResult err = pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   6110         ASSERT_VK_SUCCESS(err);
   6111 
   6112         m_commandBuffer->begin();
   6113         m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   6114 
   6115         vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   6116         vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
   6117                                 &ds.set_, 0, nullptr);
   6118 
   6119         VkViewport viewport = {0, 0, 16, 16, 0, 1};
   6120         vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   6121         VkRect2D scissor = {{0, 0}, {16, 16}};
   6122         vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
   6123         vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
   6124         vkCmdEndRenderPass(m_commandBuffer->handle());
   6125         m_commandBuffer->end();
   6126     }
   6127     // buffer2 just went out of scope and was destroyed along with its memory
   6128     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Buffer ");
   6129     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound DeviceMemory ");
   6130     VkSubmitInfo submit_info = {};
   6131     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   6132     submit_info.commandBufferCount = 1;
   6133     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   6134     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   6135     m_errorMonitor->VerifyFound();
   6136 }
   6137 
   6138 TEST_F(VkLayerTest, CreatePipelineLayoutExceedsSetLimit) {
   6139     TEST_DESCRIPTION("Attempt to create a pipeline layout using more than the physical limit of SetLayouts.");
   6140 
   6141     ASSERT_NO_FATAL_FAILURE(Init());
   6142 
   6143     VkDescriptorSetLayoutBinding layout_binding = {};
   6144     layout_binding.binding = 0;
   6145     layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   6146     layout_binding.descriptorCount = 1;
   6147     layout_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
   6148     layout_binding.pImmutableSamplers = NULL;
   6149 
   6150     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
   6151     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
   6152     ds_layout_ci.bindingCount = 1;
   6153     ds_layout_ci.pBindings = &layout_binding;
   6154     VkDescriptorSetLayout ds_layout = {};
   6155     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
   6156     ASSERT_VK_SUCCESS(err);
   6157 
   6158     // Create an array of DSLs, one larger than the physical limit
   6159     const auto excess_layouts = 1 + m_device->phy().properties().limits.maxBoundDescriptorSets;
   6160     std::vector<VkDescriptorSetLayout> dsl_array(excess_layouts, ds_layout);
   6161 
   6162     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
   6163     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
   6164     pipeline_layout_ci.pNext = NULL;
   6165     pipeline_layout_ci.setLayoutCount = excess_layouts;
   6166     pipeline_layout_ci.pSetLayouts = dsl_array.data();
   6167 
   6168     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe0023c);
   6169     VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
   6170     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
   6171     m_errorMonitor->VerifyFound();
   6172 
   6173     // Clean up
   6174     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
   6175 }
   6176 
   6177 TEST_F(VkLayerTest, CreatePipelineLayoutExcessPerStageDescriptors) {
   6178     TEST_DESCRIPTION("Attempt to create a pipeline layout where total descriptors exceed per-stage limits");
   6179 
   6180     ASSERT_NO_FATAL_FAILURE(Init());
   6181 
   6182     uint32_t max_uniform_buffers = m_device->phy().properties().limits.maxPerStageDescriptorUniformBuffers;
   6183     uint32_t max_storage_buffers = m_device->phy().properties().limits.maxPerStageDescriptorStorageBuffers;
   6184     uint32_t max_sampled_images = m_device->phy().properties().limits.maxPerStageDescriptorSampledImages;
   6185     uint32_t max_storage_images = m_device->phy().properties().limits.maxPerStageDescriptorStorageImages;
   6186     uint32_t max_samplers = m_device->phy().properties().limits.maxPerStageDescriptorSamplers;
   6187     uint32_t max_combined = std::min(max_samplers, max_sampled_images);
   6188     uint32_t max_input_attachments = m_device->phy().properties().limits.maxPerStageDescriptorInputAttachments;
   6189 
   6190     uint32_t sum_dyn_uniform_buffers = m_device->phy().properties().limits.maxDescriptorSetUniformBuffersDynamic;
   6191     uint32_t sum_uniform_buffers = m_device->phy().properties().limits.maxDescriptorSetUniformBuffers;
   6192     uint32_t sum_dyn_storage_buffers = m_device->phy().properties().limits.maxDescriptorSetStorageBuffersDynamic;
   6193     uint32_t sum_storage_buffers = m_device->phy().properties().limits.maxDescriptorSetStorageBuffers;
   6194     uint32_t sum_sampled_images = m_device->phy().properties().limits.maxDescriptorSetSampledImages;
   6195     uint32_t sum_storage_images = m_device->phy().properties().limits.maxDescriptorSetStorageImages;
   6196     uint32_t sum_samplers = m_device->phy().properties().limits.maxDescriptorSetSamplers;
   6197     uint32_t sum_input_attachments = m_device->phy().properties().limits.maxDescriptorSetInputAttachments;
   6198 
   6199     uint32_t gfx_stages = 2;  // vtx, frag
   6200     gfx_stages += (m_device->phy().features().geometryShader ? 1 : 0);
   6201     gfx_stages += (m_device->phy().features().tessellationShader ? 2 : 0);
   6202 
   6203     // Devices that report UINT_MAX for any of these limits can't run this test
   6204     if (UINT_MAX == std::max({max_uniform_buffers, max_storage_buffers, max_sampled_images, max_storage_images, max_samplers})) {
   6205         printf("             Physical device limits report as 2^32-1. Skipping test.\n");
   6206         return;
   6207     }
   6208 
   6209     VkDescriptorSetLayoutBinding dslb = {};
   6210     std::vector<VkDescriptorSetLayoutBinding> dslb_vec = {};
   6211     VkDescriptorSetLayout ds_layout = VK_NULL_HANDLE;
   6212     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
   6213     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
   6214     ds_layout_ci.pNext = NULL;
   6215     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
   6216     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
   6217     pipeline_layout_ci.pNext = NULL;
   6218     pipeline_layout_ci.setLayoutCount = 1;
   6219     pipeline_layout_ci.pSetLayouts = &ds_layout;
   6220     VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
   6221 
   6222     // VU 0fe0023e - too many sampler type descriptors in fragment stage
   6223     dslb_vec.clear();
   6224     dslb.binding = 0;
   6225     dslb.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
   6226     dslb.descriptorCount = max_samplers;
   6227     dslb.stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS;
   6228     dslb.pImmutableSamplers = NULL;
   6229     dslb_vec.push_back(dslb);
   6230     dslb.binding = 1;
   6231     dslb.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
   6232     dslb.descriptorCount = max_combined;
   6233     dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
   6234     dslb_vec.push_back(dslb);
   6235 
   6236     ds_layout_ci.bindingCount = dslb_vec.size();
   6237     ds_layout_ci.pBindings = dslb_vec.data();
   6238     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
   6239     ASSERT_VK_SUCCESS(err);
   6240 
   6241     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe0023e);
   6242     if ((max_samplers * gfx_stages + max_combined) > sum_samplers) {
   6243         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   6244                                              VALIDATION_ERROR_0fe00d1a);  // expect all-stages sum too
   6245     }
   6246     if (max_combined > sum_sampled_images) {
   6247         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   6248                                              VALIDATION_ERROR_0fe00d24);  // expect all-stages sum too
   6249     }
   6250     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
   6251     m_errorMonitor->VerifyFound();
   6252     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
   6253     pipeline_layout = VK_NULL_HANDLE;
   6254     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
   6255 
   6256     // VU 0fe00240 - too many uniform buffer type descriptors in vertex stage
   6257     dslb_vec.clear();
   6258     dslb.binding = 0;
   6259     dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   6260     dslb.descriptorCount = 1 + (max_uniform_buffers / 2);
   6261     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
   6262     dslb_vec.push_back(dslb);
   6263     dslb.binding = 1;
   6264     dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
   6265     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
   6266     dslb_vec.push_back(dslb);
   6267 
   6268     ds_layout_ci.bindingCount = dslb_vec.size();
   6269     ds_layout_ci.pBindings = dslb_vec.data();
   6270     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
   6271     ASSERT_VK_SUCCESS(err);
   6272 
   6273     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00240);
   6274     if ((2 * dslb.descriptorCount) > sum_uniform_buffers) {
   6275         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   6276                                              VALIDATION_ERROR_0fe00d1c);  // expect all-stages sum too
   6277     }
   6278     if (dslb.descriptorCount > sum_dyn_uniform_buffers) {
   6279         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   6280                                              VALIDATION_ERROR_0fe00d1e);  // expect all-stages sum too
   6281     }
   6282     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
   6283     m_errorMonitor->VerifyFound();
   6284     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
   6285     pipeline_layout = VK_NULL_HANDLE;
   6286     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
   6287 
   6288     // VU 0fe00242 - too many storage buffer type descriptors in compute stage
   6289     dslb_vec.clear();
   6290     dslb.binding = 0;
   6291     dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
   6292     dslb.descriptorCount = 1 + (max_storage_buffers / 3);
   6293     dslb.stageFlags = VK_SHADER_STAGE_ALL;
   6294     dslb_vec.push_back(dslb);
   6295     dslb.binding = 1;
   6296     dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
   6297     dslb_vec.push_back(dslb);
   6298     dslb.binding = 2;
   6299     dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
   6300     dslb.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
   6301     dslb_vec.push_back(dslb);
   6302 
   6303     ds_layout_ci.bindingCount = dslb_vec.size();
   6304     ds_layout_ci.pBindings = dslb_vec.data();
   6305     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
   6306     ASSERT_VK_SUCCESS(err);
   6307 
   6308     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00242);
   6309     if (((gfx_stages + 1) * dslb.descriptorCount) > sum_dyn_storage_buffers) {
   6310         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   6311                                              VALIDATION_ERROR_0fe00d22);  // expect all-stages sum too
   6312     }
   6313     if (((gfx_stages + 2) * dslb.descriptorCount) > sum_storage_buffers) {
   6314         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   6315                                              VALIDATION_ERROR_0fe00d20);  // expect all-stages sum too
   6316     }
   6317     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
   6318     m_errorMonitor->VerifyFound();
   6319     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
   6320     pipeline_layout = VK_NULL_HANDLE;
   6321     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
   6322 
   6323     // VU 0fe00244 - too many sampled image type descriptors in multiple stages
   6324     dslb_vec.clear();
   6325     dslb.binding = 0;
   6326     dslb.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
   6327     dslb.descriptorCount = max_sampled_images / 2;
   6328     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
   6329     dslb_vec.push_back(dslb);
   6330     dslb.binding = 1;
   6331     dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
   6332     dslb.stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS;
   6333     dslb_vec.push_back(dslb);
   6334     dslb.binding = 2;
   6335     dslb.descriptorCount = max_combined;
   6336     dslb.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
   6337     dslb_vec.push_back(dslb);
   6338 
   6339     ds_layout_ci.bindingCount = dslb_vec.size();
   6340     ds_layout_ci.pBindings = dslb_vec.data();
   6341     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
   6342     ASSERT_VK_SUCCESS(err);
   6343 
   6344     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00244);
   6345     if (max_combined + ((gfx_stages + 2) * (max_sampled_images / 2)) > sum_sampled_images) {
   6346         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   6347                                              VALIDATION_ERROR_0fe00d24);  // expect all-stages sum too
   6348     }
   6349     if ((gfx_stages * max_combined) > sum_samplers) {
   6350         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   6351                                              VALIDATION_ERROR_0fe00d1a);  // expect all-stages sum too
   6352     }
   6353     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
   6354     m_errorMonitor->VerifyFound();
   6355     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
   6356     pipeline_layout = VK_NULL_HANDLE;
   6357     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
   6358 
   6359     // VU 0fe00246 - too many storage image type descriptors in fragment stage
   6360     dslb_vec.clear();
   6361     dslb.binding = 0;
   6362     dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
   6363     dslb.descriptorCount = 1 + (max_storage_images / 2);
   6364     dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
   6365     dslb_vec.push_back(dslb);
   6366     dslb.binding = 1;
   6367     dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
   6368     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
   6369     dslb_vec.push_back(dslb);
   6370 
   6371     ds_layout_ci.bindingCount = dslb_vec.size();
   6372     ds_layout_ci.pBindings = dslb_vec.data();
   6373     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
   6374     ASSERT_VK_SUCCESS(err);
   6375 
   6376     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00246);
   6377     if ((4 * dslb.descriptorCount) > sum_storage_images) {
   6378         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   6379                                              VALIDATION_ERROR_0fe00d26);  // expect all-stages sum too
   6380     }
   6381     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
   6382     m_errorMonitor->VerifyFound();
   6383     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
   6384     pipeline_layout = VK_NULL_HANDLE;
   6385     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
   6386 
   6387     // VU 0fe00d18 - too many input attachments in fragment stage
   6388     dslb_vec.clear();
   6389     dslb.binding = 0;
   6390     dslb.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
   6391     dslb.descriptorCount = 1 + max_input_attachments;
   6392     dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
   6393     dslb_vec.push_back(dslb);
   6394 
   6395     ds_layout_ci.bindingCount = dslb_vec.size();
   6396     ds_layout_ci.pBindings = dslb_vec.data();
   6397     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
   6398     ASSERT_VK_SUCCESS(err);
   6399 
   6400     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00d18);
   6401     if (dslb.descriptorCount > sum_input_attachments) {
   6402         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   6403                                              VALIDATION_ERROR_0fe00d28);  // expect all-stages sum too
   6404     }
   6405     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
   6406     m_errorMonitor->VerifyFound();
   6407     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
   6408     pipeline_layout = VK_NULL_HANDLE;
   6409     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
   6410 }
   6411 
   6412 TEST_F(VkLayerTest, CreatePipelineLayoutExcessDescriptorsOverall) {
   6413     TEST_DESCRIPTION("Attempt to create a pipeline layout where total descriptors summed over all stages exceed limits");
   6414 
   6415     ASSERT_NO_FATAL_FAILURE(Init());
   6416 
   6417     uint32_t max_uniform_buffers = m_device->phy().properties().limits.maxPerStageDescriptorUniformBuffers;
   6418     uint32_t max_storage_buffers = m_device->phy().properties().limits.maxPerStageDescriptorStorageBuffers;
   6419     uint32_t max_sampled_images = m_device->phy().properties().limits.maxPerStageDescriptorSampledImages;
   6420     uint32_t max_storage_images = m_device->phy().properties().limits.maxPerStageDescriptorStorageImages;
   6421     uint32_t max_samplers = m_device->phy().properties().limits.maxPerStageDescriptorSamplers;
   6422     uint32_t max_input_attachments = m_device->phy().properties().limits.maxPerStageDescriptorInputAttachments;
   6423 
   6424     uint32_t sum_dyn_uniform_buffers = m_device->phy().properties().limits.maxDescriptorSetUniformBuffersDynamic;
   6425     uint32_t sum_uniform_buffers = m_device->phy().properties().limits.maxDescriptorSetUniformBuffers;
   6426     uint32_t sum_dyn_storage_buffers = m_device->phy().properties().limits.maxDescriptorSetStorageBuffersDynamic;
   6427     uint32_t sum_storage_buffers = m_device->phy().properties().limits.maxDescriptorSetStorageBuffers;
   6428     uint32_t sum_sampled_images = m_device->phy().properties().limits.maxDescriptorSetSampledImages;
   6429     uint32_t sum_storage_images = m_device->phy().properties().limits.maxDescriptorSetStorageImages;
   6430     uint32_t sum_samplers = m_device->phy().properties().limits.maxDescriptorSetSamplers;
   6431     uint32_t sum_input_attachments = m_device->phy().properties().limits.maxDescriptorSetInputAttachments;
   6432 
   6433     // Devices that report UINT_MAX for any of these limits can't run this test
   6434     if (UINT_MAX == std::max({sum_dyn_uniform_buffers, sum_uniform_buffers, sum_dyn_storage_buffers, sum_storage_buffers,
   6435                               sum_sampled_images, sum_storage_images, sum_samplers, sum_input_attachments})) {
   6436         printf("             Physical device limits report as 2^32-1. Skipping test.\n");
   6437         return;
   6438     }
   6439 
   6440     VkDescriptorSetLayoutBinding dslb = {};
   6441     std::vector<VkDescriptorSetLayoutBinding> dslb_vec = {};
   6442     VkDescriptorSetLayout ds_layout = VK_NULL_HANDLE;
   6443     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
   6444     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
   6445     ds_layout_ci.pNext = NULL;
   6446     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
   6447     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
   6448     pipeline_layout_ci.pNext = NULL;
   6449     pipeline_layout_ci.setLayoutCount = 1;
   6450     pipeline_layout_ci.pSetLayouts = &ds_layout;
   6451     VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
   6452 
   6453     // VU 0fe00d1a - too many sampler type descriptors overall
   6454     dslb_vec.clear();
   6455     dslb.binding = 0;
   6456     dslb.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
   6457     dslb.descriptorCount = 1 + (sum_samplers / 2);
   6458     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
   6459     dslb.pImmutableSamplers = NULL;
   6460     dslb_vec.push_back(dslb);
   6461     dslb.binding = 1;
   6462     dslb.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
   6463     dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
   6464     dslb_vec.push_back(dslb);
   6465 
   6466     ds_layout_ci.bindingCount = dslb_vec.size();
   6467     ds_layout_ci.pBindings = dslb_vec.data();
   6468     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
   6469     ASSERT_VK_SUCCESS(err);
   6470 
   6471     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00d1a);
   6472     if (dslb.descriptorCount > max_samplers) {
   6473         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   6474                                              VALIDATION_ERROR_0fe0023e);  // expect max-per-stage too
   6475     }
   6476     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
   6477     m_errorMonitor->VerifyFound();
   6478     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
   6479     pipeline_layout = VK_NULL_HANDLE;
   6480     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
   6481 
   6482     // VU 0fe00d1c - too many uniform buffer type descriptors overall
   6483     dslb_vec.clear();
   6484     dslb.binding = 0;
   6485     dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   6486     dslb.descriptorCount = 1 + (sum_uniform_buffers / 2);
   6487     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
   6488     dslb.pImmutableSamplers = NULL;
   6489     dslb_vec.push_back(dslb);
   6490 
   6491     ds_layout_ci.bindingCount = dslb_vec.size();
   6492     ds_layout_ci.pBindings = dslb_vec.data();
   6493     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
   6494     ASSERT_VK_SUCCESS(err);
   6495 
   6496     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00d1c);
   6497     if (dslb.descriptorCount > max_uniform_buffers) {
   6498         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   6499                                              VALIDATION_ERROR_0fe00240);  // expect max-per-stage too
   6500     }
   6501     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
   6502     m_errorMonitor->VerifyFound();
   6503     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
   6504     pipeline_layout = VK_NULL_HANDLE;
   6505     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
   6506 
   6507     // VU 0fe00d1e - too many dynamic uniform buffer type descriptors overall
   6508     dslb_vec.clear();
   6509     dslb.binding = 0;
   6510     dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
   6511     dslb.descriptorCount = 1 + (sum_dyn_uniform_buffers / 2);
   6512     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
   6513     dslb.pImmutableSamplers = NULL;
   6514     dslb_vec.push_back(dslb);
   6515 
   6516     ds_layout_ci.bindingCount = dslb_vec.size();
   6517     ds_layout_ci.pBindings = dslb_vec.data();
   6518     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
   6519     ASSERT_VK_SUCCESS(err);
   6520 
   6521     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00d1e);
   6522     if (dslb.descriptorCount > max_uniform_buffers) {
   6523         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   6524                                              VALIDATION_ERROR_0fe00240);  // expect max-per-stage too
   6525     }
   6526     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
   6527     m_errorMonitor->VerifyFound();
   6528     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
   6529     pipeline_layout = VK_NULL_HANDLE;
   6530     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
   6531 
   6532     // VU 0fe00d20 - too many storage buffer type descriptors overall
   6533     dslb_vec.clear();
   6534     dslb.binding = 0;
   6535     dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
   6536     dslb.descriptorCount = 1 + (sum_storage_buffers / 2);
   6537     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
   6538     dslb.pImmutableSamplers = NULL;
   6539     dslb_vec.push_back(dslb);
   6540 
   6541     ds_layout_ci.bindingCount = dslb_vec.size();
   6542     ds_layout_ci.pBindings = dslb_vec.data();
   6543     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
   6544     ASSERT_VK_SUCCESS(err);
   6545 
   6546     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00d20);
   6547     if (dslb.descriptorCount > max_storage_buffers) {
   6548         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   6549                                              VALIDATION_ERROR_0fe00242);  // expect max-per-stage too
   6550     }
   6551     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
   6552     m_errorMonitor->VerifyFound();
   6553     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
   6554     pipeline_layout = VK_NULL_HANDLE;
   6555     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
   6556 
   6557     // VU 0fe00d22 - too many dynamic storage buffer type descriptors overall
   6558     dslb_vec.clear();
   6559     dslb.binding = 0;
   6560     dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
   6561     dslb.descriptorCount = 1 + (sum_dyn_storage_buffers / 2);
   6562     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
   6563     dslb.pImmutableSamplers = NULL;
   6564     dslb_vec.push_back(dslb);
   6565 
   6566     ds_layout_ci.bindingCount = dslb_vec.size();
   6567     ds_layout_ci.pBindings = dslb_vec.data();
   6568     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
   6569     ASSERT_VK_SUCCESS(err);
   6570 
   6571     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00d22);
   6572     if (dslb.descriptorCount > max_storage_buffers) {
   6573         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   6574                                              VALIDATION_ERROR_0fe00242);  // expect max-per-stage too
   6575     }
   6576     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
   6577     m_errorMonitor->VerifyFound();
   6578     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
   6579     pipeline_layout = VK_NULL_HANDLE;
   6580     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
   6581 
   6582     // VU 0fe00d24 - too many sampled image type descriptors overall
   6583     dslb_vec.clear();
   6584     dslb.binding = 0;
   6585     dslb.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
   6586     dslb.descriptorCount = max_samplers;
   6587     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
   6588     dslb.pImmutableSamplers = NULL;
   6589     dslb_vec.push_back(dslb);
   6590     dslb.binding = 1;
   6591     dslb.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
   6592     uint32_t remaining = (max_samplers > sum_sampled_images ? 0 : (sum_sampled_images - max_samplers) / 2);
   6593     dslb.descriptorCount = 1 + remaining;
   6594     dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
   6595     dslb_vec.push_back(dslb);
   6596     dslb.binding = 2;
   6597     dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
   6598     dslb.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
   6599     dslb_vec.push_back(dslb);
   6600 
   6601     ds_layout_ci.bindingCount = dslb_vec.size();
   6602     ds_layout_ci.pBindings = dslb_vec.data();
   6603     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
   6604     ASSERT_VK_SUCCESS(err);
   6605 
   6606     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00d24);
   6607     if (dslb.descriptorCount > max_sampled_images) {
   6608         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   6609                                              VALIDATION_ERROR_0fe00244);  // expect max-per-stage too
   6610     }
   6611     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
   6612     m_errorMonitor->VerifyFound();
   6613     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
   6614     pipeline_layout = VK_NULL_HANDLE;
   6615     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
   6616 
   6617     // VU 0fe00d26 - too many storage image type descriptors overall
   6618     dslb_vec.clear();
   6619     dslb.binding = 0;
   6620     dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
   6621     dslb.descriptorCount = 1 + (sum_storage_images / 2);
   6622     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
   6623     dslb.pImmutableSamplers = NULL;
   6624     dslb_vec.push_back(dslb);
   6625     dslb.binding = 1;
   6626     dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
   6627     dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
   6628     dslb_vec.push_back(dslb);
   6629 
   6630     ds_layout_ci.bindingCount = dslb_vec.size();
   6631     ds_layout_ci.pBindings = dslb_vec.data();
   6632     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
   6633     ASSERT_VK_SUCCESS(err);
   6634 
   6635     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00d26);
   6636     if (dslb.descriptorCount > max_storage_images) {
   6637         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   6638                                              VALIDATION_ERROR_0fe00246);  // expect max-per-stage too
   6639     }
   6640     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
   6641     m_errorMonitor->VerifyFound();
   6642     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
   6643     pipeline_layout = VK_NULL_HANDLE;
   6644     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
   6645 
   6646     // VU 0fe00d28 - too many input attachment type descriptors overall
   6647     dslb_vec.clear();
   6648     dslb.binding = 0;
   6649     dslb.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
   6650     dslb.descriptorCount = 1 + (sum_input_attachments / 2);
   6651     dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
   6652     dslb.pImmutableSamplers = NULL;
   6653     dslb_vec.push_back(dslb);
   6654 
   6655     ds_layout_ci.bindingCount = dslb_vec.size();
   6656     ds_layout_ci.pBindings = dslb_vec.data();
   6657     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
   6658     ASSERT_VK_SUCCESS(err);
   6659 
   6660     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00d28);
   6661     if (dslb.descriptorCount > max_input_attachments) {
   6662         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   6663                                              VALIDATION_ERROR_0fe00d18);  // expect max-per-stage too
   6664     }
   6665     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
   6666     m_errorMonitor->VerifyFound();
   6667     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
   6668     pipeline_layout = VK_NULL_HANDLE;
   6669     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
   6670 }
   6671 
   6672 TEST_F(VkLayerTest, InvalidCmdBufferBufferDestroyed) {
   6673     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid due to a buffer dependency being destroyed.");
   6674     ASSERT_NO_FATAL_FAILURE(Init());
   6675 
   6676     VkBuffer buffer;
   6677     VkDeviceMemory mem;
   6678     VkMemoryRequirements mem_reqs;
   6679 
   6680     VkBufferCreateInfo buf_info = {};
   6681     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   6682     buf_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
   6683     buf_info.size = 256;
   6684     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   6685     VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
   6686     ASSERT_VK_SUCCESS(err);
   6687 
   6688     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
   6689 
   6690     VkMemoryAllocateInfo alloc_info = {};
   6691     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   6692     alloc_info.allocationSize = mem_reqs.size;
   6693     bool pass = false;
   6694     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
   6695     if (!pass) {
   6696         vkDestroyBuffer(m_device->device(), buffer, NULL);
   6697         return;
   6698     }
   6699     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
   6700     ASSERT_VK_SUCCESS(err);
   6701 
   6702     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
   6703     ASSERT_VK_SUCCESS(err);
   6704 
   6705     m_commandBuffer->begin();
   6706     vkCmdFillBuffer(m_commandBuffer->handle(), buffer, 0, VK_WHOLE_SIZE, 0);
   6707     m_commandBuffer->end();
   6708 
   6709     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Buffer ");
   6710     // Destroy buffer dependency prior to submit to cause ERROR
   6711     vkDestroyBuffer(m_device->device(), buffer, NULL);
   6712 
   6713     VkSubmitInfo submit_info = {};
   6714     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   6715     submit_info.commandBufferCount = 1;
   6716     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   6717     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   6718 
   6719     m_errorMonitor->VerifyFound();
   6720     vkQueueWaitIdle(m_device->m_queue);
   6721     vkFreeMemory(m_device->handle(), mem, NULL);
   6722 }
   6723 
   6724 TEST_F(VkLayerTest, InvalidCmdBufferBufferViewDestroyed) {
   6725     TEST_DESCRIPTION("Delete bufferView bound to cmd buffer, then attempt to submit cmd buffer.");
   6726 
   6727     ASSERT_NO_FATAL_FAILURE(Init());
   6728     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   6729 
   6730     VkDescriptorPoolSize ds_type_count;
   6731     ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
   6732     ds_type_count.descriptorCount = 1;
   6733 
   6734     VkDescriptorPoolCreateInfo ds_pool_ci = {};
   6735     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
   6736     ds_pool_ci.maxSets = 1;
   6737     ds_pool_ci.poolSizeCount = 1;
   6738     ds_pool_ci.pPoolSizes = &ds_type_count;
   6739 
   6740     VkDescriptorPool ds_pool;
   6741     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
   6742     ASSERT_VK_SUCCESS(err);
   6743 
   6744     VkDescriptorSetLayoutBinding layout_binding;
   6745     layout_binding.binding = 0;
   6746     layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
   6747     layout_binding.descriptorCount = 1;
   6748     layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
   6749     layout_binding.pImmutableSamplers = NULL;
   6750 
   6751     const VkDescriptorSetLayoutObj ds_layout(m_device, {layout_binding});
   6752 
   6753     VkDescriptorSetAllocateInfo alloc_info = {};
   6754     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
   6755     alloc_info.descriptorSetCount = 1;
   6756     alloc_info.descriptorPool = ds_pool;
   6757     alloc_info.pSetLayouts = &ds_layout.handle();
   6758     VkDescriptorSet descriptor_set;
   6759     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
   6760     ASSERT_VK_SUCCESS(err);
   6761 
   6762     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout});
   6763 
   6764     VkBuffer buffer;
   6765     uint32_t queue_family_index = 0;
   6766     VkBufferCreateInfo buffer_create_info = {};
   6767     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   6768     buffer_create_info.size = 1024;
   6769     buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
   6770     buffer_create_info.queueFamilyIndexCount = 1;
   6771     buffer_create_info.pQueueFamilyIndices = &queue_family_index;
   6772 
   6773     err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
   6774     ASSERT_VK_SUCCESS(err);
   6775 
   6776     VkMemoryRequirements memory_reqs;
   6777     VkDeviceMemory buffer_memory;
   6778 
   6779     VkMemoryAllocateInfo memory_info = {};
   6780     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   6781     memory_info.allocationSize = 0;
   6782     memory_info.memoryTypeIndex = 0;
   6783 
   6784     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
   6785     memory_info.allocationSize = memory_reqs.size;
   6786     bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
   6787     ASSERT_TRUE(pass);
   6788 
   6789     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
   6790     ASSERT_VK_SUCCESS(err);
   6791     err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
   6792     ASSERT_VK_SUCCESS(err);
   6793 
   6794     VkBufferView view;
   6795     VkBufferViewCreateInfo bvci = {};
   6796     bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
   6797     bvci.buffer = buffer;
   6798     bvci.format = VK_FORMAT_R32_SFLOAT;
   6799     bvci.range = VK_WHOLE_SIZE;
   6800 
   6801     err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view);
   6802     ASSERT_VK_SUCCESS(err);
   6803 
   6804     VkWriteDescriptorSet descriptor_write = {};
   6805     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   6806     descriptor_write.dstSet = descriptor_set;
   6807     descriptor_write.dstBinding = 0;
   6808     descriptor_write.descriptorCount = 1;
   6809     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
   6810     descriptor_write.pTexelBufferView = &view;
   6811 
   6812     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   6813 
   6814     char const *vsSource =
   6815         "#version 450\n"
   6816         "\n"
   6817         "void main(){\n"
   6818         "   gl_Position = vec4(1);\n"
   6819         "}\n";
   6820     char const *fsSource =
   6821         "#version 450\n"
   6822         "\n"
   6823         "layout(set=0, binding=0, r32f) uniform imageBuffer s;\n"
   6824         "layout(location=0) out vec4 x;\n"
   6825         "void main(){\n"
   6826         "   x = imageLoad(s, 0);\n"
   6827         "}\n";
   6828     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   6829     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   6830     VkPipelineObj pipe(m_device);
   6831     pipe.AddShader(&vs);
   6832     pipe.AddShader(&fs);
   6833     pipe.AddDefaultColorAttachment();
   6834     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   6835 
   6836     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound BufferView ");
   6837 
   6838     m_commandBuffer->begin();
   6839     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   6840 
   6841     VkViewport viewport = {0, 0, 16, 16, 0, 1};
   6842     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   6843     VkRect2D scissor = {{0, 0}, {16, 16}};
   6844     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
   6845     // Bind pipeline to cmd buffer - This causes crash on Mali
   6846     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   6847     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
   6848                             &descriptor_set, 0, nullptr);
   6849     m_commandBuffer->Draw(1, 0, 0, 0);
   6850     m_commandBuffer->EndRenderPass();
   6851     m_commandBuffer->end();
   6852 
   6853     // Delete BufferView in order to invalidate cmd buffer
   6854     vkDestroyBufferView(m_device->device(), view, NULL);
   6855     // Now attempt submit of cmd buffer
   6856     VkSubmitInfo submit_info = {};
   6857     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   6858     submit_info.commandBufferCount = 1;
   6859     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   6860     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   6861     m_errorMonitor->VerifyFound();
   6862 
   6863     // Clean-up
   6864     vkDestroyBuffer(m_device->device(), buffer, NULL);
   6865     vkFreeMemory(m_device->device(), buffer_memory, NULL);
   6866     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
   6867 }
   6868 
   6869 TEST_F(VkLayerTest, InvalidCmdBufferImageDestroyed) {
   6870     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid due to an image dependency being destroyed.");
   6871     ASSERT_NO_FATAL_FAILURE(Init());
   6872 
   6873     VkImage image;
   6874     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
   6875     VkImageCreateInfo image_create_info = {};
   6876     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   6877     image_create_info.pNext = NULL;
   6878     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   6879     image_create_info.format = tex_format;
   6880     image_create_info.extent.width = 32;
   6881     image_create_info.extent.height = 32;
   6882     image_create_info.extent.depth = 1;
   6883     image_create_info.mipLevels = 1;
   6884     image_create_info.arrayLayers = 1;
   6885     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   6886     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   6887     image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   6888     image_create_info.flags = 0;
   6889     VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
   6890     ASSERT_VK_SUCCESS(err);
   6891     // Have to bind memory to image before recording cmd in cmd buffer using it
   6892     VkMemoryRequirements mem_reqs;
   6893     VkDeviceMemory image_mem;
   6894     bool pass;
   6895     VkMemoryAllocateInfo mem_alloc = {};
   6896     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   6897     mem_alloc.pNext = NULL;
   6898     mem_alloc.memoryTypeIndex = 0;
   6899     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
   6900     mem_alloc.allocationSize = mem_reqs.size;
   6901     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
   6902     ASSERT_TRUE(pass);
   6903     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
   6904     ASSERT_VK_SUCCESS(err);
   6905     err = vkBindImageMemory(m_device->device(), image, image_mem, 0);
   6906     ASSERT_VK_SUCCESS(err);
   6907 
   6908     m_commandBuffer->begin();
   6909     VkClearColorValue ccv;
   6910     ccv.float32[0] = 1.0f;
   6911     ccv.float32[1] = 1.0f;
   6912     ccv.float32[2] = 1.0f;
   6913     ccv.float32[3] = 1.0f;
   6914     VkImageSubresourceRange isr = {};
   6915     isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   6916     isr.baseArrayLayer = 0;
   6917     isr.baseMipLevel = 0;
   6918     isr.layerCount = 1;
   6919     isr.levelCount = 1;
   6920     vkCmdClearColorImage(m_commandBuffer->handle(), image, VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &isr);
   6921     m_commandBuffer->end();
   6922 
   6923     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Image ");
   6924     // Destroy image dependency prior to submit to cause ERROR
   6925     vkDestroyImage(m_device->device(), image, NULL);
   6926 
   6927     VkSubmitInfo submit_info = {};
   6928     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   6929     submit_info.commandBufferCount = 1;
   6930     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   6931     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   6932 
   6933     m_errorMonitor->VerifyFound();
   6934     vkFreeMemory(m_device->device(), image_mem, nullptr);
   6935 }
   6936 
   6937 TEST_F(VkLayerTest, InvalidCmdBufferFramebufferImageDestroyed) {
   6938     TEST_DESCRIPTION(
   6939         "Attempt to draw with a command buffer that is invalid due to a framebuffer image dependency being destroyed.");
   6940     ASSERT_NO_FATAL_FAILURE(Init());
   6941     VkFormatProperties format_properties;
   6942     VkResult err = VK_SUCCESS;
   6943     vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
   6944     if (!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
   6945         return;
   6946     }
   6947 
   6948     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   6949 
   6950     VkImageCreateInfo image_ci = {};
   6951     image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   6952     image_ci.pNext = NULL;
   6953     image_ci.imageType = VK_IMAGE_TYPE_2D;
   6954     image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
   6955     image_ci.extent.width = 32;
   6956     image_ci.extent.height = 32;
   6957     image_ci.extent.depth = 1;
   6958     image_ci.mipLevels = 1;
   6959     image_ci.arrayLayers = 1;
   6960     image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
   6961     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
   6962     image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
   6963     image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   6964     image_ci.flags = 0;
   6965     VkImage image;
   6966     ASSERT_VK_SUCCESS(vkCreateImage(m_device->handle(), &image_ci, NULL, &image));
   6967 
   6968     VkMemoryRequirements memory_reqs;
   6969     VkDeviceMemory image_memory;
   6970     bool pass;
   6971     VkMemoryAllocateInfo memory_info = {};
   6972     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   6973     memory_info.pNext = NULL;
   6974     memory_info.allocationSize = 0;
   6975     memory_info.memoryTypeIndex = 0;
   6976     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
   6977     memory_info.allocationSize = memory_reqs.size;
   6978     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
   6979     ASSERT_TRUE(pass);
   6980     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
   6981     ASSERT_VK_SUCCESS(err);
   6982     err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
   6983     ASSERT_VK_SUCCESS(err);
   6984 
   6985     VkImageViewCreateInfo ivci = {
   6986         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
   6987         nullptr,
   6988         0,
   6989         image,
   6990         VK_IMAGE_VIEW_TYPE_2D,
   6991         VK_FORMAT_B8G8R8A8_UNORM,
   6992         {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
   6993         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
   6994     };
   6995     VkImageView view;
   6996     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
   6997     ASSERT_VK_SUCCESS(err);
   6998 
   6999     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 32, 32, 1};
   7000     VkFramebuffer fb;
   7001     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
   7002     ASSERT_VK_SUCCESS(err);
   7003 
   7004     // Just use default renderpass with our framebuffer
   7005     m_renderPassBeginInfo.framebuffer = fb;
   7006     m_renderPassBeginInfo.renderArea.extent.width = 32;
   7007     m_renderPassBeginInfo.renderArea.extent.height = 32;
   7008     // Create Null cmd buffer for submit
   7009     m_commandBuffer->begin();
   7010     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   7011     m_commandBuffer->EndRenderPass();
   7012     m_commandBuffer->end();
   7013     // Destroy image attached to framebuffer to invalidate cmd buffer
   7014     vkDestroyImage(m_device->device(), image, NULL);
   7015     // Now attempt to submit cmd buffer and verify error
   7016     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Image ");
   7017     m_commandBuffer->QueueCommandBuffer(false);
   7018     m_errorMonitor->VerifyFound();
   7019 
   7020     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
   7021     vkDestroyImageView(m_device->device(), view, nullptr);
   7022     vkFreeMemory(m_device->device(), image_memory, nullptr);
   7023 }
   7024 
   7025 TEST_F(VkLayerTest, FramebufferInUseDestroyedSignaled) {
   7026     TEST_DESCRIPTION("Delete in-use framebuffer.");
   7027     ASSERT_NO_FATAL_FAILURE(Init());
   7028     VkFormatProperties format_properties;
   7029     VkResult err = VK_SUCCESS;
   7030     vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
   7031 
   7032     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   7033 
   7034     VkImageObj image(m_device);
   7035     image.Init(256, 256, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   7036     ASSERT_TRUE(image.initialized());
   7037     VkImageView view = image.targetView(VK_FORMAT_B8G8R8A8_UNORM);
   7038 
   7039     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 256, 256, 1};
   7040     VkFramebuffer fb;
   7041     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
   7042     ASSERT_VK_SUCCESS(err);
   7043 
   7044     // Just use default renderpass with our framebuffer
   7045     m_renderPassBeginInfo.framebuffer = fb;
   7046     // Create Null cmd buffer for submit
   7047     m_commandBuffer->begin();
   7048     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   7049     m_commandBuffer->EndRenderPass();
   7050     m_commandBuffer->end();
   7051     // Submit cmd buffer to put it in-flight
   7052     VkSubmitInfo submit_info = {};
   7053     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   7054     submit_info.commandBufferCount = 1;
   7055     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   7056     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   7057     // Destroy framebuffer while in-flight
   7058     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_250006f8);
   7059     vkDestroyFramebuffer(m_device->device(), fb, NULL);
   7060     m_errorMonitor->VerifyFound();
   7061     // Wait for queue to complete so we can safely destroy everything
   7062     vkQueueWaitIdle(m_device->m_queue);
   7063     m_errorMonitor->SetUnexpectedError("If framebuffer is not VK_NULL_HANDLE, framebuffer must be a valid VkFramebuffer handle");
   7064     m_errorMonitor->SetUnexpectedError("Unable to remove Framebuffer obj");
   7065     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
   7066 }
   7067 
   7068 TEST_F(VkLayerTest, FramebufferImageInUseDestroyedSignaled) {
   7069     TEST_DESCRIPTION("Delete in-use image that's child of framebuffer.");
   7070     ASSERT_NO_FATAL_FAILURE(Init());
   7071     VkFormatProperties format_properties;
   7072     VkResult err = VK_SUCCESS;
   7073     vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
   7074 
   7075     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   7076 
   7077     VkImageCreateInfo image_ci = {};
   7078     image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   7079     image_ci.pNext = NULL;
   7080     image_ci.imageType = VK_IMAGE_TYPE_2D;
   7081     image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
   7082     image_ci.extent.width = 256;
   7083     image_ci.extent.height = 256;
   7084     image_ci.extent.depth = 1;
   7085     image_ci.mipLevels = 1;
   7086     image_ci.arrayLayers = 1;
   7087     image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
   7088     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
   7089     image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
   7090     image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   7091     image_ci.flags = 0;
   7092     VkImage image;
   7093     ASSERT_VK_SUCCESS(vkCreateImage(m_device->handle(), &image_ci, NULL, &image));
   7094 
   7095     VkMemoryRequirements memory_reqs;
   7096     VkDeviceMemory image_memory;
   7097     bool pass;
   7098     VkMemoryAllocateInfo memory_info = {};
   7099     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   7100     memory_info.pNext = NULL;
   7101     memory_info.allocationSize = 0;
   7102     memory_info.memoryTypeIndex = 0;
   7103     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
   7104     memory_info.allocationSize = memory_reqs.size;
   7105     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
   7106     ASSERT_TRUE(pass);
   7107     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
   7108     ASSERT_VK_SUCCESS(err);
   7109     err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
   7110     ASSERT_VK_SUCCESS(err);
   7111 
   7112     VkImageViewCreateInfo ivci = {
   7113         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
   7114         nullptr,
   7115         0,
   7116         image,
   7117         VK_IMAGE_VIEW_TYPE_2D,
   7118         VK_FORMAT_B8G8R8A8_UNORM,
   7119         {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
   7120         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
   7121     };
   7122     VkImageView view;
   7123     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
   7124     ASSERT_VK_SUCCESS(err);
   7125 
   7126     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 256, 256, 1};
   7127     VkFramebuffer fb;
   7128     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
   7129     ASSERT_VK_SUCCESS(err);
   7130 
   7131     // Just use default renderpass with our framebuffer
   7132     m_renderPassBeginInfo.framebuffer = fb;
   7133     // Create Null cmd buffer for submit
   7134     m_commandBuffer->begin();
   7135     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   7136     m_commandBuffer->EndRenderPass();
   7137     m_commandBuffer->end();
   7138     // Submit cmd buffer to put it (and attached imageView) in-flight
   7139     VkSubmitInfo submit_info = {};
   7140     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   7141     submit_info.commandBufferCount = 1;
   7142     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   7143     // Submit cmd buffer to put framebuffer and children in-flight
   7144     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   7145     // Destroy image attached to framebuffer while in-flight
   7146     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_252007d0);
   7147     vkDestroyImage(m_device->device(), image, NULL);
   7148     m_errorMonitor->VerifyFound();
   7149     // Wait for queue to complete so we can safely destroy image and other objects
   7150     vkQueueWaitIdle(m_device->m_queue);
   7151     m_errorMonitor->SetUnexpectedError("If image is not VK_NULL_HANDLE, image must be a valid VkImage handle");
   7152     m_errorMonitor->SetUnexpectedError("Unable to remove Image obj");
   7153     vkDestroyImage(m_device->device(), image, NULL);
   7154     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
   7155     vkDestroyImageView(m_device->device(), view, nullptr);
   7156     vkFreeMemory(m_device->device(), image_memory, nullptr);
   7157 }
   7158 
   7159 TEST_F(VkLayerTest, RenderPassInUseDestroyedSignaled) {
   7160     TEST_DESCRIPTION("Delete in-use renderPass.");
   7161 
   7162     ASSERT_NO_FATAL_FAILURE(Init());
   7163     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   7164 
   7165     // Create simple renderpass
   7166     VkAttachmentReference attach = {};
   7167     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
   7168     VkSubpassDescription subpass = {};
   7169     subpass.colorAttachmentCount = 1;
   7170     subpass.pColorAttachments = &attach;
   7171     VkRenderPassCreateInfo rpci = {};
   7172     rpci.subpassCount = 1;
   7173     rpci.pSubpasses = &subpass;
   7174     rpci.attachmentCount = 1;
   7175     VkAttachmentDescription attach_desc = {};
   7176     attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
   7177     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
   7178     attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
   7179     rpci.pAttachments = &attach_desc;
   7180     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
   7181     VkRenderPass rp;
   7182     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
   7183     ASSERT_VK_SUCCESS(err);
   7184 
   7185     m_errorMonitor->ExpectSuccess();
   7186 
   7187     m_commandBuffer->begin();
   7188     VkRenderPassBeginInfo rpbi = {};
   7189     rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
   7190     rpbi.framebuffer = m_framebuffer;
   7191     rpbi.renderPass = rp;
   7192     m_commandBuffer->BeginRenderPass(rpbi);
   7193     m_commandBuffer->EndRenderPass();
   7194     m_commandBuffer->end();
   7195 
   7196     VkSubmitInfo submit_info = {};
   7197     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   7198     submit_info.commandBufferCount = 1;
   7199     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   7200     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   7201     m_errorMonitor->VerifyNotFound();
   7202 
   7203     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_264006d2);
   7204     vkDestroyRenderPass(m_device->device(), rp, nullptr);
   7205     m_errorMonitor->VerifyFound();
   7206 
   7207     // Wait for queue to complete so we can safely destroy rp
   7208     vkQueueWaitIdle(m_device->m_queue);
   7209     m_errorMonitor->SetUnexpectedError("If renderPass is not VK_NULL_HANDLE, renderPass must be a valid VkRenderPass handle");
   7210     m_errorMonitor->SetUnexpectedError("Was it created? Has it already been destroyed?");
   7211     vkDestroyRenderPass(m_device->device(), rp, nullptr);
   7212 }
   7213 
   7214 TEST_F(VkLayerTest, ImageMemoryNotBound) {
   7215     TEST_DESCRIPTION("Attempt to draw with an image which has not had memory bound to it.");
   7216     ASSERT_NO_FATAL_FAILURE(Init());
   7217 
   7218     VkImage image;
   7219     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
   7220     VkImageCreateInfo image_create_info = {};
   7221     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   7222     image_create_info.pNext = NULL;
   7223     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   7224     image_create_info.format = tex_format;
   7225     image_create_info.extent.width = 32;
   7226     image_create_info.extent.height = 32;
   7227     image_create_info.extent.depth = 1;
   7228     image_create_info.mipLevels = 1;
   7229     image_create_info.arrayLayers = 1;
   7230     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   7231     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   7232     image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   7233     image_create_info.flags = 0;
   7234     VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
   7235     ASSERT_VK_SUCCESS(err);
   7236     // Have to bind memory to image before recording cmd in cmd buffer using it
   7237     VkMemoryRequirements mem_reqs;
   7238     VkDeviceMemory image_mem;
   7239     bool pass;
   7240     VkMemoryAllocateInfo mem_alloc = {};
   7241     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   7242     mem_alloc.pNext = NULL;
   7243     mem_alloc.memoryTypeIndex = 0;
   7244     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
   7245     mem_alloc.allocationSize = mem_reqs.size;
   7246     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
   7247     ASSERT_TRUE(pass);
   7248     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
   7249     ASSERT_VK_SUCCESS(err);
   7250 
   7251     // Introduce error, do not call vkBindImageMemory(m_device->device(), image, image_mem, 0);
   7252     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   7253                                          " used with no memory bound. Memory should be bound by calling vkBindImageMemory().");
   7254 
   7255     m_commandBuffer->begin();
   7256     VkClearColorValue ccv;
   7257     ccv.float32[0] = 1.0f;
   7258     ccv.float32[1] = 1.0f;
   7259     ccv.float32[2] = 1.0f;
   7260     ccv.float32[3] = 1.0f;
   7261     VkImageSubresourceRange isr = {};
   7262     isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   7263     isr.baseArrayLayer = 0;
   7264     isr.baseMipLevel = 0;
   7265     isr.layerCount = 1;
   7266     isr.levelCount = 1;
   7267     vkCmdClearColorImage(m_commandBuffer->handle(), image, VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &isr);
   7268     m_commandBuffer->end();
   7269 
   7270     m_errorMonitor->VerifyFound();
   7271     vkDestroyImage(m_device->device(), image, NULL);
   7272     vkFreeMemory(m_device->device(), image_mem, nullptr);
   7273 }
   7274 
   7275 TEST_F(VkLayerTest, BufferMemoryNotBound) {
   7276     TEST_DESCRIPTION("Attempt to copy from a buffer which has not had memory bound to it.");
   7277     ASSERT_NO_FATAL_FAILURE(Init());
   7278 
   7279     VkImageObj image(m_device);
   7280     image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
   7281                VK_IMAGE_TILING_OPTIMAL, 0);
   7282     ASSERT_TRUE(image.initialized());
   7283 
   7284     VkBuffer buffer;
   7285     VkDeviceMemory mem;
   7286     VkMemoryRequirements mem_reqs;
   7287 
   7288     VkBufferCreateInfo buf_info = {};
   7289     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   7290     buf_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
   7291     buf_info.size = 1024;
   7292     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   7293     VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
   7294     ASSERT_VK_SUCCESS(err);
   7295 
   7296     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
   7297 
   7298     VkMemoryAllocateInfo alloc_info = {};
   7299     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   7300     alloc_info.allocationSize = 1024;
   7301     bool pass = false;
   7302     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
   7303     if (!pass) {
   7304         vkDestroyBuffer(m_device->device(), buffer, NULL);
   7305         return;
   7306     }
   7307     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
   7308     ASSERT_VK_SUCCESS(err);
   7309 
   7310     // Introduce failure by not calling vkBindBufferMemory(m_device->device(), buffer, mem, 0);
   7311     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   7312                                          " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
   7313     VkBufferImageCopy region = {};
   7314     region.bufferRowLength = 16;
   7315     region.bufferImageHeight = 16;
   7316     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   7317 
   7318     region.imageSubresource.layerCount = 1;
   7319     region.imageExtent.height = 4;
   7320     region.imageExtent.width = 4;
   7321     region.imageExtent.depth = 1;
   7322     m_commandBuffer->begin();
   7323     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer, image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
   7324     m_commandBuffer->end();
   7325 
   7326     m_errorMonitor->VerifyFound();
   7327 
   7328     vkDestroyBuffer(m_device->device(), buffer, NULL);
   7329     vkFreeMemory(m_device->handle(), mem, NULL);
   7330 }
   7331 
   7332 TEST_F(VkLayerTest, InvalidCmdBufferEventDestroyed) {
   7333     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid due to an event dependency being destroyed.");
   7334     ASSERT_NO_FATAL_FAILURE(Init());
   7335 
   7336     VkEvent event;
   7337     VkEventCreateInfo evci = {};
   7338     evci.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
   7339     VkResult result = vkCreateEvent(m_device->device(), &evci, NULL, &event);
   7340     ASSERT_VK_SUCCESS(result);
   7341 
   7342     m_commandBuffer->begin();
   7343     vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
   7344     m_commandBuffer->end();
   7345 
   7346     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Event ");
   7347     // Destroy event dependency prior to submit to cause ERROR
   7348     vkDestroyEvent(m_device->device(), event, NULL);
   7349 
   7350     VkSubmitInfo submit_info = {};
   7351     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   7352     submit_info.commandBufferCount = 1;
   7353     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   7354     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   7355 
   7356     m_errorMonitor->VerifyFound();
   7357 }
   7358 
   7359 TEST_F(VkLayerTest, InvalidCmdBufferQueryPoolDestroyed) {
   7360     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid due to a query pool dependency being destroyed.");
   7361     ASSERT_NO_FATAL_FAILURE(Init());
   7362 
   7363     VkQueryPool query_pool;
   7364     VkQueryPoolCreateInfo qpci{};
   7365     qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
   7366     qpci.queryType = VK_QUERY_TYPE_TIMESTAMP;
   7367     qpci.queryCount = 1;
   7368     VkResult result = vkCreateQueryPool(m_device->device(), &qpci, nullptr, &query_pool);
   7369     ASSERT_VK_SUCCESS(result);
   7370 
   7371     m_commandBuffer->begin();
   7372     vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
   7373     m_commandBuffer->end();
   7374 
   7375     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound QueryPool ");
   7376     // Destroy query pool dependency prior to submit to cause ERROR
   7377     vkDestroyQueryPool(m_device->device(), query_pool, NULL);
   7378 
   7379     VkSubmitInfo submit_info = {};
   7380     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   7381     submit_info.commandBufferCount = 1;
   7382     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   7383     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   7384 
   7385     m_errorMonitor->VerifyFound();
   7386 }
   7387 
   7388 TEST_F(VkLayerTest, InvalidCmdBufferPipelineDestroyed) {
   7389     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid due to a pipeline dependency being destroyed.");
   7390     ASSERT_NO_FATAL_FAILURE(Init());
   7391     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   7392 
   7393     {
   7394         // Use helper to create graphics pipeline
   7395         CreatePipelineHelper helper(*this);
   7396         helper.InitInfo();
   7397         helper.InitState();
   7398         helper.CreateGraphicsPipeline();
   7399 
   7400         // Bind helper pipeline to command buffer
   7401         m_commandBuffer->begin();
   7402         vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, helper.pipeline_);
   7403         m_commandBuffer->end();
   7404 
   7405         // pipeline will be destroyed when helper goes out of scope
   7406     }
   7407 
   7408     // Cause error by submitting command buffer that references destroyed pipeline
   7409     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Pipeline ");
   7410     m_commandBuffer->QueueCommandBuffer(false);
   7411     m_errorMonitor->VerifyFound();
   7412 }
   7413 
   7414 TEST_F(VkPositiveLayerTest, DestroyPipelineRenderPass) {
   7415     TEST_DESCRIPTION("Draw using a pipeline whose create renderPass has been destroyed.");
   7416     m_errorMonitor->ExpectSuccess();
   7417     ASSERT_NO_FATAL_FAILURE(Init());
   7418     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   7419 
   7420     VkResult err;
   7421 
   7422     // Create a renderPass that's compatible with Draw-time renderPass
   7423     VkAttachmentDescription att = {};
   7424     att.format = m_render_target_fmt;
   7425     att.samples = VK_SAMPLE_COUNT_1_BIT;
   7426     att.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
   7427     att.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
   7428     att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
   7429     att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
   7430     att.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   7431     att.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   7432 
   7433     VkAttachmentReference ref = {};
   7434     ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   7435     ref.attachment = 0;
   7436 
   7437     m_renderPassClearValues.clear();
   7438     VkClearValue clear = {};
   7439     clear.color = m_clear_color;
   7440 
   7441     VkSubpassDescription subpass = {};
   7442     subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
   7443     subpass.flags = 0;
   7444     subpass.inputAttachmentCount = 0;
   7445     subpass.pInputAttachments = NULL;
   7446     subpass.colorAttachmentCount = 1;
   7447     subpass.pColorAttachments = &ref;
   7448     subpass.pResolveAttachments = NULL;
   7449 
   7450     subpass.pDepthStencilAttachment = NULL;
   7451     subpass.preserveAttachmentCount = 0;
   7452     subpass.pPreserveAttachments = NULL;
   7453 
   7454     VkRenderPassCreateInfo rp_info = {};
   7455     rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
   7456     rp_info.attachmentCount = 1;
   7457     rp_info.pAttachments = &att;
   7458     rp_info.subpassCount = 1;
   7459     rp_info.pSubpasses = &subpass;
   7460 
   7461     VkRenderPass rp;
   7462     err = vkCreateRenderPass(device(), &rp_info, NULL, &rp);
   7463     ASSERT_VK_SUCCESS(err);
   7464 
   7465     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   7466     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   7467 
   7468     VkPipelineObj pipe(m_device);
   7469     pipe.AddDefaultColorAttachment();
   7470     pipe.AddShader(&vs);
   7471     pipe.AddShader(&fs);
   7472     VkViewport view_port = {};
   7473     m_viewports.push_back(view_port);
   7474     pipe.SetViewport(m_viewports);
   7475     VkRect2D rect = {};
   7476     m_scissors.push_back(rect);
   7477     pipe.SetScissor(m_scissors);
   7478 
   7479     const VkPipelineLayoutObj pl(m_device);
   7480     pipe.CreateVKPipeline(pl.handle(), rp);
   7481 
   7482     m_commandBuffer->begin();
   7483     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   7484     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   7485     // Destroy renderPass before pipeline is used in Draw
   7486     //  We delay until after CmdBindPipeline to verify that invalid binding isn't
   7487     //  created between CB & renderPass, which we used to do.
   7488     vkDestroyRenderPass(m_device->device(), rp, nullptr);
   7489     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
   7490     vkCmdEndRenderPass(m_commandBuffer->handle());
   7491     m_commandBuffer->end();
   7492 
   7493     VkSubmitInfo submit_info = {};
   7494     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   7495     submit_info.commandBufferCount = 1;
   7496     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   7497     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   7498     m_errorMonitor->VerifyNotFound();
   7499     vkQueueWaitIdle(m_device->m_queue);
   7500 }
   7501 
   7502 TEST_F(VkLayerTest, InvalidCmdBufferDescriptorSetBufferDestroyed) {
   7503     TEST_DESCRIPTION(
   7504         "Attempt to draw with a command buffer that is invalid due to a bound descriptor set with a buffer dependency being "
   7505         "destroyed.");
   7506     ASSERT_NO_FATAL_FAILURE(Init());
   7507     ASSERT_NO_FATAL_FAILURE(InitViewport());
   7508     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   7509 
   7510     VkDescriptorPoolSize ds_type_count = {};
   7511     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   7512     ds_type_count.descriptorCount = 1;
   7513 
   7514     VkDescriptorPoolCreateInfo ds_pool_ci = {};
   7515     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
   7516     ds_pool_ci.pNext = NULL;
   7517     ds_pool_ci.maxSets = 1;
   7518     ds_pool_ci.poolSizeCount = 1;
   7519     ds_pool_ci.pPoolSizes = &ds_type_count;
   7520 
   7521     VkDescriptorPool ds_pool;
   7522     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
   7523     ASSERT_VK_SUCCESS(err);
   7524 
   7525     VkDescriptorSetLayoutBinding dsl_binding = {};
   7526     dsl_binding.binding = 0;
   7527     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   7528     dsl_binding.descriptorCount = 1;
   7529     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
   7530     dsl_binding.pImmutableSamplers = NULL;
   7531 
   7532     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
   7533 
   7534     VkDescriptorSet descriptorSet;
   7535     VkDescriptorSetAllocateInfo alloc_info = {};
   7536     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
   7537     alloc_info.descriptorSetCount = 1;
   7538     alloc_info.descriptorPool = ds_pool;
   7539     alloc_info.pSetLayouts = &ds_layout.handle();
   7540     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
   7541     ASSERT_VK_SUCCESS(err);
   7542 
   7543     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout});
   7544 
   7545     // Create a buffer to update the descriptor with
   7546     uint32_t qfi = 0;
   7547     VkBufferCreateInfo buffCI = {};
   7548     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   7549     buffCI.size = 1024;
   7550     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
   7551     buffCI.queueFamilyIndexCount = 1;
   7552     buffCI.pQueueFamilyIndices = &qfi;
   7553 
   7554     VkBuffer buffer;
   7555     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &buffer);
   7556     ASSERT_VK_SUCCESS(err);
   7557     // Allocate memory and bind to buffer so we can make it to the appropriate
   7558     // error
   7559     VkMemoryRequirements memReqs;
   7560     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
   7561     VkMemoryAllocateInfo mem_alloc = {};
   7562     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   7563     mem_alloc.pNext = NULL;
   7564     mem_alloc.allocationSize = memReqs.size;
   7565     mem_alloc.memoryTypeIndex = 0;
   7566     bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
   7567     if (!pass) {
   7568         vkDestroyBuffer(m_device->device(), buffer, NULL);
   7569         return;
   7570     }
   7571 
   7572     VkDeviceMemory mem;
   7573     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
   7574     ASSERT_VK_SUCCESS(err);
   7575     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
   7576     ASSERT_VK_SUCCESS(err);
   7577     // Correctly update descriptor to avoid "NOT_UPDATED" error
   7578     VkDescriptorBufferInfo buffInfo = {};
   7579     buffInfo.buffer = buffer;
   7580     buffInfo.offset = 0;
   7581     buffInfo.range = 1024;
   7582 
   7583     VkWriteDescriptorSet descriptor_write;
   7584     memset(&descriptor_write, 0, sizeof(descriptor_write));
   7585     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   7586     descriptor_write.dstSet = descriptorSet;
   7587     descriptor_write.dstBinding = 0;
   7588     descriptor_write.descriptorCount = 1;
   7589     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   7590     descriptor_write.pBufferInfo = &buffInfo;
   7591 
   7592     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   7593 
   7594     // Create PSO to be used for draw-time errors below
   7595     char const *vsSource =
   7596         "#version 450\n"
   7597         "\n"
   7598         "void main(){\n"
   7599         "   gl_Position = vec4(1);\n"
   7600         "}\n";
   7601     char const *fsSource =
   7602         "#version 450\n"
   7603         "\n"
   7604         "layout(location=0) out vec4 x;\n"
   7605         "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
   7606         "void main(){\n"
   7607         "   x = vec4(bar.y);\n"
   7608         "}\n";
   7609     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   7610     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   7611     VkPipelineObj pipe(m_device);
   7612     pipe.AddShader(&vs);
   7613     pipe.AddShader(&fs);
   7614     pipe.AddDefaultColorAttachment();
   7615     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   7616 
   7617     m_commandBuffer->begin();
   7618     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   7619     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   7620     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
   7621                             &descriptorSet, 0, NULL);
   7622 
   7623     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &m_viewports[0]);
   7624     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &m_scissors[0]);
   7625 
   7626     m_commandBuffer->Draw(1, 0, 0, 0);
   7627     m_commandBuffer->EndRenderPass();
   7628     m_commandBuffer->end();
   7629     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Buffer ");
   7630     // Destroy buffer should invalidate the cmd buffer, causing error on submit
   7631     vkDestroyBuffer(m_device->device(), buffer, NULL);
   7632     // Attempt to submit cmd buffer
   7633     VkSubmitInfo submit_info = {};
   7634     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   7635     submit_info.commandBufferCount = 1;
   7636     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   7637     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   7638     m_errorMonitor->VerifyFound();
   7639     // Cleanup
   7640     vkFreeMemory(m_device->device(), mem, NULL);
   7641 
   7642     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
   7643 }
   7644 
   7645 TEST_F(VkLayerTest, InvalidCmdBufferDescriptorSetImageSamplerDestroyed) {
   7646     TEST_DESCRIPTION(
   7647         "Attempt to draw with a command buffer that is invalid due to a bound descriptor sets with a combined image sampler having "
   7648         "their image, sampler, and descriptor set each respectively destroyed and then attempting to submit associated cmd "
   7649         "buffers. Attempt to destroy a DescriptorSet that is in use.");
   7650     ASSERT_NO_FATAL_FAILURE(Init(nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
   7651     ASSERT_NO_FATAL_FAILURE(InitViewport());
   7652     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   7653 
   7654     VkDescriptorPoolSize ds_type_count = {};
   7655     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
   7656     ds_type_count.descriptorCount = 1;
   7657 
   7658     VkDescriptorPoolCreateInfo ds_pool_ci = {};
   7659     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
   7660     ds_pool_ci.pNext = NULL;
   7661     ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
   7662     ds_pool_ci.maxSets = 1;
   7663     ds_pool_ci.poolSizeCount = 1;
   7664     ds_pool_ci.pPoolSizes = &ds_type_count;
   7665 
   7666     VkDescriptorPool ds_pool;
   7667     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
   7668     ASSERT_VK_SUCCESS(err);
   7669 
   7670     VkDescriptorSetLayoutBinding dsl_binding = {};
   7671     dsl_binding.binding = 0;
   7672     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
   7673     dsl_binding.descriptorCount = 1;
   7674     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
   7675     dsl_binding.pImmutableSamplers = NULL;
   7676 
   7677     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
   7678 
   7679     VkDescriptorSet descriptorSet;
   7680     VkDescriptorSetAllocateInfo alloc_info = {};
   7681     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
   7682     alloc_info.descriptorSetCount = 1;
   7683     alloc_info.descriptorPool = ds_pool;
   7684     alloc_info.pSetLayouts = &ds_layout.handle();
   7685     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
   7686     ASSERT_VK_SUCCESS(err);
   7687 
   7688     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout});
   7689 
   7690     // Create images to update the descriptor with
   7691     VkImage image;
   7692     VkImage image2;
   7693     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
   7694     const int32_t tex_width = 32;
   7695     const int32_t tex_height = 32;
   7696     VkImageCreateInfo image_create_info = {};
   7697     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   7698     image_create_info.pNext = NULL;
   7699     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   7700     image_create_info.format = tex_format;
   7701     image_create_info.extent.width = tex_width;
   7702     image_create_info.extent.height = tex_height;
   7703     image_create_info.extent.depth = 1;
   7704     image_create_info.mipLevels = 1;
   7705     image_create_info.arrayLayers = 1;
   7706     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   7707     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   7708     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
   7709     image_create_info.flags = 0;
   7710     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
   7711     ASSERT_VK_SUCCESS(err);
   7712     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image2);
   7713     ASSERT_VK_SUCCESS(err);
   7714 
   7715     VkMemoryRequirements memory_reqs;
   7716     VkDeviceMemory image_memory;
   7717     bool pass;
   7718     VkMemoryAllocateInfo memory_info = {};
   7719     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   7720     memory_info.pNext = NULL;
   7721     memory_info.allocationSize = 0;
   7722     memory_info.memoryTypeIndex = 0;
   7723     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
   7724     // Allocate enough memory for both images
   7725     memory_info.allocationSize = memory_reqs.size * 2;
   7726     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
   7727     ASSERT_TRUE(pass);
   7728     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
   7729     ASSERT_VK_SUCCESS(err);
   7730     err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
   7731     ASSERT_VK_SUCCESS(err);
   7732     // Bind second image to memory right after first image
   7733     err = vkBindImageMemory(m_device->device(), image2, image_memory, memory_reqs.size);
   7734     ASSERT_VK_SUCCESS(err);
   7735 
   7736     VkImageViewCreateInfo image_view_create_info = {};
   7737     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   7738     image_view_create_info.image = image;
   7739     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
   7740     image_view_create_info.format = tex_format;
   7741     image_view_create_info.subresourceRange.layerCount = 1;
   7742     image_view_create_info.subresourceRange.baseMipLevel = 0;
   7743     image_view_create_info.subresourceRange.levelCount = 1;
   7744     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   7745 
   7746     VkImageView tmp_view;  // First test deletes this view
   7747     VkImageView view;
   7748     VkImageView view2;
   7749     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &tmp_view);
   7750     ASSERT_VK_SUCCESS(err);
   7751     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
   7752     ASSERT_VK_SUCCESS(err);
   7753     image_view_create_info.image = image2;
   7754     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view2);
   7755     ASSERT_VK_SUCCESS(err);
   7756     // Create Samplers
   7757     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
   7758     VkSampler sampler;
   7759     VkSampler sampler2;
   7760     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
   7761     ASSERT_VK_SUCCESS(err);
   7762     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler2);
   7763     ASSERT_VK_SUCCESS(err);
   7764     // Update descriptor with image and sampler
   7765     VkDescriptorImageInfo img_info = {};
   7766     img_info.sampler = sampler;
   7767     img_info.imageView = tmp_view;
   7768     img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
   7769 
   7770     VkWriteDescriptorSet descriptor_write;
   7771     memset(&descriptor_write, 0, sizeof(descriptor_write));
   7772     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   7773     descriptor_write.dstSet = descriptorSet;
   7774     descriptor_write.dstBinding = 0;
   7775     descriptor_write.descriptorCount = 1;
   7776     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
   7777     descriptor_write.pImageInfo = &img_info;
   7778 
   7779     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   7780 
   7781     // Create PSO to be used for draw-time errors below
   7782     char const *vsSource =
   7783         "#version 450\n"
   7784         "\n"
   7785         "void main(){\n"
   7786         "   gl_Position = vec4(1);\n"
   7787         "}\n";
   7788     char const *fsSource =
   7789         "#version 450\n"
   7790         "\n"
   7791         "layout(set=0, binding=0) uniform sampler2D s;\n"
   7792         "layout(location=0) out vec4 x;\n"
   7793         "void main(){\n"
   7794         "   x = texture(s, vec2(1));\n"
   7795         "}\n";
   7796     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   7797     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   7798     VkPipelineObj pipe(m_device);
   7799     pipe.AddShader(&vs);
   7800     pipe.AddShader(&fs);
   7801     pipe.AddDefaultColorAttachment();
   7802     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   7803 
   7804     // First error case is destroying sampler prior to cmd buffer submission
   7805     m_commandBuffer->begin();
   7806     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   7807     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   7808     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
   7809                             &descriptorSet, 0, NULL);
   7810     VkViewport viewport = {0, 0, 16, 16, 0, 1};
   7811     VkRect2D scissor = {{0, 0}, {16, 16}};
   7812     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   7813     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
   7814     m_commandBuffer->Draw(1, 0, 0, 0);
   7815     m_commandBuffer->EndRenderPass();
   7816     m_commandBuffer->end();
   7817     VkSubmitInfo submit_info = {};
   7818     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   7819     submit_info.commandBufferCount = 1;
   7820     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   7821     // This first submit should be successful
   7822     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   7823     vkQueueWaitIdle(m_device->m_queue);
   7824 
   7825     // Now destroy imageview and reset cmdBuffer
   7826     vkDestroyImageView(m_device->device(), tmp_view, NULL);
   7827     m_commandBuffer->reset(0);
   7828     m_commandBuffer->begin();
   7829     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   7830     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   7831     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
   7832                             &descriptorSet, 0, NULL);
   7833     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   7834     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
   7835     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that has been destroyed.");
   7836     m_commandBuffer->Draw(1, 0, 0, 0);
   7837     m_errorMonitor->VerifyFound();
   7838     m_commandBuffer->reset(0);
   7839 
   7840     // Re-update descriptor with new view
   7841     img_info.imageView = view;
   7842     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   7843     // Now test destroying sampler prior to cmd buffer submission
   7844     m_commandBuffer->begin();
   7845     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   7846     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   7847     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
   7848                             &descriptorSet, 0, NULL);
   7849     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   7850     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
   7851     m_commandBuffer->Draw(1, 0, 0, 0);
   7852     m_commandBuffer->EndRenderPass();
   7853     m_commandBuffer->end();
   7854     // Destroy sampler invalidates the cmd buffer, causing error on submit
   7855     vkDestroySampler(m_device->device(), sampler, NULL);
   7856     // Attempt to submit cmd buffer
   7857     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is invalid because bound Sampler");
   7858     submit_info = {};
   7859     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   7860     submit_info.commandBufferCount = 1;
   7861     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   7862     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   7863     m_errorMonitor->VerifyFound();
   7864 
   7865     // Now re-update descriptor with valid sampler and delete image
   7866     img_info.sampler = sampler2;
   7867     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   7868 
   7869     VkCommandBufferBeginInfo info = {};
   7870     info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   7871     info.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
   7872 
   7873     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Image ");
   7874     m_commandBuffer->begin(&info);
   7875     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   7876     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   7877     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
   7878                             &descriptorSet, 0, NULL);
   7879     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   7880     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
   7881     m_commandBuffer->Draw(1, 0, 0, 0);
   7882     m_commandBuffer->EndRenderPass();
   7883     m_commandBuffer->end();
   7884     // Destroy image invalidates the cmd buffer, causing error on submit
   7885     vkDestroyImage(m_device->device(), image, NULL);
   7886     // Attempt to submit cmd buffer
   7887     submit_info = {};
   7888     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   7889     submit_info.commandBufferCount = 1;
   7890     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   7891     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   7892     m_errorMonitor->VerifyFound();
   7893     // Now update descriptor to be valid, but then free descriptor
   7894     img_info.imageView = view2;
   7895     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   7896     m_commandBuffer->begin(&info);
   7897     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   7898     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   7899     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
   7900                             &descriptorSet, 0, NULL);
   7901     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   7902     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
   7903     m_commandBuffer->Draw(1, 0, 0, 0);
   7904     m_commandBuffer->EndRenderPass();
   7905     m_commandBuffer->end();
   7906     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   7907 
   7908     // Immediately try to destroy the descriptor set in the active command buffer - failure expected
   7909     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot call vkFreeDescriptorSets() on descriptor set 0x");
   7910     vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptorSet);
   7911     m_errorMonitor->VerifyFound();
   7912 
   7913     // Try again once the queue is idle - should succeed w/o error
   7914     // TODO - though the particular error above doesn't re-occur, there are other 'unexpecteds' still to clean up
   7915     vkQueueWaitIdle(m_device->m_queue);
   7916     m_errorMonitor->SetUnexpectedError(
   7917         "pDescriptorSets must be a valid pointer to an array of descriptorSetCount VkDescriptorSet handles, each element of which "
   7918         "must either be a valid handle or VK_NULL_HANDLE");
   7919     m_errorMonitor->SetUnexpectedError("Unable to remove DescriptorSet obj");
   7920     vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptorSet);
   7921 
   7922     // Attempt to submit cmd buffer containing the freed descriptor set
   7923     submit_info = {};
   7924     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   7925     submit_info.commandBufferCount = 1;
   7926     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   7927     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound DescriptorSet ");
   7928     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   7929     m_errorMonitor->VerifyFound();
   7930 
   7931     // Cleanup
   7932     vkFreeMemory(m_device->device(), image_memory, NULL);
   7933     vkDestroySampler(m_device->device(), sampler2, NULL);
   7934     vkDestroyImage(m_device->device(), image2, NULL);
   7935     vkDestroyImageView(m_device->device(), view, NULL);
   7936     vkDestroyImageView(m_device->device(), view2, NULL);
   7937     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
   7938 }
   7939 
   7940 TEST_F(VkLayerTest, ImageDescriptorLayoutMismatch) {
   7941     TEST_DESCRIPTION("Update an image sampler with a layout that doesn't match the actual image layout at the image is used.");
   7942     ASSERT_NO_FATAL_FAILURE(Init(nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
   7943     ASSERT_NO_FATAL_FAILURE(InitViewport());
   7944     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   7945 
   7946     VkDescriptorPoolSize ds_type_count = {};
   7947     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
   7948     ds_type_count.descriptorCount = 1;
   7949 
   7950     VkDescriptorPoolCreateInfo ds_pool_ci = {};
   7951     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
   7952     ds_pool_ci.pNext = NULL;
   7953     ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
   7954     ds_pool_ci.maxSets = 1;
   7955     ds_pool_ci.poolSizeCount = 1;
   7956     ds_pool_ci.pPoolSizes = &ds_type_count;
   7957 
   7958     VkDescriptorPool ds_pool;
   7959     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
   7960     ASSERT_VK_SUCCESS(err);
   7961 
   7962     VkDescriptorSetLayoutBinding dsl_binding = {};
   7963     dsl_binding.binding = 0;
   7964     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
   7965     dsl_binding.descriptorCount = 1;
   7966     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
   7967     dsl_binding.pImmutableSamplers = NULL;
   7968 
   7969     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
   7970 
   7971     VkDescriptorSet descriptorSet;
   7972     VkDescriptorSetAllocateInfo alloc_info = {};
   7973     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
   7974     alloc_info.descriptorSetCount = 1;
   7975     alloc_info.descriptorPool = ds_pool;
   7976     alloc_info.pSetLayouts = &ds_layout.handle();
   7977     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
   7978     ASSERT_VK_SUCCESS(err);
   7979 
   7980     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout});
   7981 
   7982     // Create images to update the descriptor with
   7983     const VkFormat format = VK_FORMAT_B8G8R8A8_UNORM;
   7984     VkImageObj image(m_device);
   7985     image.Init(32, 32, 1, format, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_TILING_OPTIMAL,
   7986                0);
   7987     ASSERT_TRUE(image.initialized());
   7988 
   7989     VkImageViewCreateInfo image_view_create_info = {};
   7990     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   7991     image_view_create_info.image = image.handle();
   7992     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
   7993     image_view_create_info.format = format;
   7994     image_view_create_info.subresourceRange.layerCount = 1;
   7995     image_view_create_info.subresourceRange.baseMipLevel = 0;
   7996     image_view_create_info.subresourceRange.levelCount = 1;
   7997     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   7998 
   7999     VkImageView view;
   8000     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
   8001     ASSERT_VK_SUCCESS(err);
   8002     // Create Sampler
   8003     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
   8004     VkSampler sampler;
   8005     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
   8006     ASSERT_VK_SUCCESS(err);
   8007     // Update descriptor with image and sampler
   8008     VkDescriptorImageInfo img_info = {};
   8009     img_info.sampler = sampler;
   8010     img_info.imageView = view;
   8011     // This should cause a mis-match. Actual layout at use time is SHADER_RO
   8012     img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
   8013 
   8014     VkWriteDescriptorSet descriptor_write;
   8015     memset(&descriptor_write, 0, sizeof(descriptor_write));
   8016     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   8017     descriptor_write.dstSet = descriptorSet;
   8018     descriptor_write.dstBinding = 0;
   8019     descriptor_write.descriptorCount = 1;
   8020     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
   8021     descriptor_write.pImageInfo = &img_info;
   8022 
   8023     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   8024 
   8025     // Create PSO to be used for draw-time errors below
   8026     char const *vsSource =
   8027         "#version 450\n"
   8028         "\n"
   8029         "void main(){\n"
   8030         "   gl_Position = vec4(1);\n"
   8031         "}\n";
   8032     char const *fsSource =
   8033         "#version 450\n"
   8034         "\n"
   8035         "layout(set=0, binding=0) uniform sampler2D s;\n"
   8036         "layout(location=0) out vec4 x;\n"
   8037         "void main(){\n"
   8038         "   x = texture(s, vec2(1));\n"
   8039         "}\n";
   8040     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   8041     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   8042     VkPipelineObj pipe(m_device);
   8043     pipe.AddShader(&vs);
   8044     pipe.AddShader(&fs);
   8045     pipe.AddDefaultColorAttachment();
   8046     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   8047 
   8048     VkCommandBufferObj cmd_buf(m_device, m_commandPool);
   8049     cmd_buf.begin();
   8050     // record layout different than actual descriptor layout of SHADER_RO
   8051     image.SetLayout(&cmd_buf, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
   8052     cmd_buf.BeginRenderPass(m_renderPassBeginInfo);
   8053     vkCmdBindPipeline(cmd_buf.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   8054     vkCmdBindDescriptorSets(cmd_buf.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &descriptorSet, 0,
   8055                             NULL);
   8056     VkViewport viewport = {0, 0, 16, 16, 0, 1};
   8057     VkRect2D scissor = {{0, 0}, {16, 16}};
   8058     vkCmdSetViewport(cmd_buf.handle(), 0, 1, &viewport);
   8059     vkCmdSetScissor(cmd_buf.handle(), 0, 1, &scissor);
   8060     // At draw time the update layout will mis-match the actual layout
   8061     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   8062                                          " with specific layout VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL that doesn't match the "
   8063                                          "actual current layout VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL.");
   8064     m_errorMonitor->SetDesiredFailureMsg(
   8065         VK_DEBUG_REPORT_ERROR_BIT_EXT,
   8066         " Image layout specified at vkUpdateDescriptorSets() time doesn't match actual image layout at time descriptor is used.");
   8067     cmd_buf.Draw(1, 0, 0, 0);
   8068     m_errorMonitor->VerifyFound();
   8069     cmd_buf.EndRenderPass();
   8070     cmd_buf.end();
   8071     // Submit cmd buffer
   8072     VkSubmitInfo submit_info = {};
   8073     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   8074     submit_info.commandBufferCount = 1;
   8075     submit_info.pCommandBuffers = &cmd_buf.handle();
   8076     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   8077     vkQueueWaitIdle(m_device->m_queue);
   8078     // Cleanup
   8079     vkDestroySampler(m_device->device(), sampler, NULL);
   8080     vkDestroyImageView(m_device->device(), view, NULL);
   8081     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
   8082 }
   8083 
   8084 TEST_F(VkLayerTest, DescriptorPoolInUseDestroyedSignaled) {
   8085     TEST_DESCRIPTION("Delete a DescriptorPool with a DescriptorSet that is in use.");
   8086     ASSERT_NO_FATAL_FAILURE(Init());
   8087     ASSERT_NO_FATAL_FAILURE(InitViewport());
   8088     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   8089 
   8090     VkDescriptorPoolSize ds_type_count = {};
   8091     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
   8092     ds_type_count.descriptorCount = 1;
   8093 
   8094     VkDescriptorPoolCreateInfo ds_pool_ci = {};
   8095     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
   8096     ds_pool_ci.pNext = NULL;
   8097     ds_pool_ci.maxSets = 1;
   8098     ds_pool_ci.poolSizeCount = 1;
   8099     ds_pool_ci.pPoolSizes = &ds_type_count;
   8100 
   8101     VkDescriptorPool ds_pool;
   8102     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
   8103     ASSERT_VK_SUCCESS(err);
   8104 
   8105     VkDescriptorSetLayoutBinding dsl_binding = {};
   8106     dsl_binding.binding = 0;
   8107     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
   8108     dsl_binding.descriptorCount = 1;
   8109     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
   8110     dsl_binding.pImmutableSamplers = NULL;
   8111 
   8112     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
   8113 
   8114     VkDescriptorSet descriptor_set;
   8115     VkDescriptorSetAllocateInfo alloc_info = {};
   8116     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
   8117     alloc_info.descriptorSetCount = 1;
   8118     alloc_info.descriptorPool = ds_pool;
   8119     alloc_info.pSetLayouts = &ds_layout.handle();
   8120     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
   8121     ASSERT_VK_SUCCESS(err);
   8122 
   8123     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout});
   8124 
   8125     // Create image to update the descriptor with
   8126     VkImageObj image(m_device);
   8127     image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   8128     ASSERT_TRUE(image.initialized());
   8129 
   8130     VkImageView view = image.targetView(VK_FORMAT_B8G8R8A8_UNORM);
   8131     // Create Sampler
   8132     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
   8133     VkSampler sampler;
   8134     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
   8135     ASSERT_VK_SUCCESS(err);
   8136     // Update descriptor with image and sampler
   8137     VkDescriptorImageInfo img_info = {};
   8138     img_info.sampler = sampler;
   8139     img_info.imageView = view;
   8140     img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
   8141 
   8142     VkWriteDescriptorSet descriptor_write;
   8143     memset(&descriptor_write, 0, sizeof(descriptor_write));
   8144     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   8145     descriptor_write.dstSet = descriptor_set;
   8146     descriptor_write.dstBinding = 0;
   8147     descriptor_write.descriptorCount = 1;
   8148     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
   8149     descriptor_write.pImageInfo = &img_info;
   8150 
   8151     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   8152 
   8153     // Create PSO to be used for draw-time errors below
   8154     char const *vsSource =
   8155         "#version 450\n"
   8156         "\n"
   8157         "void main(){\n"
   8158         "   gl_Position = vec4(1);\n"
   8159         "}\n";
   8160     char const *fsSource =
   8161         "#version 450\n"
   8162         "\n"
   8163         "layout(set=0, binding=0) uniform sampler2D s;\n"
   8164         "layout(location=0) out vec4 x;\n"
   8165         "void main(){\n"
   8166         "   x = texture(s, vec2(1));\n"
   8167         "}\n";
   8168     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   8169     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   8170     VkPipelineObj pipe(m_device);
   8171     pipe.AddShader(&vs);
   8172     pipe.AddShader(&fs);
   8173     pipe.AddDefaultColorAttachment();
   8174     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   8175 
   8176     m_commandBuffer->begin();
   8177     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   8178     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   8179     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
   8180                             &descriptor_set, 0, NULL);
   8181 
   8182     VkViewport viewport = {0, 0, 16, 16, 0, 1};
   8183     VkRect2D scissor = {{0, 0}, {16, 16}};
   8184     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   8185     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
   8186 
   8187     m_commandBuffer->Draw(1, 0, 0, 0);
   8188     m_commandBuffer->EndRenderPass();
   8189     m_commandBuffer->end();
   8190     // Submit cmd buffer to put pool in-flight
   8191     VkSubmitInfo submit_info = {};
   8192     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   8193     submit_info.commandBufferCount = 1;
   8194     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   8195     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   8196     // Destroy pool while in-flight, causing error
   8197     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_2440025e);
   8198     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
   8199     m_errorMonitor->VerifyFound();
   8200     vkQueueWaitIdle(m_device->m_queue);
   8201     // Cleanup
   8202     vkDestroySampler(m_device->device(), sampler, NULL);
   8203     m_errorMonitor->SetUnexpectedError(
   8204         "If descriptorPool is not VK_NULL_HANDLE, descriptorPool must be a valid VkDescriptorPool handle");
   8205     m_errorMonitor->SetUnexpectedError("Unable to remove DescriptorPool obj");
   8206     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
   8207     // TODO : It seems Validation layers think ds_pool was already destroyed, even though it wasn't?
   8208 }
   8209 
   8210 TEST_F(VkLayerTest, DescriptorImageUpdateNoMemoryBound) {
   8211     TEST_DESCRIPTION("Attempt an image descriptor set update where image's bound memory has been freed.");
   8212     ASSERT_NO_FATAL_FAILURE(Init());
   8213     ASSERT_NO_FATAL_FAILURE(InitViewport());
   8214     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   8215 
   8216     VkDescriptorPoolSize ds_type_count = {};
   8217     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
   8218     ds_type_count.descriptorCount = 1;
   8219 
   8220     VkDescriptorPoolCreateInfo ds_pool_ci = {};
   8221     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
   8222     ds_pool_ci.pNext = NULL;
   8223     ds_pool_ci.maxSets = 1;
   8224     ds_pool_ci.poolSizeCount = 1;
   8225     ds_pool_ci.pPoolSizes = &ds_type_count;
   8226 
   8227     VkDescriptorPool ds_pool;
   8228     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
   8229     ASSERT_VK_SUCCESS(err);
   8230 
   8231     VkDescriptorSetLayoutBinding dsl_binding = {};
   8232     dsl_binding.binding = 0;
   8233     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
   8234     dsl_binding.descriptorCount = 1;
   8235     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
   8236     dsl_binding.pImmutableSamplers = NULL;
   8237 
   8238     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
   8239 
   8240     VkDescriptorSet descriptorSet;
   8241     VkDescriptorSetAllocateInfo alloc_info = {};
   8242     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
   8243     alloc_info.descriptorSetCount = 1;
   8244     alloc_info.descriptorPool = ds_pool;
   8245     alloc_info.pSetLayouts = &ds_layout.handle();
   8246     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
   8247     ASSERT_VK_SUCCESS(err);
   8248 
   8249     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout});
   8250 
   8251     // Create images to update the descriptor with
   8252     VkImage image;
   8253     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
   8254     const int32_t tex_width = 32;
   8255     const int32_t tex_height = 32;
   8256     VkImageCreateInfo image_create_info = {};
   8257     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   8258     image_create_info.pNext = NULL;
   8259     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   8260     image_create_info.format = tex_format;
   8261     image_create_info.extent.width = tex_width;
   8262     image_create_info.extent.height = tex_height;
   8263     image_create_info.extent.depth = 1;
   8264     image_create_info.mipLevels = 1;
   8265     image_create_info.arrayLayers = 1;
   8266     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   8267     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   8268     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
   8269     image_create_info.flags = 0;
   8270     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
   8271     ASSERT_VK_SUCCESS(err);
   8272     // Initially bind memory to avoid error at bind view time. We'll break binding before update.
   8273     VkMemoryRequirements memory_reqs;
   8274     VkDeviceMemory image_memory;
   8275     bool pass;
   8276     VkMemoryAllocateInfo memory_info = {};
   8277     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   8278     memory_info.pNext = NULL;
   8279     memory_info.allocationSize = 0;
   8280     memory_info.memoryTypeIndex = 0;
   8281     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
   8282     // Allocate enough memory for image
   8283     memory_info.allocationSize = memory_reqs.size;
   8284     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
   8285     ASSERT_TRUE(pass);
   8286     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
   8287     ASSERT_VK_SUCCESS(err);
   8288     err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
   8289     ASSERT_VK_SUCCESS(err);
   8290 
   8291     VkImageViewCreateInfo image_view_create_info = {};
   8292     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   8293     image_view_create_info.image = image;
   8294     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
   8295     image_view_create_info.format = tex_format;
   8296     image_view_create_info.subresourceRange.layerCount = 1;
   8297     image_view_create_info.subresourceRange.baseMipLevel = 0;
   8298     image_view_create_info.subresourceRange.levelCount = 1;
   8299     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   8300 
   8301     VkImageView view;
   8302     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
   8303     ASSERT_VK_SUCCESS(err);
   8304     // Create Samplers
   8305     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
   8306     VkSampler sampler;
   8307     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
   8308     ASSERT_VK_SUCCESS(err);
   8309     // Update descriptor with image and sampler
   8310     VkDescriptorImageInfo img_info = {};
   8311     img_info.sampler = sampler;
   8312     img_info.imageView = view;
   8313     img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
   8314 
   8315     VkWriteDescriptorSet descriptor_write;
   8316     memset(&descriptor_write, 0, sizeof(descriptor_write));
   8317     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   8318     descriptor_write.dstSet = descriptorSet;
   8319     descriptor_write.dstBinding = 0;
   8320     descriptor_write.descriptorCount = 1;
   8321     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
   8322     descriptor_write.pImageInfo = &img_info;
   8323     // Break memory binding and attempt update
   8324     vkFreeMemory(m_device->device(), image_memory, nullptr);
   8325     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   8326                                          " previously bound memory was freed. Memory must not be freed prior to this operation.");
   8327     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   8328                                          "vkUpdateDescriptorSets() failed write update validation for Descriptor Set 0x");
   8329     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   8330     m_errorMonitor->VerifyFound();
   8331     // Cleanup
   8332     vkDestroyImage(m_device->device(), image, NULL);
   8333     vkDestroySampler(m_device->device(), sampler, NULL);
   8334     vkDestroyImageView(m_device->device(), view, NULL);
   8335     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
   8336 }
   8337 
   8338 TEST_F(VkLayerTest, InvalidPipeline) {
   8339     // Attempt to bind an invalid Pipeline to a valid Command Buffer
   8340     // ObjectTracker should catch this.
   8341     // Create a valid cmd buffer
   8342     // call vkCmdBindPipeline w/ false Pipeline
   8343     uint64_t fake_pipeline_handle = 0xbaad6001;
   8344     VkPipeline bad_pipeline = reinterpret_cast<VkPipeline &>(fake_pipeline_handle);
   8345     ASSERT_NO_FATAL_FAILURE(Init());
   8346     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   8347 
   8348     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18027c01);
   8349     m_commandBuffer->begin();
   8350     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   8351     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, bad_pipeline);
   8352     m_errorMonitor->VerifyFound();
   8353 
   8354     // Now issue a draw call with no pipeline bound
   8355     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "At Draw/Dispatch time no valid VkPipeline is bound!");
   8356     m_commandBuffer->Draw(1, 0, 0, 0);
   8357     m_errorMonitor->VerifyFound();
   8358 
   8359     // Finally same check once more but with Dispatch/Compute
   8360     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "At Draw/Dispatch time no valid VkPipeline is bound!");
   8361     vkCmdEndRenderPass(m_commandBuffer->handle());  // must be outside renderpass
   8362     vkCmdDispatch(m_commandBuffer->handle(), 0, 0, 0);
   8363     m_errorMonitor->VerifyFound();
   8364 }
   8365 
   8366 TEST_F(VkLayerTest, CmdDispatchExceedLimits) {
   8367     TEST_DESCRIPTION("Compute dispatch with dimensions that exceed device limits");
   8368 
   8369     // Enable KHX device group extensions, if available
   8370     if (InstanceExtensionSupported(VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME)) {
   8371         m_instance_extension_names.push_back(VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME);
   8372     }
   8373     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   8374     bool khx_dg_ext_available = false;
   8375     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHX_DEVICE_GROUP_EXTENSION_NAME)) {
   8376         m_device_extension_names.push_back(VK_KHX_DEVICE_GROUP_EXTENSION_NAME);
   8377         khx_dg_ext_available = true;
   8378     }
   8379     ASSERT_NO_FATAL_FAILURE(InitState());
   8380 
   8381     uint32_t x_limit = m_device->props.limits.maxComputeWorkGroupCount[0];
   8382     uint32_t y_limit = m_device->props.limits.maxComputeWorkGroupCount[1];
   8383     uint32_t z_limit = m_device->props.limits.maxComputeWorkGroupCount[2];
   8384     if (std::max({x_limit, y_limit, z_limit}) == UINT32_MAX) {
   8385         printf("             device maxComputeWorkGroupCount limit reports UINT32_MAX, test not possible, skipping.\n");
   8386         return;
   8387     }
   8388 
   8389     // Create a minimal compute pipeline
   8390     std::string cs_text = "#version 450\nvoid main() {}\n";  // minimal no-op shader
   8391     VkShaderObj cs_obj(m_device, cs_text.c_str(), VK_SHADER_STAGE_COMPUTE_BIT, this);
   8392 
   8393     VkPipelineLayoutCreateInfo info = {};
   8394     info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
   8395     info.pNext = nullptr;
   8396     VkPipelineLayout pipe_layout;
   8397     vkCreatePipelineLayout(device(), &info, nullptr, &pipe_layout);
   8398 
   8399     VkComputePipelineCreateInfo pipeline_info = {};
   8400     pipeline_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
   8401     pipeline_info.pNext = nullptr;
   8402     pipeline_info.flags = khx_dg_ext_available ? VK_PIPELINE_CREATE_DISPATCH_BASE_KHX : 0;
   8403     pipeline_info.layout = pipe_layout;
   8404     pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
   8405     pipeline_info.basePipelineIndex = -1;
   8406     pipeline_info.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
   8407     pipeline_info.stage.pNext = nullptr;
   8408     pipeline_info.stage.flags = 0;
   8409     pipeline_info.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
   8410     pipeline_info.stage.module = cs_obj.handle();
   8411     pipeline_info.stage.pName = "main";
   8412     pipeline_info.stage.pSpecializationInfo = nullptr;
   8413     VkPipeline cs_pipeline;
   8414     vkCreateComputePipelines(device(), VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &cs_pipeline);
   8415 
   8416     // Bind pipeline to command buffer
   8417     m_commandBuffer->begin();
   8418     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, cs_pipeline);
   8419 
   8420     // Dispatch counts that exceed device limits
   8421     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19c00304);
   8422     vkCmdDispatch(m_commandBuffer->handle(), x_limit + 1, y_limit, z_limit);
   8423     m_errorMonitor->VerifyFound();
   8424 
   8425     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19c00306);
   8426     vkCmdDispatch(m_commandBuffer->handle(), x_limit, y_limit + 1, z_limit);
   8427     m_errorMonitor->VerifyFound();
   8428 
   8429     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19c00308);
   8430     vkCmdDispatch(m_commandBuffer->handle(), x_limit, y_limit, z_limit + 1);
   8431     m_errorMonitor->VerifyFound();
   8432 
   8433     if (khx_dg_ext_available) {
   8434         PFN_vkCmdDispatchBaseKHX fp_vkCmdDispatchBaseKHX =
   8435             (PFN_vkCmdDispatchBaseKHX)vkGetInstanceProcAddr(instance(), "vkCmdDispatchBaseKHX");
   8436 
   8437         // Base equals or exceeds limit
   8438         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19e0034a);
   8439         fp_vkCmdDispatchBaseKHX(m_commandBuffer->handle(), x_limit, y_limit - 1, z_limit - 1, 0, 0, 0);
   8440         m_errorMonitor->VerifyFound();
   8441 
   8442         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19e0034c);
   8443         fp_vkCmdDispatchBaseKHX(m_commandBuffer->handle(), x_limit - 1, y_limit, z_limit - 1, 0, 0, 0);
   8444         m_errorMonitor->VerifyFound();
   8445 
   8446         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19e0034e);
   8447         fp_vkCmdDispatchBaseKHX(m_commandBuffer->handle(), x_limit - 1, y_limit - 1, z_limit, 0, 0, 0);
   8448         m_errorMonitor->VerifyFound();
   8449 
   8450         // (Base + count) exceeds limit
   8451         uint32_t x_base = x_limit / 2;
   8452         uint32_t y_base = y_limit / 2;
   8453         uint32_t z_base = z_limit / 2;
   8454         x_limit -= x_base;
   8455         y_limit -= y_base;
   8456         z_limit -= z_base;
   8457 
   8458         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19e00350);
   8459         fp_vkCmdDispatchBaseKHX(m_commandBuffer->handle(), x_base, y_base, z_base, x_limit + 1, y_limit, z_limit);
   8460         m_errorMonitor->VerifyFound();
   8461 
   8462         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19e00352);
   8463         fp_vkCmdDispatchBaseKHX(m_commandBuffer->handle(), x_base, y_base, z_base, x_limit, y_limit + 1, z_limit);
   8464         m_errorMonitor->VerifyFound();
   8465 
   8466         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19e00354);
   8467         fp_vkCmdDispatchBaseKHX(m_commandBuffer->handle(), x_base, y_base, z_base, x_limit, y_limit, z_limit + 1);
   8468         m_errorMonitor->VerifyFound();
   8469     } else {
   8470         printf("             KHX_DEVICE_GROUP_* extensions not supported, skipping CmdDispatchBaseKHX() tests.\n");
   8471     }
   8472 
   8473     // Clean up
   8474     vkDestroyPipeline(device(), cs_pipeline, nullptr);
   8475     vkDestroyPipelineLayout(device(), pipe_layout, nullptr);
   8476 }
   8477 
   8478 TEST_F(VkLayerTest, MultiplaneImageLayoutBadAspectFlags) {
   8479     TEST_DESCRIPTION("Query layout of a multiplane image using illegal aspect flag masks");
   8480 
   8481     // Enable KHR multiplane req'd extensions
   8482     bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
   8483                                                     VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
   8484     if (mp_extensions) {
   8485         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
   8486     }
   8487     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   8488     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
   8489     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
   8490     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
   8491     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
   8492     if (mp_extensions) {
   8493         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
   8494         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
   8495         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
   8496         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
   8497     } else {
   8498         printf("             test requires KHR multiplane extensions, not available.  Skipping.\n");
   8499         return;
   8500     }
   8501     ASSERT_NO_FATAL_FAILURE(InitState());
   8502 
   8503     // Query format support
   8504     PFN_vkGetPhysicalDeviceImageFormatProperties2KHR GetPDIFP2KHR =
   8505         (PFN_vkGetPhysicalDeviceImageFormatProperties2KHR)vkGetInstanceProcAddr(instance(),
   8506                                                                                 "vkGetPhysicalDeviceImageFormatProperties2KHR");
   8507     VkPhysicalDeviceImageFormatInfo2KHR fmt_info = {};
   8508     fmt_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR;
   8509     fmt_info.pNext = nullptr;
   8510     fmt_info.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR;
   8511     fmt_info.type = VK_IMAGE_TYPE_2D;
   8512     fmt_info.tiling = VK_IMAGE_TILING_LINEAR;
   8513     fmt_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   8514     fmt_info.flags = 0;
   8515 
   8516     VkImageFormatProperties2KHR fmt_props = {};
   8517     fmt_props.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR;
   8518     VkResult err_2 = GetPDIFP2KHR(gpu(), &fmt_info, &fmt_props);
   8519 
   8520     fmt_info.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR;
   8521     VkResult err_3 = GetPDIFP2KHR(gpu(), &fmt_info, &fmt_props);
   8522 
   8523     if ((VK_SUCCESS != err_2) || (VK_SUCCESS != err_3)) {
   8524         printf("             Multiplane image format not supported.  Skipping test.\n");
   8525         return;  // Assume there's low ROI on searching for different mp formats
   8526     }
   8527 
   8528     VkImageCreateInfo ci = {};
   8529     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   8530     ci.pNext = NULL;
   8531     ci.flags = fmt_info.flags;
   8532     ci.imageType = fmt_info.type;
   8533     ci.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR;
   8534     ci.extent = {128, 128, 1};
   8535     ci.mipLevels = 1;
   8536     ci.arrayLayers = 1;
   8537     ci.samples = VK_SAMPLE_COUNT_1_BIT;
   8538     ci.tiling = fmt_info.tiling;
   8539     ci.usage = fmt_info.usage;
   8540     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   8541     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   8542     VkImage image_2plane;
   8543     VkResult err = vkCreateImage(device(), &ci, NULL, &image_2plane);
   8544     ASSERT_VK_SUCCESS(err);
   8545 
   8546     ci.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR;
   8547     VkImage image_3plane;
   8548     err = vkCreateImage(device(), &ci, NULL, &image_3plane);
   8549     ASSERT_VK_SUCCESS(err);
   8550 
   8551     // Query layout of 3rd plane, for a 2-plane image
   8552     VkImageSubresource subres = {};
   8553     subres.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
   8554     subres.mipLevel = 0;
   8555     subres.arrayLayer = 0;
   8556     VkSubresourceLayout layout = {};
   8557 
   8558     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_2a600c5a);
   8559     vkGetImageSubresourceLayout(device(), image_2plane, &subres, &layout);
   8560     m_errorMonitor->VerifyFound();
   8561 
   8562     // Query layout using color aspect, for a 3-plane image
   8563     subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   8564     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_2a600c5c);
   8565     vkGetImageSubresourceLayout(device(), image_3plane, &subres, &layout);
   8566     m_errorMonitor->VerifyFound();
   8567 
   8568     // Clean up
   8569     vkDestroyImage(device(), image_2plane, NULL);
   8570     vkDestroyImage(device(), image_3plane, NULL);
   8571 }
   8572 
   8573 TEST_F(VkPositiveLayerTest, MultiplaneGetImageSubresourceLayout) {
   8574     TEST_DESCRIPTION("Positive test, query layout of a single plane of a multiplane image. (repro Github #2530)");
   8575 
   8576     // Enable KHR multiplane req'd extensions
   8577     bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
   8578                                                     VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
   8579     if (mp_extensions) {
   8580         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
   8581     }
   8582     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   8583     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
   8584     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
   8585     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
   8586     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
   8587     if (mp_extensions) {
   8588         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
   8589         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
   8590         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
   8591         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
   8592     } else {
   8593         printf("             test requires KHR multiplane extensions, not available.  Skipping.\n");
   8594         return;
   8595     }
   8596     ASSERT_NO_FATAL_FAILURE(InitState());
   8597 
   8598     // Query format support
   8599     PFN_vkGetPhysicalDeviceImageFormatProperties2KHR GetPDIFP2KHR =
   8600         (PFN_vkGetPhysicalDeviceImageFormatProperties2KHR)vkGetInstanceProcAddr(instance(),
   8601                                                                                 "vkGetPhysicalDeviceImageFormatProperties2KHR");
   8602     VkPhysicalDeviceImageFormatInfo2KHR fmt_info = {};
   8603     fmt_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR;
   8604     fmt_info.pNext = nullptr;
   8605     fmt_info.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR;
   8606     fmt_info.type = VK_IMAGE_TYPE_2D;
   8607     fmt_info.tiling = VK_IMAGE_TILING_LINEAR;
   8608     fmt_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   8609     fmt_info.flags = 0;
   8610 
   8611     m_errorMonitor->ExpectSuccess();
   8612     VkImageFormatProperties2KHR fmt_props = {};
   8613     fmt_props.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR;
   8614     VkResult err = GetPDIFP2KHR(gpu(), &fmt_info, &fmt_props);
   8615     m_errorMonitor->VerifyNotFound();
   8616     if (VK_SUCCESS != err) {
   8617         printf("             Multiplane image format not supported.  Skipping test.\n");
   8618         return;  // Assume there's low ROI on searching for a different mp format
   8619     }
   8620 
   8621     VkImageCreateInfo ci = {};
   8622     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   8623     ci.pNext = NULL;
   8624     ci.flags = fmt_info.flags;
   8625     ci.imageType = fmt_info.type;
   8626     ci.format = fmt_info.format;
   8627     ci.extent = {128, 128, 1};
   8628     ci.mipLevels = 1;
   8629     ci.arrayLayers = 1;
   8630     ci.samples = VK_SAMPLE_COUNT_1_BIT;
   8631     ci.tiling = fmt_info.tiling;
   8632     ci.usage = fmt_info.usage;
   8633     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   8634     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   8635     VkImage image;
   8636     err = vkCreateImage(device(), &ci, NULL, &image);
   8637     ASSERT_VK_SUCCESS(err);
   8638 
   8639     // Query layout of 3rd plane
   8640     VkImageSubresource subres = {};
   8641     subres.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
   8642     subres.mipLevel = 0;
   8643     subres.arrayLayer = 0;
   8644     VkSubresourceLayout layout = {};
   8645 
   8646     m_errorMonitor->ExpectSuccess();
   8647     vkGetImageSubresourceLayout(device(), image, &subres, &layout);
   8648     m_errorMonitor->VerifyNotFound();
   8649 
   8650     vkDestroyImage(device(), image, NULL);
   8651 }
   8652 
   8653 TEST_F(VkLayerTest, DescriptorSetNotUpdated) {
   8654     TEST_DESCRIPTION("Bind a descriptor set that hasn't been updated.");
   8655     VkResult err;
   8656 
   8657     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, " bound but it was never updated. ");
   8658 
   8659     ASSERT_NO_FATAL_FAILURE(Init());
   8660     ASSERT_NO_FATAL_FAILURE(InitViewport());
   8661     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   8662     VkDescriptorPoolSize ds_type_count = {};
   8663     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   8664     ds_type_count.descriptorCount = 1;
   8665 
   8666     VkDescriptorPoolCreateInfo ds_pool_ci = {};
   8667     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
   8668     ds_pool_ci.pNext = NULL;
   8669     ds_pool_ci.maxSets = 1;
   8670     ds_pool_ci.poolSizeCount = 1;
   8671     ds_pool_ci.pPoolSizes = &ds_type_count;
   8672 
   8673     VkDescriptorPool ds_pool;
   8674     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
   8675     ASSERT_VK_SUCCESS(err);
   8676 
   8677     VkDescriptorSetLayoutBinding dsl_binding = {};
   8678     dsl_binding.binding = 0;
   8679     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   8680     dsl_binding.descriptorCount = 1;
   8681     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
   8682     dsl_binding.pImmutableSamplers = NULL;
   8683 
   8684     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
   8685 
   8686     VkDescriptorSet descriptorSet;
   8687     VkDescriptorSetAllocateInfo alloc_info = {};
   8688     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
   8689     alloc_info.descriptorSetCount = 1;
   8690     alloc_info.descriptorPool = ds_pool;
   8691     alloc_info.pSetLayouts = &ds_layout.handle();
   8692     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
   8693     ASSERT_VK_SUCCESS(err);
   8694 
   8695     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout});
   8696 
   8697     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   8698     //  We shouldn't need a fragment shader but add it to be able to run
   8699     //  on more devices
   8700     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   8701 
   8702     VkPipelineObj pipe(m_device);
   8703     pipe.AddShader(&vs);
   8704     pipe.AddShader(&fs);
   8705     pipe.AddDefaultColorAttachment();
   8706     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   8707 
   8708     m_commandBuffer->begin();
   8709     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   8710     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
   8711                             &descriptorSet, 0, NULL);
   8712 
   8713     m_errorMonitor->VerifyFound();
   8714 
   8715     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
   8716 }
   8717 
   8718 TEST_F(VkLayerTest, InvalidBufferViewObject) {
   8719     // Create a single TEXEL_BUFFER descriptor and send it an invalid bufferView
   8720     // First, cause the bufferView to be invalid due to underlying buffer being destroyed
   8721     // Then destroy view itself and verify that same error is hit
   8722     VkResult err;
   8723 
   8724     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15c00286);
   8725 
   8726     ASSERT_NO_FATAL_FAILURE(Init());
   8727     VkDescriptorPoolSize ds_type_count = {};
   8728     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
   8729     ds_type_count.descriptorCount = 1;
   8730 
   8731     VkDescriptorPoolCreateInfo ds_pool_ci = {};
   8732     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
   8733     ds_pool_ci.pNext = NULL;
   8734     ds_pool_ci.maxSets = 1;
   8735     ds_pool_ci.poolSizeCount = 1;
   8736     ds_pool_ci.pPoolSizes = &ds_type_count;
   8737 
   8738     VkDescriptorPool ds_pool;
   8739     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
   8740     ASSERT_VK_SUCCESS(err);
   8741 
   8742     VkDescriptorSetLayoutBinding dsl_binding = {};
   8743     dsl_binding.binding = 0;
   8744     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
   8745     dsl_binding.descriptorCount = 1;
   8746     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
   8747     dsl_binding.pImmutableSamplers = NULL;
   8748 
   8749     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
   8750 
   8751     VkDescriptorSet descriptorSet;
   8752     VkDescriptorSetAllocateInfo alloc_info = {};
   8753     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
   8754     alloc_info.descriptorSetCount = 1;
   8755     alloc_info.descriptorPool = ds_pool;
   8756     alloc_info.pSetLayouts = &ds_layout.handle();
   8757     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
   8758     ASSERT_VK_SUCCESS(err);
   8759 
   8760     // Create a valid bufferView to start with
   8761     VkBuffer buffer;
   8762     uint32_t queue_family_index = 0;
   8763     VkBufferCreateInfo buffer_create_info = {};
   8764     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   8765     buffer_create_info.size = 1024;
   8766     buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
   8767     buffer_create_info.queueFamilyIndexCount = 1;
   8768     buffer_create_info.pQueueFamilyIndices = &queue_family_index;
   8769 
   8770     err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
   8771     ASSERT_VK_SUCCESS(err);
   8772 
   8773     VkMemoryRequirements memory_reqs;
   8774     VkDeviceMemory buffer_memory;
   8775 
   8776     VkMemoryAllocateInfo memory_info = {};
   8777     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   8778     memory_info.allocationSize = 0;
   8779     memory_info.memoryTypeIndex = 0;
   8780 
   8781     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
   8782     memory_info.allocationSize = memory_reqs.size;
   8783     bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
   8784     ASSERT_TRUE(pass);
   8785 
   8786     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
   8787     ASSERT_VK_SUCCESS(err);
   8788     err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
   8789     ASSERT_VK_SUCCESS(err);
   8790 
   8791     VkBufferView view;
   8792     VkBufferViewCreateInfo bvci = {};
   8793     bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
   8794     bvci.buffer = buffer;
   8795     bvci.format = VK_FORMAT_R32_SFLOAT;
   8796     bvci.range = VK_WHOLE_SIZE;
   8797 
   8798     err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view);
   8799     ASSERT_VK_SUCCESS(err);
   8800 
   8801     // First Destroy buffer underlying view which should hit error in CV
   8802     vkDestroyBuffer(m_device->device(), buffer, NULL);
   8803 
   8804     VkWriteDescriptorSet descriptor_write;
   8805     memset(&descriptor_write, 0, sizeof(descriptor_write));
   8806     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   8807     descriptor_write.dstSet = descriptorSet;
   8808     descriptor_write.dstBinding = 0;
   8809     descriptor_write.descriptorCount = 1;
   8810     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
   8811     descriptor_write.pTexelBufferView = &view;
   8812 
   8813     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   8814     m_errorMonitor->VerifyFound();
   8815 
   8816     // Now destroy view itself and verify same error, which is hit in PV this time
   8817     vkDestroyBufferView(m_device->device(), view, NULL);
   8818     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15c00286);
   8819     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   8820     m_errorMonitor->VerifyFound();
   8821 
   8822     vkFreeMemory(m_device->device(), buffer_memory, NULL);
   8823     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
   8824 }
   8825 
   8826 TEST_F(VkLayerTest, CreateBufferViewNoMemoryBoundToBuffer) {
   8827     TEST_DESCRIPTION("Attempt to create a buffer view with a buffer that has no memory bound to it.");
   8828 
   8829     VkResult err;
   8830     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   8831                                          " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
   8832 
   8833     ASSERT_NO_FATAL_FAILURE(Init());
   8834 
   8835     // Create a buffer with no bound memory and then attempt to create
   8836     // a buffer view.
   8837     VkBufferCreateInfo buff_ci = {};
   8838     buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   8839     buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
   8840     buff_ci.size = 256;
   8841     buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   8842     VkBuffer buffer;
   8843     err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
   8844     ASSERT_VK_SUCCESS(err);
   8845 
   8846     VkBufferViewCreateInfo buff_view_ci = {};
   8847     buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
   8848     buff_view_ci.buffer = buffer;
   8849     buff_view_ci.format = VK_FORMAT_R8_UNORM;
   8850     buff_view_ci.range = VK_WHOLE_SIZE;
   8851     VkBufferView buff_view;
   8852     err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buff_view);
   8853 
   8854     m_errorMonitor->VerifyFound();
   8855     vkDestroyBuffer(m_device->device(), buffer, NULL);
   8856     // If last error is success, it still created the view, so delete it.
   8857     if (err == VK_SUCCESS) {
   8858         vkDestroyBufferView(m_device->device(), buff_view, NULL);
   8859     }
   8860 }
   8861 
   8862 TEST_F(VkLayerTest, InvalidDynamicOffsetCases) {
   8863     // Create a descriptorSet w/ dynamic descriptor and then hit 3 offset error
   8864     // cases:
   8865     // 1. No dynamicOffset supplied
   8866     // 2. Too many dynamicOffsets supplied
   8867     // 3. Dynamic offset oversteps buffer being updated
   8868     VkResult err;
   8869     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   8870                                          " requires 1 dynamicOffsets, but only 0 dynamicOffsets are left in pDynamicOffsets ");
   8871 
   8872     ASSERT_NO_FATAL_FAILURE(Init());
   8873     ASSERT_NO_FATAL_FAILURE(InitViewport());
   8874     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   8875 
   8876     VkDescriptorPoolSize ds_type_count = {};
   8877     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
   8878     ds_type_count.descriptorCount = 1;
   8879 
   8880     VkDescriptorPoolCreateInfo ds_pool_ci = {};
   8881     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
   8882     ds_pool_ci.pNext = NULL;
   8883     ds_pool_ci.maxSets = 1;
   8884     ds_pool_ci.poolSizeCount = 1;
   8885     ds_pool_ci.pPoolSizes = &ds_type_count;
   8886 
   8887     VkDescriptorPool ds_pool;
   8888     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
   8889     ASSERT_VK_SUCCESS(err);
   8890 
   8891     VkDescriptorSetLayoutBinding dsl_binding = {};
   8892     dsl_binding.binding = 0;
   8893     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
   8894     dsl_binding.descriptorCount = 1;
   8895     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
   8896     dsl_binding.pImmutableSamplers = NULL;
   8897 
   8898     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
   8899 
   8900     VkDescriptorSet descriptorSet;
   8901     VkDescriptorSetAllocateInfo alloc_info = {};
   8902     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
   8903     alloc_info.descriptorSetCount = 1;
   8904     alloc_info.descriptorPool = ds_pool;
   8905     alloc_info.pSetLayouts = &ds_layout.handle();
   8906     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
   8907     ASSERT_VK_SUCCESS(err);
   8908 
   8909     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout});
   8910 
   8911     // Create a buffer to update the descriptor with
   8912     uint32_t qfi = 0;
   8913     VkBufferCreateInfo buffCI = {};
   8914     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   8915     buffCI.size = 1024;
   8916     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
   8917     buffCI.queueFamilyIndexCount = 1;
   8918     buffCI.pQueueFamilyIndices = &qfi;
   8919 
   8920     VkBuffer dyub;
   8921     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
   8922     ASSERT_VK_SUCCESS(err);
   8923     // Allocate memory and bind to buffer so we can make it to the appropriate error
   8924     VkMemoryRequirements memReqs;
   8925     vkGetBufferMemoryRequirements(m_device->device(), dyub, &memReqs);
   8926     VkMemoryAllocateInfo mem_alloc = {};
   8927     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   8928     mem_alloc.pNext = NULL;
   8929     mem_alloc.allocationSize = memReqs.size;
   8930     mem_alloc.memoryTypeIndex = 0;
   8931     bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
   8932     if (!pass) {
   8933         vkDestroyBuffer(m_device->device(), dyub, NULL);
   8934         return;
   8935     }
   8936 
   8937     VkDeviceMemory mem;
   8938     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
   8939     ASSERT_VK_SUCCESS(err);
   8940     err = vkBindBufferMemory(m_device->device(), dyub, mem, 0);
   8941     ASSERT_VK_SUCCESS(err);
   8942     // Correctly update descriptor to avoid "NOT_UPDATED" error
   8943     VkDescriptorBufferInfo buffInfo = {};
   8944     buffInfo.buffer = dyub;
   8945     buffInfo.offset = 0;
   8946     buffInfo.range = 1024;
   8947 
   8948     VkWriteDescriptorSet descriptor_write;
   8949     memset(&descriptor_write, 0, sizeof(descriptor_write));
   8950     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   8951     descriptor_write.dstSet = descriptorSet;
   8952     descriptor_write.dstBinding = 0;
   8953     descriptor_write.descriptorCount = 1;
   8954     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
   8955     descriptor_write.pBufferInfo = &buffInfo;
   8956 
   8957     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   8958 
   8959     m_commandBuffer->begin();
   8960     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   8961     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
   8962                             &descriptorSet, 0, NULL);
   8963     m_errorMonitor->VerifyFound();
   8964     uint32_t pDynOff[2] = {512, 756};
   8965     // Now cause error b/c too many dynOffsets in array for # of dyn descriptors
   8966     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   8967                                          "Attempting to bind 1 descriptorSets with 1 dynamic descriptors, but ");
   8968     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
   8969                             &descriptorSet, 2, pDynOff);
   8970     m_errorMonitor->VerifyFound();
   8971     // Finally cause error due to dynamicOffset being too big
   8972     m_errorMonitor->SetDesiredFailureMsg(
   8973         VK_DEBUG_REPORT_ERROR_BIT_EXT,
   8974         " dynamic offset 512 combined with offset 0 and range 1024 that oversteps the buffer size of 1024");
   8975     // Create PSO to be used for draw-time errors below
   8976     char const *vsSource =
   8977         "#version 450\n"
   8978         "\n"
   8979         "void main(){\n"
   8980         "   gl_Position = vec4(1);\n"
   8981         "}\n";
   8982     char const *fsSource =
   8983         "#version 450\n"
   8984         "\n"
   8985         "layout(location=0) out vec4 x;\n"
   8986         "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
   8987         "void main(){\n"
   8988         "   x = vec4(bar.y);\n"
   8989         "}\n";
   8990     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   8991     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   8992     VkPipelineObj pipe(m_device);
   8993     pipe.AddShader(&vs);
   8994     pipe.AddShader(&fs);
   8995     pipe.AddDefaultColorAttachment();
   8996     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   8997 
   8998     VkViewport viewport = {0, 0, 16, 16, 0, 1};
   8999     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   9000     VkRect2D scissor = {{0, 0}, {16, 16}};
   9001     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
   9002 
   9003     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   9004     // This update should succeed, but offset size of 512 will overstep buffer
   9005     // /w range 1024 & size 1024
   9006     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
   9007                             &descriptorSet, 1, pDynOff);
   9008     m_commandBuffer->Draw(1, 0, 0, 0);
   9009     m_errorMonitor->VerifyFound();
   9010 
   9011     vkDestroyBuffer(m_device->device(), dyub, NULL);
   9012     vkFreeMemory(m_device->device(), mem, NULL);
   9013 
   9014     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
   9015 }
   9016 
   9017 TEST_F(VkLayerTest, DescriptorBufferUpdateNoMemoryBound) {
   9018     TEST_DESCRIPTION("Attempt to update a descriptor with a non-sparse buffer that doesn't have memory bound");
   9019     VkResult err;
   9020     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   9021                                          " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
   9022     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   9023                                          "vkUpdateDescriptorSets() failed write update validation for Descriptor Set 0x");
   9024 
   9025     ASSERT_NO_FATAL_FAILURE(Init());
   9026     ASSERT_NO_FATAL_FAILURE(InitViewport());
   9027     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   9028 
   9029     VkDescriptorPoolSize ds_type_count = {};
   9030     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
   9031     ds_type_count.descriptorCount = 1;
   9032 
   9033     VkDescriptorPoolCreateInfo ds_pool_ci = {};
   9034     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
   9035     ds_pool_ci.pNext = NULL;
   9036     ds_pool_ci.maxSets = 1;
   9037     ds_pool_ci.poolSizeCount = 1;
   9038     ds_pool_ci.pPoolSizes = &ds_type_count;
   9039 
   9040     VkDescriptorPool ds_pool;
   9041     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
   9042     ASSERT_VK_SUCCESS(err);
   9043 
   9044     VkDescriptorSetLayoutBinding dsl_binding = {};
   9045     dsl_binding.binding = 0;
   9046     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
   9047     dsl_binding.descriptorCount = 1;
   9048     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
   9049     dsl_binding.pImmutableSamplers = NULL;
   9050 
   9051     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
   9052 
   9053     VkDescriptorSet descriptorSet;
   9054     VkDescriptorSetAllocateInfo alloc_info = {};
   9055     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
   9056     alloc_info.descriptorSetCount = 1;
   9057     alloc_info.descriptorPool = ds_pool;
   9058     alloc_info.pSetLayouts = &ds_layout.handle();
   9059     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
   9060     ASSERT_VK_SUCCESS(err);
   9061 
   9062     // Create a buffer to update the descriptor with
   9063     uint32_t qfi = 0;
   9064     VkBufferCreateInfo buffCI = {};
   9065     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   9066     buffCI.size = 1024;
   9067     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
   9068     buffCI.queueFamilyIndexCount = 1;
   9069     buffCI.pQueueFamilyIndices = &qfi;
   9070 
   9071     VkBuffer dyub;
   9072     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
   9073     ASSERT_VK_SUCCESS(err);
   9074 
   9075     // Attempt to update descriptor without binding memory to it
   9076     VkDescriptorBufferInfo buffInfo = {};
   9077     buffInfo.buffer = dyub;
   9078     buffInfo.offset = 0;
   9079     buffInfo.range = 1024;
   9080 
   9081     VkWriteDescriptorSet descriptor_write;
   9082     memset(&descriptor_write, 0, sizeof(descriptor_write));
   9083     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   9084     descriptor_write.dstSet = descriptorSet;
   9085     descriptor_write.dstBinding = 0;
   9086     descriptor_write.descriptorCount = 1;
   9087     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
   9088     descriptor_write.pBufferInfo = &buffInfo;
   9089 
   9090     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   9091     m_errorMonitor->VerifyFound();
   9092 
   9093     vkDestroyBuffer(m_device->device(), dyub, NULL);
   9094     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
   9095 }
   9096 
   9097 TEST_F(VkLayerTest, InvalidPushConstants) {
   9098     ASSERT_NO_FATAL_FAILURE(Init());
   9099     ASSERT_NO_FATAL_FAILURE(InitViewport());
   9100     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   9101 
   9102     VkPipelineLayout pipeline_layout;
   9103     VkPushConstantRange pc_range = {};
   9104     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
   9105     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
   9106     pipeline_layout_ci.pushConstantRangeCount = 1;
   9107     pipeline_layout_ci.pPushConstantRanges = &pc_range;
   9108 
   9109     //
   9110     // Check for invalid push constant ranges in pipeline layouts.
   9111     //
   9112     struct PipelineLayoutTestCase {
   9113         VkPushConstantRange const range;
   9114         char const *msg;
   9115     };
   9116 
   9117     const uint32_t too_big = m_device->props.limits.maxPushConstantsSize + 0x4;
   9118     const std::array<PipelineLayoutTestCase, 10> range_tests = {{
   9119         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 0}, "vkCreatePipelineLayout() call has push constants index 0 with size 0."},
   9120         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 1}, "vkCreatePipelineLayout() call has push constants index 0 with size 1."},
   9121         {{VK_SHADER_STAGE_VERTEX_BIT, 4, 1}, "vkCreatePipelineLayout() call has push constants index 0 with size 1."},
   9122         {{VK_SHADER_STAGE_VERTEX_BIT, 4, 0}, "vkCreatePipelineLayout() call has push constants index 0 with size 0."},
   9123         {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4}, "vkCreatePipelineLayout() call has push constants index 0 with offset 1. Offset must"},
   9124         {{VK_SHADER_STAGE_VERTEX_BIT, 0, too_big}, "vkCreatePipelineLayout() call has push constants index 0 with offset "},
   9125         {{VK_SHADER_STAGE_VERTEX_BIT, too_big, too_big}, "vkCreatePipelineLayout() call has push constants index 0 with offset "},
   9126         {{VK_SHADER_STAGE_VERTEX_BIT, too_big, 4}, "vkCreatePipelineLayout() call has push constants index 0 with offset "},
   9127         {{VK_SHADER_STAGE_VERTEX_BIT, 0xFFFFFFF0, 0x00000020},
   9128          "vkCreatePipelineLayout() call has push constants index 0 with offset "},
   9129         {{VK_SHADER_STAGE_VERTEX_BIT, 0x00000020, 0xFFFFFFF0},
   9130          "vkCreatePipelineLayout() call has push constants index 0 with offset "},
   9131     }};
   9132 
   9133     // Check for invalid offset and size
   9134     for (const auto &iter : range_tests) {
   9135         pc_range = iter.range;
   9136         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg);
   9137         vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
   9138         m_errorMonitor->VerifyFound();
   9139     }
   9140 
   9141     // Check for invalid stage flag
   9142     pc_range.offset = 0;
   9143     pc_range.size = 16;
   9144     pc_range.stageFlags = 0;
   9145     m_errorMonitor->SetDesiredFailureMsg(
   9146         VK_DEBUG_REPORT_ERROR_BIT_EXT,
   9147         "vkCreatePipelineLayout: value of pCreateInfo->pPushConstantRanges[0].stageFlags must not be 0");
   9148     vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
   9149     m_errorMonitor->VerifyFound();
   9150 
   9151     // Check for duplicate stage flags in a list of push constant ranges.
   9152     // A shader can only have one push constant block and that block is mapped
   9153     // to the push constant range that has that shader's stage flag set.
   9154     // The shader's stage flag can only appear once in all the ranges, so the
   9155     // implementation can find the one and only range to map it to.
   9156     const uint32_t ranges_per_test = 5;
   9157     struct DuplicateStageFlagsTestCase {
   9158         VkPushConstantRange const ranges[ranges_per_test];
   9159         std::vector<char const *> const msg;
   9160     };
   9161     // Overlapping ranges are OK, but a stage flag can appear only once.
   9162     const std::array<DuplicateStageFlagsTestCase, 3> duplicate_stageFlags_tests = {
   9163         {
   9164             {{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
   9165               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
   9166               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
   9167               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
   9168               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
   9169              {
   9170                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 1.",
   9171                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 2.",
   9172                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 3.",
   9173                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 4.",
   9174                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 2.",
   9175                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 3.",
   9176                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 4.",
   9177                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 2 and 3.",
   9178                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 2 and 4.",
   9179                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 3 and 4.",
   9180              }},
   9181             {{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
   9182               {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 4},
   9183               {VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4},
   9184               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
   9185               {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 4}},
   9186              {
   9187                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 3.",
   9188                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 4.",
   9189              }},
   9190             {{{VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4},
   9191               {VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0, 4},
   9192               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
   9193               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
   9194               {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 4}},
   9195              {
   9196                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 2 and 3.",
   9197              }},
   9198         },
   9199     };
   9200 
   9201     for (const auto &iter : duplicate_stageFlags_tests) {
   9202         pipeline_layout_ci.pPushConstantRanges = iter.ranges;
   9203         pipeline_layout_ci.pushConstantRangeCount = ranges_per_test;
   9204         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg.begin(), iter.msg.end());
   9205         vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
   9206         m_errorMonitor->VerifyFound();
   9207     }
   9208 
   9209     //
   9210     // CmdPushConstants tests
   9211     //
   9212 
   9213     // Setup a pipeline layout with ranges: [0,16) [64,80)
   9214     const std::vector<VkPushConstantRange> pc_range2 = {{VK_SHADER_STAGE_VERTEX_BIT, 64, 16},
   9215                                                         {VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16}};
   9216     const VkPipelineLayoutObj pipeline_layout_obj(m_device, {}, pc_range2);
   9217 
   9218     const uint8_t dummy_values[100] = {};
   9219 
   9220     m_commandBuffer->begin();
   9221     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   9222 
   9223     // Check for invalid stage flag
   9224     // Note that VU 00996 isn't reached due to parameter validation
   9225     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdPushConstants: value of stageFlags must not be 0");
   9226     vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), 0, 0, 16, dummy_values);
   9227     m_errorMonitor->VerifyFound();
   9228 
   9229     m_errorMonitor->ExpectSuccess();
   9230     vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16, dummy_values);
   9231     m_errorMonitor->VerifyNotFound();
   9232     m_errorMonitor->ExpectSuccess();
   9233     vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_VERTEX_BIT, 64, 16, dummy_values);
   9234     m_errorMonitor->VerifyNotFound();
   9235     const std::array<VkPushConstantRange, 6> cmd_range_tests = {{
   9236         {VK_SHADER_STAGE_FRAGMENT_BIT, 64, 16},
   9237         {VK_SHADER_STAGE_VERTEX_BIT, 0, 16},
   9238         {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 16},
   9239         {VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16},
   9240         {VK_SHADER_STAGE_VERTEX_BIT, 24, 16},
   9241         {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
   9242     }};
   9243     for (const auto &iter : cmd_range_tests) {
   9244         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1bc002de);
   9245         vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), iter.stageFlags, iter.offset, iter.size,
   9246                            dummy_values);
   9247         m_errorMonitor->VerifyFound();
   9248     }
   9249 
   9250     m_commandBuffer->EndRenderPass();
   9251     m_commandBuffer->end();
   9252 }
   9253 
   9254 TEST_F(VkLayerTest, DescriptorSetCompatibility) {
   9255     // Test various desriptorSet errors with bad binding combinations
   9256     using std::vector;
   9257     VkResult err;
   9258 
   9259     ASSERT_NO_FATAL_FAILURE(Init());
   9260     ASSERT_NO_FATAL_FAILURE(InitViewport());
   9261     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   9262 
   9263     static const uint32_t NUM_DESCRIPTOR_TYPES = 5;
   9264     VkDescriptorPoolSize ds_type_count[NUM_DESCRIPTOR_TYPES] = {};
   9265     ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   9266     ds_type_count[0].descriptorCount = 10;
   9267     ds_type_count[1].type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
   9268     ds_type_count[1].descriptorCount = 2;
   9269     ds_type_count[2].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
   9270     ds_type_count[2].descriptorCount = 2;
   9271     ds_type_count[3].type = VK_DESCRIPTOR_TYPE_SAMPLER;
   9272     ds_type_count[3].descriptorCount = 5;
   9273     // TODO : LunarG ILO driver currently asserts in desc.c w/ INPUT_ATTACHMENT
   9274     // type
   9275     // ds_type_count[4].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
   9276     ds_type_count[4].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
   9277     ds_type_count[4].descriptorCount = 2;
   9278 
   9279     VkDescriptorPoolCreateInfo ds_pool_ci = {};
   9280     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
   9281     ds_pool_ci.pNext = NULL;
   9282     ds_pool_ci.maxSets = 5;
   9283     ds_pool_ci.poolSizeCount = NUM_DESCRIPTOR_TYPES;
   9284     ds_pool_ci.pPoolSizes = ds_type_count;
   9285 
   9286     VkDescriptorPool ds_pool;
   9287     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
   9288     ASSERT_VK_SUCCESS(err);
   9289 
   9290     static const uint32_t MAX_DS_TYPES_IN_LAYOUT = 2;
   9291     VkDescriptorSetLayoutBinding dsl_binding[MAX_DS_TYPES_IN_LAYOUT] = {};
   9292     dsl_binding[0].binding = 0;
   9293     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   9294     dsl_binding[0].descriptorCount = 5;
   9295     dsl_binding[0].stageFlags = VK_SHADER_STAGE_ALL;
   9296     dsl_binding[0].pImmutableSamplers = NULL;
   9297 
   9298     // Create layout identical to set0 layout but w/ different stageFlags
   9299     VkDescriptorSetLayoutBinding dsl_fs_stage_only = {};
   9300     dsl_fs_stage_only.binding = 0;
   9301     dsl_fs_stage_only.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   9302     dsl_fs_stage_only.descriptorCount = 5;
   9303     dsl_fs_stage_only.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;  // Different stageFlags to cause error at
   9304                                                                   // bind time
   9305     dsl_fs_stage_only.pImmutableSamplers = NULL;
   9306 
   9307     vector<VkDescriptorSetLayoutObj> ds_layouts;
   9308     // Create 4 unique layouts for full pipelineLayout, and 1 special fs-only
   9309     // layout for error case
   9310     ds_layouts.emplace_back(m_device, std::vector<VkDescriptorSetLayoutBinding>(1, dsl_binding[0]));
   9311 
   9312     const VkDescriptorSetLayoutObj ds_layout_fs_only(m_device, {dsl_fs_stage_only});
   9313 
   9314     dsl_binding[0].binding = 0;
   9315     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
   9316     dsl_binding[0].descriptorCount = 2;
   9317     dsl_binding[1].binding = 1;
   9318     dsl_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
   9319     dsl_binding[1].descriptorCount = 2;
   9320     dsl_binding[1].stageFlags = VK_SHADER_STAGE_ALL;
   9321     dsl_binding[1].pImmutableSamplers = NULL;
   9322     ds_layouts.emplace_back(m_device, std::vector<VkDescriptorSetLayoutBinding>({dsl_binding[0], dsl_binding[1]}));
   9323 
   9324     dsl_binding[0].binding = 0;
   9325     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
   9326     dsl_binding[0].descriptorCount = 5;
   9327     ds_layouts.emplace_back(m_device, std::vector<VkDescriptorSetLayoutBinding>(1, dsl_binding[0]));
   9328 
   9329     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
   9330     dsl_binding[0].descriptorCount = 2;
   9331     ds_layouts.emplace_back(m_device, std::vector<VkDescriptorSetLayoutBinding>(1, dsl_binding[0]));
   9332 
   9333     const auto &ds_vk_layouts = MakeVkHandles<VkDescriptorSetLayout>(ds_layouts);
   9334 
   9335     static const uint32_t NUM_SETS = 4;
   9336     VkDescriptorSet descriptorSet[NUM_SETS] = {};
   9337     VkDescriptorSetAllocateInfo alloc_info = {};
   9338     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
   9339     alloc_info.descriptorPool = ds_pool;
   9340     alloc_info.descriptorSetCount = ds_vk_layouts.size();
   9341     alloc_info.pSetLayouts = ds_vk_layouts.data();
   9342     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, descriptorSet);
   9343     ASSERT_VK_SUCCESS(err);
   9344     VkDescriptorSet ds0_fs_only = {};
   9345     alloc_info.descriptorSetCount = 1;
   9346     alloc_info.pSetLayouts = &ds_layout_fs_only.handle();
   9347     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &ds0_fs_only);
   9348     ASSERT_VK_SUCCESS(err);
   9349 
   9350     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layouts[0], &ds_layouts[1]});
   9351     // Create pipelineLayout with only one setLayout
   9352     const VkPipelineLayoutObj single_pipe_layout(m_device, {&ds_layouts[0]});
   9353     // Create pipelineLayout with 2 descriptor setLayout at index 0
   9354     const VkPipelineLayoutObj pipe_layout_one_desc(m_device, {&ds_layouts[3]});
   9355     // Create pipelineLayout with 5 SAMPLER descriptor setLayout at index 0
   9356     const VkPipelineLayoutObj pipe_layout_five_samp(m_device, {&ds_layouts[2]});
   9357     // Create pipelineLayout with UB type, but stageFlags for FS only
   9358     VkPipelineLayoutObj pipe_layout_fs_only(m_device, {&ds_layout_fs_only});
   9359     // Create pipelineLayout w/ incompatible set0 layout, but set1 is fine
   9360     const VkPipelineLayoutObj pipe_layout_bad_set0(m_device, {&ds_layout_fs_only, &ds_layouts[1]});
   9361 
   9362     // Create PSO to be used for draw-time errors below
   9363     char const *vsSource =
   9364         "#version 450\n"
   9365         "\n"
   9366         "void main(){\n"
   9367         "   gl_Position = vec4(1);\n"
   9368         "}\n";
   9369     char const *fsSource =
   9370         "#version 450\n"
   9371         "\n"
   9372         "layout(location=0) out vec4 x;\n"
   9373         "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
   9374         "void main(){\n"
   9375         "   x = vec4(bar.y);\n"
   9376         "}\n";
   9377     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   9378     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   9379     VkPipelineObj pipe(m_device);
   9380     pipe.AddShader(&vs);
   9381     pipe.AddShader(&fs);
   9382     pipe.AddDefaultColorAttachment();
   9383     pipe.CreateVKPipeline(pipe_layout_fs_only.handle(), renderPass());
   9384 
   9385     m_commandBuffer->begin();
   9386     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   9387 
   9388     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   9389     // NOTE : I believe LunarG ilo driver has bug (LX#189) that requires binding
   9390     // of PSO
   9391     //  here before binding DSs. Otherwise we assert in cmd_copy_dset_data() of
   9392     //  cmd_pipeline.c
   9393     //  due to the fact that cmd_alloc_dset_data() has not been called in
   9394     //  cmd_bind_graphics_pipeline()
   9395     // TODO : Want to cause various binding incompatibility issues here to test
   9396     // DrawState
   9397     //  First cause various verify_layout_compatibility() fails
   9398     //  Second disturb early and late sets and verify INFO msgs
   9399     // verify_set_layout_compatibility fail cases:
   9400     // 1. invalid VkPipelineLayout (layout) passed into vkCmdBindDescriptorSets
   9401     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_17c0be01);
   9402     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, (VkPipelineLayout)((size_t)0xbaadb1be), 0,
   9403                             1, &descriptorSet[0], 0, NULL);
   9404     m_errorMonitor->VerifyFound();
   9405 
   9406     // 2. layoutIndex exceeds # of layouts in layout
   9407     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " attempting to bind set to index 1");
   9408     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, single_pipe_layout.handle(), 0, 2,
   9409                             &descriptorSet[0], 0, NULL);
   9410     m_errorMonitor->VerifyFound();
   9411 
   9412     // 3. Pipeline setLayout[0] has 2 descriptors, but set being bound has 5
   9413     // descriptors
   9414     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has 2 descriptors, but DescriptorSetLayout ");
   9415     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_one_desc.handle(), 0, 1,
   9416                             &descriptorSet[0], 0, NULL);
   9417     m_errorMonitor->VerifyFound();
   9418 
   9419     // 4. same # of descriptors but mismatch in type
   9420     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is type 'VK_DESCRIPTOR_TYPE_SAMPLER' but binding ");
   9421     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_five_samp.handle(), 0, 1,
   9422                             &descriptorSet[0], 0, NULL);
   9423     m_errorMonitor->VerifyFound();
   9424 
   9425     // 5. same # of descriptors but mismatch in stageFlags
   9426     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   9427                                          " has stageFlags 16 but binding 0 for DescriptorSetLayout ");
   9428     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_fs_only.handle(), 0, 1,
   9429                             &descriptorSet[0], 0, NULL);
   9430     m_errorMonitor->VerifyFound();
   9431 
   9432     // Now that we're done actively using the pipelineLayout that gfx pipeline
   9433     //  was created with, we should be able to delete it. Do that now to verify
   9434     //  that validation obeys pipelineLayout lifetime
   9435     pipe_layout_fs_only.Reset();
   9436 
   9437     // Cause draw-time errors due to PSO incompatibilities
   9438     // 1. Error due to not binding required set (we actually use same code as
   9439     // above to disturb set0)
   9440     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 2,
   9441                             &descriptorSet[0], 0, NULL);
   9442     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_bad_set0.handle(), 1, 1,
   9443                             &descriptorSet[1], 0, NULL);
   9444     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " uses set #0 but that set is not bound.");
   9445 
   9446     VkViewport viewport = {0, 0, 16, 16, 0, 1};
   9447     VkRect2D scissor = {{0, 0}, {16, 16}};
   9448     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   9449     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
   9450 
   9451     m_commandBuffer->Draw(1, 0, 0, 0);
   9452     m_errorMonitor->VerifyFound();
   9453 
   9454     // 2. Error due to bound set not being compatible with PSO's
   9455     // VkPipelineLayout (diff stageFlags in this case)
   9456     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 2,
   9457                             &descriptorSet[0], 0, NULL);
   9458     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " bound as set #0 is not compatible with ");
   9459     m_commandBuffer->Draw(1, 0, 0, 0);
   9460     m_errorMonitor->VerifyFound();
   9461 
   9462     // Remaining clean-up
   9463     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
   9464 }
   9465 
   9466 TEST_F(VkLayerTest, NoBeginCommandBuffer) {
   9467     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   9468                                          "You must call vkBeginCommandBuffer() before this call to ");
   9469 
   9470     ASSERT_NO_FATAL_FAILURE(Init());
   9471     VkCommandBufferObj commandBuffer(m_device, m_commandPool);
   9472     // Call EndCommandBuffer() w/o calling BeginCommandBuffer()
   9473     vkEndCommandBuffer(commandBuffer.handle());
   9474 
   9475     m_errorMonitor->VerifyFound();
   9476 }
   9477 
   9478 TEST_F(VkLayerTest, SecondaryCommandBufferNullRenderpass) {
   9479     ASSERT_NO_FATAL_FAILURE(Init());
   9480 
   9481     VkCommandBufferObj cb(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
   9482 
   9483     // Force the failure by not setting the Renderpass and Framebuffer fields
   9484     VkCommandBufferInheritanceInfo cmd_buf_hinfo = {};
   9485     cmd_buf_hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
   9486 
   9487     VkCommandBufferBeginInfo cmd_buf_info = {};
   9488     cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   9489     cmd_buf_info.pNext = NULL;
   9490     cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
   9491     cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
   9492 
   9493     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0280006a);
   9494     vkBeginCommandBuffer(cb.handle(), &cmd_buf_info);
   9495     m_errorMonitor->VerifyFound();
   9496 }
   9497 
   9498 TEST_F(VkLayerTest, SecondaryCommandBufferRerecordedExplicitReset) {
   9499     ASSERT_NO_FATAL_FAILURE(Init());
   9500 
   9501     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was destroyed or rerecorded");
   9502 
   9503     // A pool we can reset in.
   9504     VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
   9505     VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
   9506 
   9507     secondary.begin();
   9508     secondary.end();
   9509 
   9510     m_commandBuffer->begin();
   9511     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
   9512 
   9513     // rerecording of secondary
   9514     secondary.reset();  // explicit reset here.
   9515     secondary.begin();
   9516     secondary.end();
   9517 
   9518     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
   9519     m_errorMonitor->VerifyFound();
   9520 }
   9521 
   9522 TEST_F(VkLayerTest, SecondaryCommandBufferRerecordedNoReset) {
   9523     ASSERT_NO_FATAL_FAILURE(Init());
   9524 
   9525     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was destroyed or rerecorded");
   9526 
   9527     // A pool we can reset in.
   9528     VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
   9529     VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
   9530 
   9531     secondary.begin();
   9532     secondary.end();
   9533 
   9534     m_commandBuffer->begin();
   9535     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
   9536 
   9537     // rerecording of secondary
   9538     secondary.begin();  // implicit reset in begin
   9539     secondary.end();
   9540 
   9541     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
   9542     m_errorMonitor->VerifyFound();
   9543 }
   9544 
   9545 TEST_F(VkLayerTest, CascadedInvalidation) {
   9546     ASSERT_NO_FATAL_FAILURE(Init());
   9547 
   9548     VkEventCreateInfo eci = {VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, nullptr, 0};
   9549     VkEvent event;
   9550     vkCreateEvent(m_device->device(), &eci, nullptr, &event);
   9551 
   9552     VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
   9553     secondary.begin();
   9554     vkCmdSetEvent(secondary.handle(), event, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
   9555     secondary.end();
   9556 
   9557     m_commandBuffer->begin();
   9558     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
   9559     m_commandBuffer->end();
   9560 
   9561     // destroying the event should invalidate both primary and secondary CB
   9562     vkDestroyEvent(m_device->device(), event, nullptr);
   9563 
   9564     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "invalid because bound Event");
   9565     m_commandBuffer->QueueCommandBuffer(false);
   9566     m_errorMonitor->VerifyFound();
   9567 }
   9568 
   9569 TEST_F(VkLayerTest, CommandBufferResetErrors) {
   9570     // Cause error due to Begin while recording CB
   9571     // Then cause 2 errors for attempting to reset CB w/o having
   9572     // VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT set for the pool from
   9573     // which CBs were allocated. Note that this bit is off by default.
   9574     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot call Begin on command buffer");
   9575 
   9576     ASSERT_NO_FATAL_FAILURE(Init());
   9577 
   9578     // Calls AllocateCommandBuffers
   9579     VkCommandBufferObj commandBuffer(m_device, m_commandPool);
   9580 
   9581     // Force the failure by setting the Renderpass and Framebuffer fields with (fake) data
   9582     VkCommandBufferInheritanceInfo cmd_buf_hinfo = {};
   9583     cmd_buf_hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
   9584     VkCommandBufferBeginInfo cmd_buf_info = {};
   9585     cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   9586     cmd_buf_info.pNext = NULL;
   9587     cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
   9588     cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
   9589 
   9590     // Begin CB to transition to recording state
   9591     vkBeginCommandBuffer(commandBuffer.handle(), &cmd_buf_info);
   9592     // Can't re-begin. This should trigger error
   9593     vkBeginCommandBuffer(commandBuffer.handle(), &cmd_buf_info);
   9594     m_errorMonitor->VerifyFound();
   9595 
   9596     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_3260005c);
   9597     VkCommandBufferResetFlags flags = 0;  // Don't care about flags for this test
   9598     // Reset attempt will trigger error due to incorrect CommandPool state
   9599     vkResetCommandBuffer(commandBuffer.handle(), flags);
   9600     m_errorMonitor->VerifyFound();
   9601 
   9602     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_16e00064);
   9603     // Transition CB to RECORDED state
   9604     vkEndCommandBuffer(commandBuffer.handle());
   9605     // Now attempting to Begin will implicitly reset, which triggers error
   9606     vkBeginCommandBuffer(commandBuffer.handle(), &cmd_buf_info);
   9607     m_errorMonitor->VerifyFound();
   9608 }
   9609 
   9610 TEST_F(VkLayerTest, InvalidPipelineCreateState) {
   9611     // Attempt to Create Gfx Pipeline w/o a VS
   9612     VkResult err;
   9613 
   9614     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   9615                                          "Invalid Pipeline CreateInfo State: Vertex Shader required");
   9616 
   9617     ASSERT_NO_FATAL_FAILURE(Init());
   9618     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   9619 
   9620     VkDescriptorPoolSize ds_type_count = {};
   9621     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   9622     ds_type_count.descriptorCount = 1;
   9623 
   9624     VkDescriptorPoolCreateInfo ds_pool_ci = {};
   9625     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
   9626     ds_pool_ci.pNext = NULL;
   9627     ds_pool_ci.maxSets = 1;
   9628     ds_pool_ci.poolSizeCount = 1;
   9629     ds_pool_ci.pPoolSizes = &ds_type_count;
   9630 
   9631     VkDescriptorPool ds_pool;
   9632     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
   9633     ASSERT_VK_SUCCESS(err);
   9634 
   9635     VkDescriptorSetLayoutBinding dsl_binding = {};
   9636     dsl_binding.binding = 0;
   9637     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   9638     dsl_binding.descriptorCount = 1;
   9639     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
   9640     dsl_binding.pImmutableSamplers = NULL;
   9641 
   9642     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
   9643 
   9644     VkDescriptorSet descriptorSet;
   9645     VkDescriptorSetAllocateInfo alloc_info = {};
   9646     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
   9647     alloc_info.descriptorSetCount = 1;
   9648     alloc_info.descriptorPool = ds_pool;
   9649     alloc_info.pSetLayouts = &ds_layout.handle();
   9650     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
   9651     ASSERT_VK_SUCCESS(err);
   9652 
   9653     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout});
   9654 
   9655     VkPipelineRasterizationStateCreateInfo rs_state_ci = {};
   9656     rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
   9657     rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL;
   9658     rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT;
   9659     rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
   9660     rs_state_ci.depthClampEnable = VK_FALSE;
   9661     rs_state_ci.rasterizerDiscardEnable = VK_TRUE;
   9662     rs_state_ci.depthBiasEnable = VK_FALSE;
   9663     rs_state_ci.lineWidth = 1.0f;
   9664 
   9665     VkPipelineVertexInputStateCreateInfo vi_ci = {};
   9666     vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
   9667     vi_ci.pNext = nullptr;
   9668     vi_ci.vertexBindingDescriptionCount = 0;
   9669     vi_ci.pVertexBindingDescriptions = nullptr;
   9670     vi_ci.vertexAttributeDescriptionCount = 0;
   9671     vi_ci.pVertexAttributeDescriptions = nullptr;
   9672 
   9673     VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
   9674     ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
   9675     ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
   9676 
   9677     VkPipelineShaderStageCreateInfo shaderStages[2];
   9678     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
   9679 
   9680     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   9681     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   9682     shaderStages[0] = fs.GetStageCreateInfo();  // should be: vs.GetStageCreateInfo();
   9683     shaderStages[1] = fs.GetStageCreateInfo();
   9684 
   9685     VkGraphicsPipelineCreateInfo gp_ci = {};
   9686     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
   9687     gp_ci.pViewportState = nullptr;  // no viewport b/c rasterizer is disabled
   9688     gp_ci.pRasterizationState = &rs_state_ci;
   9689     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
   9690     gp_ci.layout = pipeline_layout.handle();
   9691     gp_ci.renderPass = renderPass();
   9692     gp_ci.pVertexInputState = &vi_ci;
   9693     gp_ci.pInputAssemblyState = &ia_ci;
   9694 
   9695     gp_ci.stageCount = 1;
   9696     gp_ci.pStages = shaderStages;
   9697 
   9698     VkPipelineCacheCreateInfo pc_ci = {};
   9699     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
   9700     pc_ci.initialDataSize = 0;
   9701     pc_ci.pInitialData = 0;
   9702 
   9703     VkPipeline pipeline;
   9704     VkPipelineCache pipelineCache;
   9705 
   9706     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
   9707     ASSERT_VK_SUCCESS(err);
   9708     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
   9709     m_errorMonitor->VerifyFound();
   9710 
   9711     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
   9712     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
   9713 }
   9714 
   9715 TEST_F(VkLayerTest, InvalidPipelineSampleRateFeatureDisable) {
   9716     // Enable sample shading in pipeline when the feature is disabled.
   9717     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   9718 
   9719     // Disable sampleRateShading here
   9720     VkPhysicalDeviceFeatures device_features = {};
   9721     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
   9722     device_features.sampleRateShading = VK_FALSE;
   9723 
   9724     ASSERT_NO_FATAL_FAILURE(InitState(&device_features));
   9725     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   9726 
   9727     // Cause the error by enabling sample shading...
   9728     auto set_shading_enable = [](CreatePipelineHelper &helper) { helper.pipe_ms_state_ci_.sampleShadingEnable = VK_TRUE; };
   9729     CreatePipelineHelper::OneshotTest(*this, set_shading_enable, VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_10000620);
   9730 }
   9731 
   9732 TEST_F(VkLayerTest, InvalidPipelineSampleRateFeatureEnable) {
   9733     // Enable sample shading in pipeline when the feature is disabled.
   9734     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   9735 
   9736     // Require sampleRateShading here
   9737     VkPhysicalDeviceFeatures device_features = {};
   9738     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
   9739     if (device_features.sampleRateShading == VK_FALSE) {
   9740         printf("             SampleRateShading feature is disabled -- skipping related checks.\n");
   9741         return;
   9742     }
   9743 
   9744     ASSERT_NO_FATAL_FAILURE(InitState(&device_features));
   9745     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   9746 
   9747     auto range_test = [this](float value, bool positive_test) {
   9748         auto info_override = [value](CreatePipelineHelper &helper) {
   9749             helper.pipe_ms_state_ci_.sampleShadingEnable = VK_TRUE;
   9750             helper.pipe_ms_state_ci_.minSampleShading = value;
   9751         };
   9752         CreatePipelineHelper::OneshotTest(*this, info_override, VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_10000624,
   9753                                           positive_test);
   9754     };
   9755 
   9756     range_test(NextAfterLess(0.0F), false);
   9757     range_test(NextAfterGreater(1.0F), false);
   9758     range_test(0.0, /* positive_test= */ true);
   9759     range_test(1.0, /* positive_test= */ true);
   9760 }
   9761 
   9762 TEST_F(VkLayerTest, InvalidPipelineSamplePNext) {
   9763     // Enable sample shading in pipeline when the feature is disabled.
   9764     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   9765 
   9766     // Set up the extension structs
   9767     auto sampleLocations = chain_util::Init<VkPipelineSampleLocationsStateCreateInfoEXT>();
   9768     auto coverageToColor = chain_util::Init<VkPipelineCoverageToColorStateCreateInfoNV>();
   9769     auto coverageModulation = chain_util::Init<VkPipelineCoverageModulationStateCreateInfoNV>();
   9770     auto discriminatrix = [this](const char *name) { return DeviceExtensionSupported(gpu(), nullptr, name); };
   9771     chain_util::ExtensionChain chain(discriminatrix, &m_device_extension_names);
   9772     chain.Add(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME, sampleLocations);
   9773     chain.Add(VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME, coverageToColor);
   9774     chain.Add(VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME, coverageModulation);
   9775     const void *extension_head = chain.Head();
   9776 
   9777     ASSERT_NO_FATAL_FAILURE(InitState());
   9778     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   9779 
   9780     if (extension_head) {
   9781         auto good_chain = [extension_head](CreatePipelineHelper &helper) { helper.pipe_ms_state_ci_.pNext = extension_head; };
   9782         CreatePipelineHelper::OneshotTest(*this, good_chain, (VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT),
   9783                                           "No error", true);
   9784     } else {
   9785         printf("             Required extension not present -- skipping positive checks.\n");
   9786     }
   9787 
   9788     auto instance_ci = chain_util::Init<VkInstanceCreateInfo>();
   9789     auto bad_chain = [&instance_ci](CreatePipelineHelper &helper) { helper.pipe_ms_state_ci_.pNext = &instance_ci; };
   9790     CreatePipelineHelper::OneshotTest(*this, bad_chain, VK_DEBUG_REPORT_WARNING_BIT_EXT, VALIDATION_ERROR_1001c40d);
   9791 }
   9792 
   9793 /*// TODO : This test should be good, but needs Tess support in compiler to run
   9794 TEST_F(VkLayerTest, InvalidPatchControlPoints)
   9795 {
   9796     // Attempt to Create Gfx Pipeline w/o a VS
   9797     VkResult        err;
   9798 
   9799     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   9800         "Invalid Pipeline CreateInfo State: VK_PRIMITIVE_TOPOLOGY_PATCH
   9801 primitive ");
   9802 
   9803     ASSERT_NO_FATAL_FAILURE(Init());
   9804     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   9805 
   9806     VkDescriptorPoolSize ds_type_count = {};
   9807         ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   9808         ds_type_count.descriptorCount = 1;
   9809 
   9810     VkDescriptorPoolCreateInfo ds_pool_ci = {};
   9811         ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
   9812         ds_pool_ci.pNext = NULL;
   9813         ds_pool_ci.poolSizeCount = 1;
   9814         ds_pool_ci.pPoolSizes = &ds_type_count;
   9815 
   9816     VkDescriptorPool ds_pool;
   9817     err = vkCreateDescriptorPool(m_device->device(),
   9818 VK_DESCRIPTOR_POOL_USAGE_NON_FREE, 1, &ds_pool_ci, NULL, &ds_pool);
   9819     ASSERT_VK_SUCCESS(err);
   9820 
   9821     VkDescriptorSetLayoutBinding dsl_binding = {};
   9822         dsl_binding.binding = 0;
   9823         dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   9824         dsl_binding.descriptorCount = 1;
   9825         dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
   9826         dsl_binding.pImmutableSamplers = NULL;
   9827 
   9828     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
   9829         ds_layout_ci.sType =
   9830 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
   9831         ds_layout_ci.pNext = NULL;
   9832         ds_layout_ci.bindingCount = 1;
   9833         ds_layout_ci.pBindings = &dsl_binding;
   9834 
   9835     VkDescriptorSetLayout ds_layout;
   9836     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL,
   9837 &ds_layout);
   9838     ASSERT_VK_SUCCESS(err);
   9839 
   9840     VkDescriptorSet descriptorSet;
   9841     err = vkAllocateDescriptorSets(m_device->device(), ds_pool,
   9842 VK_DESCRIPTOR_SET_USAGE_NON_FREE, 1, &ds_layout, &descriptorSet);
   9843     ASSERT_VK_SUCCESS(err);
   9844 
   9845     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
   9846         pipeline_layout_ci.sType =
   9847 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
   9848         pipeline_layout_ci.pNext = NULL;
   9849         pipeline_layout_ci.setLayoutCount = 1;
   9850         pipeline_layout_ci.pSetLayouts = &ds_layout;
   9851 
   9852     VkPipelineLayout pipeline_layout;
   9853     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL,
   9854 &pipeline_layout);
   9855     ASSERT_VK_SUCCESS(err);
   9856 
   9857     VkPipelineShaderStageCreateInfo shaderStages[3];
   9858     memset(&shaderStages, 0, 3 * sizeof(VkPipelineShaderStageCreateInfo));
   9859 
   9860     VkShaderObj vs(m_device,bindStateVertShaderText,VK_SHADER_STAGE_VERTEX_BIT,
   9861 this);
   9862     // Just using VS txt for Tess shaders as we don't care about functionality
   9863     VkShaderObj
   9864 tc(m_device,bindStateVertShaderText,VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
   9865 this);
   9866     VkShaderObj
   9867 te(m_device,bindStateVertShaderText,VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
   9868 this);
   9869 
   9870     shaderStages[0].sType  =
   9871 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
   9872     shaderStages[0].stage  = VK_SHADER_STAGE_VERTEX_BIT;
   9873     shaderStages[0].shader = vs.handle();
   9874     shaderStages[1].sType  =
   9875 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
   9876     shaderStages[1].stage  = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
   9877     shaderStages[1].shader = tc.handle();
   9878     shaderStages[2].sType  =
   9879 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
   9880     shaderStages[2].stage  = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
   9881     shaderStages[2].shader = te.handle();
   9882 
   9883     VkPipelineInputAssemblyStateCreateInfo iaCI = {};
   9884         iaCI.sType =
   9885 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
   9886         iaCI.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
   9887 
   9888     VkPipelineTessellationStateCreateInfo tsCI = {};
   9889         tsCI.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
   9890         tsCI.patchControlPoints = 0; // This will cause an error
   9891 
   9892     VkGraphicsPipelineCreateInfo gp_ci = {};
   9893         gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
   9894         gp_ci.pNext = NULL;
   9895         gp_ci.stageCount = 3;
   9896         gp_ci.pStages = shaderStages;
   9897         gp_ci.pVertexInputState = NULL;
   9898         gp_ci.pInputAssemblyState = &iaCI;
   9899         gp_ci.pTessellationState = &tsCI;
   9900         gp_ci.pViewportState = NULL;
   9901         gp_ci.pRasterizationState = NULL;
   9902         gp_ci.pMultisampleState = NULL;
   9903         gp_ci.pDepthStencilState = NULL;
   9904         gp_ci.pColorBlendState = NULL;
   9905         gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
   9906         gp_ci.layout = pipeline_layout;
   9907         gp_ci.renderPass = renderPass();
   9908 
   9909     VkPipelineCacheCreateInfo pc_ci = {};
   9910         pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
   9911         pc_ci.pNext = NULL;
   9912         pc_ci.initialSize = 0;
   9913         pc_ci.initialData = 0;
   9914         pc_ci.maxSize = 0;
   9915 
   9916     VkPipeline pipeline;
   9917     VkPipelineCache pipelineCache;
   9918 
   9919     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL,
   9920 &pipelineCache);
   9921     ASSERT_VK_SUCCESS(err);
   9922     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1,
   9923 &gp_ci, NULL, &pipeline);
   9924 
   9925     m_errorMonitor->VerifyFound();
   9926 
   9927     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
   9928     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
   9929     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
   9930     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
   9931 }
   9932 */
   9933 
   9934 TEST_F(VkLayerTest, PSOViewportStateTests) {
   9935     TEST_DESCRIPTION("Test VkPipelineViewportStateCreateInfo viewport and scissor count validation for non-multiViewport");
   9936 
   9937     VkPhysicalDeviceFeatures features{};
   9938     ASSERT_NO_FATAL_FAILURE(Init(&features));
   9939     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   9940 
   9941     const auto break_vp_state = [](CreatePipelineHelper &helper) {
   9942         helper.rs_state_ci_.rasterizerDiscardEnable = VK_FALSE;
   9943         helper.gp_ci_.pViewportState = nullptr;
   9944     };
   9945     CreatePipelineHelper::OneshotTest(*this, break_vp_state, VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_096005dc);
   9946 
   9947     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
   9948     VkViewport viewports[] = {viewport, viewport};
   9949     VkRect2D scissor = {{0, 0}, {64, 64}};
   9950     VkRect2D scissors[] = {scissor, scissor};
   9951 
   9952     // test viewport and scissor arrays
   9953     using std::vector;
   9954     struct TestCase {
   9955         uint32_t viewport_count;
   9956         VkViewport *viewports;
   9957         uint32_t scissor_count;
   9958         VkRect2D *scissors;
   9959 
   9960         vector<UNIQUE_VALIDATION_ERROR_CODE> vuids;
   9961     };
   9962 
   9963     vector<TestCase> test_cases = {
   9964         {0, viewports, 1, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00988}},
   9965         {2, viewports, 1, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00988}},
   9966         {1, viewports, 0, scissors, {VALIDATION_ERROR_10c00982, VALIDATION_ERROR_10c00988}},
   9967         {1, viewports, 2, scissors, {VALIDATION_ERROR_10c00982, VALIDATION_ERROR_10c00988}},
   9968         {0, viewports, 0, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982}},
   9969         {2, viewports, 2, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982}},
   9970         {0, viewports, 2, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982, VALIDATION_ERROR_10c00988}},
   9971         {2, viewports, 0, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982, VALIDATION_ERROR_10c00988}},
   9972         {1, nullptr, 1, scissors, {VALIDATION_ERROR_096005d6}},
   9973         {1, viewports, 1, nullptr, {VALIDATION_ERROR_096005d8}},
   9974         {1, nullptr, 1, nullptr, {VALIDATION_ERROR_096005d6, VALIDATION_ERROR_096005d8}},
   9975         {2,
   9976          nullptr,
   9977          3,
   9978          nullptr,
   9979          {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982, VALIDATION_ERROR_10c00988, VALIDATION_ERROR_096005d6,
   9980           VALIDATION_ERROR_096005d8}},
   9981         {0, nullptr, 0, nullptr, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982}},
   9982     };
   9983 
   9984     for (const auto &test_case : test_cases) {
   9985         const auto break_vp = [&test_case](CreatePipelineHelper &helper) {
   9986             helper.vp_state_ci_.viewportCount = test_case.viewport_count;
   9987             helper.vp_state_ci_.pViewports = test_case.viewports;
   9988             helper.vp_state_ci_.scissorCount = test_case.scissor_count;
   9989             helper.vp_state_ci_.pScissors = test_case.scissors;
   9990         };
   9991         CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids);
   9992     }
   9993 
   9994     vector<TestCase> dyn_test_cases = {
   9995         {0, viewports, 1, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00988}},
   9996         {2, viewports, 1, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00988}},
   9997         {1, viewports, 0, scissors, {VALIDATION_ERROR_10c00982, VALIDATION_ERROR_10c00988}},
   9998         {1, viewports, 2, scissors, {VALIDATION_ERROR_10c00982, VALIDATION_ERROR_10c00988}},
   9999         {0, viewports, 0, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982}},
   10000         {2, viewports, 2, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982}},
   10001         {0, viewports, 2, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982, VALIDATION_ERROR_10c00988}},
   10002         {2, viewports, 0, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982, VALIDATION_ERROR_10c00988}},
   10003         {2, nullptr, 3, nullptr, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982, VALIDATION_ERROR_10c00988}},
   10004         {0, nullptr, 0, nullptr, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982}},
   10005     };
   10006 
   10007     const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
   10008 
   10009     for (const auto &test_case : dyn_test_cases) {
   10010         const auto break_vp = [&](CreatePipelineHelper &helper) {
   10011             VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
   10012             dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
   10013             dyn_state_ci.dynamicStateCount = size(dyn_states);
   10014             dyn_state_ci.pDynamicStates = dyn_states;
   10015             helper.dyn_state_ci_ = dyn_state_ci;
   10016 
   10017             helper.vp_state_ci_.viewportCount = test_case.viewport_count;
   10018             helper.vp_state_ci_.pViewports = test_case.viewports;
   10019             helper.vp_state_ci_.scissorCount = test_case.scissor_count;
   10020             helper.vp_state_ci_.pScissors = test_case.scissors;
   10021         };
   10022         CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids);
   10023     }
   10024 }
   10025 
   10026 // Set Extension dynamic states without enabling the required Extensions.
   10027 TEST_F(VkLayerTest, ExtensionDynamicStatesSetWOExtensionEnabled) {
   10028     TEST_DESCRIPTION("Create a graphics pipeline with Extension dynamic states without enabling the required Extensions.");
   10029 
   10030     ASSERT_NO_FATAL_FAILURE(Init());
   10031     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   10032 
   10033     using std::vector;
   10034     struct TestCase {
   10035         uint32_t dynamic_state_count;
   10036         VkDynamicState dynamic_state;
   10037 
   10038         char const *errmsg;
   10039     };
   10040 
   10041     vector<TestCase> dyn_test_cases = {
   10042         {1, VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV,
   10043          "contains VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV, but VK_NV_clip_space_w_scaling"},
   10044         {1, VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT,
   10045          "contains VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT, but VK_EXT_discard_rectangles"},
   10046         {1, VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT, "contains VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT, but VK_EXT_sample_locations"},
   10047     };
   10048 
   10049     for (const auto &test_case : dyn_test_cases) {
   10050         VkDynamicState state[1];
   10051         state[0] = test_case.dynamic_state;
   10052         const auto break_vp = [&](CreatePipelineHelper &helper) {
   10053             VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
   10054             dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
   10055             dyn_state_ci.dynamicStateCount = test_case.dynamic_state_count;
   10056             dyn_state_ci.pDynamicStates = state;
   10057             helper.dyn_state_ci_ = dyn_state_ci;
   10058         };
   10059         CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.errmsg);
   10060     }
   10061 }
   10062 
   10063 TEST_F(VkLayerTest, PSOViewportStateMultiViewportTests) {
   10064     TEST_DESCRIPTION("Test VkPipelineViewportStateCreateInfo viewport and scissor count validation for multiViewport feature");
   10065 
   10066     ASSERT_NO_FATAL_FAILURE(Init());  // enables all supported features
   10067 
   10068     if (!m_device->phy().features().multiViewport) {
   10069         printf("             VkPhysicalDeviceFeatures::multiViewport is not supported -- skipping test.\n");
   10070         return;
   10071     }
   10072     // at least 16 viewports supported from here on
   10073 
   10074     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   10075 
   10076     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
   10077     VkViewport viewports[] = {viewport, viewport};
   10078     VkRect2D scissor = {{0, 0}, {64, 64}};
   10079     VkRect2D scissors[] = {scissor, scissor};
   10080 
   10081     using std::vector;
   10082     struct TestCase {
   10083         uint32_t viewport_count;
   10084         VkViewport *viewports;
   10085         uint32_t scissor_count;
   10086         VkRect2D *scissors;
   10087 
   10088         vector<UNIQUE_VALIDATION_ERROR_CODE> vuids;
   10089     };
   10090 
   10091     vector<TestCase> test_cases = {
   10092         {0, viewports, 2, scissors, {VALIDATION_ERROR_10c30a1b, VALIDATION_ERROR_10c00988}},
   10093         {2, viewports, 0, scissors, {VALIDATION_ERROR_10c2b61b, VALIDATION_ERROR_10c00988}},
   10094         {0, viewports, 0, scissors, {VALIDATION_ERROR_10c30a1b, VALIDATION_ERROR_10c2b61b}},
   10095         {2, nullptr, 2, scissors, {VALIDATION_ERROR_096005d6}},
   10096         {2, viewports, 2, nullptr, {VALIDATION_ERROR_096005d8}},
   10097         {2, nullptr, 2, nullptr, {VALIDATION_ERROR_096005d6, VALIDATION_ERROR_096005d8}},
   10098         {0, nullptr, 0, nullptr, {VALIDATION_ERROR_10c30a1b, VALIDATION_ERROR_10c2b61b}},
   10099     };
   10100 
   10101     const auto max_viewports = m_device->phy().properties().limits.maxViewports;
   10102     const bool max_viewports_maxxed = max_viewports == std::numeric_limits<decltype(max_viewports)>::max();
   10103     if (max_viewports_maxxed) {
   10104         printf(
   10105             "             VkPhysicalDeviceLimits::maxViewports is UINT32_MAX -- skipping part of test requiring to exceed "
   10106             "maxViewports.\n");
   10107     } else {
   10108         const auto too_much_viewports = max_viewports + 1;
   10109         // avoid potentially big allocations by using only nullptr
   10110         test_cases.push_back({too_much_viewports,
   10111                               nullptr,
   10112                               2,
   10113                               scissors,
   10114                               {VALIDATION_ERROR_10c00984, VALIDATION_ERROR_10c00988, VALIDATION_ERROR_096005d6}});
   10115         test_cases.push_back({2,
   10116                               viewports,
   10117                               too_much_viewports,
   10118                               nullptr,
   10119                               {VALIDATION_ERROR_10c00986, VALIDATION_ERROR_10c00988, VALIDATION_ERROR_096005d8}});
   10120         test_cases.push_back(
   10121             {too_much_viewports,
   10122              nullptr,
   10123              too_much_viewports,
   10124              nullptr,
   10125              {VALIDATION_ERROR_10c00984, VALIDATION_ERROR_10c00986, VALIDATION_ERROR_096005d6, VALIDATION_ERROR_096005d8}});
   10126     }
   10127 
   10128     for (const auto &test_case : test_cases) {
   10129         const auto break_vp = [&test_case](CreatePipelineHelper &helper) {
   10130             helper.vp_state_ci_.viewportCount = test_case.viewport_count;
   10131             helper.vp_state_ci_.pViewports = test_case.viewports;
   10132             helper.vp_state_ci_.scissorCount = test_case.scissor_count;
   10133             helper.vp_state_ci_.pScissors = test_case.scissors;
   10134         };
   10135         CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids);
   10136     }
   10137 
   10138     vector<TestCase> dyn_test_cases = {
   10139         {0, viewports, 2, scissors, {VALIDATION_ERROR_10c30a1b, VALIDATION_ERROR_10c00988}},
   10140         {2, viewports, 0, scissors, {VALIDATION_ERROR_10c2b61b, VALIDATION_ERROR_10c00988}},
   10141         {0, viewports, 0, scissors, {VALIDATION_ERROR_10c30a1b, VALIDATION_ERROR_10c2b61b}},
   10142         {0, nullptr, 0, nullptr, {VALIDATION_ERROR_10c30a1b, VALIDATION_ERROR_10c2b61b}},
   10143     };
   10144 
   10145     if (!max_viewports_maxxed) {
   10146         const auto too_much_viewports = max_viewports + 1;
   10147         // avoid potentially big allocations by using only nullptr
   10148         dyn_test_cases.push_back(
   10149             {too_much_viewports, nullptr, 2, scissors, {VALIDATION_ERROR_10c00984, VALIDATION_ERROR_10c00988}});
   10150         dyn_test_cases.push_back(
   10151             {2, viewports, too_much_viewports, nullptr, {VALIDATION_ERROR_10c00986, VALIDATION_ERROR_10c00988}});
   10152         dyn_test_cases.push_back(
   10153             {too_much_viewports, nullptr, too_much_viewports, nullptr, {VALIDATION_ERROR_10c00984, VALIDATION_ERROR_10c00986}});
   10154     }
   10155 
   10156     const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
   10157 
   10158     for (const auto &test_case : dyn_test_cases) {
   10159         const auto break_vp = [&](CreatePipelineHelper &helper) {
   10160             VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
   10161             dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
   10162             dyn_state_ci.dynamicStateCount = size(dyn_states);
   10163             dyn_state_ci.pDynamicStates = dyn_states;
   10164             helper.dyn_state_ci_ = dyn_state_ci;
   10165 
   10166             helper.vp_state_ci_.viewportCount = test_case.viewport_count;
   10167             helper.vp_state_ci_.pViewports = test_case.viewports;
   10168             helper.vp_state_ci_.scissorCount = test_case.scissor_count;
   10169             helper.vp_state_ci_.pScissors = test_case.scissors;
   10170         };
   10171         CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids);
   10172     }
   10173 }
   10174 
   10175 TEST_F(VkLayerTest, DynViewportAndScissorUndefinedDrawState) {
   10176     TEST_DESCRIPTION("Test viewport and scissor dynamic state that is not set before draw");
   10177 
   10178     ASSERT_NO_FATAL_FAILURE(Init());
   10179 
   10180     // TODO: should also test on !multiViewport
   10181     if (!m_device->phy().features().multiViewport) {
   10182         printf("             Device does not support multiple viewports/scissors; skipped.\n");
   10183         return;
   10184     }
   10185 
   10186     ASSERT_NO_FATAL_FAILURE(InitViewport());
   10187     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   10188 
   10189     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   10190     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   10191 
   10192     const VkPipelineLayoutObj pipeline_layout(m_device);
   10193 
   10194     VkPipelineObj pipeline_dyn_vp(m_device);
   10195     pipeline_dyn_vp.AddShader(&vs);
   10196     pipeline_dyn_vp.AddShader(&fs);
   10197     pipeline_dyn_vp.AddDefaultColorAttachment();
   10198     pipeline_dyn_vp.MakeDynamic(VK_DYNAMIC_STATE_VIEWPORT);
   10199     pipeline_dyn_vp.SetScissor(m_scissors);
   10200     ASSERT_VK_SUCCESS(pipeline_dyn_vp.CreateVKPipeline(pipeline_layout.handle(), m_renderPass));
   10201 
   10202     VkPipelineObj pipeline_dyn_sc(m_device);
   10203     pipeline_dyn_sc.AddShader(&vs);
   10204     pipeline_dyn_sc.AddShader(&fs);
   10205     pipeline_dyn_sc.AddDefaultColorAttachment();
   10206     pipeline_dyn_sc.SetViewport(m_viewports);
   10207     pipeline_dyn_sc.MakeDynamic(VK_DYNAMIC_STATE_SCISSOR);
   10208     ASSERT_VK_SUCCESS(pipeline_dyn_sc.CreateVKPipeline(pipeline_layout.handle(), m_renderPass));
   10209 
   10210     m_commandBuffer->begin();
   10211     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   10212 
   10213     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   10214                                          "Dynamic viewport(s) 0 are used by pipeline state object, ");
   10215     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_dyn_vp.handle());
   10216     vkCmdSetViewport(m_commandBuffer->handle(), 1, 1,
   10217                      &m_viewports[0]);  // Forgetting to set needed 0th viweport (PSO viewportCount == 1)
   10218     m_commandBuffer->Draw(1, 0, 0, 0);
   10219     m_errorMonitor->VerifyFound();
   10220 
   10221     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic scissor(s) 0 are used by pipeline state object, ");
   10222     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_dyn_sc.handle());
   10223     vkCmdSetScissor(m_commandBuffer->handle(), 1, 1,
   10224                     &m_scissors[0]);  // Forgetting to set needed 0th scissor (PSO scissorCount == 1)
   10225     m_commandBuffer->Draw(1, 0, 0, 0);
   10226     m_errorMonitor->VerifyFound();
   10227 }
   10228 
   10229 TEST_F(VkLayerTest, PSOLineWidthInvalid) {
   10230     TEST_DESCRIPTION("Test non-1.0 lineWidth errors when pipeline is created and in vkCmdSetLineWidth");
   10231     VkPhysicalDeviceFeatures features{};
   10232     ASSERT_NO_FATAL_FAILURE(Init(&features));
   10233     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   10234 
   10235     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   10236     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   10237     VkPipelineShaderStageCreateInfo shader_state_cis[] = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
   10238 
   10239     VkPipelineVertexInputStateCreateInfo vi_state_ci = {};
   10240     vi_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
   10241 
   10242     VkPipelineInputAssemblyStateCreateInfo ia_state_ci = {};
   10243     ia_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
   10244     ia_state_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
   10245 
   10246     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
   10247     VkRect2D scissor = {{0, 0}, {64, 64}};
   10248     VkPipelineViewportStateCreateInfo vp_state_ci = {};
   10249     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
   10250     vp_state_ci.viewportCount = 1;
   10251     vp_state_ci.pViewports = &viewport;
   10252     vp_state_ci.scissorCount = 1;
   10253     vp_state_ci.pScissors = &scissor;
   10254 
   10255     VkPipelineRasterizationStateCreateInfo rs_state_ci = {};
   10256     rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
   10257     rs_state_ci.rasterizerDiscardEnable = VK_FALSE;
   10258     // lineWidth to be set by checks
   10259 
   10260     VkPipelineMultisampleStateCreateInfo ms_state_ci = {};
   10261     ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
   10262     ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;  // must match subpass att.
   10263 
   10264     VkPipelineColorBlendAttachmentState cba_state = {};
   10265 
   10266     VkPipelineColorBlendStateCreateInfo cb_state_ci = {};
   10267     cb_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
   10268     cb_state_ci.attachmentCount = 1;  // must match count in subpass
   10269     cb_state_ci.pAttachments = &cba_state;
   10270 
   10271     const VkPipelineLayoutObj pipeline_layout(m_device);
   10272 
   10273     VkGraphicsPipelineCreateInfo gp_ci = {};
   10274     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
   10275     gp_ci.stageCount = sizeof(shader_state_cis) / sizeof(VkPipelineShaderStageCreateInfo);
   10276     gp_ci.pStages = shader_state_cis;
   10277     gp_ci.pVertexInputState = &vi_state_ci;
   10278     gp_ci.pInputAssemblyState = &ia_state_ci;
   10279     gp_ci.pViewportState = &vp_state_ci;
   10280     gp_ci.pRasterizationState = &rs_state_ci;
   10281     gp_ci.pMultisampleState = &ms_state_ci;
   10282     gp_ci.pColorBlendState = &cb_state_ci;
   10283     gp_ci.layout = pipeline_layout.handle();
   10284     gp_ci.renderPass = renderPass();
   10285     gp_ci.subpass = 0;
   10286 
   10287     const std::vector<float> test_cases = {-1.0f, 0.0f, nextafterf(1.0f, 0.0f), nextafterf(1.0f, 2.0f), NAN};
   10288 
   10289     // test VkPipelineRasterizationStateCreateInfo::lineWidth
   10290     for (const auto test_case : test_cases) {
   10291         rs_state_ci.lineWidth = test_case;
   10292 
   10293         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_096005da);
   10294         VkPipeline pipeline;
   10295         vkCreateGraphicsPipelines(m_device->device(), VK_NULL_HANDLE, 1, &gp_ci, nullptr, &pipeline);
   10296         m_errorMonitor->VerifyFound();
   10297     }
   10298 
   10299     // test vkCmdSetLineWidth
   10300     m_commandBuffer->begin();
   10301 
   10302     for (const auto test_case : test_cases) {
   10303         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1d600628);
   10304         vkCmdSetLineWidth(m_commandBuffer->handle(), test_case);
   10305         m_errorMonitor->VerifyFound();
   10306     }
   10307 }
   10308 
   10309 TEST_F(VkLayerTest, VALIDATION_ERROR_14c004d4) {
   10310     TEST_DESCRIPTION("Test VALIDATION_ERROR_14c004d4: binding must be less than VkPhysicalDeviceLimits::maxVertexInputBindings");
   10311 
   10312     ASSERT_NO_FATAL_FAILURE(Init());
   10313     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   10314 
   10315     VkPipelineCache pipeline_cache;
   10316     {
   10317         VkPipelineCacheCreateInfo create_info{};
   10318         create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
   10319 
   10320         VkResult err = vkCreatePipelineCache(m_device->device(), &create_info, nullptr, &pipeline_cache);
   10321         ASSERT_VK_SUCCESS(err);
   10322     }
   10323 
   10324     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   10325     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   10326 
   10327     VkPipelineShaderStageCreateInfo stages[2]{{}};
   10328     stages[0] = vs.GetStageCreateInfo();
   10329     stages[1] = fs.GetStageCreateInfo();
   10330 
   10331     // Test when binding is greater than or equal to VkPhysicalDeviceLimits::maxVertexInputBindings.
   10332     VkVertexInputBindingDescription vertex_input_binding_description{};
   10333     vertex_input_binding_description.binding = m_device->props.limits.maxVertexInputBindings;
   10334 
   10335     VkPipelineVertexInputStateCreateInfo vertex_input_state{};
   10336     vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
   10337     vertex_input_state.pNext = nullptr;
   10338     vertex_input_state.vertexBindingDescriptionCount = 1;
   10339     vertex_input_state.pVertexBindingDescriptions = &vertex_input_binding_description;
   10340     vertex_input_state.vertexAttributeDescriptionCount = 0;
   10341     vertex_input_state.pVertexAttributeDescriptions = nullptr;
   10342 
   10343     VkPipelineInputAssemblyStateCreateInfo input_assembly_state{};
   10344     input_assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
   10345     input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
   10346 
   10347     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
   10348     VkRect2D scissor = {{0, 0}, {64, 64}};
   10349     VkPipelineViewportStateCreateInfo viewport_state{};
   10350     viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
   10351     viewport_state.viewportCount = 1;
   10352     viewport_state.pViewports = &viewport;
   10353     viewport_state.scissorCount = 1;
   10354     viewport_state.pScissors = &scissor;
   10355 
   10356     VkPipelineMultisampleStateCreateInfo multisample_state{};
   10357     multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
   10358     multisample_state.pNext = nullptr;
   10359     multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
   10360     multisample_state.sampleShadingEnable = 0;
   10361     multisample_state.minSampleShading = 1.0;
   10362     multisample_state.pSampleMask = nullptr;
   10363 
   10364     VkPipelineRasterizationStateCreateInfo rasterization_state{};
   10365     rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
   10366     rasterization_state.polygonMode = VK_POLYGON_MODE_FILL;
   10367     rasterization_state.cullMode = VK_CULL_MODE_BACK_BIT;
   10368     rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
   10369     rasterization_state.depthClampEnable = VK_FALSE;
   10370     rasterization_state.rasterizerDiscardEnable = VK_FALSE;
   10371     rasterization_state.depthBiasEnable = VK_FALSE;
   10372     rasterization_state.lineWidth = 1.0f;
   10373 
   10374     const VkPipelineLayoutObj pipeline_layout(m_device);
   10375 
   10376     {
   10377         VkGraphicsPipelineCreateInfo create_info{};
   10378         create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
   10379         create_info.stageCount = 2;
   10380         create_info.pStages = stages;
   10381         create_info.pVertexInputState = &vertex_input_state;
   10382         create_info.pInputAssemblyState = &input_assembly_state;
   10383         create_info.pViewportState = &viewport_state;
   10384         create_info.pMultisampleState = &multisample_state;
   10385         create_info.pRasterizationState = &rasterization_state;
   10386         create_info.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
   10387         create_info.layout = pipeline_layout.handle();
   10388         create_info.renderPass = renderPass();
   10389 
   10390         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_14c004d4);
   10391         VkPipeline pipeline;
   10392         vkCreateGraphicsPipelines(m_device->device(), pipeline_cache, 1, &create_info, nullptr, &pipeline);
   10393         m_errorMonitor->VerifyFound();
   10394     }
   10395 
   10396     vkDestroyPipelineCache(m_device->device(), pipeline_cache, nullptr);
   10397 }
   10398 
   10399 TEST_F(VkLayerTest, VALIDATION_ERROR_14c004d6) {
   10400     TEST_DESCRIPTION(
   10401         "Test VALIDATION_ERROR_14c004d6: stride must be less than or equal to VkPhysicalDeviceLimits::maxVertexInputBindingStride");
   10402 
   10403     ASSERT_NO_FATAL_FAILURE(Init());
   10404     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   10405 
   10406     VkPipelineCache pipeline_cache;
   10407     {
   10408         VkPipelineCacheCreateInfo create_info{};
   10409         create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
   10410 
   10411         VkResult err = vkCreatePipelineCache(m_device->device(), &create_info, nullptr, &pipeline_cache);
   10412         ASSERT_VK_SUCCESS(err);
   10413     }
   10414 
   10415     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   10416     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   10417 
   10418     VkPipelineShaderStageCreateInfo stages[2]{{}};
   10419     stages[0] = vs.GetStageCreateInfo();
   10420     stages[1] = fs.GetStageCreateInfo();
   10421 
   10422     // Test when stride is greater than VkPhysicalDeviceLimits::maxVertexInputBindingStride.
   10423     VkVertexInputBindingDescription vertex_input_binding_description{};
   10424     vertex_input_binding_description.stride = m_device->props.limits.maxVertexInputBindingStride + 1;
   10425 
   10426     VkPipelineVertexInputStateCreateInfo vertex_input_state{};
   10427     vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
   10428     vertex_input_state.pNext = nullptr;
   10429     vertex_input_state.vertexBindingDescriptionCount = 1;
   10430     vertex_input_state.pVertexBindingDescriptions = &vertex_input_binding_description;
   10431     vertex_input_state.vertexAttributeDescriptionCount = 0;
   10432     vertex_input_state.pVertexAttributeDescriptions = nullptr;
   10433 
   10434     VkPipelineInputAssemblyStateCreateInfo input_assembly_state{};
   10435     input_assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
   10436     input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
   10437 
   10438     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
   10439     VkRect2D scissor = {{0, 0}, {64, 64}};
   10440     VkPipelineViewportStateCreateInfo viewport_state{};
   10441     viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
   10442     viewport_state.viewportCount = 1;
   10443     viewport_state.pViewports = &viewport;
   10444     viewport_state.scissorCount = 1;
   10445     viewport_state.pScissors = &scissor;
   10446 
   10447     VkPipelineMultisampleStateCreateInfo multisample_state{};
   10448     multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
   10449     multisample_state.pNext = nullptr;
   10450     multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
   10451     multisample_state.sampleShadingEnable = 0;
   10452     multisample_state.minSampleShading = 1.0;
   10453     multisample_state.pSampleMask = nullptr;
   10454 
   10455     VkPipelineRasterizationStateCreateInfo rasterization_state{};
   10456     rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
   10457     rasterization_state.polygonMode = VK_POLYGON_MODE_FILL;
   10458     rasterization_state.cullMode = VK_CULL_MODE_BACK_BIT;
   10459     rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
   10460     rasterization_state.depthClampEnable = VK_FALSE;
   10461     rasterization_state.rasterizerDiscardEnable = VK_FALSE;
   10462     rasterization_state.depthBiasEnable = VK_FALSE;
   10463     rasterization_state.lineWidth = 1.0f;
   10464 
   10465     const VkPipelineLayoutObj pipeline_layout(m_device);
   10466 
   10467     {
   10468         VkGraphicsPipelineCreateInfo create_info{};
   10469         create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
   10470         create_info.stageCount = 2;
   10471         create_info.pStages = stages;
   10472         create_info.pVertexInputState = &vertex_input_state;
   10473         create_info.pInputAssemblyState = &input_assembly_state;
   10474         create_info.pViewportState = &viewport_state;
   10475         create_info.pMultisampleState = &multisample_state;
   10476         create_info.pRasterizationState = &rasterization_state;
   10477         create_info.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
   10478         create_info.layout = pipeline_layout.handle();
   10479         create_info.renderPass = renderPass();
   10480 
   10481         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_14c004d6);
   10482         VkPipeline pipeline;
   10483         vkCreateGraphicsPipelines(m_device->device(), pipeline_cache, 1, &create_info, nullptr, &pipeline);
   10484         m_errorMonitor->VerifyFound();
   10485     }
   10486 
   10487     vkDestroyPipelineCache(m_device->device(), pipeline_cache, nullptr);
   10488 }
   10489 
   10490 TEST_F(VkLayerTest, VALIDATION_ERROR_14a004d8) {
   10491     TEST_DESCRIPTION("Test VALIDATION_ERROR_14a004d8: location must be less than VkPhysicalDeviceLimits::maxVertexInputAttributes");
   10492 
   10493     ASSERT_NO_FATAL_FAILURE(Init());
   10494     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   10495 
   10496     VkPipelineCache pipeline_cache;
   10497     {
   10498         VkPipelineCacheCreateInfo create_info{};
   10499         create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
   10500 
   10501         VkResult err = vkCreatePipelineCache(m_device->device(), &create_info, nullptr, &pipeline_cache);
   10502         ASSERT_VK_SUCCESS(err);
   10503     }
   10504 
   10505     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   10506     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   10507 
   10508     VkPipelineShaderStageCreateInfo stages[2]{{}};
   10509     stages[0] = vs.GetStageCreateInfo();
   10510     stages[1] = fs.GetStageCreateInfo();
   10511 
   10512     // Test when location is greater than or equal to VkPhysicalDeviceLimits::maxVertexInputAttributes.
   10513     VkVertexInputAttributeDescription vertex_input_attribute_description{};
   10514     vertex_input_attribute_description.location = m_device->props.limits.maxVertexInputAttributes;
   10515 
   10516     VkPipelineVertexInputStateCreateInfo vertex_input_state{};
   10517     vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
   10518     vertex_input_state.pNext = nullptr;
   10519     vertex_input_state.vertexBindingDescriptionCount = 0;
   10520     vertex_input_state.pVertexBindingDescriptions = nullptr;
   10521     vertex_input_state.vertexAttributeDescriptionCount = 1;
   10522     vertex_input_state.pVertexAttributeDescriptions = &vertex_input_attribute_description;
   10523 
   10524     VkPipelineInputAssemblyStateCreateInfo input_assembly_state{};
   10525     input_assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
   10526     input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
   10527 
   10528     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
   10529     VkRect2D scissor = {{0, 0}, {64, 64}};
   10530     VkPipelineViewportStateCreateInfo viewport_state{};
   10531     viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
   10532     viewport_state.viewportCount = 1;
   10533     viewport_state.pViewports = &viewport;
   10534     viewport_state.scissorCount = 1;
   10535     viewport_state.pScissors = &scissor;
   10536 
   10537     VkPipelineMultisampleStateCreateInfo multisample_state{};
   10538     multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
   10539     multisample_state.pNext = nullptr;
   10540     multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
   10541     multisample_state.sampleShadingEnable = 0;
   10542     multisample_state.minSampleShading = 1.0;
   10543     multisample_state.pSampleMask = nullptr;
   10544 
   10545     VkPipelineRasterizationStateCreateInfo rasterization_state{};
   10546     rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
   10547     rasterization_state.polygonMode = VK_POLYGON_MODE_FILL;
   10548     rasterization_state.cullMode = VK_CULL_MODE_BACK_BIT;
   10549     rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
   10550     rasterization_state.depthClampEnable = VK_FALSE;
   10551     rasterization_state.rasterizerDiscardEnable = VK_FALSE;
   10552     rasterization_state.depthBiasEnable = VK_FALSE;
   10553     rasterization_state.lineWidth = 1.0f;
   10554 
   10555     const VkPipelineLayoutObj pipeline_layout(m_device);
   10556 
   10557     {
   10558         VkGraphicsPipelineCreateInfo create_info{};
   10559         create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
   10560         create_info.stageCount = 2;
   10561         create_info.pStages = stages;
   10562         create_info.pVertexInputState = &vertex_input_state;
   10563         create_info.pInputAssemblyState = &input_assembly_state;
   10564         create_info.pViewportState = &viewport_state;
   10565         create_info.pMultisampleState = &multisample_state;
   10566         create_info.pRasterizationState = &rasterization_state;
   10567         create_info.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
   10568         create_info.layout = pipeline_layout.handle();
   10569         create_info.renderPass = renderPass();
   10570 
   10571         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_14a004d8);
   10572         VkPipeline pipeline;
   10573         vkCreateGraphicsPipelines(m_device->device(), pipeline_cache, 1, &create_info, nullptr, &pipeline);
   10574         m_errorMonitor->VerifyFound();
   10575     }
   10576 
   10577     vkDestroyPipelineCache(m_device->device(), pipeline_cache, nullptr);
   10578 }
   10579 
   10580 TEST_F(VkLayerTest, VALIDATION_ERROR_14a004da) {
   10581     TEST_DESCRIPTION("Test VALIDATION_ERROR_14a004da: binding must be less than VkPhysicalDeviceLimits::maxVertexInputBindings");
   10582 
   10583     ASSERT_NO_FATAL_FAILURE(Init());
   10584     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   10585 
   10586     VkPipelineCache pipeline_cache;
   10587     {
   10588         VkPipelineCacheCreateInfo create_info{};
   10589         create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
   10590 
   10591         VkResult err = vkCreatePipelineCache(m_device->device(), &create_info, nullptr, &pipeline_cache);
   10592         ASSERT_VK_SUCCESS(err);
   10593     }
   10594 
   10595     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   10596     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   10597 
   10598     VkPipelineShaderStageCreateInfo stages[2]{{}};
   10599     stages[0] = vs.GetStageCreateInfo();
   10600     stages[1] = fs.GetStageCreateInfo();
   10601 
   10602     // Test when binding is greater than or equal to VkPhysicalDeviceLimits::maxVertexInputBindings.
   10603     VkVertexInputAttributeDescription vertex_input_attribute_description{};
   10604     vertex_input_attribute_description.binding = m_device->props.limits.maxVertexInputBindings;
   10605 
   10606     VkPipelineVertexInputStateCreateInfo vertex_input_state{};
   10607     vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
   10608     vertex_input_state.pNext = nullptr;
   10609     vertex_input_state.vertexBindingDescriptionCount = 0;
   10610     vertex_input_state.pVertexBindingDescriptions = nullptr;
   10611     vertex_input_state.vertexAttributeDescriptionCount = 1;
   10612     vertex_input_state.pVertexAttributeDescriptions = &vertex_input_attribute_description;
   10613 
   10614     VkPipelineInputAssemblyStateCreateInfo input_assembly_state{};
   10615     input_assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
   10616     input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
   10617 
   10618     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
   10619     VkRect2D scissor = {{0, 0}, {64, 64}};
   10620     VkPipelineViewportStateCreateInfo viewport_state{};
   10621     viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
   10622     viewport_state.viewportCount = 1;
   10623     viewport_state.pViewports = &viewport;
   10624     viewport_state.scissorCount = 1;
   10625     viewport_state.pScissors = &scissor;
   10626 
   10627     VkPipelineMultisampleStateCreateInfo multisample_state{};
   10628     multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
   10629     multisample_state.pNext = nullptr;
   10630     multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
   10631     multisample_state.sampleShadingEnable = 0;
   10632     multisample_state.minSampleShading = 1.0;
   10633     multisample_state.pSampleMask = nullptr;
   10634 
   10635     VkPipelineRasterizationStateCreateInfo rasterization_state{};
   10636     rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
   10637     rasterization_state.polygonMode = VK_POLYGON_MODE_FILL;
   10638     rasterization_state.cullMode = VK_CULL_MODE_BACK_BIT;
   10639     rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
   10640     rasterization_state.depthClampEnable = VK_FALSE;
   10641     rasterization_state.rasterizerDiscardEnable = VK_FALSE;
   10642     rasterization_state.depthBiasEnable = VK_FALSE;
   10643     rasterization_state.lineWidth = 1.0f;
   10644 
   10645     const VkPipelineLayoutObj pipeline_layout(m_device);
   10646 
   10647     {
   10648         VkGraphicsPipelineCreateInfo create_info{};
   10649         create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
   10650         create_info.stageCount = 2;
   10651         create_info.pStages = stages;
   10652         create_info.pVertexInputState = &vertex_input_state;
   10653         create_info.pInputAssemblyState = &input_assembly_state;
   10654         create_info.pViewportState = &viewport_state;
   10655         create_info.pMultisampleState = &multisample_state;
   10656         create_info.pRasterizationState = &rasterization_state;
   10657         create_info.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
   10658         create_info.layout = pipeline_layout.handle();
   10659         create_info.renderPass = renderPass();
   10660 
   10661         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_14a004da);
   10662         VkPipeline pipeline;
   10663         vkCreateGraphicsPipelines(m_device->device(), pipeline_cache, 1, &create_info, nullptr, &pipeline);
   10664         m_errorMonitor->VerifyFound();
   10665     }
   10666 
   10667     vkDestroyPipelineCache(m_device->device(), pipeline_cache, nullptr);
   10668 }
   10669 
   10670 TEST_F(VkLayerTest, VALIDATION_ERROR_14a004dc) {
   10671     TEST_DESCRIPTION(
   10672         "Test VALIDATION_ERROR_14a004dc: offset must be less than or equal to "
   10673         "VkPhysicalDeviceLimits::maxVertexInputAttributeOffset");
   10674 
   10675     EnableDeviceProfileLayer();
   10676 
   10677     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   10678 
   10679     uint32_t maxVertexInputAttributeOffset = 0;
   10680     {
   10681         VkPhysicalDeviceProperties device_props = {};
   10682         vkGetPhysicalDeviceProperties(gpu(), &device_props);
   10683         maxVertexInputAttributeOffset = device_props.limits.maxVertexInputAttributeOffset;
   10684         if (maxVertexInputAttributeOffset == 0xFFFFFFFF) {
   10685             // Attempt to artificially lower maximum offset
   10686             PFN_vkSetPhysicalDeviceLimitsEXT fpvkSetPhysicalDeviceLimitsEXT =
   10687                 (PFN_vkSetPhysicalDeviceLimitsEXT)vkGetInstanceProcAddr(instance(), "vkSetPhysicalDeviceLimitsEXT");
   10688             if (!fpvkSetPhysicalDeviceLimitsEXT) {
   10689                 printf("             All offsets are valid & device_profile_api not found; skipped.\n");
   10690                 return;
   10691             }
   10692             device_props.limits.maxVertexInputAttributeOffset = device_props.limits.maxVertexInputBindingStride - 2;
   10693             fpvkSetPhysicalDeviceLimitsEXT(gpu(), &device_props.limits);
   10694             maxVertexInputAttributeOffset = device_props.limits.maxVertexInputAttributeOffset;
   10695         }
   10696     }
   10697     ASSERT_NO_FATAL_FAILURE(InitState());
   10698     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   10699 
   10700     VkPipelineCache pipeline_cache;
   10701     {
   10702         VkPipelineCacheCreateInfo create_info{};
   10703         create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
   10704 
   10705         VkResult err = vkCreatePipelineCache(m_device->device(), &create_info, nullptr, &pipeline_cache);
   10706         ASSERT_VK_SUCCESS(err);
   10707     }
   10708 
   10709     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   10710     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   10711 
   10712     VkPipelineShaderStageCreateInfo stages[2]{{}};
   10713     stages[0] = vs.GetStageCreateInfo();
   10714     stages[1] = fs.GetStageCreateInfo();
   10715 
   10716     VkVertexInputBindingDescription vertex_input_binding_description{};
   10717     vertex_input_binding_description.binding = 0;
   10718     vertex_input_binding_description.stride = m_device->props.limits.maxVertexInputBindingStride;
   10719     vertex_input_binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
   10720     // Test when offset is greater than maximum.
   10721     VkVertexInputAttributeDescription vertex_input_attribute_description{};
   10722     vertex_input_attribute_description.format = VK_FORMAT_R8_UNORM;
   10723     vertex_input_attribute_description.offset = maxVertexInputAttributeOffset + 1;
   10724 
   10725     VkPipelineVertexInputStateCreateInfo vertex_input_state{};
   10726     vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
   10727     vertex_input_state.pNext = nullptr;
   10728     vertex_input_state.vertexBindingDescriptionCount = 1;
   10729     vertex_input_state.pVertexBindingDescriptions = &vertex_input_binding_description;
   10730     vertex_input_state.vertexAttributeDescriptionCount = 1;
   10731     vertex_input_state.pVertexAttributeDescriptions = &vertex_input_attribute_description;
   10732 
   10733     VkPipelineInputAssemblyStateCreateInfo input_assembly_state{};
   10734     input_assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
   10735     input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
   10736 
   10737     VkPipelineMultisampleStateCreateInfo multisample_state{};
   10738     multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
   10739     multisample_state.pNext = nullptr;
   10740     multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
   10741     multisample_state.sampleShadingEnable = 0;
   10742     multisample_state.minSampleShading = 1.0;
   10743     multisample_state.pSampleMask = nullptr;
   10744 
   10745     VkPipelineRasterizationStateCreateInfo rasterization_state{};
   10746     rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
   10747     rasterization_state.polygonMode = VK_POLYGON_MODE_FILL;
   10748     rasterization_state.cullMode = VK_CULL_MODE_BACK_BIT;
   10749     rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
   10750     rasterization_state.depthClampEnable = VK_FALSE;
   10751     rasterization_state.rasterizerDiscardEnable = VK_TRUE;
   10752     rasterization_state.depthBiasEnable = VK_FALSE;
   10753     rasterization_state.lineWidth = 1.0f;
   10754 
   10755     const VkPipelineLayoutObj pipeline_layout(m_device);
   10756 
   10757     {
   10758         VkGraphicsPipelineCreateInfo create_info{};
   10759         create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
   10760         create_info.stageCount = 2;
   10761         create_info.pStages = stages;
   10762         create_info.pVertexInputState = &vertex_input_state;
   10763         create_info.pInputAssemblyState = &input_assembly_state;
   10764         create_info.pViewportState = nullptr;  // no viewport b/c rasterizer is disabled
   10765         create_info.pMultisampleState = &multisample_state;
   10766         create_info.pRasterizationState = &rasterization_state;
   10767         create_info.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
   10768         create_info.layout = pipeline_layout.handle();
   10769         create_info.renderPass = renderPass();
   10770 
   10771         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_14a004dc);
   10772         VkPipeline pipeline;
   10773         vkCreateGraphicsPipelines(m_device->device(), pipeline_cache, 1, &create_info, nullptr, &pipeline);
   10774         m_errorMonitor->VerifyFound();
   10775     }
   10776 
   10777     vkDestroyPipelineCache(m_device->device(), pipeline_cache, nullptr);
   10778 }
   10779 
   10780 TEST_F(VkLayerTest, NullRenderPass) {
   10781     // Bind a NULL RenderPass
   10782     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   10783                                          "vkCmdBeginRenderPass: required parameter pRenderPassBegin specified as NULL");
   10784 
   10785     ASSERT_NO_FATAL_FAILURE(Init());
   10786     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   10787 
   10788     m_commandBuffer->begin();
   10789     // Don't care about RenderPass handle b/c error should be flagged before
   10790     // that
   10791     vkCmdBeginRenderPass(m_commandBuffer->handle(), NULL, VK_SUBPASS_CONTENTS_INLINE);
   10792 
   10793     m_errorMonitor->VerifyFound();
   10794 }
   10795 
   10796 TEST_F(VkLayerTest, RenderPassWithinRenderPass) {
   10797     // Bind a BeginRenderPass within an active RenderPass
   10798     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   10799                                          "It is invalid to issue this call inside an active render pass");
   10800 
   10801     ASSERT_NO_FATAL_FAILURE(Init());
   10802     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   10803 
   10804     m_commandBuffer->begin();
   10805     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   10806     // Just create a dummy Renderpass that's non-NULL so we can get to the
   10807     // proper error
   10808     vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
   10809 
   10810     m_errorMonitor->VerifyFound();
   10811 }
   10812 
   10813 TEST_F(VkLayerTest, RenderPassClearOpMismatch) {
   10814     TEST_DESCRIPTION(
   10815         "Begin a renderPass where clearValueCount is less than the number of renderPass attachments that use "
   10816         "loadOpVK_ATTACHMENT_LOAD_OP_CLEAR.");
   10817 
   10818     ASSERT_NO_FATAL_FAILURE(Init());
   10819     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   10820 
   10821     // Create a renderPass with a single attachment that uses loadOp CLEAR
   10822     VkAttachmentReference attach = {};
   10823     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
   10824     VkSubpassDescription subpass = {};
   10825     subpass.colorAttachmentCount = 1;
   10826     subpass.pColorAttachments = &attach;
   10827     VkRenderPassCreateInfo rpci = {};
   10828     rpci.subpassCount = 1;
   10829     rpci.pSubpasses = &subpass;
   10830     rpci.attachmentCount = 1;
   10831     VkAttachmentDescription attach_desc = {};
   10832     attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
   10833     // Set loadOp to CLEAR
   10834     attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
   10835     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
   10836     attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
   10837     rpci.pAttachments = &attach_desc;
   10838     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
   10839     VkRenderPass rp;
   10840     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
   10841 
   10842     VkCommandBufferInheritanceInfo hinfo = {};
   10843     hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
   10844     hinfo.renderPass = VK_NULL_HANDLE;
   10845     hinfo.subpass = 0;
   10846     hinfo.framebuffer = VK_NULL_HANDLE;
   10847     hinfo.occlusionQueryEnable = VK_FALSE;
   10848     hinfo.queryFlags = 0;
   10849     hinfo.pipelineStatistics = 0;
   10850     VkCommandBufferBeginInfo info = {};
   10851     info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
   10852     info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   10853     info.pInheritanceInfo = &hinfo;
   10854 
   10855     vkBeginCommandBuffer(m_commandBuffer->handle(), &info);
   10856     VkRenderPassBeginInfo rp_begin = {};
   10857     rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
   10858     rp_begin.pNext = NULL;
   10859     rp_begin.renderPass = renderPass();
   10860     rp_begin.framebuffer = framebuffer();
   10861     rp_begin.clearValueCount = 0;  // Should be 1
   10862 
   10863     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1200070c);
   10864 
   10865     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rp_begin, VK_SUBPASS_CONTENTS_INLINE);
   10866 
   10867     m_errorMonitor->VerifyFound();
   10868 
   10869     vkDestroyRenderPass(m_device->device(), rp, NULL);
   10870 }
   10871 
   10872 TEST_F(VkLayerTest, EndCommandBufferWithinRenderPass) {
   10873     TEST_DESCRIPTION("End a command buffer with an active render pass");
   10874 
   10875     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   10876                                          "It is invalid to issue this call inside an active render pass");
   10877 
   10878     ASSERT_NO_FATAL_FAILURE(Init());
   10879     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   10880 
   10881     m_commandBuffer->begin();
   10882     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   10883     vkEndCommandBuffer(m_commandBuffer->handle());
   10884 
   10885     m_errorMonitor->VerifyFound();
   10886 
   10887     // TODO: Add test for VK_COMMAND_BUFFER_LEVEL_SECONDARY
   10888     // TODO: Add test for VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT
   10889 }
   10890 
   10891 TEST_F(VkLayerTest, FillBufferWithinRenderPass) {
   10892     // Call CmdFillBuffer within an active renderpass
   10893     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   10894                                          "It is invalid to issue this call inside an active render pass");
   10895 
   10896     ASSERT_NO_FATAL_FAILURE(Init());
   10897     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   10898 
   10899     m_commandBuffer->begin();
   10900     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   10901 
   10902     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
   10903     vk_testing::Buffer dstBuffer;
   10904     dstBuffer.init_as_dst(*m_device, (VkDeviceSize)1024, reqs);
   10905 
   10906     m_commandBuffer->FillBuffer(dstBuffer.handle(), 0, 4, 0x11111111);
   10907 
   10908     m_errorMonitor->VerifyFound();
   10909 }
   10910 
   10911 TEST_F(VkLayerTest, UpdateBufferWithinRenderPass) {
   10912     // Call CmdUpdateBuffer within an active renderpass
   10913     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   10914                                          "It is invalid to issue this call inside an active render pass");
   10915 
   10916     ASSERT_NO_FATAL_FAILURE(Init());
   10917     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   10918 
   10919     m_commandBuffer->begin();
   10920     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   10921 
   10922     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
   10923     vk_testing::Buffer dstBuffer;
   10924     dstBuffer.init_as_dst(*m_device, (VkDeviceSize)1024, reqs);
   10925 
   10926     VkDeviceSize dstOffset = 0;
   10927     uint32_t Data[] = {1, 2, 3, 4, 5, 6, 7, 8};
   10928     VkDeviceSize dataSize = sizeof(Data) / sizeof(uint32_t);
   10929     vkCmdUpdateBuffer(m_commandBuffer->handle(), dstBuffer.handle(), dstOffset, dataSize, &Data);
   10930 
   10931     m_errorMonitor->VerifyFound();
   10932 }
   10933 
   10934 TEST_F(VkLayerTest, ClearColorImageWithBadRange) {
   10935     TEST_DESCRIPTION("Record clear color with an invalid VkImageSubresourceRange");
   10936 
   10937     ASSERT_NO_FATAL_FAILURE(Init());
   10938     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   10939 
   10940     VkImageObj image(m_device);
   10941     image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
   10942     ASSERT_TRUE(image.create_info().arrayLayers == 1);
   10943     ASSERT_TRUE(image.initialized());
   10944     image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
   10945 
   10946     const VkClearColorValue clear_color = {{0.0f, 0.0f, 0.0f, 1.0f}};
   10947 
   10948     m_commandBuffer->begin();
   10949     const auto cb_handle = m_commandBuffer->handle();
   10950 
   10951     // Try baseMipLevel >= image.mipLevels with VK_REMAINING_MIP_LEVELS
   10952     {
   10953         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800b7c);
   10954         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, VK_REMAINING_MIP_LEVELS, 0, 1};
   10955         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
   10956         m_errorMonitor->VerifyFound();
   10957     }
   10958 
   10959     // Try baseMipLevel >= image.mipLevels without VK_REMAINING_MIP_LEVELS
   10960     {
   10961         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800b7c);
   10962         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800b7e);
   10963         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 0, 1};
   10964         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
   10965         m_errorMonitor->VerifyFound();
   10966     }
   10967 
   10968     // Try levelCount = 0
   10969     {
   10970         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800b7e);
   10971         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 0, 1};
   10972         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
   10973         m_errorMonitor->VerifyFound();
   10974     }
   10975 
   10976     // Try baseMipLevel + levelCount > image.mipLevels
   10977     {
   10978         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800b7e);
   10979         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 2, 0, 1};
   10980         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
   10981         m_errorMonitor->VerifyFound();
   10982     }
   10983 
   10984     // Try baseArrayLayer >= image.arrayLayers with VK_REMAINING_ARRAY_LAYERS
   10985     {
   10986         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800b80);
   10987         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, VK_REMAINING_ARRAY_LAYERS};
   10988         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
   10989         m_errorMonitor->VerifyFound();
   10990     }
   10991 
   10992     // Try baseArrayLayer >= image.arrayLayers without VK_REMAINING_ARRAY_LAYERS
   10993     {
   10994         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800b80);
   10995         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800b82);
   10996         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, 1};
   10997         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
   10998         m_errorMonitor->VerifyFound();
   10999     }
   11000 
   11001     // Try layerCount = 0
   11002     {
   11003         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800b82);
   11004         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 0};
   11005         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
   11006         m_errorMonitor->VerifyFound();
   11007     }
   11008 
   11009     // Try baseArrayLayer + layerCount > image.arrayLayers
   11010     {
   11011         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800b82);
   11012         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 2};
   11013         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
   11014         m_errorMonitor->VerifyFound();
   11015     }
   11016 }
   11017 
   11018 TEST_F(VkLayerTest, ClearDepthStencilWithBadRange) {
   11019     TEST_DESCRIPTION("Record clear depth with an invalid VkImageSubresourceRange");
   11020 
   11021     ASSERT_NO_FATAL_FAILURE(Init());
   11022     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   11023 
   11024     const auto depth_format = FindSupportedDepthStencilFormat(gpu());
   11025     if (!depth_format) {
   11026         printf("             No Depth + Stencil format found. Skipped.\n");
   11027         return;
   11028     }
   11029 
   11030     VkImageObj image(m_device);
   11031     image.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
   11032     ASSERT_TRUE(image.create_info().arrayLayers == 1);
   11033     ASSERT_TRUE(image.initialized());
   11034     const VkImageAspectFlags ds_aspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
   11035     image.SetLayout(ds_aspect, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
   11036 
   11037     const VkClearDepthStencilValue clear_value = {};
   11038 
   11039     m_commandBuffer->begin();
   11040     const auto cb_handle = m_commandBuffer->handle();
   11041 
   11042     // Try baseMipLevel >= image.mipLevels with VK_REMAINING_MIP_LEVELS
   11043     {
   11044         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00b84);
   11045         const VkImageSubresourceRange range = {ds_aspect, 1, VK_REMAINING_MIP_LEVELS, 0, 1};
   11046         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
   11047         m_errorMonitor->VerifyFound();
   11048     }
   11049 
   11050     // Try baseMipLevel >= image.mipLevels without VK_REMAINING_MIP_LEVELS
   11051     {
   11052         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00b84);
   11053         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00b86);
   11054         const VkImageSubresourceRange range = {ds_aspect, 1, 1, 0, 1};
   11055         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
   11056         m_errorMonitor->VerifyFound();
   11057     }
   11058 
   11059     // Try levelCount = 0
   11060     {
   11061         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00b86);
   11062         const VkImageSubresourceRange range = {ds_aspect, 0, 0, 0, 1};
   11063         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
   11064         m_errorMonitor->VerifyFound();
   11065     }
   11066 
   11067     // Try baseMipLevel + levelCount > image.mipLevels
   11068     {
   11069         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00b86);
   11070         const VkImageSubresourceRange range = {ds_aspect, 0, 2, 0, 1};
   11071         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
   11072         m_errorMonitor->VerifyFound();
   11073     }
   11074 
   11075     // Try baseArrayLayer >= image.arrayLayers with VK_REMAINING_ARRAY_LAYERS
   11076     {
   11077         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00b88);
   11078         const VkImageSubresourceRange range = {ds_aspect, 0, 1, 1, VK_REMAINING_ARRAY_LAYERS};
   11079         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
   11080         m_errorMonitor->VerifyFound();
   11081     }
   11082 
   11083     // Try baseArrayLayer >= image.arrayLayers without VK_REMAINING_ARRAY_LAYERS
   11084     {
   11085         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00b88);
   11086         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00b8a);
   11087         const VkImageSubresourceRange range = {ds_aspect, 0, 1, 1, 1};
   11088         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
   11089         m_errorMonitor->VerifyFound();
   11090     }
   11091 
   11092     // Try layerCount = 0
   11093     {
   11094         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00b8a);
   11095         const VkImageSubresourceRange range = {ds_aspect, 0, 1, 0, 0};
   11096         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
   11097         m_errorMonitor->VerifyFound();
   11098     }
   11099 
   11100     // Try baseArrayLayer + layerCount > image.arrayLayers
   11101     {
   11102         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00b8a);
   11103         const VkImageSubresourceRange range = {ds_aspect, 0, 1, 0, 2};
   11104         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
   11105         m_errorMonitor->VerifyFound();
   11106     }
   11107 }
   11108 
   11109 TEST_F(VkLayerTest, ClearColorImageWithinRenderPass) {
   11110     // Call CmdClearColorImage within an active RenderPass
   11111     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   11112                                          "It is invalid to issue this call inside an active render pass");
   11113 
   11114     ASSERT_NO_FATAL_FAILURE(Init());
   11115     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   11116 
   11117     m_commandBuffer->begin();
   11118     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   11119 
   11120     VkClearColorValue clear_color;
   11121     memset(clear_color.uint32, 0, sizeof(uint32_t) * 4);
   11122     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
   11123     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
   11124     const int32_t tex_width = 32;
   11125     const int32_t tex_height = 32;
   11126     VkImageCreateInfo image_create_info = {};
   11127     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   11128     image_create_info.pNext = NULL;
   11129     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   11130     image_create_info.format = tex_format;
   11131     image_create_info.extent.width = tex_width;
   11132     image_create_info.extent.height = tex_height;
   11133     image_create_info.extent.depth = 1;
   11134     image_create_info.mipLevels = 1;
   11135     image_create_info.arrayLayers = 1;
   11136     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   11137     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
   11138     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   11139 
   11140     vk_testing::Image dstImage;
   11141     dstImage.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
   11142 
   11143     const VkImageSubresourceRange range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT);
   11144 
   11145     vkCmdClearColorImage(m_commandBuffer->handle(), dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &range);
   11146 
   11147     m_errorMonitor->VerifyFound();
   11148 }
   11149 
   11150 TEST_F(VkLayerTest, ClearDepthStencilImageErrors) {
   11151     // Hit errors related to vkCmdClearDepthStencilImage()
   11152     // 1. Use an image that doesn't have VK_IMAGE_USAGE_TRANSFER_DST_BIT set
   11153     // 2. Call CmdClearDepthStencilImage within an active RenderPass
   11154 
   11155     ASSERT_NO_FATAL_FAILURE(Init());
   11156     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   11157 
   11158     auto depth_format = FindSupportedDepthStencilFormat(gpu());
   11159     if (!depth_format) {
   11160         printf("             No Depth + Stencil format found. Skipped.\n");
   11161         return;
   11162     }
   11163 
   11164     VkClearDepthStencilValue clear_value = {0};
   11165     VkMemoryPropertyFlags reqs = 0;
   11166     VkImageCreateInfo image_create_info = vk_testing::Image::create_info();
   11167     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   11168     image_create_info.format = depth_format;
   11169     image_create_info.extent.width = 64;
   11170     image_create_info.extent.height = 64;
   11171     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   11172     // Error here is that VK_IMAGE_USAGE_TRANSFER_DST_BIT is excluded for DS image that we'll call Clear on below
   11173     image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
   11174 
   11175     vk_testing::Image dst_image_bad_usage;
   11176     dst_image_bad_usage.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
   11177     const VkImageSubresourceRange range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT);
   11178 
   11179     m_commandBuffer->begin();
   11180     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00012);
   11181     vkCmdClearDepthStencilImage(m_commandBuffer->handle(), dst_image_bad_usage.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1,
   11182                                 &range);
   11183     m_errorMonitor->VerifyFound();
   11184 
   11185     // Fix usage for next test case
   11186     image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   11187     vk_testing::Image dst_image;
   11188     dst_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
   11189 
   11190     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   11191 
   11192     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00017);
   11193     vkCmdClearDepthStencilImage(m_commandBuffer->handle(), dst_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1, &range);
   11194     m_errorMonitor->VerifyFound();
   11195 }
   11196 
   11197 TEST_F(VkLayerTest, ClearColorAttachmentsOutsideRenderPass) {
   11198     // Call CmdClearAttachmentss outside of an active RenderPass
   11199 
   11200     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   11201                                          "vkCmdClearAttachments(): This call must be issued inside an active render pass");
   11202 
   11203     ASSERT_NO_FATAL_FAILURE(Init());
   11204     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   11205 
   11206     // Start no RenderPass
   11207     m_commandBuffer->begin();
   11208 
   11209     VkClearAttachment color_attachment;
   11210     color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   11211     color_attachment.clearValue.color.float32[0] = 0;
   11212     color_attachment.clearValue.color.float32[1] = 0;
   11213     color_attachment.clearValue.color.float32[2] = 0;
   11214     color_attachment.clearValue.color.float32[3] = 0;
   11215     color_attachment.colorAttachment = 0;
   11216     VkClearRect clear_rect = {{{0, 0}, {32, 32}}};
   11217     vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
   11218 
   11219     m_errorMonitor->VerifyFound();
   11220 }
   11221 
   11222 TEST_F(VkLayerTest, RenderPassExcessiveNextSubpass) {
   11223     TEST_DESCRIPTION("Test that an error is produced when CmdNextSubpass is called too many times in a renderpass instance");
   11224 
   11225     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   11226                                          "vkCmdNextSubpass(): Attempted to advance beyond final subpass");
   11227 
   11228     ASSERT_NO_FATAL_FAILURE(Init());
   11229     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   11230 
   11231     m_commandBuffer->begin();
   11232     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   11233 
   11234     // error here.
   11235     vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
   11236     m_errorMonitor->VerifyFound();
   11237 
   11238     m_commandBuffer->EndRenderPass();
   11239     m_commandBuffer->end();
   11240 }
   11241 
   11242 TEST_F(VkLayerTest, RenderPassEndedBeforeFinalSubpass) {
   11243     TEST_DESCRIPTION("Test that an error is produced when CmdEndRenderPass is called before the final subpass has been reached");
   11244 
   11245     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   11246                                          "vkCmdEndRenderPass(): Called before reaching final subpass");
   11247 
   11248     ASSERT_NO_FATAL_FAILURE(Init());
   11249     VkSubpassDescription sd[2] = {{0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr},
   11250                                   {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}};
   11251 
   11252     VkRenderPassCreateInfo rcpi = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 2, sd, 0, nullptr};
   11253 
   11254     VkRenderPass rp;
   11255     VkResult err = vkCreateRenderPass(m_device->device(), &rcpi, nullptr, &rp);
   11256     ASSERT_VK_SUCCESS(err);
   11257 
   11258     VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 16, 16, 1};
   11259 
   11260     VkFramebuffer fb;
   11261     err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
   11262     ASSERT_VK_SUCCESS(err);
   11263 
   11264     m_commandBuffer->begin();  // no implicit RP begin
   11265 
   11266     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {16, 16}}, 0, nullptr};
   11267 
   11268     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
   11269 
   11270     // Error here.
   11271     vkCmdEndRenderPass(m_commandBuffer->handle());
   11272     m_errorMonitor->VerifyFound();
   11273 
   11274     // Clean up.
   11275     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
   11276     vkDestroyRenderPass(m_device->device(), rp, nullptr);
   11277 }
   11278 
   11279 TEST_F(VkLayerTest, BufferMemoryBarrierNoBuffer) {
   11280     // Try to add a buffer memory barrier with no buffer.
   11281     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   11282                                          "required parameter pBufferMemoryBarriers[0].buffer specified as VK_NULL_HANDLE");
   11283 
   11284     ASSERT_NO_FATAL_FAILURE(Init());
   11285     m_commandBuffer->begin();
   11286 
   11287     VkBufferMemoryBarrier buf_barrier = {};
   11288     buf_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
   11289     buf_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
   11290     buf_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
   11291     buf_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   11292     buf_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   11293     buf_barrier.buffer = VK_NULL_HANDLE;
   11294     buf_barrier.offset = 0;
   11295     buf_barrier.size = VK_WHOLE_SIZE;
   11296     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr,
   11297                          1, &buf_barrier, 0, nullptr);
   11298 
   11299     m_errorMonitor->VerifyFound();
   11300 }
   11301 
   11302 TEST_F(VkLayerTest, InvalidBarriers) {
   11303     TEST_DESCRIPTION("A variety of ways to get VK_INVALID_BARRIER ");
   11304 
   11305     ASSERT_NO_FATAL_FAILURE(Init());
   11306     auto depth_format = FindSupportedDepthStencilFormat(gpu());
   11307     if (!depth_format) {
   11308         printf("             No Depth + Stencil format found. Skipped.\n");
   11309         return;
   11310     }
   11311     // Add a token self-dependency for this test to avoid unexpected errors
   11312     m_addRenderPassSelfDependency = true;
   11313     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   11314 
   11315     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image Layout cannot be transitioned to UNDEFINED");
   11316     VkImageObj image(m_device);
   11317     image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   11318     ASSERT_TRUE(image.initialized());
   11319     VkImageMemoryBarrier img_barrier = {};
   11320     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
   11321     img_barrier.pNext = NULL;
   11322     img_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
   11323     img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
   11324     img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   11325     // New layout can't be UNDEFINED
   11326     img_barrier.newLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   11327     img_barrier.image = m_renderTargets[0]->handle();
   11328     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   11329     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   11330     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   11331     img_barrier.subresourceRange.baseArrayLayer = 0;
   11332     img_barrier.subresourceRange.baseMipLevel = 0;
   11333     img_barrier.subresourceRange.layerCount = 1;
   11334     img_barrier.subresourceRange.levelCount = 1;
   11335     m_commandBuffer->begin();
   11336     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   11337                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
   11338                          &img_barrier);
   11339     m_errorMonitor->VerifyFound();
   11340 
   11341     // Transition image to color attachment optimal
   11342     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   11343     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   11344                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
   11345                          &img_barrier);
   11346     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   11347 
   11348     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   11349 
   11350     // Can't send buffer memory barrier during a render pass
   11351     vkCmdEndRenderPass(m_commandBuffer->handle());
   11352 
   11353     vk_testing::Buffer buffer;
   11354     VkMemoryPropertyFlags mem_reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
   11355     buffer.init_as_src_and_dst(*m_device, 256, mem_reqs);
   11356     VkBufferMemoryBarrier buf_barrier = {};
   11357     buf_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
   11358     buf_barrier.pNext = NULL;
   11359     buf_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
   11360     buf_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
   11361     buf_barrier.buffer = buffer.handle();
   11362     buf_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   11363     buf_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   11364     buf_barrier.offset = 0;
   11365     buf_barrier.size = VK_WHOLE_SIZE;
   11366 
   11367     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "which is not less than total size");
   11368     // Exceed the internal memory size
   11369     buf_barrier.offset = buffer.memory_requirements().size + 1;
   11370     // Offset greater than total size
   11371     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   11372                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1, &buf_barrier, 0,
   11373                          nullptr);
   11374     m_errorMonitor->VerifyFound();
   11375     buf_barrier.offset = 0;
   11376 
   11377     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "whose sum is greater than total size");
   11378     buf_barrier.size = buffer.memory_requirements().size + 1;
   11379     // Size greater than total size
   11380     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   11381                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1, &buf_barrier, 0,
   11382                          nullptr);
   11383     m_errorMonitor->VerifyFound();
   11384 
   11385     // Now exercise barrier aspect bit errors, first DS
   11386     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a400c01);
   11387     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a00096e);
   11388     VkDepthStencilObj ds_image(m_device);
   11389     ds_image.Init(m_device, 128, 128, depth_format);
   11390     ASSERT_TRUE(ds_image.initialized());
   11391     img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
   11392     img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
   11393     img_barrier.image = ds_image.handle();
   11394 
   11395     // Not having DEPTH or STENCIL set is an error
   11396     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
   11397     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   11398                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
   11399                          &img_barrier);
   11400     m_errorMonitor->VerifyFound();
   11401 
   11402     // Having only one of depth or stencil set for DS image is an error
   11403     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a00096e);
   11404     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
   11405     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   11406                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
   11407                          &img_barrier);
   11408     m_errorMonitor->VerifyFound();
   11409 
   11410     // Having anything other than DEPTH and STENCIL is an error
   11411     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a400c01);
   11412     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_COLOR_BIT;
   11413     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   11414                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
   11415                          &img_barrier);
   11416     m_errorMonitor->VerifyFound();
   11417 
   11418     // Now test depth-only
   11419     VkFormatProperties format_props;
   11420     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D16_UNORM, &format_props);
   11421     if (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
   11422         VkDepthStencilObj d_image(m_device);
   11423         d_image.Init(m_device, 128, 128, VK_FORMAT_D16_UNORM);
   11424         ASSERT_TRUE(d_image.initialized());
   11425         img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
   11426         img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
   11427         img_barrier.image = d_image.handle();
   11428 
   11429         // DEPTH bit must be set
   11430         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   11431                                              "Depth-only image formats must have the VK_IMAGE_ASPECT_DEPTH_BIT set.");
   11432         img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
   11433         vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   11434                              VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
   11435                              &img_barrier);
   11436         m_errorMonitor->VerifyFound();
   11437 
   11438         // No bits other than DEPTH may be set
   11439         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   11440                                              "Depth-only image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT set.");
   11441         img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_COLOR_BIT;
   11442         vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   11443                              VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
   11444                              &img_barrier);
   11445         m_errorMonitor->VerifyFound();
   11446     }
   11447 
   11448     // Now test stencil-only
   11449     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_S8_UINT, &format_props);
   11450     if (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
   11451         VkDepthStencilObj s_image(m_device);
   11452         s_image.Init(m_device, 128, 128, VK_FORMAT_S8_UINT);
   11453         ASSERT_TRUE(s_image.initialized());
   11454         img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
   11455         img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
   11456         img_barrier.image = s_image.handle();
   11457         // Use of COLOR aspect on depth image is error
   11458         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   11459                                              "Stencil-only image formats must have the VK_IMAGE_ASPECT_STENCIL_BIT set.");
   11460         img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   11461         vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   11462                              VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
   11463                              &img_barrier);
   11464         m_errorMonitor->VerifyFound();
   11465     }
   11466 
   11467     // Finally test color
   11468     VkImageObj c_image(m_device);
   11469     c_image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   11470     ASSERT_TRUE(c_image.initialized());
   11471     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   11472     img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
   11473     img_barrier.image = c_image.handle();
   11474 
   11475     // COLOR bit must be set
   11476     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   11477                                          "Color image formats must have the VK_IMAGE_ASPECT_COLOR_BIT set.");
   11478     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
   11479     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   11480                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
   11481                          &img_barrier);
   11482     m_errorMonitor->VerifyFound();
   11483 
   11484     // No bits other than COLOR may be set
   11485     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   11486                                          "Color image formats must have ONLY the VK_IMAGE_ASPECT_COLOR_BIT set.");
   11487     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
   11488     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   11489                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
   11490                          &img_barrier);
   11491     m_errorMonitor->VerifyFound();
   11492 
   11493     // A barrier's new and old VkImageLayout must be compatible with an image's VkImageUsageFlags.
   11494     {
   11495         VkImageObj img_color(m_device);
   11496         img_color.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
   11497         ASSERT_TRUE(img_color.initialized());
   11498 
   11499         VkImageObj img_ds(m_device);
   11500         img_ds.Init(128, 128, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
   11501         ASSERT_TRUE(img_ds.initialized());
   11502 
   11503         VkImageObj img_xfer_src(m_device);
   11504         img_xfer_src.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL);
   11505         ASSERT_TRUE(img_xfer_src.initialized());
   11506 
   11507         VkImageObj img_xfer_dst(m_device);
   11508         img_xfer_dst.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
   11509         ASSERT_TRUE(img_xfer_dst.initialized());
   11510 
   11511         VkImageObj img_sampled(m_device);
   11512         img_sampled.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL);
   11513         ASSERT_TRUE(img_sampled.initialized());
   11514 
   11515         VkImageObj img_input(m_device);
   11516         img_input.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
   11517         ASSERT_TRUE(img_input.initialized());
   11518 
   11519         const struct {
   11520             VkImageObj &image_obj;
   11521             VkImageLayout bad_layout;
   11522             UNIQUE_VALIDATION_ERROR_CODE msg_code;
   11523         } bad_buffer_layouts[] = {
   11524             // clang-format off
   11525             // images _without_ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
   11526             {img_ds,       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,         VALIDATION_ERROR_0a000970},
   11527             {img_xfer_src, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,         VALIDATION_ERROR_0a000970},
   11528             {img_xfer_dst, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,         VALIDATION_ERROR_0a000970},
   11529             {img_sampled,  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,         VALIDATION_ERROR_0a000970},
   11530             {img_input,    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,         VALIDATION_ERROR_0a000970},
   11531             // images _without_ VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
   11532             {img_color,    VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VALIDATION_ERROR_0a000972},
   11533             {img_xfer_src, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VALIDATION_ERROR_0a000972},
   11534             {img_xfer_dst, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VALIDATION_ERROR_0a000972},
   11535             {img_sampled,  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VALIDATION_ERROR_0a000972},
   11536             {img_input,    VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VALIDATION_ERROR_0a000972},
   11537             {img_color,    VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,  VALIDATION_ERROR_0a000974},
   11538             {img_xfer_src, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,  VALIDATION_ERROR_0a000974},
   11539             {img_xfer_dst, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,  VALIDATION_ERROR_0a000974},
   11540             {img_sampled,  VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,  VALIDATION_ERROR_0a000974},
   11541             {img_input,    VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,  VALIDATION_ERROR_0a000974},
   11542             // images _without_ VK_IMAGE_USAGE_SAMPLED_BIT or VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
   11543             {img_color,    VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,         VALIDATION_ERROR_0a000976},
   11544             {img_ds,       VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,         VALIDATION_ERROR_0a000976},
   11545             {img_xfer_src, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,         VALIDATION_ERROR_0a000976},
   11546             {img_xfer_dst, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,         VALIDATION_ERROR_0a000976},
   11547             // images _without_ VK_IMAGE_USAGE_TRANSFER_SRC_BIT
   11548             {img_color,    VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,             VALIDATION_ERROR_0a000978},
   11549             {img_ds,       VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,             VALIDATION_ERROR_0a000978},
   11550             {img_xfer_dst, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,             VALIDATION_ERROR_0a000978},
   11551             {img_sampled,  VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,             VALIDATION_ERROR_0a000978},
   11552             {img_input,    VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,             VALIDATION_ERROR_0a000978},
   11553             // images _without_ VK_IMAGE_USAGE_TRANSFER_DST_BIT
   11554             {img_color,    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,             VALIDATION_ERROR_0a00097a},
   11555             {img_ds,       VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,             VALIDATION_ERROR_0a00097a},
   11556             {img_xfer_src, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,             VALIDATION_ERROR_0a00097a},
   11557             {img_sampled,  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,             VALIDATION_ERROR_0a00097a},
   11558             {img_input,    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,             VALIDATION_ERROR_0a00097a},
   11559             // clang-format on
   11560         };
   11561         const uint32_t layout_count = sizeof(bad_buffer_layouts) / sizeof(bad_buffer_layouts[0]);
   11562 
   11563         for (uint32_t i = 0; i < layout_count; ++i) {
   11564             img_barrier.image = bad_buffer_layouts[i].image_obj.handle();
   11565             const VkImageUsageFlags usage = bad_buffer_layouts[i].image_obj.usage();
   11566             img_barrier.subresourceRange.aspectMask = (usage == VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
   11567                                                           ? (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)
   11568                                                           : VK_IMAGE_ASPECT_COLOR_BIT;
   11569 
   11570             img_barrier.oldLayout = bad_buffer_layouts[i].bad_layout;
   11571             img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
   11572             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, bad_buffer_layouts[i].msg_code);
   11573             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   11574                                  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
   11575                                  &img_barrier);
   11576             m_errorMonitor->VerifyFound();
   11577 
   11578             img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
   11579             img_barrier.newLayout = bad_buffer_layouts[i].bad_layout;
   11580             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, bad_buffer_layouts[i].msg_code);
   11581             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   11582                                  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
   11583                                  &img_barrier);
   11584             m_errorMonitor->VerifyFound();
   11585         }
   11586 
   11587         img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
   11588         img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
   11589     }
   11590     // Attempt barrier where srcAccessMask is not supported by srcStageMask
   11591     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800940);
   11592     // Have lower-order bit that's supported (shader write), but higher-order bit not supported to verify multi-bit validation
   11593     buf_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_WRITE_BIT;
   11594     buf_barrier.offset = 0;
   11595     buf_barrier.size = VK_WHOLE_SIZE;
   11596     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
   11597                          VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1, &buf_barrier, 0, nullptr);
   11598     m_errorMonitor->VerifyFound();
   11599     // Attempt barrier where dsAccessMask is not supported by dstStageMask
   11600     buf_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
   11601     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800942);
   11602     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   11603                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1, &buf_barrier, 0,
   11604                          nullptr);
   11605     m_errorMonitor->VerifyFound();
   11606 
   11607     // Attempt to mismatch barriers/waitEvents calls with incompatible queues
   11608     // Create command pool with incompatible queueflags
   11609     const std::vector<VkQueueFamilyProperties> queue_props = m_device->queue_props;
   11610     uint32_t queue_family_index = m_device->QueueFamilyWithoutCapabilities(VK_QUEUE_COMPUTE_BIT);
   11611     if (queue_family_index == UINT32_MAX) {
   11612         printf("             No non-compute queue found; skipped.\n");
   11613         return;  // NOTE: this exits the test function!
   11614     }
   11615     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b80093e);
   11616 
   11617     VkCommandPoolObj command_pool(m_device, queue_family_index, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
   11618     VkCommandBufferObj bad_command_buffer(m_device, &command_pool);
   11619 
   11620     bad_command_buffer.begin();
   11621     buf_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
   11622     // Set two bits that should both be supported as a bonus positive check
   11623     buf_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT;
   11624     vkCmdPipelineBarrier(bad_command_buffer.handle(), VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
   11625                          VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1, &buf_barrier, 0, nullptr);
   11626     m_errorMonitor->VerifyFound();
   11627 
   11628     if ((queue_props[queue_family_index].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0) {
   11629         printf("             The non-compute queue does not support graphics; skipped.\n");
   11630         return;  // NOTE: this exits the test function!
   11631     }
   11632     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1e600918);
   11633     VkEvent event;
   11634     VkEventCreateInfo event_create_info{};
   11635     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
   11636     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
   11637     vkCmdWaitEvents(bad_command_buffer.handle(), 1, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0,
   11638                     nullptr, 0, nullptr, 0, nullptr);
   11639     m_errorMonitor->VerifyFound();
   11640     bad_command_buffer.end();
   11641 }
   11642 
   11643 class BarrierQueueFamilyTestHelper {
   11644    public:
   11645     BarrierQueueFamilyTestHelper(VkLayerTest &test) : layer_test_(test), image_(test.DeviceObj()) {}
   11646     // Init with queue familes non-null for CONCURRENT sharing mode (which requires them)
   11647     void Init(std::vector<uint32_t> *families) {
   11648         VkDeviceObj *device_obj = layer_test_.DeviceObj();
   11649         image_.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0, families);
   11650         ASSERT_TRUE(image_.initialized());
   11651 
   11652         image_barrier_ =
   11653             image_.image_memory_barrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, image_.Layout(),
   11654                                         image_.Layout(), image_.subresource_range(VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1));
   11655 
   11656         VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
   11657         buffer_.init_as_src_and_dst(*device_obj, 256, mem_prop, families);
   11658         ASSERT_TRUE(buffer_.initialized());
   11659         buffer_barrier_ =
   11660             buffer_.buffer_memory_barrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, 0, VK_WHOLE_SIZE);
   11661     }
   11662 
   11663     void operator()(UNIQUE_VALIDATION_ERROR_CODE img_err, UNIQUE_VALIDATION_ERROR_CODE buf_err, uint32_t src, uint32_t dst,
   11664                     bool positive = false, VkQueue submit = VK_NULL_HANDLE) {
   11665         auto monitor = layer_test_.Monitor();
   11666         monitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, img_err);
   11667         monitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, buf_err);
   11668 
   11669         layer_test_.CommandBuffer()->begin();
   11670         image_barrier_.srcQueueFamilyIndex = src;
   11671         image_barrier_.dstQueueFamilyIndex = dst;
   11672         buffer_barrier_.srcQueueFamilyIndex = src;
   11673         buffer_barrier_.dstQueueFamilyIndex = dst;
   11674         vkCmdPipelineBarrier(layer_test_.CommandBuffer()->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   11675                              VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1, &buffer_barrier_, 1,
   11676                              &image_barrier_);
   11677         layer_test_.CommandBuffer()->end();
   11678 
   11679         VkCommandBuffer cb_handle = layer_test_.CommandBuffer()->handle();
   11680         if (submit != VK_NULL_HANDLE) {
   11681             VkSubmitInfo submit_info = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &cb_handle, 0, nullptr};
   11682             VkResult err = vkQueueSubmit(submit, 1, &submit_info, VK_NULL_HANDLE);
   11683             if (positive) {
   11684                 ASSERT_TRUE(err == VK_SUCCESS);
   11685                 err = vkQueueWaitIdle(submit);
   11686             }
   11687         }
   11688         vkResetCommandBuffer(cb_handle, 0);
   11689 
   11690         if (positive) {
   11691             monitor->VerifyNotFound();
   11692         } else {
   11693             monitor->VerifyFound();
   11694         }
   11695     };
   11696 
   11697    protected:
   11698     VkLayerTest &layer_test_;
   11699     VkImageObj image_;
   11700     VkImageMemoryBarrier image_barrier_;
   11701     vk_testing::Buffer buffer_;
   11702     VkBufferMemoryBarrier buffer_barrier_;
   11703 };
   11704 
   11705 TEST_F(VkLayerTest, InvalidBarrierQueueFamily) {
   11706     TEST_DESCRIPTION("Create and submit barriers with invalid queue families");
   11707     ASSERT_NO_FATAL_FAILURE(Init(nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
   11708 
   11709     // Find queues of two families
   11710     const uint32_t submit_family = m_device->graphics_queue_node_index_;
   11711     const uint32_t invalid = static_cast<uint32_t>(m_device->queue_props.size());
   11712     const uint32_t other_family = submit_family != 0 ? 0 : 1;
   11713     const bool only_one_family = invalid == 1;
   11714 
   11715     if (only_one_family) {
   11716         printf("             Single queue family found -- VK_SHARING_MODE_CONCURRENT testcases skipped.\n");
   11717     } else {
   11718         std::vector<uint32_t> families = {submit_family, other_family};
   11719         BarrierQueueFamilyTestHelper conc_test(*this);
   11720         conc_test.Init(&families);
   11721         // core_validation::barrier_queue_families::kSrcAndDestMustBeIgnore
   11722         conc_test(VALIDATION_ERROR_0a00095e, VALIDATION_ERROR_0180094c, VK_QUEUE_FAMILY_IGNORED, submit_family);
   11723         conc_test(VALIDATION_ERROR_0a00095e, VALIDATION_ERROR_0180094c, submit_family, VK_QUEUE_FAMILY_IGNORED);
   11724         conc_test(VALIDATION_ERROR_0a00095e, VALIDATION_ERROR_0180094c, submit_family, submit_family);
   11725         // true -> positive test
   11726         conc_test(VALIDATION_ERROR_0a00095e, VALIDATION_ERROR_0180094c, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, true);
   11727     }
   11728 
   11729     BarrierQueueFamilyTestHelper excl_test(*this);
   11730     excl_test.Init(nullptr);  // no queue families means *exclusive* sharing mode.
   11731 
   11732     // core_validation::barrier_queue_families::kBothIgnoreOrBothValid
   11733     excl_test(VALIDATION_ERROR_0a000960, VALIDATION_ERROR_01800950, VK_QUEUE_FAMILY_IGNORED, submit_family);
   11734     excl_test(VALIDATION_ERROR_0a000960, VALIDATION_ERROR_01800950, submit_family, VK_QUEUE_FAMILY_IGNORED);
   11735     // true -> positive test
   11736     excl_test(VALIDATION_ERROR_0a000960, VALIDATION_ERROR_01800950, submit_family, submit_family, true);
   11737     excl_test(VALIDATION_ERROR_0a000960, VALIDATION_ERROR_01800950, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, true);
   11738 
   11739     if (only_one_family) {
   11740         printf("             Single queue family found -- VK_SHARING_MODE_EXCLUSIVE submit testcases skipped.\n");
   11741     } else {
   11742         // core_validation::barrier_queue_families::kSubmitQueueMustMatchSrcOrDst
   11743         excl_test(VALIDATION_ERROR_0a00096a, VALIDATION_ERROR_01800958, other_family, other_family, false, m_device->m_queue);
   11744         // true -> positive test
   11745         // Note: when we start tracking resource onwership, we'll need a way to reset the buffers s.t. this doesn't
   11746         //       trigger unexpected errors
   11747         excl_test(VALIDATION_ERROR_0a00096a, VALIDATION_ERROR_01800958, submit_family, other_family, true, m_device->m_queue);
   11748         excl_test(VALIDATION_ERROR_0a00096a, VALIDATION_ERROR_01800958, other_family, submit_family, true, m_device->m_queue);
   11749     }
   11750 }
   11751 
   11752 TEST_F(VkLayerTest, InvalidBarrierQueueFamilyWithMemExt) {
   11753     TEST_DESCRIPTION("Create and submit barriers with invalid queue families when memory extension is enabled ");
   11754     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   11755     // Check for external memory device extensions
   11756     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME)) {
   11757         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
   11758     } else {
   11759         printf("             External memory extension not supported, skipping test\n");
   11760         return;
   11761     }
   11762 
   11763     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
   11764 
   11765     // Find queues of two families
   11766     const uint32_t submit_family = m_device->graphics_queue_node_index_;
   11767     const uint32_t invalid = static_cast<uint32_t>(m_device->queue_props.size());
   11768     const uint32_t other_family = submit_family != 0 ? 0 : 1;
   11769     const bool only_one_family = invalid == 1;
   11770 
   11771     if (only_one_family) {
   11772         printf("             Single queue family found -- VK_SHARING_MODE_CONCURRENT testcases skipped.\n");
   11773     } else {
   11774         std::vector<uint32_t> families = {submit_family, other_family};
   11775         BarrierQueueFamilyTestHelper conc_test(*this);
   11776 
   11777         // core_validation::barrier_queue_families::kSrcOrDstMustBeIgnore
   11778         conc_test.Init(&families);
   11779         conc_test(VALIDATION_ERROR_0a000aca, VALIDATION_ERROR_0180094e, submit_family, submit_family);
   11780         // true -> positive test
   11781         conc_test(VALIDATION_ERROR_0a000aca, VALIDATION_ERROR_0180094e, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, true);
   11782         conc_test(VALIDATION_ERROR_0a000aca, VALIDATION_ERROR_0180094e, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_EXTERNAL_KHR,
   11783                   true);
   11784         conc_test(VALIDATION_ERROR_0a000aca, VALIDATION_ERROR_0180094e, VK_QUEUE_FAMILY_EXTERNAL_KHR, VK_QUEUE_FAMILY_IGNORED,
   11785                   true);
   11786 
   11787         // core_validation::barrier_queue_families::kSpecialOrIgnoreOnly
   11788         conc_test(VALIDATION_ERROR_0a000dcc, VALIDATION_ERROR_01800dc6, submit_family, VK_QUEUE_FAMILY_IGNORED);
   11789         conc_test(VALIDATION_ERROR_0a000dcc, VALIDATION_ERROR_01800dc6, VK_QUEUE_FAMILY_IGNORED, submit_family);
   11790         // This is to flag the errors that would be considered only "unexpected" in the parallel case above
   11791         // true -> positive test
   11792         conc_test(VALIDATION_ERROR_0a000dcc, VALIDATION_ERROR_01800dc6, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_EXTERNAL_KHR,
   11793                   true);
   11794         conc_test(VALIDATION_ERROR_0a000dcc, VALIDATION_ERROR_01800dc6, VK_QUEUE_FAMILY_EXTERNAL_KHR, VK_QUEUE_FAMILY_IGNORED,
   11795                   true);
   11796     }
   11797 
   11798     BarrierQueueFamilyTestHelper excl_test(*this);
   11799     excl_test.Init(nullptr);  // no queue families means *exclusive* sharing mode.
   11800 
   11801     // core_validation::barrier_queue_families::kSrcIgnoreRequiresDstIgnore
   11802     excl_test(VALIDATION_ERROR_0a000962, VALIDATION_ERROR_01800952, VK_QUEUE_FAMILY_IGNORED, submit_family);
   11803     excl_test(VALIDATION_ERROR_0a000962, VALIDATION_ERROR_01800952, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_EXTERNAL_KHR);
   11804     // true -> positive test
   11805     excl_test(VALIDATION_ERROR_0a000962, VALIDATION_ERROR_01800952, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, true);
   11806 
   11807     // core_validation::barrier_queue_families::kDstValidOrSpecialIfNotIgnore
   11808     excl_test(VALIDATION_ERROR_0a000dd0, VALIDATION_ERROR_01800dca, submit_family, invalid);
   11809     // true -> positive test
   11810     excl_test(VALIDATION_ERROR_0a000dd0, VALIDATION_ERROR_01800dca, submit_family, submit_family, true);
   11811     excl_test(VALIDATION_ERROR_0a000dd0, VALIDATION_ERROR_01800dca, submit_family, VK_QUEUE_FAMILY_IGNORED, true);
   11812     excl_test(VALIDATION_ERROR_0a000dd0, VALIDATION_ERROR_01800dca, submit_family, VK_QUEUE_FAMILY_EXTERNAL_KHR, true);
   11813 
   11814     // core_validation::barrier_queue_families::kSrcValidOrSpecialIfNotIgnore
   11815     excl_test(VALIDATION_ERROR_0a000dce, VALIDATION_ERROR_01800dc8, invalid, submit_family);
   11816     // true -> positive test
   11817     excl_test(VALIDATION_ERROR_0a000dce, VALIDATION_ERROR_01800dc8, submit_family, submit_family, true);
   11818     excl_test(VALIDATION_ERROR_0a000dce, VALIDATION_ERROR_01800dc8, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, true);
   11819     excl_test(VALIDATION_ERROR_0a000dce, VALIDATION_ERROR_01800dc8, VK_QUEUE_FAMILY_EXTERNAL_KHR, submit_family, true);
   11820 }
   11821 
   11822 TEST_F(VkLayerTest, ImageBarrierWithBadRange) {
   11823     TEST_DESCRIPTION("VkImageMemoryBarrier with an invalid subresourceRange");
   11824 
   11825     ASSERT_NO_FATAL_FAILURE(Init());
   11826     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   11827 
   11828     VkImageObj image(m_device);
   11829     image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
   11830     ASSERT_TRUE(image.create_info().arrayLayers == 1);
   11831     ASSERT_TRUE(image.initialized());
   11832 
   11833     VkImageMemoryBarrier img_barrier_template = {};
   11834     img_barrier_template.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
   11835     img_barrier_template.pNext = NULL;
   11836     img_barrier_template.srcAccessMask = 0;
   11837     img_barrier_template.dstAccessMask = 0;
   11838     img_barrier_template.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   11839     img_barrier_template.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   11840     img_barrier_template.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   11841     img_barrier_template.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   11842     img_barrier_template.image = image.handle();
   11843     // subresourceRange to be set later for the for the purposes of this test
   11844     img_barrier_template.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   11845     img_barrier_template.subresourceRange.baseArrayLayer = 0;
   11846     img_barrier_template.subresourceRange.baseMipLevel = 0;
   11847     img_barrier_template.subresourceRange.layerCount = 0;
   11848     img_barrier_template.subresourceRange.levelCount = 0;
   11849 
   11850     m_commandBuffer->begin();
   11851 
   11852     // Nested scope here confuses clang-format, somehow
   11853     // clang-format off
   11854 
   11855     // try for vkCmdPipelineBarrier
   11856     {
   11857         // Try baseMipLevel >= image.mipLevels with VK_REMAINING_MIP_LEVELS
   11858         {
   11859             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000b9c);
   11860             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, VK_REMAINING_MIP_LEVELS, 0, 1};
   11861             VkImageMemoryBarrier img_barrier = img_barrier_template;
   11862             img_barrier.subresourceRange = range;
   11863             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
   11864                                  nullptr, 0, nullptr, 1, &img_barrier);
   11865             m_errorMonitor->VerifyFound();
   11866         }
   11867 
   11868         // Try baseMipLevel >= image.mipLevels without VK_REMAINING_MIP_LEVELS
   11869         {
   11870             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000b9c);
   11871             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000b9e);
   11872             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 0, 1};
   11873             VkImageMemoryBarrier img_barrier = img_barrier_template;
   11874             img_barrier.subresourceRange = range;
   11875             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
   11876                                  nullptr, 0, nullptr, 1, &img_barrier);
   11877             m_errorMonitor->VerifyFound();
   11878         }
   11879 
   11880         // Try levelCount = 0
   11881         {
   11882             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000b9e);
   11883             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 0, 1};
   11884             VkImageMemoryBarrier img_barrier = img_barrier_template;
   11885             img_barrier.subresourceRange = range;
   11886             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
   11887                                  nullptr, 0, nullptr, 1, &img_barrier);
   11888             m_errorMonitor->VerifyFound();
   11889         }
   11890 
   11891         // Try baseMipLevel + levelCount > image.mipLevels
   11892         {
   11893             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000b9e);
   11894             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 2, 0, 1};
   11895             VkImageMemoryBarrier img_barrier = img_barrier_template;
   11896             img_barrier.subresourceRange = range;
   11897             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
   11898                                  nullptr, 0, nullptr, 1, &img_barrier);
   11899             m_errorMonitor->VerifyFound();
   11900         }
   11901 
   11902         // Try baseArrayLayer >= image.arrayLayers with VK_REMAINING_ARRAY_LAYERS
   11903         {
   11904             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000ba0);
   11905             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, VK_REMAINING_ARRAY_LAYERS};
   11906             VkImageMemoryBarrier img_barrier = img_barrier_template;
   11907             img_barrier.subresourceRange = range;
   11908             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
   11909                                  nullptr, 0, nullptr, 1, &img_barrier);
   11910             m_errorMonitor->VerifyFound();
   11911         }
   11912 
   11913         // Try baseArrayLayer >= image.arrayLayers without VK_REMAINING_ARRAY_LAYERS
   11914         {
   11915             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000ba0);
   11916             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000ba2);
   11917             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, 1};
   11918             VkImageMemoryBarrier img_barrier = img_barrier_template;
   11919             img_barrier.subresourceRange = range;
   11920             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
   11921                                  nullptr, 0, nullptr, 1, &img_barrier);
   11922             m_errorMonitor->VerifyFound();
   11923         }
   11924 
   11925         // Try layerCount = 0
   11926         {
   11927             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000ba2);
   11928             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 0};
   11929             VkImageMemoryBarrier img_barrier = img_barrier_template;
   11930             img_barrier.subresourceRange = range;
   11931             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
   11932                                  nullptr, 0, nullptr, 1, &img_barrier);
   11933             m_errorMonitor->VerifyFound();
   11934         }
   11935 
   11936         // Try baseArrayLayer + layerCount > image.arrayLayers
   11937         {
   11938             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000ba2);
   11939             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 2};
   11940             VkImageMemoryBarrier img_barrier = img_barrier_template;
   11941             img_barrier.subresourceRange = range;
   11942             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
   11943                                  nullptr, 0, nullptr, 1, &img_barrier);
   11944             m_errorMonitor->VerifyFound();
   11945         }
   11946     }
   11947 
   11948     // try for vkCmdWaitEvents
   11949     {
   11950         VkEvent event;
   11951         VkEventCreateInfo eci{VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, NULL, 0};
   11952         VkResult err = vkCreateEvent(m_device->handle(), &eci, nullptr, &event);
   11953         ASSERT_VK_SUCCESS(err);
   11954 
   11955         // Try baseMipLevel >= image.mipLevels with VK_REMAINING_MIP_LEVELS
   11956         {
   11957             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000b9c);
   11958             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, VK_REMAINING_MIP_LEVELS, 0, 1};
   11959             VkImageMemoryBarrier img_barrier = img_barrier_template;
   11960             img_barrier.subresourceRange = range;
   11961             vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
   11962                             VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
   11963             m_errorMonitor->VerifyFound();
   11964         }
   11965 
   11966         // Try baseMipLevel >= image.mipLevels without VK_REMAINING_MIP_LEVELS
   11967         {
   11968             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000b9c);
   11969             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000b9e);
   11970             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 0, 1};
   11971             VkImageMemoryBarrier img_barrier = img_barrier_template;
   11972             img_barrier.subresourceRange = range;
   11973             vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
   11974                             VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
   11975             m_errorMonitor->VerifyFound();
   11976         }
   11977 
   11978         // Try levelCount = 0
   11979         {
   11980             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000b9e);
   11981             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 0, 1};
   11982             VkImageMemoryBarrier img_barrier = img_barrier_template;
   11983             img_barrier.subresourceRange = range;
   11984             vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
   11985                             VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
   11986             m_errorMonitor->VerifyFound();
   11987         }
   11988 
   11989         // Try baseMipLevel + levelCount > image.mipLevels
   11990         {
   11991             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000b9e);
   11992             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 2, 0, 1};
   11993             VkImageMemoryBarrier img_barrier = img_barrier_template;
   11994             img_barrier.subresourceRange = range;
   11995             vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
   11996                             VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
   11997             m_errorMonitor->VerifyFound();
   11998         }
   11999 
   12000         // Try baseArrayLayer >= image.arrayLayers with VK_REMAINING_ARRAY_LAYERS
   12001         {
   12002             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000ba0);
   12003             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, VK_REMAINING_ARRAY_LAYERS};
   12004             VkImageMemoryBarrier img_barrier = img_barrier_template;
   12005             img_barrier.subresourceRange = range;
   12006             vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
   12007                             VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
   12008             m_errorMonitor->VerifyFound();
   12009         }
   12010 
   12011         // Try baseArrayLayer >= image.arrayLayers without VK_REMAINING_ARRAY_LAYERS
   12012         {
   12013             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000ba0);
   12014             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000ba2);
   12015             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, 1};
   12016             VkImageMemoryBarrier img_barrier = img_barrier_template;
   12017             img_barrier.subresourceRange = range;
   12018             vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
   12019                             VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
   12020             m_errorMonitor->VerifyFound();
   12021         }
   12022 
   12023         // Try layerCount = 0
   12024         {
   12025             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000ba2);
   12026             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 0};
   12027             VkImageMemoryBarrier img_barrier = img_barrier_template;
   12028             img_barrier.subresourceRange = range;
   12029             vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
   12030                             VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
   12031             m_errorMonitor->VerifyFound();
   12032         }
   12033 
   12034         // Try baseArrayLayer + layerCount > image.arrayLayers
   12035         {
   12036             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000ba2);
   12037             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 2};
   12038             VkImageMemoryBarrier img_barrier = img_barrier_template;
   12039             img_barrier.subresourceRange = range;
   12040             vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
   12041                             VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
   12042             m_errorMonitor->VerifyFound();
   12043         }
   12044 
   12045         vkDestroyEvent(m_device->handle(), event, nullptr);
   12046     }
   12047 // clang-format on
   12048 }
   12049 
   12050 TEST_F(VkLayerTest, ValidationCacheTestBadMerge) {
   12051     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   12052     if (DeviceExtensionSupported(gpu(), "VK_LAYER_LUNARG_core_validation", VK_EXT_VALIDATION_CACHE_EXTENSION_NAME)) {
   12053         m_device_extension_names.push_back(VK_EXT_VALIDATION_CACHE_EXTENSION_NAME);
   12054     } else {
   12055         printf("             %s not supported, skipping test\n", VK_EXT_VALIDATION_CACHE_EXTENSION_NAME);
   12056         return;
   12057     }
   12058     ASSERT_NO_FATAL_FAILURE(InitState());
   12059 
   12060     // Load extension functions
   12061     auto fpCreateValidationCache =
   12062         (PFN_vkCreateValidationCacheEXT)vkGetDeviceProcAddr(m_device->device(), "vkCreateValidationCacheEXT");
   12063     auto fpDestroyValidationCache =
   12064         (PFN_vkDestroyValidationCacheEXT)vkGetDeviceProcAddr(m_device->device(), "vkDestroyValidationCacheEXT");
   12065     auto fpMergeValidationCaches =
   12066         (PFN_vkMergeValidationCachesEXT)vkGetDeviceProcAddr(m_device->device(), "vkMergeValidationCachesEXT");
   12067     if (!fpCreateValidationCache || !fpDestroyValidationCache || !fpMergeValidationCaches) {
   12068         printf("             Failed to load function pointers for %s\n", VK_EXT_VALIDATION_CACHE_EXTENSION_NAME);
   12069         return;
   12070     }
   12071 
   12072     VkValidationCacheCreateInfoEXT validationCacheCreateInfo;
   12073     validationCacheCreateInfo.sType = VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT;
   12074     validationCacheCreateInfo.pNext = NULL;
   12075     validationCacheCreateInfo.initialDataSize = 0;
   12076     validationCacheCreateInfo.pInitialData = NULL;
   12077     validationCacheCreateInfo.flags = 0;
   12078     VkValidationCacheEXT validationCache = VK_NULL_HANDLE;
   12079     VkResult res = fpCreateValidationCache(m_device->device(), &validationCacheCreateInfo, nullptr, &validationCache);
   12080     ASSERT_VK_SUCCESS(res);
   12081 
   12082     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_3e600c00);
   12083     res = fpMergeValidationCaches(m_device->device(), validationCache, 1, &validationCache);
   12084     m_errorMonitor->VerifyFound();
   12085 
   12086     fpDestroyValidationCache(m_device->device(), validationCache, nullptr);
   12087 }
   12088 
   12089 TEST_F(VkPositiveLayerTest, LayoutFromPresentWithoutAccessMemoryRead) {
   12090     // Transition an image away from PRESENT_SRC_KHR without ACCESS_MEMORY_READ
   12091     // in srcAccessMask.
   12092 
   12093     // The required behavior here was a bit unclear in earlier versions of the
   12094     // spec, but there is no memory dependency required here, so this should
   12095     // work without warnings.
   12096 
   12097     m_errorMonitor->ExpectSuccess();
   12098     ASSERT_NO_FATAL_FAILURE(Init());
   12099     VkImageObj image(m_device);
   12100     image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT),
   12101                VK_IMAGE_TILING_OPTIMAL, 0);
   12102     ASSERT_TRUE(image.initialized());
   12103 
   12104     VkImageMemoryBarrier barrier = {};
   12105     VkImageSubresourceRange range;
   12106     barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
   12107     barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
   12108     barrier.dstAccessMask = 0;
   12109     barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   12110     barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
   12111     barrier.image = image.handle();
   12112     range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   12113     range.baseMipLevel = 0;
   12114     range.levelCount = 1;
   12115     range.baseArrayLayer = 0;
   12116     range.layerCount = 1;
   12117     barrier.subresourceRange = range;
   12118     VkCommandBufferObj cmdbuf(m_device, m_commandPool);
   12119     cmdbuf.begin();
   12120     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
   12121                            &barrier);
   12122     barrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
   12123     barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   12124     barrier.srcAccessMask = 0;
   12125     barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
   12126     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
   12127                            &barrier);
   12128 
   12129     m_errorMonitor->VerifyNotFound();
   12130 }
   12131 
   12132 TEST_F(VkLayerTest, IdxBufferAlignmentError) {
   12133     // Bind a BeginRenderPass within an active RenderPass
   12134     ASSERT_NO_FATAL_FAILURE(Init());
   12135     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   12136 
   12137     uint32_t const indices[] = {0};
   12138     VkBufferCreateInfo buf_info = {};
   12139     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   12140     buf_info.size = 1024;
   12141     buf_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
   12142     buf_info.queueFamilyIndexCount = 1;
   12143     buf_info.pQueueFamilyIndices = indices;
   12144 
   12145     VkBuffer buffer;
   12146     VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
   12147     ASSERT_VK_SUCCESS(err);
   12148 
   12149     VkMemoryRequirements requirements;
   12150     vkGetBufferMemoryRequirements(m_device->device(), buffer, &requirements);
   12151 
   12152     VkMemoryAllocateInfo alloc_info{};
   12153     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   12154     alloc_info.pNext = NULL;
   12155     alloc_info.memoryTypeIndex = 0;
   12156     alloc_info.allocationSize = requirements.size;
   12157     bool pass = m_device->phy().set_memory_type(requirements.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
   12158     ASSERT_TRUE(pass);
   12159 
   12160     VkDeviceMemory memory;
   12161     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &memory);
   12162     ASSERT_VK_SUCCESS(err);
   12163 
   12164     err = vkBindBufferMemory(m_device->device(), buffer, memory, 0);
   12165     ASSERT_VK_SUCCESS(err);
   12166 
   12167     m_commandBuffer->begin();
   12168     ASSERT_VK_SUCCESS(err);
   12169 
   12170     // vkCmdBindPipeline(m_commandBuffer->handle(),
   12171     // VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   12172     // Should error before calling to driver so don't care about actual data
   12173     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdBindIndexBuffer() offset (0x7) does not fall on ");
   12174     vkCmdBindIndexBuffer(m_commandBuffer->handle(), buffer, 7, VK_INDEX_TYPE_UINT16);
   12175     m_errorMonitor->VerifyFound();
   12176 
   12177     vkFreeMemory(m_device->device(), memory, NULL);
   12178     vkDestroyBuffer(m_device->device(), buffer, NULL);
   12179 }
   12180 
   12181 TEST_F(VkLayerTest, InvalidQueueFamilyIndex) {
   12182     // Create an out-of-range queueFamilyIndex
   12183     ASSERT_NO_FATAL_FAILURE(Init());
   12184     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   12185     VkBufferCreateInfo buffCI = {};
   12186     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   12187     buffCI.size = 1024;
   12188     buffCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
   12189     buffCI.queueFamilyIndexCount = 2;
   12190     // Introduce failure by specifying invalid queue_family_index
   12191     uint32_t qfi[2];
   12192     qfi[0] = 777;
   12193     qfi[1] = 0;
   12194 
   12195     buffCI.pQueueFamilyIndices = qfi;
   12196     buffCI.sharingMode = VK_SHARING_MODE_CONCURRENT;  // qfi only matters in CONCURRENT mode
   12197 
   12198     VkBuffer ib;
   12199     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   12200                                          "vkCreateBuffer: pCreateInfo->pQueueFamilyIndices[0] (= 777) is not one of the queue "
   12201                                          "families given via VkDeviceQueueCreateInfo structures when the device was created.");
   12202     vkCreateBuffer(m_device->device(), &buffCI, NULL, &ib);
   12203     m_errorMonitor->VerifyFound();
   12204 
   12205     if (m_device->queue_props.size() > 2) {
   12206         VkBuffer ib2;
   12207         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "which was not created allowing concurrent");
   12208 
   12209         // Create buffer shared to queue families 1 and 2, but submitted on queue family 0
   12210         buffCI.queueFamilyIndexCount = 2;
   12211         qfi[0] = 1;
   12212         qfi[1] = 2;
   12213         vkCreateBuffer(m_device->device(), &buffCI, NULL, &ib2);
   12214         VkDeviceMemory mem;
   12215         VkMemoryRequirements mem_reqs;
   12216         vkGetBufferMemoryRequirements(m_device->device(), ib2, &mem_reqs);
   12217 
   12218         VkMemoryAllocateInfo alloc_info = {};
   12219         alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   12220         alloc_info.allocationSize = 1024;
   12221         bool pass = false;
   12222         pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
   12223         if (!pass) {
   12224             vkDestroyBuffer(m_device->device(), ib2, NULL);
   12225             return;
   12226         }
   12227         vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
   12228         vkBindBufferMemory(m_device->device(), ib2, mem, 0);
   12229 
   12230         m_commandBuffer->begin();
   12231         vkCmdFillBuffer(m_commandBuffer->handle(), ib2, 0, 16, 5);
   12232         m_commandBuffer->end();
   12233         m_commandBuffer->QueueCommandBuffer(false);
   12234         m_errorMonitor->VerifyFound();
   12235         vkDestroyBuffer(m_device->device(), ib2, NULL);
   12236         vkFreeMemory(m_device->device(), mem, NULL);
   12237     }
   12238 }
   12239 
   12240 TEST_F(VkLayerTest, ExecuteCommandsPrimaryCB) {
   12241     TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a primary command buffer (should only be secondary)");
   12242 
   12243     ASSERT_NO_FATAL_FAILURE(Init());
   12244     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   12245 
   12246     // An empty primary command buffer
   12247     VkCommandBufferObj cb(m_device, m_commandPool);
   12248     cb.begin();
   12249     cb.end();
   12250 
   12251     m_commandBuffer->begin();
   12252     vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
   12253     VkCommandBuffer handle = cb.handle();
   12254 
   12255     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdExecuteCommands() called w/ Primary Cmd Buffer ");
   12256     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &handle);
   12257     m_errorMonitor->VerifyFound();
   12258 
   12259     m_errorMonitor->SetUnexpectedError("All elements of pCommandBuffers must not be in the pending state");
   12260 }
   12261 
   12262 TEST_F(VkLayerTest, DSUsageBitsErrors) {
   12263     TEST_DESCRIPTION("Attempt to update descriptor sets for images and buffers that do not have correct usage bits sets.");
   12264 
   12265     ASSERT_NO_FATAL_FAILURE(Init());
   12266     std::array<VkDescriptorPoolSize, VK_DESCRIPTOR_TYPE_RANGE_SIZE> ds_type_count;
   12267     for (uint32_t i = 0; i < ds_type_count.size(); ++i) {
   12268         ds_type_count[i].type = VkDescriptorType(i);
   12269         ds_type_count[i].descriptorCount = 1;
   12270     }
   12271 
   12272     vk_testing::DescriptorPool ds_pool;
   12273     ds_pool.init(*m_device, vk_testing::DescriptorPool::create_info(0, VK_DESCRIPTOR_TYPE_RANGE_SIZE, ds_type_count));
   12274     ASSERT_TRUE(ds_pool.initialized());
   12275 
   12276     std::vector<VkDescriptorSetLayoutBinding> dsl_bindings(1);
   12277     dsl_bindings[0].binding = 0;
   12278     dsl_bindings[0].descriptorType = VkDescriptorType(0);
   12279     dsl_bindings[0].descriptorCount = 1;
   12280     dsl_bindings[0].stageFlags = VK_SHADER_STAGE_ALL;
   12281     dsl_bindings[0].pImmutableSamplers = NULL;
   12282 
   12283     // Create arrays of layout and descriptor objects
   12284     using UpDescriptorSet = std::unique_ptr<vk_testing::DescriptorSet>;
   12285     std::vector<UpDescriptorSet> descriptor_sets;
   12286     using UpDescriptorSetLayout = std::unique_ptr<VkDescriptorSetLayoutObj>;
   12287     std::vector<UpDescriptorSetLayout> ds_layouts;
   12288     descriptor_sets.reserve(VK_DESCRIPTOR_TYPE_RANGE_SIZE);
   12289     ds_layouts.reserve(VK_DESCRIPTOR_TYPE_RANGE_SIZE);
   12290     for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
   12291         dsl_bindings[0].descriptorType = VkDescriptorType(i);
   12292         ds_layouts.push_back(UpDescriptorSetLayout(new VkDescriptorSetLayoutObj(m_device, dsl_bindings)));
   12293         descriptor_sets.push_back(UpDescriptorSet(ds_pool.alloc_sets(*m_device, *ds_layouts.back())));
   12294         ASSERT_TRUE(descriptor_sets.back()->initialized());
   12295     }
   12296 
   12297     // Create a buffer & bufferView to be used for invalid updates
   12298     const VkDeviceSize buffer_size = 256;
   12299     uint8_t data[buffer_size];
   12300     VkConstantBufferObj buffer(m_device, buffer_size, data, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT);
   12301     VkConstantBufferObj storage_texel_buffer(m_device, buffer_size, data, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
   12302     ASSERT_TRUE(buffer.initialized() && storage_texel_buffer.initialized());
   12303 
   12304     auto buff_view_ci = vk_testing::BufferView::createInfo(buffer.handle(), VK_FORMAT_R8_UNORM);
   12305     vk_testing::BufferView buffer_view_obj, storage_texel_buffer_view_obj;
   12306     buffer_view_obj.init(*m_device, buff_view_ci);
   12307     buff_view_ci.buffer = storage_texel_buffer.handle();
   12308     storage_texel_buffer_view_obj.init(*m_device, buff_view_ci);
   12309     ASSERT_TRUE(buffer_view_obj.initialized() && storage_texel_buffer_view_obj.initialized());
   12310     VkBufferView buffer_view = buffer_view_obj.handle();
   12311     VkBufferView storage_texel_buffer_view = storage_texel_buffer_view_obj.handle();
   12312 
   12313     // Create an image to be used for invalid updates
   12314     VkImageObj image_obj(m_device);
   12315     image_obj.InitNoLayout(64, 64, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   12316     ASSERT_TRUE(image_obj.initialized());
   12317     VkImageView image_view = image_obj.targetView(VK_FORMAT_R8G8B8A8_UNORM);
   12318 
   12319     VkDescriptorBufferInfo buff_info = {};
   12320     buff_info.buffer = buffer.handle();
   12321     VkDescriptorImageInfo img_info = {};
   12322     img_info.imageView = image_view;
   12323     VkWriteDescriptorSet descriptor_write = {};
   12324     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   12325     descriptor_write.dstBinding = 0;
   12326     descriptor_write.descriptorCount = 1;
   12327     descriptor_write.pTexelBufferView = &buffer_view;
   12328     descriptor_write.pBufferInfo = &buff_info;
   12329     descriptor_write.pImageInfo = &img_info;
   12330 
   12331     // These error messages align with VkDescriptorType struct
   12332     UNIQUE_VALIDATION_ERROR_CODE error_codes[] = {
   12333         VALIDATION_ERROR_15c0028c,  // placeholder, no error for SAMPLER descriptor
   12334         VALIDATION_ERROR_15c0028c,  // COMBINED_IMAGE_SAMPLER
   12335         VALIDATION_ERROR_15c0028c,  // SAMPLED_IMAGE
   12336         VALIDATION_ERROR_15c0028c,  // STORAGE_IMAGE
   12337         VALIDATION_ERROR_15c0029c,  // UNIFORM_TEXEL_BUFFER
   12338         VALIDATION_ERROR_15c0029e,  // STORAGE_TEXEL_BUFFER
   12339         VALIDATION_ERROR_15c00292,  // UNIFORM_BUFFER
   12340         VALIDATION_ERROR_15c00296,  // STORAGE_BUFFER
   12341         VALIDATION_ERROR_15c00292,  // UNIFORM_BUFFER_DYNAMIC
   12342         VALIDATION_ERROR_15c00296,  // STORAGE_BUFFER_DYNAMIC
   12343         VALIDATION_ERROR_15c0028c   // INPUT_ATTACHMENT
   12344     };
   12345     // Start loop at 1 as SAMPLER desc type has no usage bit error
   12346     for (uint32_t i = 1; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
   12347         if (VkDescriptorType(i) == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) {
   12348             // Now check for UNIFORM_TEXEL_BUFFER using storage_texel_buffer_view
   12349             descriptor_write.pTexelBufferView = &storage_texel_buffer_view;
   12350         }
   12351         descriptor_write.descriptorType = VkDescriptorType(i);
   12352         descriptor_write.dstSet = descriptor_sets[i]->handle();
   12353         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error_codes[i]);
   12354 
   12355         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   12356 
   12357         m_errorMonitor->VerifyFound();
   12358         if (VkDescriptorType(i) == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) {
   12359             descriptor_write.pTexelBufferView = &buffer_view;
   12360         }
   12361     }
   12362 }
   12363 
   12364 TEST_F(VkLayerTest, DSBufferInfoErrors) {
   12365     TEST_DESCRIPTION(
   12366         "Attempt to update buffer descriptor set that has incorrect parameters in VkDescriptorBufferInfo struct. This includes:\n"
   12367         "1. offset value greater than or equal to buffer size\n"
   12368         "2. range value of 0\n"
   12369         "3. range value greater than buffer (size - offset)");
   12370     VkResult err;
   12371 
   12372     ASSERT_NO_FATAL_FAILURE(Init());
   12373     OneOffDescriptorSet ds(m_device, {
   12374                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
   12375                                      });
   12376 
   12377     // Create a buffer to be used for invalid updates
   12378     VkBufferCreateInfo buff_ci = {};
   12379     buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   12380     buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
   12381     buff_ci.size = m_device->props.limits.minUniformBufferOffsetAlignment;
   12382     buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   12383     VkBuffer buffer;
   12384     err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
   12385     ASSERT_VK_SUCCESS(err);
   12386 
   12387     // Have to bind memory to buffer before descriptor update
   12388     VkMemoryRequirements mem_reqs;
   12389     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
   12390     VkMemoryAllocateInfo mem_alloc = {};
   12391     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   12392     mem_alloc.pNext = NULL;
   12393     mem_alloc.allocationSize = mem_reqs.size;
   12394     mem_alloc.memoryTypeIndex = 0;
   12395     bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
   12396     if (!pass) {
   12397         vkDestroyBuffer(m_device->device(), buffer, NULL);
   12398         return;
   12399     }
   12400 
   12401     VkDeviceMemory mem;
   12402     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
   12403     ASSERT_VK_SUCCESS(err);
   12404     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
   12405     ASSERT_VK_SUCCESS(err);
   12406 
   12407     VkDescriptorBufferInfo buff_info = {};
   12408     buff_info.buffer = buffer;
   12409     // Cause error due to offset out of range
   12410     buff_info.offset = buff_ci.size;
   12411     buff_info.range = VK_WHOLE_SIZE;
   12412     VkWriteDescriptorSet descriptor_write = {};
   12413     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   12414     descriptor_write.dstBinding = 0;
   12415     descriptor_write.descriptorCount = 1;
   12416     descriptor_write.pTexelBufferView = nullptr;
   12417     descriptor_write.pBufferInfo = &buff_info;
   12418     descriptor_write.pImageInfo = nullptr;
   12419 
   12420     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   12421     descriptor_write.dstSet = ds.set_;
   12422     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_044002a8);
   12423 
   12424     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   12425 
   12426     m_errorMonitor->VerifyFound();
   12427     // Now cause error due to range of 0
   12428     buff_info.offset = 0;
   12429     buff_info.range = 0;
   12430     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_044002aa);
   12431 
   12432     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   12433 
   12434     m_errorMonitor->VerifyFound();
   12435     // Now cause error due to range exceeding buffer size - offset
   12436     buff_info.offset = 0;
   12437     buff_info.range = buff_ci.size + 1;
   12438     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_044002ac);
   12439 
   12440     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   12441 
   12442     m_errorMonitor->VerifyFound();
   12443     vkFreeMemory(m_device->device(), mem, NULL);
   12444     vkDestroyBuffer(m_device->device(), buffer, NULL);
   12445 }
   12446 
   12447 TEST_F(VkLayerTest, DSBufferLimitErrors) {
   12448     TEST_DESCRIPTION(
   12449         "Attempt to update buffer descriptor set that has VkDescriptorBufferInfo values that violate device limits.\n"
   12450         "Test cases include:\n"
   12451         "1. range of uniform buffer update exceeds maxUniformBufferRange\n"
   12452         "2. offset of uniform buffer update is not multiple of minUniformBufferOffsetAlignment\n"
   12453         "3. range of storage buffer update exceeds maxStorageBufferRange\n"
   12454         "4. offset of storage buffer update is not multiple of minStorageBufferOffsetAlignment");
   12455     VkResult err;
   12456 
   12457     ASSERT_NO_FATAL_FAILURE(Init());
   12458 
   12459     struct TestCase {
   12460         VkDescriptorType descriptor_type;
   12461         VkBufferUsageFlagBits buffer_usage;
   12462         VkDeviceSize max_range;
   12463         UNIQUE_VALIDATION_ERROR_CODE max_range_vu;
   12464         VkDeviceSize min_align;
   12465         UNIQUE_VALIDATION_ERROR_CODE min_align_vu;
   12466     };
   12467 
   12468     for (const auto &test_case : {
   12469              TestCase({VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
   12470                        m_device->props.limits.maxUniformBufferRange, VALIDATION_ERROR_15c00298,
   12471                        m_device->props.limits.minUniformBufferOffsetAlignment, VALIDATION_ERROR_15c0028e}),
   12472              TestCase({VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
   12473                        m_device->props.limits.maxStorageBufferRange, VALIDATION_ERROR_15c0029a,
   12474                        m_device->props.limits.minStorageBufferOffsetAlignment, VALIDATION_ERROR_15c00290}),
   12475          }) {
   12476         // Create layout with single buffer
   12477         OneOffDescriptorSet ds(m_device, {
   12478                                              {0, test_case.descriptor_type, 1, VK_SHADER_STAGE_ALL, nullptr},
   12479                                          });
   12480 
   12481         // Create a buffer to be used for invalid updates
   12482         VkBufferCreateInfo bci = {};
   12483         bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   12484         bci.usage = test_case.buffer_usage;
   12485         bci.size = test_case.max_range + test_case.min_align;  // Make buffer bigger than range limit
   12486         bci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   12487         VkBuffer buffer;
   12488         err = vkCreateBuffer(m_device->device(), &bci, NULL, &buffer);
   12489         ASSERT_VK_SUCCESS(err);
   12490 
   12491         // Have to bind memory to buffer before descriptor update
   12492         VkMemoryRequirements mem_reqs;
   12493         vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
   12494 
   12495         VkMemoryAllocateInfo mem_alloc = {};
   12496         mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   12497         mem_alloc.pNext = NULL;
   12498         mem_alloc.allocationSize = mem_reqs.size;
   12499         bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
   12500         if (!pass) {
   12501             printf("             Failed to allocate memory in DSBufferLimitErrors; skipped.\n");
   12502             vkDestroyBuffer(m_device->device(), buffer, NULL);
   12503             continue;
   12504         }
   12505 
   12506         VkDeviceMemory mem;
   12507         err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
   12508         if (VK_SUCCESS != err) {
   12509             printf("             Failed to allocate memory in DSBufferLimitErrors; skipped.\n");
   12510             vkDestroyBuffer(m_device->device(), buffer, NULL);
   12511             continue;
   12512         }
   12513         err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
   12514         ASSERT_VK_SUCCESS(err);
   12515 
   12516         VkDescriptorBufferInfo buff_info = {};
   12517         buff_info.buffer = buffer;
   12518         VkWriteDescriptorSet descriptor_write = {};
   12519         descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   12520         descriptor_write.dstBinding = 0;
   12521         descriptor_write.descriptorCount = 1;
   12522         descriptor_write.pTexelBufferView = nullptr;
   12523         descriptor_write.pBufferInfo = &buff_info;
   12524         descriptor_write.pImageInfo = nullptr;
   12525         descriptor_write.descriptorType = test_case.descriptor_type;
   12526         descriptor_write.dstSet = ds.set_;
   12527 
   12528         // Exceed range limit
   12529         if (test_case.max_range != UINT32_MAX) {
   12530             buff_info.range = test_case.max_range + 1;
   12531             buff_info.offset = 0;
   12532             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.max_range_vu);
   12533             vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   12534             m_errorMonitor->VerifyFound();
   12535         }
   12536 
   12537         // Reduce size of range to acceptable limit and cause offset error
   12538         if (test_case.min_align > 1) {
   12539             buff_info.range = test_case.max_range;
   12540             buff_info.offset = test_case.min_align - 1;
   12541             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.min_align_vu);
   12542             vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   12543             m_errorMonitor->VerifyFound();
   12544         }
   12545 
   12546         // Cleanup
   12547         vkFreeMemory(m_device->device(), mem, NULL);
   12548         vkDestroyBuffer(m_device->device(), buffer, NULL);
   12549     }
   12550 }
   12551 
   12552 TEST_F(VkLayerTest, DSAspectBitsErrors) {
   12553     // TODO : Initially only catching case where DEPTH & STENCIL aspect bits
   12554     //  are set, but could expand this test to hit more cases.
   12555     TEST_DESCRIPTION("Attempt to update descriptor sets for images that do not have correct aspect bits sets.");
   12556     VkResult err;
   12557 
   12558     ASSERT_NO_FATAL_FAILURE(Init());
   12559     auto depth_format = FindSupportedDepthStencilFormat(gpu());
   12560     if (!depth_format) {
   12561         printf("             No Depth + Stencil format found. Skipped.\n");
   12562         return;
   12563     }
   12564 
   12565     OneOffDescriptorSet ds(m_device, {
   12566                                          {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_ALL, nullptr},
   12567                                      });
   12568 
   12569     // Create an image to be used for invalid updates
   12570     VkImageCreateInfo image_ci = {};
   12571     image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   12572     image_ci.imageType = VK_IMAGE_TYPE_2D;
   12573     image_ci.format = depth_format;
   12574     image_ci.extent.width = 64;
   12575     image_ci.extent.height = 64;
   12576     image_ci.extent.depth = 1;
   12577     image_ci.mipLevels = 1;
   12578     image_ci.arrayLayers = 1;
   12579     image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
   12580     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
   12581     image_ci.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
   12582     image_ci.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
   12583     image_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   12584     VkImage image;
   12585     err = vkCreateImage(m_device->device(), &image_ci, NULL, &image);
   12586     ASSERT_VK_SUCCESS(err);
   12587     // Bind memory to image
   12588     VkMemoryRequirements mem_reqs;
   12589     VkDeviceMemory image_mem;
   12590     bool pass;
   12591     VkMemoryAllocateInfo mem_alloc = {};
   12592     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   12593     mem_alloc.pNext = NULL;
   12594     mem_alloc.allocationSize = 0;
   12595     mem_alloc.memoryTypeIndex = 0;
   12596     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
   12597     mem_alloc.allocationSize = mem_reqs.size;
   12598     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
   12599     ASSERT_TRUE(pass);
   12600     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
   12601     ASSERT_VK_SUCCESS(err);
   12602     err = vkBindImageMemory(m_device->device(), image, image_mem, 0);
   12603     ASSERT_VK_SUCCESS(err);
   12604     // Now create view for image
   12605     VkImageViewCreateInfo image_view_ci = {};
   12606     image_view_ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   12607     image_view_ci.image = image;
   12608     image_view_ci.format = depth_format;
   12609     image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
   12610     image_view_ci.subresourceRange.layerCount = 1;
   12611     image_view_ci.subresourceRange.baseArrayLayer = 0;
   12612     image_view_ci.subresourceRange.levelCount = 1;
   12613     // Setting both depth & stencil aspect bits is illegal for descriptor
   12614     image_view_ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
   12615 
   12616     VkImageView image_view;
   12617     err = vkCreateImageView(m_device->device(), &image_view_ci, NULL, &image_view);
   12618     ASSERT_VK_SUCCESS(err);
   12619 
   12620     VkDescriptorImageInfo img_info = {};
   12621     img_info.imageView = image_view;
   12622     VkWriteDescriptorSet descriptor_write = {};
   12623     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   12624     descriptor_write.dstBinding = 0;
   12625     descriptor_write.descriptorCount = 1;
   12626     descriptor_write.pTexelBufferView = NULL;
   12627     descriptor_write.pBufferInfo = NULL;
   12628     descriptor_write.pImageInfo = &img_info;
   12629     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
   12630     descriptor_write.dstSet = ds.set_;
   12631     const char *error_msg = " please only set either VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT ";
   12632     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error_msg);
   12633 
   12634     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   12635 
   12636     m_errorMonitor->VerifyFound();
   12637     vkDestroyImage(m_device->device(), image, NULL);
   12638     vkFreeMemory(m_device->device(), image_mem, NULL);
   12639     vkDestroyImageView(m_device->device(), image_view, NULL);
   12640 }
   12641 
   12642 TEST_F(VkLayerTest, DSTypeMismatch) {
   12643     // Create DS w/ layout of one type and attempt Update w/ mis-matched type
   12644     VkResult err;
   12645 
   12646     m_errorMonitor->SetDesiredFailureMsg(
   12647         VK_DEBUG_REPORT_ERROR_BIT_EXT,
   12648         " binding #0 with type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER but update type is VK_DESCRIPTOR_TYPE_SAMPLER");
   12649 
   12650     ASSERT_NO_FATAL_FAILURE(Init());
   12651     OneOffDescriptorSet ds(m_device, {
   12652                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
   12653                                      });
   12654 
   12655     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
   12656     VkSampler sampler;
   12657     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
   12658     ASSERT_VK_SUCCESS(err);
   12659 
   12660     VkDescriptorImageInfo info = {};
   12661     info.sampler = sampler;
   12662 
   12663     VkWriteDescriptorSet descriptor_write;
   12664     memset(&descriptor_write, 0, sizeof(descriptor_write));
   12665     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   12666     descriptor_write.dstSet = ds.set_;
   12667     descriptor_write.descriptorCount = 1;
   12668     // This is a mismatched type for the layout which expects BUFFER
   12669     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
   12670     descriptor_write.pImageInfo = &info;
   12671 
   12672     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   12673 
   12674     m_errorMonitor->VerifyFound();
   12675 
   12676     vkDestroySampler(m_device->device(), sampler, NULL);
   12677 }
   12678 
   12679 TEST_F(VkLayerTest, DSUpdateOutOfBounds) {
   12680     // For overlapping Update, have arrayIndex exceed that of layout
   12681     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15c00282);
   12682 
   12683     ASSERT_NO_FATAL_FAILURE(Init());
   12684     OneOffDescriptorSet ds(m_device, {
   12685                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
   12686                                      });
   12687 
   12688     VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
   12689     if (!buffer_test.GetBufferCurrent()) {
   12690         // Something prevented creation of buffer so abort
   12691         printf("             Buffer creation failed, skipping test\n");
   12692         return;
   12693     }
   12694 
   12695     // Correctly update descriptor to avoid "NOT_UPDATED" error
   12696     VkDescriptorBufferInfo buff_info = {};
   12697     buff_info.buffer = buffer_test.GetBuffer();
   12698     buff_info.offset = 0;
   12699     buff_info.range = 1024;
   12700 
   12701     VkWriteDescriptorSet descriptor_write;
   12702     memset(&descriptor_write, 0, sizeof(descriptor_write));
   12703     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   12704     descriptor_write.dstSet = ds.set_;
   12705     descriptor_write.dstArrayElement = 1; /* This index out of bounds for the update */
   12706     descriptor_write.descriptorCount = 1;
   12707     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   12708     descriptor_write.pBufferInfo = &buff_info;
   12709 
   12710     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   12711 
   12712     m_errorMonitor->VerifyFound();
   12713 }
   12714 
   12715 TEST_F(VkLayerTest, InvalidDSUpdateIndex) {
   12716     // Create layout w/ count of 1 and attempt update to that layout w/ binding index 2
   12717     VkResult err;
   12718 
   12719     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15c00276);
   12720 
   12721     ASSERT_NO_FATAL_FAILURE(Init());
   12722     OneOffDescriptorSet ds(m_device, {
   12723                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
   12724                                      });
   12725 
   12726     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
   12727     VkSampler sampler;
   12728     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
   12729     ASSERT_VK_SUCCESS(err);
   12730 
   12731     VkDescriptorImageInfo info = {};
   12732     info.sampler = sampler;
   12733 
   12734     VkWriteDescriptorSet descriptor_write;
   12735     memset(&descriptor_write, 0, sizeof(descriptor_write));
   12736     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   12737     descriptor_write.dstSet = ds.set_;
   12738     descriptor_write.dstBinding = 2;
   12739     descriptor_write.descriptorCount = 1;
   12740     // This is the wrong type, but out of bounds will be flagged first
   12741     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
   12742     descriptor_write.pImageInfo = &info;
   12743 
   12744     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   12745 
   12746     m_errorMonitor->VerifyFound();
   12747 
   12748     vkDestroySampler(m_device->device(), sampler, NULL);
   12749 }
   12750 
   12751 TEST_F(VkLayerTest, DSUpdateEmptyBinding) {
   12752     // Create layout w/ empty binding and attempt to update it
   12753     VkResult err;
   12754 
   12755     ASSERT_NO_FATAL_FAILURE(Init());
   12756 
   12757     OneOffDescriptorSet ds(m_device, {
   12758                                          {0, VK_DESCRIPTOR_TYPE_SAMPLER, 0 /* !! */, VK_SHADER_STAGE_ALL, nullptr},
   12759                                      });
   12760 
   12761     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
   12762     VkSampler sampler;
   12763     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
   12764     ASSERT_VK_SUCCESS(err);
   12765 
   12766     VkDescriptorImageInfo info = {};
   12767     info.sampler = sampler;
   12768 
   12769     VkWriteDescriptorSet descriptor_write;
   12770     memset(&descriptor_write, 0, sizeof(descriptor_write));
   12771     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   12772     descriptor_write.dstSet = ds.set_;
   12773     descriptor_write.dstBinding = 0;
   12774     descriptor_write.descriptorCount = 1;  // Lie here to avoid parameter_validation error
   12775     // This is the wrong type, but empty binding error will be flagged first
   12776     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
   12777     descriptor_write.pImageInfo = &info;
   12778 
   12779     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15c00278);
   12780     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   12781     m_errorMonitor->VerifyFound();
   12782 
   12783     vkDestroySampler(m_device->device(), sampler, NULL);
   12784 }
   12785 
   12786 TEST_F(VkLayerTest, InvalidDSUpdateStruct) {
   12787     // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_*
   12788     // types
   12789     VkResult err;
   12790 
   12791     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, ".sType must be VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET");
   12792 
   12793     ASSERT_NO_FATAL_FAILURE(Init());
   12794 
   12795     OneOffDescriptorSet ds(m_device, {
   12796                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
   12797                                      });
   12798 
   12799     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
   12800     VkSampler sampler;
   12801     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
   12802     ASSERT_VK_SUCCESS(err);
   12803 
   12804     VkDescriptorImageInfo info = {};
   12805     info.sampler = sampler;
   12806 
   12807     VkWriteDescriptorSet descriptor_write;
   12808     memset(&descriptor_write, 0, sizeof(descriptor_write));
   12809     descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
   12810     descriptor_write.dstSet = ds.set_;
   12811     descriptor_write.descriptorCount = 1;
   12812     // This is the wrong type, but out of bounds will be flagged first
   12813     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
   12814     descriptor_write.pImageInfo = &info;
   12815 
   12816     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   12817 
   12818     m_errorMonitor->VerifyFound();
   12819 
   12820     vkDestroySampler(m_device->device(), sampler, NULL);
   12821 }
   12822 
   12823 TEST_F(VkLayerTest, SampleDescriptorUpdateError) {
   12824     // Create a single Sampler descriptor and send it an invalid Sampler
   12825     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15c0028a);
   12826 
   12827     ASSERT_NO_FATAL_FAILURE(Init());
   12828     OneOffDescriptorSet ds(m_device, {
   12829                                          {0, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
   12830                                      });
   12831 
   12832     VkSampler sampler = (VkSampler)((size_t)0xbaadbeef);  // Sampler with invalid handle
   12833 
   12834     VkDescriptorImageInfo descriptor_info;
   12835     memset(&descriptor_info, 0, sizeof(VkDescriptorImageInfo));
   12836     descriptor_info.sampler = sampler;
   12837 
   12838     VkWriteDescriptorSet descriptor_write;
   12839     memset(&descriptor_write, 0, sizeof(descriptor_write));
   12840     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   12841     descriptor_write.dstSet = ds.set_;
   12842     descriptor_write.dstBinding = 0;
   12843     descriptor_write.descriptorCount = 1;
   12844     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
   12845     descriptor_write.pImageInfo = &descriptor_info;
   12846 
   12847     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   12848 
   12849     m_errorMonitor->VerifyFound();
   12850 }
   12851 
   12852 TEST_F(VkLayerTest, ImageViewDescriptorUpdateError) {
   12853     // Create a single combined Image/Sampler descriptor and send it an invalid
   12854     // imageView
   12855     VkResult err;
   12856 
   12857     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15c0028c);
   12858 
   12859     ASSERT_NO_FATAL_FAILURE(Init());
   12860     OneOffDescriptorSet ds(m_device, {
   12861                                          {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
   12862                                      });
   12863 
   12864     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
   12865     VkSampler sampler;
   12866     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
   12867     ASSERT_VK_SUCCESS(err);
   12868 
   12869     VkImageView view = (VkImageView)((size_t)0xbaadbeef);  // invalid imageView object
   12870 
   12871     VkDescriptorImageInfo descriptor_info;
   12872     memset(&descriptor_info, 0, sizeof(VkDescriptorImageInfo));
   12873     descriptor_info.sampler = sampler;
   12874     descriptor_info.imageView = view;
   12875 
   12876     VkWriteDescriptorSet descriptor_write;
   12877     memset(&descriptor_write, 0, sizeof(descriptor_write));
   12878     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   12879     descriptor_write.dstSet = ds.set_;
   12880     descriptor_write.dstBinding = 0;
   12881     descriptor_write.descriptorCount = 1;
   12882     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
   12883     descriptor_write.pImageInfo = &descriptor_info;
   12884 
   12885     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   12886 
   12887     m_errorMonitor->VerifyFound();
   12888 
   12889     vkDestroySampler(m_device->device(), sampler, NULL);
   12890 }
   12891 
   12892 TEST_F(VkLayerTest, CopyDescriptorUpdateErrors) {
   12893     // Create DS w/ layout of 2 types, write update 1 and attempt to copy-update
   12894     // into the other
   12895     VkResult err;
   12896 
   12897     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   12898                                          " binding #1 with type VK_DESCRIPTOR_TYPE_SAMPLER. Types do not match.");
   12899 
   12900     ASSERT_NO_FATAL_FAILURE(Init());
   12901     OneOffDescriptorSet ds(m_device, {
   12902                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
   12903                                          {1, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
   12904                                      });
   12905 
   12906     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
   12907     VkSampler sampler;
   12908     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
   12909     ASSERT_VK_SUCCESS(err);
   12910 
   12911     VkDescriptorImageInfo info = {};
   12912     info.sampler = sampler;
   12913 
   12914     VkWriteDescriptorSet descriptor_write;
   12915     memset(&descriptor_write, 0, sizeof(VkWriteDescriptorSet));
   12916     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   12917     descriptor_write.dstSet = ds.set_;
   12918     descriptor_write.dstBinding = 1;  // SAMPLER binding from layout above
   12919     descriptor_write.descriptorCount = 1;
   12920     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
   12921     descriptor_write.pImageInfo = &info;
   12922     // This write update should succeed
   12923     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   12924     // Now perform a copy update that fails due to type mismatch
   12925     VkCopyDescriptorSet copy_ds_update;
   12926     memset(&copy_ds_update, 0, sizeof(VkCopyDescriptorSet));
   12927     copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
   12928     copy_ds_update.srcSet = ds.set_;
   12929     copy_ds_update.srcBinding = 1;  // Copy from SAMPLER binding
   12930     copy_ds_update.dstSet = ds.set_;
   12931     copy_ds_update.dstBinding = 0;       // ERROR : copy to UNIFORM binding
   12932     copy_ds_update.descriptorCount = 1;  // copy 1 descriptor
   12933     vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, &copy_ds_update);
   12934 
   12935     m_errorMonitor->VerifyFound();
   12936     // Now perform a copy update that fails due to binding out of bounds
   12937     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " does not have copy update src binding of 3.");
   12938     memset(&copy_ds_update, 0, sizeof(VkCopyDescriptorSet));
   12939     copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
   12940     copy_ds_update.srcSet = ds.set_;
   12941     copy_ds_update.srcBinding = 3;  // ERROR : Invalid binding for matching layout
   12942     copy_ds_update.dstSet = ds.set_;
   12943     copy_ds_update.dstBinding = 0;
   12944     copy_ds_update.descriptorCount = 1;  // Copy 1 descriptor
   12945     vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, &copy_ds_update);
   12946 
   12947     m_errorMonitor->VerifyFound();
   12948 
   12949     // Now perform a copy update that fails due to binding out of bounds
   12950     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   12951                                          " binding#1 with offset index of 1 plus update array offset of 0 and update of 5 "
   12952                                          "descriptors oversteps total number of descriptors in set: 2.");
   12953 
   12954     memset(&copy_ds_update, 0, sizeof(VkCopyDescriptorSet));
   12955     copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
   12956     copy_ds_update.srcSet = ds.set_;
   12957     copy_ds_update.srcBinding = 1;
   12958     copy_ds_update.dstSet = ds.set_;
   12959     copy_ds_update.dstBinding = 0;
   12960     copy_ds_update.descriptorCount = 5;  // ERROR copy 5 descriptors (out of bounds for layout)
   12961     vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, &copy_ds_update);
   12962 
   12963     m_errorMonitor->VerifyFound();
   12964 
   12965     vkDestroySampler(m_device->device(), sampler, NULL);
   12966 }
   12967 
   12968 TEST_F(VkPositiveLayerTest, CopyNonupdatedDescriptors) {
   12969     TEST_DESCRIPTION("Copy nonupdated descriptors");
   12970     unsigned int i;
   12971 
   12972     ASSERT_NO_FATAL_FAILURE(Init());
   12973     OneOffDescriptorSet src_ds(m_device, {
   12974                                              {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
   12975                                              {1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr},
   12976                                              {2, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
   12977                                          });
   12978     OneOffDescriptorSet dst_ds(m_device, {
   12979                                              {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
   12980                                              {1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr},
   12981                                          });
   12982 
   12983     m_errorMonitor->ExpectSuccess();
   12984 
   12985     const unsigned int copy_size = 2;
   12986     VkCopyDescriptorSet copy_ds_update[copy_size];
   12987     memset(copy_ds_update, 0, sizeof(copy_ds_update));
   12988     for (i = 0; i < copy_size; i++) {
   12989         copy_ds_update[i].sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
   12990         copy_ds_update[i].srcSet = src_ds.set_;
   12991         copy_ds_update[i].srcBinding = i;
   12992         copy_ds_update[i].dstSet = dst_ds.set_;
   12993         copy_ds_update[i].dstBinding = i;
   12994         copy_ds_update[i].descriptorCount = 1;
   12995     }
   12996     vkUpdateDescriptorSets(m_device->device(), 0, NULL, copy_size, copy_ds_update);
   12997 
   12998     m_errorMonitor->VerifyNotFound();
   12999 }
   13000 
   13001 TEST_F(VkLayerTest, NumSamplesMismatch) {
   13002     // Create CommandBuffer where MSAA samples doesn't match RenderPass
   13003     // sampleCount
   13004     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Num samples mismatch! ");
   13005 
   13006     ASSERT_NO_FATAL_FAILURE(Init());
   13007     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   13008 
   13009     OneOffDescriptorSet ds(m_device, {
   13010                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
   13011                                      });
   13012 
   13013     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
   13014     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
   13015     pipe_ms_state_ci.pNext = NULL;
   13016     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
   13017     pipe_ms_state_ci.sampleShadingEnable = 0;
   13018     pipe_ms_state_ci.minSampleShading = 1.0;
   13019     pipe_ms_state_ci.pSampleMask = NULL;
   13020 
   13021     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
   13022 
   13023     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   13024     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);  // We shouldn't need a fragment shader
   13025     // but add it to be able to run on more devices
   13026     VkPipelineObj pipe(m_device);
   13027     pipe.AddShader(&vs);
   13028     pipe.AddShader(&fs);
   13029     pipe.AddDefaultColorAttachment();
   13030     pipe.SetMSAA(&pipe_ms_state_ci);
   13031     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   13032 
   13033     m_commandBuffer->begin();
   13034     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   13035     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   13036 
   13037     VkViewport viewport = {0, 0, 16, 16, 0, 1};
   13038     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   13039     VkRect2D scissor = {{0, 0}, {16, 16}};
   13040     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
   13041 
   13042     // Render triangle (the error should trigger on the attempt to draw).
   13043     m_commandBuffer->Draw(3, 1, 0, 0);
   13044 
   13045     // Finalize recording of the command buffer
   13046     m_commandBuffer->EndRenderPass();
   13047     m_commandBuffer->end();
   13048 
   13049     m_errorMonitor->VerifyFound();
   13050 }
   13051 
   13052 TEST_F(VkLayerTest, RenderPassIncompatible) {
   13053     TEST_DESCRIPTION(
   13054         "Hit RenderPass incompatible cases. Initial case is drawing with an active renderpass that's not compatible with the bound "
   13055         "pipeline state object's creation renderpass");
   13056 
   13057     ASSERT_NO_FATAL_FAILURE(Init());
   13058     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   13059 
   13060     OneOffDescriptorSet ds(m_device, {
   13061                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
   13062                                      });
   13063 
   13064     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
   13065 
   13066     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   13067     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);  // We shouldn't need a fragment shader
   13068     // but add it to be able to run on more devices
   13069     // Create a renderpass that will be incompatible with default renderpass
   13070     VkAttachmentReference color_att = {};
   13071     color_att.layout = VK_IMAGE_LAYOUT_GENERAL;
   13072     VkSubpassDescription subpass = {};
   13073     subpass.colorAttachmentCount = 1;
   13074     subpass.pColorAttachments = &color_att;
   13075     VkRenderPassCreateInfo rpci = {};
   13076     rpci.subpassCount = 1;
   13077     rpci.pSubpasses = &subpass;
   13078     rpci.attachmentCount = 1;
   13079     VkAttachmentDescription attach_desc = {};
   13080     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
   13081     // Format incompatible with PSO RP color attach format B8G8R8A8_UNORM
   13082     attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM;
   13083     attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
   13084     rpci.pAttachments = &attach_desc;
   13085     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
   13086     VkRenderPass rp;
   13087     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
   13088     VkPipelineObj pipe(m_device);
   13089     pipe.AddShader(&vs);
   13090     pipe.AddShader(&fs);
   13091     pipe.AddDefaultColorAttachment();
   13092     VkViewport view_port = {};
   13093     m_viewports.push_back(view_port);
   13094     pipe.SetViewport(m_viewports);
   13095     VkRect2D rect = {};
   13096     m_scissors.push_back(rect);
   13097     pipe.SetScissor(m_scissors);
   13098     pipe.CreateVKPipeline(pipeline_layout.handle(), rp);
   13099 
   13100     VkCommandBufferInheritanceInfo cbii = {};
   13101     cbii.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
   13102     cbii.renderPass = rp;
   13103     cbii.subpass = 0;
   13104     VkCommandBufferBeginInfo cbbi = {};
   13105     cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   13106     cbbi.pInheritanceInfo = &cbii;
   13107     vkBeginCommandBuffer(m_commandBuffer->handle(), &cbbi);
   13108     vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
   13109     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   13110 
   13111     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1a200366);
   13112     // Render triangle (the error should trigger on the attempt to draw).
   13113     m_commandBuffer->Draw(3, 1, 0, 0);
   13114 
   13115     // Finalize recording of the command buffer
   13116     m_commandBuffer->EndRenderPass();
   13117     m_commandBuffer->end();
   13118 
   13119     m_errorMonitor->VerifyFound();
   13120 
   13121     vkDestroyRenderPass(m_device->device(), rp, NULL);
   13122 }
   13123 
   13124 TEST_F(VkLayerTest, NumBlendAttachMismatch) {
   13125     // Create Pipeline where the number of blend attachments doesn't match the
   13126     // number of color attachments.  In this case, we don't add any color
   13127     // blend attachments even though we have a color attachment.
   13128     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_096005d4);
   13129 
   13130     ASSERT_NO_FATAL_FAILURE(Init());
   13131     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   13132 
   13133     OneOffDescriptorSet ds(m_device, {
   13134                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
   13135                                      });
   13136 
   13137     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
   13138     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
   13139     pipe_ms_state_ci.pNext = NULL;
   13140     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
   13141     pipe_ms_state_ci.sampleShadingEnable = 0;
   13142     pipe_ms_state_ci.minSampleShading = 1.0;
   13143     pipe_ms_state_ci.pSampleMask = NULL;
   13144 
   13145     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
   13146 
   13147     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   13148     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);  // We shouldn't need a fragment shader
   13149     // but add it to be able to run on more devices
   13150     VkPipelineObj pipe(m_device);
   13151     pipe.AddShader(&vs);
   13152     pipe.AddShader(&fs);
   13153     pipe.SetMSAA(&pipe_ms_state_ci);
   13154     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   13155     m_errorMonitor->VerifyFound();
   13156 }
   13157 
   13158 TEST_F(VkLayerTest, Maint1BindingSliceOf3DImage) {
   13159     TEST_DESCRIPTION(
   13160         "Attempt to bind a slice of a 3D texture in a descriptor set. This is explicitly disallowed by KHR_maintenance1 to keep "
   13161         "things simple for drivers.");
   13162     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   13163     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
   13164         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
   13165     } else {
   13166         printf(VK_KHR_MAINTENANCE1_EXTENSION_NAME " is not supported; skipping\n");
   13167         return;
   13168     }
   13169     ASSERT_NO_FATAL_FAILURE(InitState());
   13170 
   13171     VkResult err;
   13172 
   13173     OneOffDescriptorSet set(m_device, {
   13174                                           {0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
   13175                                       });
   13176 
   13177     VkImageCreateInfo ici = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
   13178                              nullptr,
   13179                              VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR,
   13180                              VK_IMAGE_TYPE_3D,
   13181                              VK_FORMAT_R8G8B8A8_UNORM,
   13182                              {32, 32, 32},
   13183                              1,
   13184                              1,
   13185                              VK_SAMPLE_COUNT_1_BIT,
   13186                              VK_IMAGE_TILING_OPTIMAL,
   13187                              VK_IMAGE_USAGE_SAMPLED_BIT,
   13188                              VK_SHARING_MODE_EXCLUSIVE,
   13189                              0,
   13190                              nullptr,
   13191                              VK_IMAGE_LAYOUT_UNDEFINED};
   13192     VkImageObj image(m_device);
   13193     image.init(&ici);
   13194     ASSERT_TRUE(image.initialized());
   13195 
   13196     VkImageViewCreateInfo ivci = {
   13197         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
   13198         nullptr,
   13199         0,
   13200         image.handle(),
   13201         VK_IMAGE_VIEW_TYPE_2D,
   13202         VK_FORMAT_R8G8B8A8_UNORM,
   13203         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
   13204          VK_COMPONENT_SWIZZLE_IDENTITY},
   13205         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
   13206     };
   13207     VkImageView view;
   13208     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
   13209     ASSERT_VK_SUCCESS(err);
   13210 
   13211     // Meat of the test.
   13212     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_046002ae);
   13213 
   13214     VkDescriptorImageInfo dii = {VK_NULL_HANDLE, view, VK_IMAGE_LAYOUT_GENERAL};
   13215     VkWriteDescriptorSet write = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, nullptr, set.set_, 0,      0, 1,
   13216                                   VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,       &dii,    nullptr,  nullptr};
   13217     vkUpdateDescriptorSets(m_device->device(), 1, &write, 0, nullptr);
   13218 
   13219     m_errorMonitor->VerifyFound();
   13220 
   13221     vkDestroyImageView(m_device->device(), view, nullptr);
   13222 }
   13223 
   13224 TEST_F(VkLayerTest, MissingClearAttachment) {
   13225     TEST_DESCRIPTION("Points to a wrong colorAttachment index in a VkClearAttachment structure passed to vkCmdClearAttachments");
   13226     ASSERT_NO_FATAL_FAILURE(Init());
   13227     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1860001e);
   13228 
   13229     VKTriangleTest(BsoFailCmdClearAttachments);
   13230     m_errorMonitor->VerifyFound();
   13231 }
   13232 
   13233 TEST_F(VkPositiveLayerTest, ConfirmNoVLErrorWhenVkCmdClearAttachmentsCalledInSecondaryCB) {
   13234     TEST_DESCRIPTION(
   13235         "This test is to verify that when vkCmdClearAttachments is called by a secondary commandbuffer, the validation layers do "
   13236         "not throw an error if the primary commandbuffer begins a renderpass before executing the secondary commandbuffer.");
   13237 
   13238     ASSERT_NO_FATAL_FAILURE(Init());
   13239     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   13240 
   13241     VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
   13242 
   13243     VkCommandBufferBeginInfo info = {};
   13244     VkCommandBufferInheritanceInfo hinfo = {};
   13245     info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
   13246     info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   13247     info.pInheritanceInfo = &hinfo;
   13248     hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
   13249     hinfo.pNext = NULL;
   13250     hinfo.renderPass = renderPass();
   13251     hinfo.subpass = 0;
   13252     hinfo.framebuffer = m_framebuffer;
   13253     hinfo.occlusionQueryEnable = VK_FALSE;
   13254     hinfo.queryFlags = 0;
   13255     hinfo.pipelineStatistics = 0;
   13256 
   13257     secondary.begin(&info);
   13258     VkClearAttachment color_attachment;
   13259     color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   13260     color_attachment.clearValue.color.float32[0] = 0.0;
   13261     color_attachment.clearValue.color.float32[1] = 0.0;
   13262     color_attachment.clearValue.color.float32[2] = 0.0;
   13263     color_attachment.clearValue.color.float32[3] = 0.0;
   13264     color_attachment.colorAttachment = 0;
   13265     VkClearRect clear_rect = {{{0, 0}, {(uint32_t)m_width, (uint32_t)m_height}}, 0, 1};
   13266     vkCmdClearAttachments(secondary.handle(), 1, &color_attachment, 1, &clear_rect);
   13267     m_errorMonitor->VerifyNotFound();
   13268     secondary.end();
   13269 
   13270     m_commandBuffer->begin();
   13271     vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
   13272     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
   13273     vkCmdEndRenderPass(m_commandBuffer->handle());
   13274     m_commandBuffer->end();
   13275 }
   13276 
   13277 TEST_F(VkLayerTest, CmdClearAttachmentTests) {
   13278     TEST_DESCRIPTION("Various tests for validating usage of vkCmdClearAttachments");
   13279 
   13280     ASSERT_NO_FATAL_FAILURE(Init());
   13281     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   13282 
   13283     OneOffDescriptorSet ds(m_device, {
   13284                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
   13285                                      });
   13286 
   13287     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
   13288     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
   13289     pipe_ms_state_ci.pNext = NULL;
   13290     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
   13291     pipe_ms_state_ci.sampleShadingEnable = 0;
   13292     pipe_ms_state_ci.minSampleShading = 1.0;
   13293     pipe_ms_state_ci.pSampleMask = NULL;
   13294 
   13295     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
   13296 
   13297     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   13298     //  We shouldn't need a fragment shader but add it to be able to run
   13299     //  on more devices
   13300     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   13301 
   13302     VkPipelineObj pipe(m_device);
   13303     pipe.AddShader(&vs);
   13304     pipe.AddShader(&fs);
   13305     pipe.AddDefaultColorAttachment();
   13306     pipe.SetMSAA(&pipe_ms_state_ci);
   13307     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   13308 
   13309     m_commandBuffer->begin();
   13310     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   13311 
   13312     // Main thing we care about for this test is that the VkImage obj we're
   13313     // clearing matches Color Attachment of FB
   13314     //  Also pass down other dummy params to keep driver and paramchecker happy
   13315     VkClearAttachment color_attachment;
   13316     color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   13317     color_attachment.clearValue.color.float32[0] = 1.0;
   13318     color_attachment.clearValue.color.float32[1] = 1.0;
   13319     color_attachment.clearValue.color.float32[2] = 1.0;
   13320     color_attachment.clearValue.color.float32[3] = 1.0;
   13321     color_attachment.colorAttachment = 0;
   13322     VkClearRect clear_rect = {{{0, 0}, {(uint32_t)m_width, (uint32_t)m_height}}, 0, 1};
   13323 
   13324     // Call for full-sized FB Color attachment prior to issuing a Draw
   13325     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
   13326                                          "vkCmdClearAttachments() issued on command buffer object ");
   13327     vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
   13328     m_errorMonitor->VerifyFound();
   13329 
   13330     clear_rect.rect.extent.width = renderPassBeginInfo().renderArea.extent.width + 4;
   13331     clear_rect.rect.extent.height = clear_rect.rect.extent.height / 2;
   13332     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18600020);
   13333     vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
   13334     m_errorMonitor->VerifyFound();
   13335 
   13336     // baseLayer >= view layers
   13337     clear_rect.rect.extent.width = (uint32_t)m_width;
   13338     clear_rect.baseArrayLayer = 1;
   13339     clear_rect.layerCount = 0;
   13340     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18600022);
   13341     vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
   13342     m_errorMonitor->VerifyFound();
   13343 
   13344     // baseLayer + layerCount > view layers
   13345     clear_rect.rect.extent.width = (uint32_t)m_width;
   13346     clear_rect.baseArrayLayer = 0;
   13347     clear_rect.layerCount = 2;
   13348     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18600022);
   13349     vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
   13350     m_errorMonitor->VerifyFound();
   13351 }
   13352 
   13353 TEST_F(VkLayerTest, VtxBufferBadIndex) {
   13354     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
   13355                                          "but no vertex buffers are attached to this Pipeline State Object");
   13356 
   13357     ASSERT_NO_FATAL_FAILURE(Init());
   13358     ASSERT_NO_FATAL_FAILURE(InitViewport());
   13359     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   13360 
   13361     OneOffDescriptorSet ds(m_device, {
   13362                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
   13363                                      });
   13364 
   13365     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
   13366     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
   13367     pipe_ms_state_ci.pNext = NULL;
   13368     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
   13369     pipe_ms_state_ci.sampleShadingEnable = 0;
   13370     pipe_ms_state_ci.minSampleShading = 1.0;
   13371     pipe_ms_state_ci.pSampleMask = NULL;
   13372 
   13373     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
   13374 
   13375     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   13376     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);  // We shouldn't need a fragment shader
   13377     // but add it to be able to run on more devices
   13378     VkPipelineObj pipe(m_device);
   13379     pipe.AddShader(&vs);
   13380     pipe.AddShader(&fs);
   13381     pipe.AddDefaultColorAttachment();
   13382     pipe.SetMSAA(&pipe_ms_state_ci);
   13383     pipe.SetViewport(m_viewports);
   13384     pipe.SetScissor(m_scissors);
   13385     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   13386 
   13387     m_commandBuffer->begin();
   13388     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   13389     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   13390     // Don't care about actual data, just need to get to draw to flag error
   13391     static const float vbo_data[3] = {1.f, 0.f, 1.f};
   13392     VkConstantBufferObj vbo(m_device, sizeof(vbo_data), (const void *)&vbo_data, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
   13393     m_commandBuffer->BindVertexBuffer(&vbo, (VkDeviceSize)0, 1);  // VBO idx 1, but no VBO in PSO
   13394     m_commandBuffer->Draw(1, 0, 0, 0);
   13395 
   13396     m_errorMonitor->VerifyFound();
   13397 }
   13398 
   13399 TEST_F(VkLayerTest, MismatchCountQueueCreateRequestedFeature) {
   13400     TEST_DESCRIPTION("Use an invalid count in a vkEnumeratePhysicalDevices call.Use invalid Queue Family Index in vkCreateDevice");
   13401     ASSERT_NO_FATAL_FAILURE(Init());
   13402 
   13403     // The following test fails with recent NVidia drivers.
   13404     // By the time core_validation is reached, the NVidia
   13405     // driver has sanitized the invalid condition and core_validation
   13406     // is not introduced to the failure condition. This is not the case
   13407     // with AMD and Mesa drivers. Futher investigation is required
   13408     //    uint32_t count = static_cast<uint32_t>(~0);
   13409     //    VkPhysicalDevice physical_device;
   13410     //    vkEnumeratePhysicalDevices(instance(), &count, &physical_device);
   13411     //    m_errorMonitor->VerifyFound();
   13412 
   13413     float queue_priority = 0.0;
   13414     VkDeviceQueueCreateInfo queue_create_info = {};
   13415     queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
   13416     queue_create_info.queueCount = 1;
   13417     queue_create_info.pQueuePriorities = &queue_priority;
   13418     queue_create_info.queueFamilyIndex = static_cast<uint32_t>(~0);
   13419 
   13420     VkPhysicalDeviceFeatures features = m_device->phy().features();
   13421     VkDevice testDevice;
   13422     VkDeviceCreateInfo device_create_info = {};
   13423     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
   13424     device_create_info.queueCreateInfoCount = 1;
   13425     device_create_info.pQueueCreateInfos = &queue_create_info;
   13426     device_create_info.pEnabledFeatures = &features;
   13427 
   13428     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_06c002fa);
   13429     // The following unexpected error is coming from the LunarG loader. Do not make it a desired message because platforms that do
   13430     // not use the LunarG loader (e.g. Android) will not see the message and the test will fail.
   13431     m_errorMonitor->SetUnexpectedError("Failed to create device chain.");
   13432     vkCreateDevice(gpu(), &device_create_info, nullptr, &testDevice);
   13433     m_errorMonitor->VerifyFound();
   13434 
   13435     vk_testing::QueueCreateInfoArray queue_info_obj(m_device->queue_props);
   13436     device_create_info.queueCreateInfoCount = queue_info_obj.size();
   13437     device_create_info.pQueueCreateInfos = queue_info_obj.data();
   13438 
   13439     unsigned feature_count = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
   13440     VkBool32 *feature_array = reinterpret_cast<VkBool32 *>(&features);
   13441     for (unsigned i = 0; i < feature_count; i++) {
   13442         if (VK_FALSE == feature_array[i]) {
   13443             feature_array[i] = VK_TRUE;
   13444             device_create_info.pEnabledFeatures = &features;
   13445             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   13446                                                  "While calling vkCreateDevice(), requesting feature");
   13447             // The following unexpected error is coming from the LunarG loader. Do not make it a desired message because platforms
   13448             // that do not use the LunarG loader (e.g. Android) will not see the message and the test will fail.
   13449             m_errorMonitor->SetUnexpectedError("Failed to create device chain.");
   13450             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   13451                                                  "You requested features that are unavailable on this device. You should first "
   13452                                                  "query feature availability by calling vkGetPhysicalDeviceFeatures().");
   13453             vkCreateDevice(gpu(), &device_create_info, nullptr, &testDevice);
   13454             m_errorMonitor->VerifyFound();
   13455             break;
   13456         }
   13457     }
   13458 }
   13459 
   13460 TEST_F(VkLayerTest, InvalidQueryPoolCreate) {
   13461     TEST_DESCRIPTION("Attempt to create a query pool for PIPELINE_STATISTICS without enabling pipeline stats for the device.");
   13462 
   13463     ASSERT_NO_FATAL_FAILURE(Init());
   13464 
   13465     vk_testing::QueueCreateInfoArray queue_info(m_device->queue_props);
   13466 
   13467     VkDevice local_device;
   13468     VkDeviceCreateInfo device_create_info = {};
   13469     auto features = m_device->phy().features();
   13470     // Intentionally disable pipeline stats
   13471     features.pipelineStatisticsQuery = VK_FALSE;
   13472     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
   13473     device_create_info.pNext = NULL;
   13474     device_create_info.queueCreateInfoCount = queue_info.size();
   13475     device_create_info.pQueueCreateInfos = queue_info.data();
   13476     device_create_info.enabledLayerCount = 0;
   13477     device_create_info.ppEnabledLayerNames = NULL;
   13478     device_create_info.pEnabledFeatures = &features;
   13479     VkResult err = vkCreateDevice(gpu(), &device_create_info, nullptr, &local_device);
   13480     ASSERT_VK_SUCCESS(err);
   13481 
   13482     VkQueryPoolCreateInfo qpci{};
   13483     qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
   13484     qpci.queryType = VK_QUERY_TYPE_PIPELINE_STATISTICS;
   13485     qpci.queryCount = 1;
   13486     VkQueryPool query_pool;
   13487 
   13488     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_11c0062e);
   13489     vkCreateQueryPool(local_device, &qpci, nullptr, &query_pool);
   13490     m_errorMonitor->VerifyFound();
   13491 
   13492     vkDestroyDevice(local_device, nullptr);
   13493 }
   13494 
   13495 TEST_F(VkLayerTest, UnclosedQuery) {
   13496     TEST_DESCRIPTION("End a command buffer with a query still in progress.");
   13497 
   13498     const char *invalid_query = "Ending command buffer with in progress query: queryPool 0x";
   13499 
   13500     ASSERT_NO_FATAL_FAILURE(Init());
   13501 
   13502     VkEvent event;
   13503     VkEventCreateInfo event_create_info{};
   13504     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
   13505     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
   13506 
   13507     VkQueue queue = VK_NULL_HANDLE;
   13508     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
   13509 
   13510     m_commandBuffer->begin();
   13511     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_query);
   13512 
   13513     VkQueryPool query_pool;
   13514     VkQueryPoolCreateInfo query_pool_create_info = {};
   13515     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
   13516     query_pool_create_info.queryType = VK_QUERY_TYPE_OCCLUSION;
   13517     query_pool_create_info.queryCount = 1;
   13518     vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
   13519 
   13520     vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0 /*startQuery*/, 1 /*queryCount*/);
   13521     vkCmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
   13522 
   13523     vkEndCommandBuffer(m_commandBuffer->handle());
   13524     m_errorMonitor->VerifyFound();
   13525 
   13526     vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
   13527     vkDestroyEvent(m_device->device(), event, nullptr);
   13528 }
   13529 
   13530 TEST_F(VkLayerTest, VertexBufferInvalid) {
   13531     TEST_DESCRIPTION(
   13532         "Submit a command buffer using deleted vertex buffer, delete a buffer twice, use an invalid offset for each buffer type, "
   13533         "and attempt to bind a null buffer");
   13534 
   13535     const char *deleted_buffer_in_command_buffer = "Cannot submit cmd buffer using deleted buffer ";
   13536     const char *invalid_offset_message = "vkBindBufferMemory(): memoryOffset is 0x";
   13537     const char *invalid_storage_buffer_offset_message = "vkBindBufferMemory(): storage memoryOffset is 0x";
   13538     const char *invalid_texel_buffer_offset_message = "vkBindBufferMemory(): texel memoryOffset is 0x";
   13539     const char *invalid_uniform_buffer_offset_message = "vkBindBufferMemory(): uniform memoryOffset is 0x";
   13540 
   13541     ASSERT_NO_FATAL_FAILURE(Init());
   13542     ASSERT_NO_FATAL_FAILURE(InitViewport());
   13543     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   13544 
   13545     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
   13546     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
   13547     pipe_ms_state_ci.pNext = NULL;
   13548     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
   13549     pipe_ms_state_ci.sampleShadingEnable = 0;
   13550     pipe_ms_state_ci.minSampleShading = 1.0;
   13551     pipe_ms_state_ci.pSampleMask = nullptr;
   13552 
   13553     const VkPipelineLayoutObj pipeline_layout(m_device);
   13554 
   13555     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   13556     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   13557     VkPipelineObj pipe(m_device);
   13558     pipe.AddShader(&vs);
   13559     pipe.AddShader(&fs);
   13560     pipe.AddDefaultColorAttachment();
   13561     pipe.SetMSAA(&pipe_ms_state_ci);
   13562     pipe.SetViewport(m_viewports);
   13563     pipe.SetScissor(m_scissors);
   13564     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   13565 
   13566     m_commandBuffer->begin();
   13567     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   13568     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   13569 
   13570     {
   13571         // Create and bind a vertex buffer in a reduced scope, which will cause
   13572         // it to be deleted upon leaving this scope
   13573         const float vbo_data[3] = {1.f, 0.f, 1.f};
   13574         VkVerticesObj draw_verticies(m_device, 1, 1, sizeof(vbo_data[0]), sizeof(vbo_data) / sizeof(vbo_data[0]), vbo_data);
   13575         draw_verticies.BindVertexBuffers(m_commandBuffer->handle());
   13576         draw_verticies.AddVertexInputToPipe(pipe);
   13577     }
   13578 
   13579     m_commandBuffer->Draw(1, 0, 0, 0);
   13580 
   13581     m_commandBuffer->EndRenderPass();
   13582     m_commandBuffer->end();
   13583 
   13584     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, deleted_buffer_in_command_buffer);
   13585     m_commandBuffer->QueueCommandBuffer(false);
   13586     m_errorMonitor->VerifyFound();
   13587 
   13588     {
   13589         // Create and bind a vertex buffer in a reduced scope, and delete it
   13590         // twice, the second through the destructor
   13591         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eDoubleDelete);
   13592         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_23c01a01);
   13593         buffer_test.TestDoubleDestroy();
   13594     }
   13595     m_errorMonitor->VerifyFound();
   13596 
   13597     m_errorMonitor->SetUnexpectedError("value of pCreateInfo->usage must not be 0");
   13598     if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidMemoryOffset)) {
   13599         // Create and bind a memory buffer with an invalid offset.
   13600         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_offset_message);
   13601         m_errorMonitor->SetUnexpectedError(
   13602             "If buffer was created with the VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT or VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, "
   13603             "memoryOffset must be a multiple of VkPhysicalDeviceLimits::minTexelBufferOffsetAlignment");
   13604         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VkBufferTest::eInvalidMemoryOffset);
   13605         (void)buffer_test;
   13606         m_errorMonitor->VerifyFound();
   13607     }
   13608 
   13609     if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset,
   13610                                             VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) {
   13611         // Create and bind a memory buffer with an invalid offset again,
   13612         // but look for a texel buffer message.
   13613         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_texel_buffer_offset_message);
   13614         m_errorMonitor->SetUnexpectedError(
   13615             "memoryOffset must be an integer multiple of the alignment member of the VkMemoryRequirements structure returned from "
   13616             "a call to vkGetBufferMemoryRequirements with buffer");
   13617         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset);
   13618         (void)buffer_test;
   13619         m_errorMonitor->VerifyFound();
   13620     }
   13621 
   13622     if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)) {
   13623         // Create and bind a memory buffer with an invalid offset again, but
   13624         // look for a uniform buffer message.
   13625         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_uniform_buffer_offset_message);
   13626         m_errorMonitor->SetUnexpectedError(
   13627             "memoryOffset must be an integer multiple of the alignment member of the VkMemoryRequirements structure returned from "
   13628             "a call to vkGetBufferMemoryRequirements with buffer");
   13629         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset);
   13630         (void)buffer_test;
   13631         m_errorMonitor->VerifyFound();
   13632     }
   13633 
   13634     if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) {
   13635         // Create and bind a memory buffer with an invalid offset again, but
   13636         // look for a storage buffer message.
   13637         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_storage_buffer_offset_message);
   13638         m_errorMonitor->SetUnexpectedError(
   13639             "memoryOffset must be an integer multiple of the alignment member of the VkMemoryRequirements structure returned from "
   13640             "a call to vkGetBufferMemoryRequirements with buffer");
   13641         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset);
   13642         (void)buffer_test;
   13643         m_errorMonitor->VerifyFound();
   13644     }
   13645 
   13646     {
   13647         // Attempt to bind a null buffer.
   13648         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   13649                                              "vkBindBufferMemory: required parameter buffer specified as VK_NULL_HANDLE");
   13650         VkBufferTest buffer_test(m_device, 0, VkBufferTest::eBindNullBuffer);
   13651         (void)buffer_test;
   13652         m_errorMonitor->VerifyFound();
   13653     }
   13654 
   13655     {
   13656         // Attempt to bind a fake buffer.
   13657         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_17001a01);
   13658         VkBufferTest buffer_test(m_device, 0, VkBufferTest::eBindFakeBuffer);
   13659         (void)buffer_test;
   13660         m_errorMonitor->VerifyFound();
   13661     }
   13662 
   13663     {
   13664         // Attempt to use an invalid handle to delete a buffer.
   13665         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_2880c601);
   13666         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eFreeInvalidHandle);
   13667         (void)buffer_test;
   13668     }
   13669     m_errorMonitor->VerifyFound();
   13670 }
   13671 
   13672 TEST_F(VkLayerTest, BadVertexBufferOffset) {
   13673     TEST_DESCRIPTION("Submit an offset past the end of a vertex buffer");
   13674 
   13675     ASSERT_NO_FATAL_FAILURE(Init());
   13676     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   13677     static const float vbo_data[3] = {1.f, 0.f, 1.f};
   13678     VkConstantBufferObj vbo(m_device, sizeof(vbo_data), (const void *)&vbo_data, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
   13679     m_commandBuffer->begin();
   13680     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   13681     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_182004e4);
   13682     m_commandBuffer->BindVertexBuffer(&vbo, (VkDeviceSize)(3 * sizeof(float)), 1);  // Offset at the end of the buffer
   13683     m_errorMonitor->VerifyFound();
   13684 }
   13685 
   13686 // INVALID_IMAGE_LAYOUT tests (one other case is hit by MapMemWithoutHostVisibleBit and not here)
   13687 TEST_F(VkLayerTest, InvalidImageLayout) {
   13688     TEST_DESCRIPTION(
   13689         "Hit all possible validation checks associated with the DRAWSTATE_INVALID_IMAGE_LAYOUT enum. Generally these involve "
   13690         "havingimages in the wrong layout when they're copied or transitioned.");
   13691     // 3 in ValidateCmdBufImageLayouts
   13692     // *  -1 Attempt to submit cmd buf w/ deleted image
   13693     // *  -2 Cmd buf submit of image w/ layout not matching first use w/ subresource
   13694     // *  -3 Cmd buf submit of image w/ layout not matching first use w/o subresource
   13695 
   13696     ASSERT_NO_FATAL_FAILURE(Init());
   13697     auto depth_format = FindSupportedDepthStencilFormat(gpu());
   13698     if (!depth_format) {
   13699         printf("             No Depth + Stencil format found. Skipped.\n");
   13700         return;
   13701     }
   13702     // Create src & dst images to use for copy operations
   13703     VkImage src_image;
   13704     VkImage dst_image;
   13705     VkImage depth_image;
   13706 
   13707     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
   13708     const int32_t tex_width = 32;
   13709     const int32_t tex_height = 32;
   13710 
   13711     VkImageCreateInfo image_create_info = {};
   13712     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   13713     image_create_info.pNext = NULL;
   13714     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   13715     image_create_info.format = tex_format;
   13716     image_create_info.extent.width = tex_width;
   13717     image_create_info.extent.height = tex_height;
   13718     image_create_info.extent.depth = 1;
   13719     image_create_info.mipLevels = 1;
   13720     image_create_info.arrayLayers = 4;
   13721     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   13722     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   13723     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   13724     image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   13725     image_create_info.flags = 0;
   13726 
   13727     VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &src_image);
   13728     ASSERT_VK_SUCCESS(err);
   13729     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   13730     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dst_image);
   13731     ASSERT_VK_SUCCESS(err);
   13732     image_create_info.format = VK_FORMAT_D16_UNORM;
   13733     image_create_info.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
   13734     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &depth_image);
   13735     ASSERT_VK_SUCCESS(err);
   13736 
   13737     // Allocate memory
   13738     VkMemoryRequirements img_mem_reqs = {};
   13739     VkMemoryAllocateInfo mem_alloc = {};
   13740     VkDeviceMemory src_image_mem, dst_image_mem, depth_image_mem;
   13741     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   13742     mem_alloc.pNext = NULL;
   13743     mem_alloc.allocationSize = 0;
   13744     mem_alloc.memoryTypeIndex = 0;
   13745 
   13746     vkGetImageMemoryRequirements(m_device->device(), src_image, &img_mem_reqs);
   13747     mem_alloc.allocationSize = img_mem_reqs.size;
   13748     bool pass = m_device->phy().set_memory_type(img_mem_reqs.memoryTypeBits, &mem_alloc, 0);
   13749     ASSERT_TRUE(pass);
   13750     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &src_image_mem);
   13751     ASSERT_VK_SUCCESS(err);
   13752 
   13753     vkGetImageMemoryRequirements(m_device->device(), dst_image, &img_mem_reqs);
   13754     mem_alloc.allocationSize = img_mem_reqs.size;
   13755     pass = m_device->phy().set_memory_type(img_mem_reqs.memoryTypeBits, &mem_alloc, 0);
   13756     ASSERT_VK_SUCCESS(err);
   13757     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &dst_image_mem);
   13758     ASSERT_VK_SUCCESS(err);
   13759 
   13760     vkGetImageMemoryRequirements(m_device->device(), depth_image, &img_mem_reqs);
   13761     mem_alloc.allocationSize = img_mem_reqs.size;
   13762     pass = m_device->phy().set_memory_type(img_mem_reqs.memoryTypeBits, &mem_alloc, 0);
   13763     ASSERT_VK_SUCCESS(err);
   13764     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &depth_image_mem);
   13765     ASSERT_VK_SUCCESS(err);
   13766 
   13767     err = vkBindImageMemory(m_device->device(), src_image, src_image_mem, 0);
   13768     ASSERT_VK_SUCCESS(err);
   13769     err = vkBindImageMemory(m_device->device(), dst_image, dst_image_mem, 0);
   13770     ASSERT_VK_SUCCESS(err);
   13771     err = vkBindImageMemory(m_device->device(), depth_image, depth_image_mem, 0);
   13772     ASSERT_VK_SUCCESS(err);
   13773 
   13774     m_commandBuffer->begin();
   13775     VkImageCopy copy_region;
   13776     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   13777     copy_region.srcSubresource.mipLevel = 0;
   13778     copy_region.srcSubresource.baseArrayLayer = 0;
   13779     copy_region.srcSubresource.layerCount = 1;
   13780     copy_region.srcOffset.x = 0;
   13781     copy_region.srcOffset.y = 0;
   13782     copy_region.srcOffset.z = 0;
   13783     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   13784     copy_region.dstSubresource.mipLevel = 0;
   13785     copy_region.dstSubresource.baseArrayLayer = 0;
   13786     copy_region.dstSubresource.layerCount = 1;
   13787     copy_region.dstOffset.x = 0;
   13788     copy_region.dstOffset.y = 0;
   13789     copy_region.dstOffset.z = 0;
   13790     copy_region.extent.width = 1;
   13791     copy_region.extent.height = 1;
   13792     copy_region.extent.depth = 1;
   13793 
   13794     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
   13795                                          "layout should be VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL instead of GENERAL.");
   13796     m_errorMonitor->SetUnexpectedError("layout should be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL instead of GENERAL.");
   13797 
   13798     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
   13799     m_errorMonitor->VerifyFound();
   13800     // The first call hits the expected WARNING and skips the call down the chain, so call a second time to call down chain and
   13801     // update layer state
   13802     m_errorMonitor->SetUnexpectedError("layout should be VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL instead of GENERAL.");
   13803     m_errorMonitor->SetUnexpectedError("layout should be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL instead of GENERAL.");
   13804     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
   13805     // Now cause error due to src image layout changing
   13806     m_errorMonitor->SetDesiredFailureMsg(
   13807         VK_DEBUG_REPORT_ERROR_BIT_EXT,
   13808         "with specific layout VK_IMAGE_LAYOUT_UNDEFINED that doesn't match the actual current layout VK_IMAGE_LAYOUT_GENERAL.");
   13809     m_errorMonitor->SetUnexpectedError("is VK_IMAGE_LAYOUT_UNDEFINED but can only be VK_IMAGE_LAYOUT");
   13810     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_UNDEFINED, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
   13811     m_errorMonitor->VerifyFound();
   13812     // Final src error is due to bad layout type
   13813     m_errorMonitor->SetDesiredFailureMsg(
   13814         VK_DEBUG_REPORT_ERROR_BIT_EXT,
   13815         "is VK_IMAGE_LAYOUT_UNDEFINED but can only be VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL.");
   13816     m_errorMonitor->SetUnexpectedError(
   13817         "with specific layout VK_IMAGE_LAYOUT_UNDEFINED that doesn't match the actual current layout VK_IMAGE_LAYOUT_GENERAL.");
   13818     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_UNDEFINED, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
   13819     m_errorMonitor->VerifyFound();
   13820     // Now verify same checks for dst
   13821     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
   13822                                          "layout should be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL instead of GENERAL.");
   13823     m_errorMonitor->SetUnexpectedError("layout should be VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL instead of GENERAL.");
   13824     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
   13825     m_errorMonitor->VerifyFound();
   13826     // Now cause error due to src image layout changing
   13827     m_errorMonitor->SetDesiredFailureMsg(
   13828         VK_DEBUG_REPORT_ERROR_BIT_EXT,
   13829         "with specific layout VK_IMAGE_LAYOUT_UNDEFINED that doesn't match the actual current layout VK_IMAGE_LAYOUT_GENERAL.");
   13830     m_errorMonitor->SetUnexpectedError(
   13831         "is VK_IMAGE_LAYOUT_UNDEFINED but can only be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL.");
   13832     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_UNDEFINED, 1, &copy_region);
   13833     m_errorMonitor->VerifyFound();
   13834     m_errorMonitor->SetDesiredFailureMsg(
   13835         VK_DEBUG_REPORT_ERROR_BIT_EXT,
   13836         "is VK_IMAGE_LAYOUT_UNDEFINED but can only be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL.");
   13837     m_errorMonitor->SetUnexpectedError(
   13838         "with specific layout VK_IMAGE_LAYOUT_UNDEFINED that doesn't match the actual current layout VK_IMAGE_LAYOUT_GENERAL.");
   13839     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_UNDEFINED, 1, &copy_region);
   13840     m_errorMonitor->VerifyFound();
   13841 
   13842     // Convert dst and depth images to TRANSFER_DST for subsequent tests
   13843     VkImageMemoryBarrier transfer_dst_image_barrier[1] = {};
   13844     transfer_dst_image_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
   13845     transfer_dst_image_barrier[0].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   13846     transfer_dst_image_barrier[0].newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   13847     transfer_dst_image_barrier[0].srcAccessMask = 0;
   13848     transfer_dst_image_barrier[0].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
   13849     transfer_dst_image_barrier[0].image = dst_image;
   13850     transfer_dst_image_barrier[0].subresourceRange.layerCount = image_create_info.arrayLayers;
   13851     transfer_dst_image_barrier[0].subresourceRange.levelCount = image_create_info.mipLevels;
   13852     transfer_dst_image_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   13853     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
   13854                          NULL, 0, NULL, 1, transfer_dst_image_barrier);
   13855     transfer_dst_image_barrier[0].image = depth_image;
   13856     transfer_dst_image_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
   13857     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
   13858                          NULL, 0, NULL, 1, transfer_dst_image_barrier);
   13859 
   13860     // Cause errors due to clearing with invalid image layouts
   13861     VkClearColorValue color_clear_value = {};
   13862     VkImageSubresourceRange clear_range;
   13863     clear_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   13864     clear_range.baseMipLevel = 0;
   13865     clear_range.baseArrayLayer = 0;
   13866     clear_range.layerCount = 1;
   13867     clear_range.levelCount = 1;
   13868 
   13869     // Fail due to explicitly prohibited layout for color clear (only GENERAL and TRANSFER_DST are permitted).
   13870     // Since the image is currently not in UNDEFINED layout, this will emit two errors.
   13871     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1880000a);
   13872     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800008);
   13873     m_commandBuffer->ClearColorImage(dst_image, VK_IMAGE_LAYOUT_UNDEFINED, &color_clear_value, 1, &clear_range);
   13874     m_errorMonitor->VerifyFound();
   13875     // Fail due to provided layout not matching actual current layout for color clear.
   13876     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800008);
   13877     m_commandBuffer->ClearColorImage(dst_image, VK_IMAGE_LAYOUT_GENERAL, &color_clear_value, 1, &clear_range);
   13878     m_errorMonitor->VerifyFound();
   13879 
   13880     VkClearDepthStencilValue depth_clear_value = {};
   13881     clear_range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
   13882 
   13883     // Fail due to explicitly prohibited layout for depth clear (only GENERAL and TRANSFER_DST are permitted).
   13884     // Since the image is currently not in UNDEFINED layout, this will emit two errors.
   13885     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00018);
   13886     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00016);
   13887     m_commandBuffer->ClearDepthStencilImage(depth_image, VK_IMAGE_LAYOUT_UNDEFINED, &depth_clear_value, 1, &clear_range);
   13888     m_errorMonitor->VerifyFound();
   13889     // Fail due to provided layout not matching actual current layout for depth clear.
   13890     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00016);
   13891     m_commandBuffer->ClearDepthStencilImage(depth_image, VK_IMAGE_LAYOUT_GENERAL, &depth_clear_value, 1, &clear_range);
   13892     m_errorMonitor->VerifyFound();
   13893 
   13894     // Now cause error due to bad image layout transition in PipelineBarrier
   13895     VkImageMemoryBarrier image_barrier[1] = {};
   13896     image_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
   13897     image_barrier[0].oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
   13898     image_barrier[0].newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   13899     image_barrier[0].image = src_image;
   13900     image_barrier[0].subresourceRange.layerCount = image_create_info.arrayLayers;
   13901     image_barrier[0].subresourceRange.levelCount = image_create_info.mipLevels;
   13902     image_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   13903     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   13904                                          "you cannot transition the layout of aspect 1 from "
   13905                                          "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL when current layout is "
   13906                                          "VK_IMAGE_LAYOUT_GENERAL.");
   13907     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000974);
   13908     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
   13909                          NULL, 0, NULL, 1, image_barrier);
   13910     m_errorMonitor->VerifyFound();
   13911 
   13912     // Finally some layout errors at RenderPass create time
   13913     // Just hacking in specific state to get to the errors we want so don't copy this unless you know what you're doing.
   13914     VkAttachmentReference attach = {};
   13915     // perf warning for GENERAL layout w/ non-DS input attachment
   13916     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
   13917     VkSubpassDescription subpass = {};
   13918     subpass.inputAttachmentCount = 1;
   13919     subpass.pInputAttachments = &attach;
   13920     VkRenderPassCreateInfo rpci = {};
   13921     rpci.subpassCount = 1;
   13922     rpci.pSubpasses = &subpass;
   13923     rpci.attachmentCount = 1;
   13924     VkAttachmentDescription attach_desc = {};
   13925     attach_desc.format = VK_FORMAT_UNDEFINED;
   13926     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
   13927     attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
   13928     rpci.pAttachments = &attach_desc;
   13929     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
   13930     VkRenderPass rp;
   13931     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
   13932                                          "Layout for input attachment is GENERAL but should be READ_ONLY_OPTIMAL.");
   13933     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
   13934     m_errorMonitor->VerifyFound();
   13935     // error w/ non-general layout
   13936     attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   13937 
   13938     m_errorMonitor->SetDesiredFailureMsg(
   13939         VK_DEBUG_REPORT_ERROR_BIT_EXT,
   13940         "Layout for input attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be READ_ONLY_OPTIMAL or GENERAL.");
   13941     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
   13942     m_errorMonitor->VerifyFound();
   13943     subpass.inputAttachmentCount = 0;
   13944     subpass.colorAttachmentCount = 1;
   13945     subpass.pColorAttachments = &attach;
   13946     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
   13947     // perf warning for GENERAL layout on color attachment
   13948     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
   13949                                          "Layout for color attachment is GENERAL but should be COLOR_ATTACHMENT_OPTIMAL.");
   13950     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
   13951     m_errorMonitor->VerifyFound();
   13952     // error w/ non-color opt or GENERAL layout for color attachment
   13953     attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   13954     m_errorMonitor->SetDesiredFailureMsg(
   13955         VK_DEBUG_REPORT_ERROR_BIT_EXT,
   13956         "Layout for color attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be COLOR_ATTACHMENT_OPTIMAL or GENERAL.");
   13957     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
   13958     m_errorMonitor->VerifyFound();
   13959     subpass.colorAttachmentCount = 0;
   13960     subpass.pDepthStencilAttachment = &attach;
   13961     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
   13962     // perf warning for GENERAL layout on DS attachment
   13963     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
   13964                                          "GENERAL layout for depth attachment may not give optimal performance.");
   13965     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
   13966     m_errorMonitor->VerifyFound();
   13967     // error w/ non-ds opt or GENERAL layout for color attachment
   13968     attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   13969     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   13970                                          "Layout for depth attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be "
   13971                                          "DEPTH_STENCIL_ATTACHMENT_OPTIMAL, DEPTH_STENCIL_READ_ONLY_OPTIMAL or GENERAL.");
   13972     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
   13973     m_errorMonitor->VerifyFound();
   13974     // For this error we need a valid renderpass so create default one
   13975     attach.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
   13976     attach.attachment = 0;
   13977     attach_desc.format = depth_format;
   13978     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
   13979     attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
   13980     attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
   13981     attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
   13982     // Can't do a CLEAR load on READ_ONLY initialLayout
   13983     attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
   13984     attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
   13985     attach_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   13986     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   13987                                          "with invalid first layout VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL");
   13988     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
   13989     m_errorMonitor->VerifyFound();
   13990 
   13991     vkFreeMemory(m_device->device(), src_image_mem, NULL);
   13992     vkFreeMemory(m_device->device(), dst_image_mem, NULL);
   13993     vkFreeMemory(m_device->device(), depth_image_mem, NULL);
   13994     vkDestroyImage(m_device->device(), src_image, NULL);
   13995     vkDestroyImage(m_device->device(), dst_image, NULL);
   13996     vkDestroyImage(m_device->device(), depth_image, NULL);
   13997 }
   13998 
   13999 TEST_F(VkLayerTest, InvalidStorageImageLayout) {
   14000     TEST_DESCRIPTION("Attempt to update a STORAGE_IMAGE descriptor w/o GENERAL layout.");
   14001 
   14002     ASSERT_NO_FATAL_FAILURE(Init());
   14003 
   14004     const VkFormat tex_format = VK_FORMAT_R8G8B8A8_UNORM;
   14005     VkImageTiling tiling;
   14006     VkFormatProperties format_properties;
   14007     vkGetPhysicalDeviceFormatProperties(gpu(), tex_format, &format_properties);
   14008     if (format_properties.linearTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) {
   14009         tiling = VK_IMAGE_TILING_LINEAR;
   14010     } else if (format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) {
   14011         tiling = VK_IMAGE_TILING_OPTIMAL;
   14012     } else {
   14013         printf("             Device does not support VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; skipped.\n");
   14014         return;
   14015     }
   14016 
   14017     OneOffDescriptorSet ds(m_device, {
   14018                                          {0, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
   14019                                      });
   14020 
   14021     VkImageObj image(m_device);
   14022     image.Init(32, 32, 1, tex_format, VK_IMAGE_USAGE_STORAGE_BIT, tiling, 0);
   14023     ASSERT_TRUE(image.initialized());
   14024     VkImageView view = image.targetView(tex_format);
   14025 
   14026     VkDescriptorImageInfo image_info = {};
   14027     image_info.imageView = view;
   14028     image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
   14029 
   14030     VkWriteDescriptorSet descriptor_write = {};
   14031     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   14032     descriptor_write.dstSet = ds.set_;
   14033     descriptor_write.dstBinding = 0;
   14034     descriptor_write.descriptorCount = 1;
   14035     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
   14036     descriptor_write.pImageInfo = &image_info;
   14037 
   14038     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   14039                                          " of VK_DESCRIPTOR_TYPE_STORAGE_IMAGE type is being updated with layout "
   14040                                          "VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL but according to spec ");
   14041     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   14042     m_errorMonitor->VerifyFound();
   14043 }
   14044 
   14045 TEST_F(VkLayerTest, NonSimultaneousSecondaryMarksPrimary) {
   14046     ASSERT_NO_FATAL_FAILURE(Init());
   14047     const char *simultaneous_use_message =
   14048         "does not have VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set and will cause primary command buffer";
   14049 
   14050     VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
   14051 
   14052     secondary.begin();
   14053     secondary.end();
   14054 
   14055     VkCommandBufferBeginInfo cbbi = {
   14056         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
   14057         nullptr,
   14058         VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
   14059         nullptr,
   14060     };
   14061 
   14062     m_commandBuffer->begin(&cbbi);
   14063     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, simultaneous_use_message);
   14064     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
   14065     m_errorMonitor->VerifyFound();
   14066     m_commandBuffer->end();
   14067 }
   14068 
   14069 TEST_F(VkLayerTest, SimultaneousUseSecondaryTwoExecutes) {
   14070     ASSERT_NO_FATAL_FAILURE(Init());
   14071 
   14072     const char *simultaneous_use_message = "without VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set!";
   14073 
   14074     VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
   14075 
   14076     VkCommandBufferInheritanceInfo inh = {
   14077         VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
   14078         nullptr,
   14079     };
   14080     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, &inh};
   14081 
   14082     secondary.begin(&cbbi);
   14083     secondary.end();
   14084 
   14085     m_commandBuffer->begin();
   14086     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
   14087     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, simultaneous_use_message);
   14088     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
   14089     m_errorMonitor->VerifyFound();
   14090     m_commandBuffer->end();
   14091 }
   14092 
   14093 TEST_F(VkLayerTest, SimultaneousUseSecondarySingleExecute) {
   14094     ASSERT_NO_FATAL_FAILURE(Init());
   14095 
   14096     // variation on previous test executing the same CB twice in the same
   14097     // CmdExecuteCommands call
   14098 
   14099     const char *simultaneous_use_message = "without VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set!";
   14100 
   14101     VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
   14102 
   14103     VkCommandBufferInheritanceInfo inh = {
   14104         VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
   14105         nullptr,
   14106     };
   14107     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, &inh};
   14108 
   14109     secondary.begin(&cbbi);
   14110     secondary.end();
   14111 
   14112     m_commandBuffer->begin();
   14113     VkCommandBuffer cbs[] = {secondary.handle(), secondary.handle()};
   14114     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, simultaneous_use_message);
   14115     vkCmdExecuteCommands(m_commandBuffer->handle(), 2, cbs);
   14116     m_errorMonitor->VerifyFound();
   14117     m_commandBuffer->end();
   14118 }
   14119 
   14120 TEST_F(VkLayerTest, SimultaneousUseOneShot) {
   14121     TEST_DESCRIPTION("Submit the same command buffer twice in one submit looking for simultaneous use and one time submit errors");
   14122     const char *simultaneous_use_message = "is already in use and is not marked for simultaneous use";
   14123     const char *one_shot_message = "VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has been submitted";
   14124     ASSERT_NO_FATAL_FAILURE(Init());
   14125 
   14126     VkCommandBuffer cmd_bufs[2];
   14127     VkCommandBufferAllocateInfo alloc_info;
   14128     alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
   14129     alloc_info.pNext = NULL;
   14130     alloc_info.commandBufferCount = 2;
   14131     alloc_info.commandPool = m_commandPool->handle();
   14132     alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
   14133     vkAllocateCommandBuffers(m_device->device(), &alloc_info, cmd_bufs);
   14134 
   14135     VkCommandBufferBeginInfo cb_binfo;
   14136     cb_binfo.pNext = NULL;
   14137     cb_binfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   14138     cb_binfo.pInheritanceInfo = VK_NULL_HANDLE;
   14139     cb_binfo.flags = 0;
   14140     vkBeginCommandBuffer(cmd_bufs[0], &cb_binfo);
   14141     VkViewport viewport = {0, 0, 16, 16, 0, 1};
   14142     vkCmdSetViewport(cmd_bufs[0], 0, 1, &viewport);
   14143     vkEndCommandBuffer(cmd_bufs[0]);
   14144     VkCommandBuffer duplicates[2] = {cmd_bufs[0], cmd_bufs[0]};
   14145 
   14146     VkSubmitInfo submit_info = {};
   14147     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   14148     submit_info.commandBufferCount = 2;
   14149     submit_info.pCommandBuffers = duplicates;
   14150     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, simultaneous_use_message);
   14151     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   14152     m_errorMonitor->VerifyFound();
   14153     vkQueueWaitIdle(m_device->m_queue);
   14154 
   14155     // Set one time use and now look for one time submit
   14156     duplicates[0] = duplicates[1] = cmd_bufs[1];
   14157     cb_binfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT | VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
   14158     vkBeginCommandBuffer(cmd_bufs[1], &cb_binfo);
   14159     vkCmdSetViewport(cmd_bufs[1], 0, 1, &viewport);
   14160     vkEndCommandBuffer(cmd_bufs[1]);
   14161     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, one_shot_message);
   14162     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   14163     m_errorMonitor->VerifyFound();
   14164     vkQueueWaitIdle(m_device->m_queue);
   14165 }
   14166 
   14167 TEST_F(VkLayerTest, StageMaskGsTsEnabled) {
   14168     TEST_DESCRIPTION(
   14169         "Attempt to use a stageMask w/ geometry shader and tesselation shader bits enabled when those features are disabled on the "
   14170         "device.");
   14171 
   14172     ASSERT_NO_FATAL_FAILURE(Init());
   14173     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   14174 
   14175     std::vector<const char *> device_extension_names;
   14176     auto features = m_device->phy().features();
   14177     // Make sure gs & ts are disabled
   14178     features.geometryShader = false;
   14179     features.tessellationShader = false;
   14180     // The sacrificial device object
   14181     VkDeviceObj test_device(0, gpu(), device_extension_names, &features);
   14182 
   14183     VkCommandPoolCreateInfo pool_create_info{};
   14184     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
   14185     pool_create_info.queueFamilyIndex = test_device.graphics_queue_node_index_;
   14186 
   14187     VkCommandPool command_pool;
   14188     vkCreateCommandPool(test_device.handle(), &pool_create_info, nullptr, &command_pool);
   14189 
   14190     VkCommandBufferAllocateInfo cmd = {};
   14191     cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
   14192     cmd.pNext = NULL;
   14193     cmd.commandPool = command_pool;
   14194     cmd.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
   14195     cmd.commandBufferCount = 1;
   14196 
   14197     VkCommandBuffer cmd_buffer;
   14198     VkResult err = vkAllocateCommandBuffers(test_device.handle(), &cmd, &cmd_buffer);
   14199     ASSERT_VK_SUCCESS(err);
   14200 
   14201     VkEvent event;
   14202     VkEventCreateInfo evci = {};
   14203     evci.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
   14204     VkResult result = vkCreateEvent(test_device.handle(), &evci, NULL, &event);
   14205     ASSERT_VK_SUCCESS(result);
   14206 
   14207     VkCommandBufferBeginInfo cbbi = {};
   14208     cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   14209     vkBeginCommandBuffer(cmd_buffer, &cbbi);
   14210     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1d4008fc);
   14211     vkCmdSetEvent(cmd_buffer, event, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT);
   14212     m_errorMonitor->VerifyFound();
   14213 
   14214     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1d4008fe);
   14215     vkCmdSetEvent(cmd_buffer, event, VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT);
   14216     m_errorMonitor->VerifyFound();
   14217 
   14218     vkDestroyEvent(test_device.handle(), event, NULL);
   14219     vkDestroyCommandPool(test_device.handle(), command_pool, NULL);
   14220 }
   14221 
   14222 TEST_F(VkLayerTest, EventInUseDestroyedSignaled) {
   14223     ASSERT_NO_FATAL_FAILURE(Init());
   14224     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   14225 
   14226     m_commandBuffer->begin();
   14227 
   14228     VkEvent event;
   14229     VkEventCreateInfo event_create_info = {};
   14230     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
   14231     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
   14232     vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
   14233 
   14234     m_commandBuffer->end();
   14235     vkDestroyEvent(m_device->device(), event, nullptr);
   14236 
   14237     VkSubmitInfo submit_info = {};
   14238     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   14239     submit_info.commandBufferCount = 1;
   14240     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   14241     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is invalid because bound");
   14242     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   14243     m_errorMonitor->VerifyFound();
   14244 }
   14245 
   14246 TEST_F(VkLayerTest, InUseDestroyedSignaled) {
   14247     TEST_DESCRIPTION(
   14248         "Use vkCmdExecuteCommands with invalid state in primary and secondary command buffers. Delete objects that are inuse. Call "
   14249         "VkQueueSubmit with an event that has been deleted.");
   14250 
   14251     ASSERT_NO_FATAL_FAILURE(Init());
   14252     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   14253 
   14254     m_errorMonitor->ExpectSuccess();
   14255 
   14256     VkSemaphoreCreateInfo semaphore_create_info = {};
   14257     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
   14258     VkSemaphore semaphore;
   14259     ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
   14260     VkFenceCreateInfo fence_create_info = {};
   14261     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
   14262     VkFence fence;
   14263     ASSERT_VK_SUCCESS(vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence));
   14264 
   14265     OneOffDescriptorSet ds(m_device, {
   14266                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
   14267                                      });
   14268 
   14269     VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
   14270 
   14271     VkDescriptorBufferInfo buffer_info = {};
   14272     buffer_info.buffer = buffer_test.GetBuffer();
   14273     buffer_info.offset = 0;
   14274     buffer_info.range = 1024;
   14275 
   14276     VkWriteDescriptorSet write_descriptor_set = {};
   14277     write_descriptor_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   14278     write_descriptor_set.dstSet = ds.set_;
   14279     write_descriptor_set.descriptorCount = 1;
   14280     write_descriptor_set.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   14281     write_descriptor_set.pBufferInfo = &buffer_info;
   14282 
   14283     vkUpdateDescriptorSets(m_device->device(), 1, &write_descriptor_set, 0, nullptr);
   14284 
   14285     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   14286     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   14287 
   14288     VkPipelineObj pipe(m_device);
   14289     pipe.AddDefaultColorAttachment();
   14290     pipe.AddShader(&vs);
   14291     pipe.AddShader(&fs);
   14292 
   14293     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
   14294 
   14295     pipe.CreateVKPipeline(pipeline_layout.handle(), m_renderPass);
   14296 
   14297     VkEvent event;
   14298     VkEventCreateInfo event_create_info = {};
   14299     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
   14300     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
   14301 
   14302     m_commandBuffer->begin();
   14303 
   14304     vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
   14305 
   14306     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   14307     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &ds.set_, 0,
   14308                             NULL);
   14309 
   14310     m_commandBuffer->end();
   14311 
   14312     VkSubmitInfo submit_info = {};
   14313     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   14314     submit_info.commandBufferCount = 1;
   14315     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   14316     submit_info.signalSemaphoreCount = 1;
   14317     submit_info.pSignalSemaphores = &semaphore;
   14318     vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
   14319     m_errorMonitor->Reset();  // resume logmsg processing
   14320 
   14321     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_24c008f2);
   14322     vkDestroyEvent(m_device->device(), event, nullptr);
   14323     m_errorMonitor->VerifyFound();
   14324 
   14325     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_268008e2);
   14326     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
   14327     m_errorMonitor->VerifyFound();
   14328 
   14329     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Fence 0x");
   14330     vkDestroyFence(m_device->device(), fence, nullptr);
   14331     m_errorMonitor->VerifyFound();
   14332 
   14333     vkQueueWaitIdle(m_device->m_queue);
   14334     m_errorMonitor->SetUnexpectedError("If semaphore is not VK_NULL_HANDLE, semaphore must be a valid VkSemaphore handle");
   14335     m_errorMonitor->SetUnexpectedError("Unable to remove Semaphore obj");
   14336     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
   14337     m_errorMonitor->SetUnexpectedError("If fence is not VK_NULL_HANDLE, fence must be a valid VkFence handle");
   14338     m_errorMonitor->SetUnexpectedError("Unable to remove Fence obj");
   14339     vkDestroyFence(m_device->device(), fence, nullptr);
   14340     m_errorMonitor->SetUnexpectedError("If event is not VK_NULL_HANDLE, event must be a valid VkEvent handle");
   14341     m_errorMonitor->SetUnexpectedError("Unable to remove Event obj");
   14342     vkDestroyEvent(m_device->device(), event, nullptr);
   14343 }
   14344 
   14345 TEST_F(VkLayerTest, QueryPoolInUseDestroyedSignaled) {
   14346     TEST_DESCRIPTION("Delete in-use query pool.");
   14347 
   14348     ASSERT_NO_FATAL_FAILURE(Init());
   14349     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   14350 
   14351     VkQueryPool query_pool;
   14352     VkQueryPoolCreateInfo query_pool_ci{};
   14353     query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
   14354     query_pool_ci.queryType = VK_QUERY_TYPE_TIMESTAMP;
   14355     query_pool_ci.queryCount = 1;
   14356     vkCreateQueryPool(m_device->device(), &query_pool_ci, nullptr, &query_pool);
   14357     m_commandBuffer->begin();
   14358     // Reset query pool to create binding with cmd buffer
   14359     vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
   14360 
   14361     m_commandBuffer->end();
   14362 
   14363     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_2fa00664);
   14364     uint32_t data_space[16];
   14365     m_errorMonitor->SetUnexpectedError("Cannot get query results on queryPool");
   14366     vkGetQueryPoolResults(m_device->handle(), query_pool, 0, 1, sizeof(data_space), &data_space, sizeof(uint32_t),
   14367                           VK_QUERY_RESULT_PARTIAL_BIT);
   14368     m_errorMonitor->VerifyFound();
   14369 
   14370     VkSubmitInfo submit_info = {};
   14371     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   14372     submit_info.commandBufferCount = 1;
   14373     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   14374     // Submit cmd buffer and then destroy query pool while in-flight
   14375     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   14376 
   14377     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_26200632);
   14378     vkDestroyQueryPool(m_device->handle(), query_pool, NULL);
   14379     m_errorMonitor->VerifyFound();
   14380 
   14381     vkQueueWaitIdle(m_device->m_queue);
   14382     // Now that cmd buffer done we can safely destroy query_pool
   14383     m_errorMonitor->SetUnexpectedError("If queryPool is not VK_NULL_HANDLE, queryPool must be a valid VkQueryPool handle");
   14384     m_errorMonitor->SetUnexpectedError("Unable to remove QueryPool obj");
   14385     vkDestroyQueryPool(m_device->handle(), query_pool, NULL);
   14386 }
   14387 
   14388 TEST_F(VkLayerTest, PipelineInUseDestroyedSignaled) {
   14389     TEST_DESCRIPTION("Delete in-use pipeline.");
   14390 
   14391     ASSERT_NO_FATAL_FAILURE(Init());
   14392     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   14393 
   14394     const VkPipelineLayoutObj pipeline_layout(m_device);
   14395 
   14396     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_25c005fa);
   14397     // Create PSO to be used for draw-time errors below
   14398     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   14399     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   14400     // Store pipeline handle so we can actually delete it before test finishes
   14401     VkPipeline delete_this_pipeline;
   14402     {  // Scope pipeline so it will be auto-deleted
   14403         VkPipelineObj pipe(m_device);
   14404         pipe.AddShader(&vs);
   14405         pipe.AddShader(&fs);
   14406         pipe.AddDefaultColorAttachment();
   14407         pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   14408         delete_this_pipeline = pipe.handle();
   14409 
   14410         m_commandBuffer->begin();
   14411         // Bind pipeline to cmd buffer
   14412         vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   14413 
   14414         m_commandBuffer->end();
   14415 
   14416         VkSubmitInfo submit_info = {};
   14417         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   14418         submit_info.commandBufferCount = 1;
   14419         submit_info.pCommandBuffers = &m_commandBuffer->handle();
   14420         // Submit cmd buffer and then pipeline destroyed while in-flight
   14421         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   14422     }  // Pipeline deletion triggered here
   14423     m_errorMonitor->VerifyFound();
   14424     // Make sure queue finished and then actually delete pipeline
   14425     vkQueueWaitIdle(m_device->m_queue);
   14426     m_errorMonitor->SetUnexpectedError("If pipeline is not VK_NULL_HANDLE, pipeline must be a valid VkPipeline handle");
   14427     m_errorMonitor->SetUnexpectedError("Unable to remove Pipeline obj");
   14428     vkDestroyPipeline(m_device->handle(), delete_this_pipeline, nullptr);
   14429 }
   14430 
   14431 TEST_F(VkLayerTest, CreateImageViewBreaksParameterCompatibilityRequirements) {
   14432     TEST_DESCRIPTION(
   14433         "Attempts to create an Image View with a view type that does not match the image type it is being created from.");
   14434 
   14435     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   14436     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
   14437         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
   14438     }
   14439     ASSERT_NO_FATAL_FAILURE(InitState());
   14440 
   14441     VkPhysicalDeviceMemoryProperties memProps;
   14442     vkGetPhysicalDeviceMemoryProperties(m_device->phy().handle(), &memProps);
   14443 
   14444     // Test mismatch detection for image of type VK_IMAGE_TYPE_1D
   14445     VkImageCreateInfo imgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
   14446                                  nullptr,
   14447                                  VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
   14448                                  VK_IMAGE_TYPE_1D,
   14449                                  VK_FORMAT_R8G8B8A8_UNORM,
   14450                                  {1, 1, 1},
   14451                                  1,
   14452                                  1,
   14453                                  VK_SAMPLE_COUNT_1_BIT,
   14454                                  VK_IMAGE_TILING_OPTIMAL,
   14455                                  VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
   14456                                  VK_SHARING_MODE_EXCLUSIVE,
   14457                                  0,
   14458                                  nullptr,
   14459                                  VK_IMAGE_LAYOUT_UNDEFINED};
   14460     VkImageObj image1D(m_device);
   14461     image1D.init(&imgInfo);
   14462     ASSERT_TRUE(image1D.initialized());
   14463 
   14464     // Initialize VkImageViewCreateInfo with mismatched viewType
   14465     VkImageView imageView;
   14466     VkImageViewCreateInfo ivci = {};
   14467     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   14468     ivci.image = image1D.handle();
   14469     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
   14470     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
   14471     ivci.subresourceRange.layerCount = 1;
   14472     ivci.subresourceRange.baseMipLevel = 0;
   14473     ivci.subresourceRange.levelCount = 1;
   14474     ivci.subresourceRange.baseArrayLayer = 0;
   14475     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   14476 
   14477     // Test for error message
   14478     m_errorMonitor->SetDesiredFailureMsg(
   14479         VK_DEBUG_REPORT_ERROR_BIT_EXT,
   14480         "vkCreateImageView(): pCreateInfo->viewType VK_IMAGE_VIEW_TYPE_2D is not compatible with image");
   14481     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
   14482     m_errorMonitor->VerifyFound();
   14483 
   14484     // Test mismatch detection for image of type VK_IMAGE_TYPE_2D
   14485     imgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
   14486                nullptr,
   14487                VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
   14488                VK_IMAGE_TYPE_2D,
   14489                VK_FORMAT_R8G8B8A8_UNORM,
   14490                {1, 1, 1},
   14491                1,
   14492                6,
   14493                VK_SAMPLE_COUNT_1_BIT,
   14494                VK_IMAGE_TILING_OPTIMAL,
   14495                VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
   14496                VK_SHARING_MODE_EXCLUSIVE,
   14497                0,
   14498                nullptr,
   14499                VK_IMAGE_LAYOUT_UNDEFINED};
   14500     VkImageObj image2D(m_device);
   14501     image2D.init(&imgInfo);
   14502     ASSERT_TRUE(image2D.initialized());
   14503 
   14504     // Initialize VkImageViewCreateInfo with mismatched viewType
   14505     ivci = {};
   14506     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   14507     ivci.image = image2D.handle();
   14508     ivci.viewType = VK_IMAGE_VIEW_TYPE_3D;
   14509     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
   14510     ivci.subresourceRange.layerCount = 1;
   14511     ivci.subresourceRange.baseMipLevel = 0;
   14512     ivci.subresourceRange.levelCount = 1;
   14513     ivci.subresourceRange.baseArrayLayer = 0;
   14514     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   14515 
   14516     // Test for error message
   14517     m_errorMonitor->SetDesiredFailureMsg(
   14518         VK_DEBUG_REPORT_ERROR_BIT_EXT,
   14519         "vkCreateImageView(): pCreateInfo->viewType VK_IMAGE_VIEW_TYPE_3D is not compatible with image");
   14520     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
   14521     m_errorMonitor->VerifyFound();
   14522 
   14523     // Change VkImageViewCreateInfo to different mismatched viewType
   14524     ivci.viewType = VK_IMAGE_VIEW_TYPE_CUBE;
   14525     ivci.subresourceRange.layerCount = 6;
   14526 
   14527     // Test for error message
   14528     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac007d6);
   14529     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
   14530     m_errorMonitor->VerifyFound();
   14531 
   14532     // Test mismatch detection for image of type VK_IMAGE_TYPE_3D
   14533     imgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
   14534                nullptr,
   14535                VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
   14536                VK_IMAGE_TYPE_3D,
   14537                VK_FORMAT_R8G8B8A8_UNORM,
   14538                {1, 1, 1},
   14539                1,
   14540                1,
   14541                VK_SAMPLE_COUNT_1_BIT,
   14542                VK_IMAGE_TILING_OPTIMAL,
   14543                VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
   14544                VK_SHARING_MODE_EXCLUSIVE,
   14545                0,
   14546                nullptr,
   14547                VK_IMAGE_LAYOUT_UNDEFINED};
   14548     VkImageObj image3D(m_device);
   14549     image3D.init(&imgInfo);
   14550     ASSERT_TRUE(image3D.initialized());
   14551 
   14552     // Initialize VkImageViewCreateInfo with mismatched viewType
   14553     ivci = {};
   14554     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   14555     ivci.image = image3D.handle();
   14556     ivci.viewType = VK_IMAGE_VIEW_TYPE_1D;
   14557     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
   14558     ivci.subresourceRange.layerCount = 1;
   14559     ivci.subresourceRange.baseMipLevel = 0;
   14560     ivci.subresourceRange.levelCount = 1;
   14561     ivci.subresourceRange.baseArrayLayer = 0;
   14562     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   14563 
   14564     // Test for error message
   14565     m_errorMonitor->SetDesiredFailureMsg(
   14566         VK_DEBUG_REPORT_ERROR_BIT_EXT,
   14567         "vkCreateImageView(): pCreateInfo->viewType VK_IMAGE_VIEW_TYPE_1D is not compatible with image");
   14568     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
   14569     m_errorMonitor->VerifyFound();
   14570 
   14571     // Change VkImageViewCreateInfo to different mismatched viewType
   14572     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
   14573 
   14574     // Test for error message
   14575     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
   14576         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac007da);
   14577     } else {
   14578         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac007fa);
   14579     }
   14580 
   14581     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
   14582     m_errorMonitor->VerifyFound();
   14583 
   14584     // Check if the device can make the image required for this test case.
   14585     VkImageFormatProperties formProps = {{0, 0, 0}, 0, 0, 0, 0};
   14586     VkResult res = vkGetPhysicalDeviceImageFormatProperties(
   14587         m_device->phy().handle(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_3D, VK_IMAGE_TILING_OPTIMAL,
   14588         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
   14589         VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR | VK_IMAGE_CREATE_SPARSE_BINDING_BIT,
   14590         &formProps);
   14591 
   14592     // If not, skip this part of the test.
   14593     if (res || !m_device->phy().features().sparseBinding ||
   14594         !DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
   14595         return;
   14596     }
   14597 
   14598     // Initialize VkImageCreateInfo with VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR and VK_IMAGE_CREATE_SPARSE_BINDING_BIT which
   14599     // are incompatible create flags.
   14600     imgInfo = {
   14601         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
   14602         nullptr,
   14603         VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR | VK_IMAGE_CREATE_SPARSE_BINDING_BIT,
   14604         VK_IMAGE_TYPE_3D,
   14605         VK_FORMAT_R8G8B8A8_UNORM,
   14606         {1, 1, 1},
   14607         1,
   14608         1,
   14609         VK_SAMPLE_COUNT_1_BIT,
   14610         VK_IMAGE_TILING_OPTIMAL,
   14611         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
   14612         VK_SHARING_MODE_EXCLUSIVE,
   14613         0,
   14614         nullptr,
   14615         VK_IMAGE_LAYOUT_UNDEFINED};
   14616     VkImage imageSparse;
   14617 
   14618     // Creating a sparse image means we should not bind memory to it.
   14619     res = vkCreateImage(m_device->device(), &imgInfo, NULL, &imageSparse);
   14620     ASSERT_FALSE(res);
   14621 
   14622     // Initialize VkImageViewCreateInfo to create a view that will attempt to utilize VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR.
   14623     ivci = {};
   14624     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   14625     ivci.image = imageSparse;
   14626     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
   14627     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
   14628     ivci.subresourceRange.layerCount = 1;
   14629     ivci.subresourceRange.baseMipLevel = 0;
   14630     ivci.subresourceRange.levelCount = 1;
   14631     ivci.subresourceRange.baseArrayLayer = 0;
   14632     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   14633 
   14634     // Test for error message
   14635     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   14636                                          " when the VK_IMAGE_CREATE_SPARSE_BINDING_BIT, VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, or "
   14637                                          "VK_IMAGE_CREATE_SPARSE_ALIASED_BIT flags are enabled.");
   14638     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
   14639     m_errorMonitor->VerifyFound();
   14640 
   14641     // Clean up
   14642     vkDestroyImage(m_device->device(), imageSparse, nullptr);
   14643 }
   14644 
   14645 TEST_F(VkLayerTest, CreateImageViewFormatFeatureMismatch) {
   14646     TEST_DESCRIPTION("Create view with a format that does not have the same features as the image format.");
   14647 
   14648     if (!EnableDeviceProfileLayer()) return;
   14649 
   14650     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   14651     ASSERT_NO_FATAL_FAILURE(InitState());
   14652 
   14653     PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr;
   14654     PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr;
   14655 
   14656     // Load required functions
   14657     if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) {
   14658         return;
   14659     }
   14660 
   14661     // List of features to be tested
   14662     VkFormatFeatureFlagBits features[] = {VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT,
   14663                                           VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT};
   14664     uint32_t feature_count = 4;
   14665     // List of usage cases for each feature test
   14666     VkImageUsageFlags usages[] = {VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
   14667                                   VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT};
   14668     // List of errors that will be thrown in order of tests run
   14669     UNIQUE_VALIDATION_ERROR_CODE optimal_error_codes[] = {
   14670         VALIDATION_ERROR_0ac007ea,
   14671         VALIDATION_ERROR_0ac007ec,
   14672         VALIDATION_ERROR_0ac007ee,
   14673         VALIDATION_ERROR_0ac007f0,
   14674     };
   14675 
   14676     VkFormatProperties formatProps;
   14677 
   14678     // First three tests
   14679     uint32_t i = 0;
   14680     for (i = 0; i < (feature_count - 1); i++) {
   14681         // Modify formats to have mismatched features
   14682 
   14683         // Format for image
   14684         fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32G32B32A32_UINT, &formatProps);
   14685         formatProps.optimalTilingFeatures |= features[i];
   14686         fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32G32B32A32_UINT, formatProps);
   14687 
   14688         memset(&formatProps, 0, sizeof(formatProps));
   14689 
   14690         // Format for view
   14691         fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32G32B32A32_SINT, &formatProps);
   14692         formatProps.optimalTilingFeatures = features[(i + 1) % feature_count];
   14693         fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32G32B32A32_SINT, formatProps);
   14694 
   14695         // Create image with modified format
   14696         VkImageCreateInfo imgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
   14697                                      nullptr,
   14698                                      VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
   14699                                      VK_IMAGE_TYPE_2D,
   14700                                      VK_FORMAT_R32G32B32A32_UINT,
   14701                                      {1, 1, 1},
   14702                                      1,
   14703                                      1,
   14704                                      VK_SAMPLE_COUNT_1_BIT,
   14705                                      VK_IMAGE_TILING_OPTIMAL,
   14706                                      usages[i],
   14707                                      VK_SHARING_MODE_EXCLUSIVE,
   14708                                      0,
   14709                                      nullptr,
   14710                                      VK_IMAGE_LAYOUT_UNDEFINED};
   14711         VkImageObj image(m_device);
   14712         image.init(&imgInfo);
   14713         ASSERT_TRUE(image.initialized());
   14714 
   14715         VkImageView imageView;
   14716 
   14717         // Initialize VkImageViewCreateInfo with modified format
   14718         VkImageViewCreateInfo ivci = {};
   14719         ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   14720         ivci.image = image.handle();
   14721         ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
   14722         ivci.format = VK_FORMAT_R32G32B32A32_SINT;
   14723         ivci.subresourceRange.layerCount = 1;
   14724         ivci.subresourceRange.baseMipLevel = 0;
   14725         ivci.subresourceRange.levelCount = 1;
   14726         ivci.subresourceRange.baseArrayLayer = 0;
   14727         ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   14728 
   14729         // Test for error message
   14730         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, optimal_error_codes[i]);
   14731         VkResult res = vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
   14732         m_errorMonitor->VerifyFound();
   14733 
   14734         if (!res) {
   14735             vkDestroyImageView(m_device->device(), imageView, nullptr);
   14736         }
   14737     }
   14738 
   14739     // Test for VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT.  Needs special formats
   14740 
   14741     // Only run this test if format supported
   14742     if (!ImageFormatIsSupported(gpu(), VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_TILING_OPTIMAL)) {
   14743         printf("             VK_FORMAT_D24_UNORM_S8_UINT format not supported - skipped.\n");
   14744         return;
   14745     }
   14746     // Modify formats to have mismatched features
   14747 
   14748     // Format for image
   14749     fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_D24_UNORM_S8_UINT, &formatProps);
   14750     formatProps.optimalTilingFeatures |= features[i];
   14751     fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_D24_UNORM_S8_UINT, formatProps);
   14752 
   14753     memset(&formatProps, 0, sizeof(formatProps));
   14754 
   14755     // Format for view
   14756     fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_D32_SFLOAT_S8_UINT, &formatProps);
   14757     formatProps.optimalTilingFeatures = features[(i + 1) % feature_count];
   14758     fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_D32_SFLOAT_S8_UINT, formatProps);
   14759 
   14760     // Create image with modified format
   14761     VkImageCreateInfo imgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
   14762                                  nullptr,
   14763                                  VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
   14764                                  VK_IMAGE_TYPE_2D,
   14765                                  VK_FORMAT_D24_UNORM_S8_UINT,
   14766                                  {1, 1, 1},
   14767                                  1,
   14768                                  1,
   14769                                  VK_SAMPLE_COUNT_1_BIT,
   14770                                  VK_IMAGE_TILING_OPTIMAL,
   14771                                  usages[i],
   14772                                  VK_SHARING_MODE_EXCLUSIVE,
   14773                                  0,
   14774                                  nullptr,
   14775                                  VK_IMAGE_LAYOUT_UNDEFINED};
   14776     VkImageObj image(m_device);
   14777     image.init(&imgInfo);
   14778     ASSERT_TRUE(image.initialized());
   14779 
   14780     VkImageView imageView;
   14781 
   14782     // Initialize VkImageViewCreateInfo with modified format
   14783     VkImageViewCreateInfo ivci = {};
   14784     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   14785     ivci.image = image.handle();
   14786     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
   14787     ivci.format = VK_FORMAT_D32_SFLOAT_S8_UINT;
   14788     ivci.subresourceRange.layerCount = 1;
   14789     ivci.subresourceRange.baseMipLevel = 0;
   14790     ivci.subresourceRange.levelCount = 1;
   14791     ivci.subresourceRange.baseArrayLayer = 0;
   14792     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
   14793 
   14794     // Test for error message
   14795     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, optimal_error_codes[i]);
   14796     VkResult res = vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
   14797     m_errorMonitor->VerifyFound();
   14798 
   14799     if (!res) {
   14800         vkDestroyImageView(m_device->device(), imageView, nullptr);
   14801     }
   14802 }
   14803 
   14804 TEST_F(VkLayerTest, ImageViewInUseDestroyedSignaled) {
   14805     TEST_DESCRIPTION("Delete in-use imageView.");
   14806 
   14807     ASSERT_NO_FATAL_FAILURE(Init());
   14808     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   14809 
   14810     OneOffDescriptorSet ds(m_device, {
   14811                                          {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
   14812                                      });
   14813 
   14814     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
   14815     VkSampler sampler;
   14816 
   14817     VkResult err;
   14818     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
   14819     ASSERT_VK_SUCCESS(err);
   14820 
   14821     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
   14822 
   14823     VkImageObj image(m_device);
   14824     image.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   14825     ASSERT_TRUE(image.initialized());
   14826 
   14827     VkImageView view;
   14828     VkImageViewCreateInfo ivci = {};
   14829     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   14830     ivci.image = image.handle();
   14831     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
   14832     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
   14833     ivci.subresourceRange.layerCount = 1;
   14834     ivci.subresourceRange.baseMipLevel = 0;
   14835     ivci.subresourceRange.levelCount = 1;
   14836     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   14837 
   14838     err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
   14839     ASSERT_VK_SUCCESS(err);
   14840 
   14841     VkDescriptorImageInfo image_info{};
   14842     image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
   14843     image_info.imageView = view;
   14844     image_info.sampler = sampler;
   14845 
   14846     VkWriteDescriptorSet descriptor_write = {};
   14847     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   14848     descriptor_write.dstSet = ds.set_;
   14849     descriptor_write.dstBinding = 0;
   14850     descriptor_write.descriptorCount = 1;
   14851     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
   14852     descriptor_write.pImageInfo = &image_info;
   14853 
   14854     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   14855 
   14856     // Create PSO to use the sampler
   14857     char const *vsSource =
   14858         "#version 450\n"
   14859         "\n"
   14860         "void main(){\n"
   14861         "   gl_Position = vec4(1);\n"
   14862         "}\n";
   14863     char const *fsSource =
   14864         "#version 450\n"
   14865         "\n"
   14866         "layout(set=0, binding=0) uniform sampler2D s;\n"
   14867         "layout(location=0) out vec4 x;\n"
   14868         "void main(){\n"
   14869         "   x = texture(s, vec2(1));\n"
   14870         "}\n";
   14871     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   14872     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   14873     VkPipelineObj pipe(m_device);
   14874     pipe.AddShader(&vs);
   14875     pipe.AddShader(&fs);
   14876     pipe.AddDefaultColorAttachment();
   14877     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   14878 
   14879     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_25400804);
   14880 
   14881     m_commandBuffer->begin();
   14882     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   14883     // Bind pipeline to cmd buffer
   14884     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   14885     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &ds.set_, 0,
   14886                             nullptr);
   14887 
   14888     VkViewport viewport = {0, 0, 16, 16, 0, 1};
   14889     VkRect2D scissor = {{0, 0}, {16, 16}};
   14890     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   14891     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
   14892 
   14893     m_commandBuffer->Draw(1, 0, 0, 0);
   14894     m_commandBuffer->EndRenderPass();
   14895     m_commandBuffer->end();
   14896     // Submit cmd buffer then destroy sampler
   14897     VkSubmitInfo submit_info = {};
   14898     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   14899     submit_info.commandBufferCount = 1;
   14900     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   14901     // Submit cmd buffer and then destroy imageView while in-flight
   14902     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   14903 
   14904     vkDestroyImageView(m_device->device(), view, nullptr);
   14905     m_errorMonitor->VerifyFound();
   14906     vkQueueWaitIdle(m_device->m_queue);
   14907     // Now we can actually destroy imageView
   14908     m_errorMonitor->SetUnexpectedError("If imageView is not VK_NULL_HANDLE, imageView must be a valid VkImageView handle");
   14909     m_errorMonitor->SetUnexpectedError("Unable to remove ImageView obj");
   14910     vkDestroyImageView(m_device->device(), view, NULL);
   14911     vkDestroySampler(m_device->device(), sampler, nullptr);
   14912 }
   14913 
   14914 TEST_F(VkLayerTest, BufferViewInUseDestroyedSignaled) {
   14915     TEST_DESCRIPTION("Delete in-use bufferView.");
   14916 
   14917     ASSERT_NO_FATAL_FAILURE(Init());
   14918     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   14919 
   14920     OneOffDescriptorSet ds(m_device, {
   14921                                          {0, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
   14922                                      });
   14923 
   14924     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
   14925 
   14926     VkBuffer buffer;
   14927     uint32_t queue_family_index = 0;
   14928     VkBufferCreateInfo buffer_create_info = {};
   14929     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   14930     buffer_create_info.size = 1024;
   14931     buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
   14932     buffer_create_info.queueFamilyIndexCount = 1;
   14933     buffer_create_info.pQueueFamilyIndices = &queue_family_index;
   14934 
   14935     VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
   14936     ASSERT_VK_SUCCESS(err);
   14937 
   14938     VkMemoryRequirements memory_reqs;
   14939     VkDeviceMemory buffer_memory;
   14940 
   14941     VkMemoryAllocateInfo memory_info = {};
   14942     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   14943     memory_info.allocationSize = 0;
   14944     memory_info.memoryTypeIndex = 0;
   14945 
   14946     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
   14947     memory_info.allocationSize = memory_reqs.size;
   14948     bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
   14949     ASSERT_TRUE(pass);
   14950 
   14951     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
   14952     ASSERT_VK_SUCCESS(err);
   14953     err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
   14954     ASSERT_VK_SUCCESS(err);
   14955 
   14956     VkBufferView view;
   14957     VkBufferViewCreateInfo bvci = {};
   14958     bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
   14959     bvci.buffer = buffer;
   14960     bvci.format = VK_FORMAT_R32_SFLOAT;
   14961     bvci.range = VK_WHOLE_SIZE;
   14962 
   14963     err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view);
   14964     ASSERT_VK_SUCCESS(err);
   14965 
   14966     VkWriteDescriptorSet descriptor_write = {};
   14967     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   14968     descriptor_write.dstSet = ds.set_;
   14969     descriptor_write.dstBinding = 0;
   14970     descriptor_write.descriptorCount = 1;
   14971     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
   14972     descriptor_write.pTexelBufferView = &view;
   14973 
   14974     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   14975 
   14976     char const *vsSource =
   14977         "#version 450\n"
   14978         "\n"
   14979         "void main(){\n"
   14980         "   gl_Position = vec4(1);\n"
   14981         "}\n";
   14982     char const *fsSource =
   14983         "#version 450\n"
   14984         "\n"
   14985         "layout(set=0, binding=0, r32f) uniform imageBuffer s;\n"
   14986         "layout(location=0) out vec4 x;\n"
   14987         "void main(){\n"
   14988         "   x = imageLoad(s, 0);\n"
   14989         "}\n";
   14990     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   14991     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   14992     VkPipelineObj pipe(m_device);
   14993     pipe.AddShader(&vs);
   14994     pipe.AddShader(&fs);
   14995     pipe.AddDefaultColorAttachment();
   14996     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   14997 
   14998     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_23e00750);
   14999 
   15000     m_commandBuffer->begin();
   15001     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   15002     VkViewport viewport = {0, 0, 16, 16, 0, 1};
   15003     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   15004     VkRect2D scissor = {{0, 0}, {16, 16}};
   15005     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
   15006     // Bind pipeline to cmd buffer
   15007     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   15008     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &ds.set_, 0,
   15009                             nullptr);
   15010     m_commandBuffer->Draw(1, 0, 0, 0);
   15011     m_commandBuffer->EndRenderPass();
   15012     m_commandBuffer->end();
   15013 
   15014     VkSubmitInfo submit_info = {};
   15015     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   15016     submit_info.commandBufferCount = 1;
   15017     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   15018     // Submit cmd buffer and then destroy bufferView while in-flight
   15019     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   15020 
   15021     vkDestroyBufferView(m_device->device(), view, nullptr);
   15022     m_errorMonitor->VerifyFound();
   15023     vkQueueWaitIdle(m_device->m_queue);
   15024     // Now we can actually destroy bufferView
   15025     m_errorMonitor->SetUnexpectedError("If bufferView is not VK_NULL_HANDLE, bufferView must be a valid VkBufferView handle");
   15026     m_errorMonitor->SetUnexpectedError("Unable to remove BufferView obj");
   15027     vkDestroyBufferView(m_device->device(), view, NULL);
   15028     vkDestroyBuffer(m_device->device(), buffer, NULL);
   15029     vkFreeMemory(m_device->device(), buffer_memory, NULL);
   15030 }
   15031 
   15032 TEST_F(VkLayerTest, SamplerInUseDestroyedSignaled) {
   15033     TEST_DESCRIPTION("Delete in-use sampler.");
   15034 
   15035     ASSERT_NO_FATAL_FAILURE(Init());
   15036     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   15037 
   15038     OneOffDescriptorSet ds(m_device, {
   15039                                          {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
   15040                                      });
   15041 
   15042     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
   15043     VkSampler sampler;
   15044 
   15045     VkResult err;
   15046     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
   15047     ASSERT_VK_SUCCESS(err);
   15048 
   15049     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
   15050 
   15051     VkImageObj image(m_device);
   15052     image.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   15053     ASSERT_TRUE(image.initialized());
   15054 
   15055     VkImageView view;
   15056     VkImageViewCreateInfo ivci = {};
   15057     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   15058     ivci.image = image.handle();
   15059     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
   15060     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
   15061     ivci.subresourceRange.layerCount = 1;
   15062     ivci.subresourceRange.baseMipLevel = 0;
   15063     ivci.subresourceRange.levelCount = 1;
   15064     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   15065 
   15066     err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
   15067     ASSERT_VK_SUCCESS(err);
   15068 
   15069     VkDescriptorImageInfo image_info{};
   15070     image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
   15071     image_info.imageView = view;
   15072     image_info.sampler = sampler;
   15073 
   15074     VkWriteDescriptorSet descriptor_write = {};
   15075     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   15076     descriptor_write.dstSet = ds.set_;
   15077     descriptor_write.dstBinding = 0;
   15078     descriptor_write.descriptorCount = 1;
   15079     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
   15080     descriptor_write.pImageInfo = &image_info;
   15081 
   15082     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   15083 
   15084     // Create PSO to use the sampler
   15085     char const *vsSource =
   15086         "#version 450\n"
   15087         "\n"
   15088         "void main(){\n"
   15089         "   gl_Position = vec4(1);\n"
   15090         "}\n";
   15091     char const *fsSource =
   15092         "#version 450\n"
   15093         "\n"
   15094         "layout(set=0, binding=0) uniform sampler2D s;\n"
   15095         "layout(location=0) out vec4 x;\n"
   15096         "void main(){\n"
   15097         "   x = texture(s, vec2(1));\n"
   15098         "}\n";
   15099     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   15100     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   15101     VkPipelineObj pipe(m_device);
   15102     pipe.AddShader(&vs);
   15103     pipe.AddShader(&fs);
   15104     pipe.AddDefaultColorAttachment();
   15105     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   15106 
   15107     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_26600874);
   15108 
   15109     m_commandBuffer->begin();
   15110     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   15111     // Bind pipeline to cmd buffer
   15112     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   15113     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &ds.set_, 0,
   15114                             nullptr);
   15115 
   15116     VkViewport viewport = {0, 0, 16, 16, 0, 1};
   15117     VkRect2D scissor = {{0, 0}, {16, 16}};
   15118     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   15119     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
   15120 
   15121     m_commandBuffer->Draw(1, 0, 0, 0);
   15122     m_commandBuffer->EndRenderPass();
   15123     m_commandBuffer->end();
   15124     // Submit cmd buffer then destroy sampler
   15125     VkSubmitInfo submit_info = {};
   15126     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   15127     submit_info.commandBufferCount = 1;
   15128     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   15129     // Submit cmd buffer and then destroy sampler while in-flight
   15130     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   15131 
   15132     vkDestroySampler(m_device->device(), sampler, nullptr);  // Destroyed too soon
   15133     m_errorMonitor->VerifyFound();
   15134     vkQueueWaitIdle(m_device->m_queue);
   15135 
   15136     // Now we can actually destroy sampler
   15137     m_errorMonitor->SetUnexpectedError("If sampler is not VK_NULL_HANDLE, sampler must be a valid VkSampler handle");
   15138     m_errorMonitor->SetUnexpectedError("Unable to remove Sampler obj");
   15139     vkDestroySampler(m_device->device(), sampler, NULL);  // Destroyed for real
   15140     vkDestroyImageView(m_device->device(), view, NULL);
   15141 }
   15142 
   15143 TEST_F(VkLayerTest, UpdateDestroyDescriptorSetLayout) {
   15144     TEST_DESCRIPTION("Attempt updates to descriptor sets with destroyed descriptor set layouts");
   15145     // TODO: Update to match the descriptor set layout specific VUIDs/VALIDATION_ERROR_* when present
   15146     const auto kWriteDestroyedLayout = VALIDATION_ERROR_15c00280;
   15147     const auto kCopyDstDestroyedLayout = VALIDATION_ERROR_03207601;
   15148     const auto kCopySrcDestroyedLayout = VALIDATION_ERROR_0322d201;
   15149 
   15150     ASSERT_NO_FATAL_FAILURE(Init());
   15151 
   15152     // Set up the descriptor (resource) and write/copy operations to use.
   15153     float data[16] = {};
   15154     VkConstantBufferObj buffer(m_device, sizeof(data), data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
   15155     ASSERT_TRUE(buffer.initialized());
   15156 
   15157     VkDescriptorBufferInfo info = {};
   15158     info.buffer = buffer.handle();
   15159     info.range = VK_WHOLE_SIZE;
   15160 
   15161     VkWriteDescriptorSet write_descriptor = {};
   15162     write_descriptor.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   15163     write_descriptor.dstSet = VK_NULL_HANDLE;  // must update this
   15164     write_descriptor.dstBinding = 0;
   15165     write_descriptor.descriptorCount = 1;
   15166     write_descriptor.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   15167     write_descriptor.pBufferInfo = &info;
   15168 
   15169     VkCopyDescriptorSet copy_descriptor = {};
   15170     copy_descriptor.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
   15171     copy_descriptor.srcSet = VK_NULL_HANDLE;  // must update
   15172     copy_descriptor.srcBinding = 0;
   15173     copy_descriptor.dstSet = VK_NULL_HANDLE;  // must update
   15174     copy_descriptor.dstBinding = 0;
   15175     copy_descriptor.descriptorCount = 1;
   15176 
   15177     // Create valid and invalid source and destination descriptor sets
   15178     std::vector<VkDescriptorSetLayoutBinding> one_uniform_buffer = {
   15179         {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
   15180     };
   15181     OneOffDescriptorSet good_dst(m_device, one_uniform_buffer);
   15182     ASSERT_TRUE(good_dst.Initialized());
   15183 
   15184     OneOffDescriptorSet bad_dst(m_device, one_uniform_buffer);
   15185     // Must assert before invalidating it below
   15186     ASSERT_TRUE(bad_dst.Initialized());
   15187     bad_dst.layout_ = VkDescriptorSetLayoutObj();
   15188 
   15189     OneOffDescriptorSet good_src(m_device, one_uniform_buffer);
   15190     ASSERT_TRUE(good_src.Initialized());
   15191 
   15192     // Put valid data in the good and bad sources, simultaneously doing a postive test on write and copy operations
   15193     m_errorMonitor->ExpectSuccess();
   15194     write_descriptor.dstSet = good_src.set_;
   15195     vkUpdateDescriptorSets(m_device->device(), 1, &write_descriptor, 0, NULL);
   15196     m_errorMonitor->VerifyNotFound();
   15197 
   15198     OneOffDescriptorSet bad_src(m_device, one_uniform_buffer);
   15199     ASSERT_TRUE(bad_src.Initialized());
   15200 
   15201     // to complete our positive testing use copy, where above we used write.
   15202     copy_descriptor.srcSet = good_src.set_;
   15203     copy_descriptor.dstSet = bad_src.set_;
   15204     vkUpdateDescriptorSets(m_device->device(), 0, nullptr, 1, &copy_descriptor);
   15205     bad_src.layout_ = VkDescriptorSetLayoutObj();
   15206     m_errorMonitor->VerifyNotFound();
   15207 
   15208     // Trigger the three invalid use errors
   15209     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, kWriteDestroyedLayout);
   15210     write_descriptor.dstSet = bad_dst.set_;
   15211     vkUpdateDescriptorSets(m_device->device(), 1, &write_descriptor, 0, NULL);
   15212     m_errorMonitor->VerifyFound();
   15213 
   15214     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, kCopyDstDestroyedLayout);
   15215     copy_descriptor.dstSet = bad_dst.set_;
   15216     vkUpdateDescriptorSets(m_device->device(), 0, nullptr, 1, &copy_descriptor);
   15217     m_errorMonitor->VerifyFound();
   15218 
   15219     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, kCopySrcDestroyedLayout);
   15220     copy_descriptor.srcSet = bad_src.set_;
   15221     copy_descriptor.dstSet = good_dst.set_;
   15222     vkUpdateDescriptorSets(m_device->device(), 0, nullptr, 1, &copy_descriptor);
   15223     m_errorMonitor->VerifyFound();
   15224 }
   15225 
   15226 TEST_F(VkLayerTest, QueueForwardProgressFenceWait) {
   15227     TEST_DESCRIPTION(
   15228         "Call VkQueueSubmit with a semaphore that is already signaled but not waited on by the queue. Wait on a fence that has not "
   15229         "yet been submitted to a queue.");
   15230 
   15231     ASSERT_NO_FATAL_FAILURE(Init());
   15232     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   15233 
   15234     const char *queue_forward_progress_message = " that has already been signaled but not waited on by queue 0x";
   15235     const char *invalid_fence_wait_message = " which has not been submitted on a Queue or during acquire next image.";
   15236 
   15237     VkCommandBufferObj cb1(m_device, m_commandPool);
   15238     cb1.begin();
   15239     cb1.end();
   15240 
   15241     VkSemaphoreCreateInfo semaphore_create_info = {};
   15242     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
   15243     VkSemaphore semaphore;
   15244     ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
   15245     VkSubmitInfo submit_info = {};
   15246     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   15247     submit_info.commandBufferCount = 1;
   15248     submit_info.pCommandBuffers = &cb1.handle();
   15249     submit_info.signalSemaphoreCount = 1;
   15250     submit_info.pSignalSemaphores = &semaphore;
   15251     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   15252 
   15253     m_commandBuffer->begin();
   15254     m_commandBuffer->end();
   15255     submit_info.pCommandBuffers = &m_commandBuffer->handle();
   15256     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, queue_forward_progress_message);
   15257     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   15258     m_errorMonitor->VerifyFound();
   15259 
   15260     VkFenceCreateInfo fence_create_info = {};
   15261     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
   15262     VkFence fence;
   15263     ASSERT_VK_SUCCESS(vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence));
   15264 
   15265     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, invalid_fence_wait_message);
   15266     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
   15267     m_errorMonitor->VerifyFound();
   15268 
   15269     vkDeviceWaitIdle(m_device->device());
   15270     vkDestroyFence(m_device->device(), fence, nullptr);
   15271     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
   15272 }
   15273 
   15274 TEST_F(VkLayerTest, FramebufferIncompatible) {
   15275     TEST_DESCRIPTION(
   15276         "Bind a secondary command buffer with with a framebuffer that does not match the framebuffer for the active renderpass.");
   15277     ASSERT_NO_FATAL_FAILURE(Init());
   15278     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   15279 
   15280     // A renderpass with one color attachment.
   15281     VkAttachmentDescription attachment = {0,
   15282                                           VK_FORMAT_B8G8R8A8_UNORM,
   15283                                           VK_SAMPLE_COUNT_1_BIT,
   15284                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   15285                                           VK_ATTACHMENT_STORE_OP_STORE,
   15286                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   15287                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
   15288                                           VK_IMAGE_LAYOUT_UNDEFINED,
   15289                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
   15290 
   15291     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
   15292 
   15293     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
   15294 
   15295     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
   15296 
   15297     VkRenderPass rp;
   15298     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   15299     ASSERT_VK_SUCCESS(err);
   15300 
   15301     // A compatible framebuffer.
   15302     VkImageObj image(m_device);
   15303     image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   15304     ASSERT_TRUE(image.initialized());
   15305 
   15306     VkImageViewCreateInfo ivci = {
   15307         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
   15308         nullptr,
   15309         0,
   15310         image.handle(),
   15311         VK_IMAGE_VIEW_TYPE_2D,
   15312         VK_FORMAT_B8G8R8A8_UNORM,
   15313         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
   15314          VK_COMPONENT_SWIZZLE_IDENTITY},
   15315         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
   15316     };
   15317     VkImageView view;
   15318     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
   15319     ASSERT_VK_SUCCESS(err);
   15320 
   15321     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
   15322     VkFramebuffer fb;
   15323     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
   15324     ASSERT_VK_SUCCESS(err);
   15325 
   15326     VkCommandBufferAllocateInfo cbai = {};
   15327     cbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
   15328     cbai.commandPool = m_commandPool->handle();
   15329     cbai.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
   15330     cbai.commandBufferCount = 1;
   15331 
   15332     VkCommandBuffer sec_cb;
   15333     err = vkAllocateCommandBuffers(m_device->device(), &cbai, &sec_cb);
   15334     ASSERT_VK_SUCCESS(err);
   15335     VkCommandBufferBeginInfo cbbi = {};
   15336     VkCommandBufferInheritanceInfo cbii = {};
   15337     cbii.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
   15338     cbii.renderPass = renderPass();
   15339     cbii.framebuffer = fb;
   15340     cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   15341     cbbi.pNext = NULL;
   15342     cbbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
   15343     cbbi.pInheritanceInfo = &cbii;
   15344     vkBeginCommandBuffer(sec_cb, &cbbi);
   15345     vkEndCommandBuffer(sec_cb);
   15346 
   15347     VkCommandBufferBeginInfo cbbi2 = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, nullptr};
   15348     vkBeginCommandBuffer(m_commandBuffer->handle(), &cbbi2);
   15349     vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
   15350 
   15351     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   15352                                          " that is not the same as the primary command buffer's current active framebuffer ");
   15353     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &sec_cb);
   15354     m_errorMonitor->VerifyFound();
   15355     // Cleanup
   15356     vkDestroyImageView(m_device->device(), view, NULL);
   15357     vkDestroyRenderPass(m_device->device(), rp, NULL);
   15358     vkDestroyFramebuffer(m_device->device(), fb, NULL);
   15359 }
   15360 
   15361 TEST_F(VkLayerTest, ColorBlendInvalidLogicOp) {
   15362     TEST_DESCRIPTION("Attempt to use invalid VkPipelineColorBlendStateCreateInfo::logicOp value.");
   15363 
   15364     ASSERT_NO_FATAL_FAILURE(Init());  // enables all supported features
   15365     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   15366 
   15367     if (!m_device->phy().features().logicOp) {
   15368         printf("             Device does not support logicOp feature; skipped.\n");
   15369         return;
   15370     }
   15371 
   15372     const auto set_shading_enable = [](CreatePipelineHelper &helper) {
   15373         helper.cb_ci_.logicOpEnable = VK_TRUE;
   15374         helper.cb_ci_.logicOp = static_cast<VkLogicOp>(VK_LOGIC_OP_END_RANGE + 1);  // invalid logicOp to be tested
   15375     };
   15376     CreatePipelineHelper::OneshotTest(*this, set_shading_enable, VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0f4004be);
   15377 }
   15378 
   15379 TEST_F(VkLayerTest, ColorBlendUnsupportedLogicOp) {
   15380     TEST_DESCRIPTION("Attempt enabling VkPipelineColorBlendStateCreateInfo::logicOpEnable when logicOp feature is disabled.");
   15381 
   15382     VkPhysicalDeviceFeatures features{};
   15383     ASSERT_NO_FATAL_FAILURE(Init(&features));
   15384     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   15385 
   15386     const auto set_shading_enable = [](CreatePipelineHelper &helper) { helper.cb_ci_.logicOpEnable = VK_TRUE; };
   15387     CreatePipelineHelper::OneshotTest(*this, set_shading_enable, VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0f4004bc);
   15388 }
   15389 
   15390 #if GTEST_IS_THREADSAFE
   15391 struct thread_data_struct {
   15392     VkCommandBuffer commandBuffer;
   15393     VkDevice device;
   15394     VkEvent event;
   15395     bool bailout;
   15396 };
   15397 
   15398 extern "C" void *AddToCommandBuffer(void *arg) {
   15399     struct thread_data_struct *data = (struct thread_data_struct *)arg;
   15400 
   15401     for (int i = 0; i < 80000; i++) {
   15402         vkCmdSetEvent(data->commandBuffer, data->event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
   15403         if (data->bailout) {
   15404             break;
   15405         }
   15406     }
   15407     return NULL;
   15408 }
   15409 
   15410 TEST_F(VkLayerTest, ThreadCommandBufferCollision) {
   15411     test_platform_thread thread;
   15412 
   15413     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "THREADING ERROR");
   15414 
   15415     ASSERT_NO_FATAL_FAILURE(Init());
   15416     ASSERT_NO_FATAL_FAILURE(InitViewport());
   15417     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   15418 
   15419     // Calls AllocateCommandBuffers
   15420     VkCommandBufferObj commandBuffer(m_device, m_commandPool);
   15421 
   15422     commandBuffer.begin();
   15423 
   15424     VkEventCreateInfo event_info;
   15425     VkEvent event;
   15426     VkResult err;
   15427 
   15428     memset(&event_info, 0, sizeof(event_info));
   15429     event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
   15430 
   15431     err = vkCreateEvent(device(), &event_info, NULL, &event);
   15432     ASSERT_VK_SUCCESS(err);
   15433 
   15434     err = vkResetEvent(device(), event);
   15435     ASSERT_VK_SUCCESS(err);
   15436 
   15437     struct thread_data_struct data;
   15438     data.commandBuffer = commandBuffer.handle();
   15439     data.event = event;
   15440     data.bailout = false;
   15441     m_errorMonitor->SetBailout(&data.bailout);
   15442 
   15443     // First do some correct operations using multiple threads.
   15444     // Add many entries to command buffer from another thread.
   15445     test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data);
   15446     // Make non-conflicting calls from this thread at the same time.
   15447     for (int i = 0; i < 80000; i++) {
   15448         uint32_t count;
   15449         vkEnumeratePhysicalDevices(instance(), &count, NULL);
   15450     }
   15451     test_platform_thread_join(thread, NULL);
   15452 
   15453     // Then do some incorrect operations using multiple threads.
   15454     // Add many entries to command buffer from another thread.
   15455     test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data);
   15456     // Add many entries to command buffer from this thread at the same time.
   15457     AddToCommandBuffer(&data);
   15458 
   15459     test_platform_thread_join(thread, NULL);
   15460     commandBuffer.end();
   15461 
   15462     m_errorMonitor->SetBailout(NULL);
   15463 
   15464     m_errorMonitor->VerifyFound();
   15465 
   15466     vkDestroyEvent(device(), event, NULL);
   15467 }
   15468 #endif  // GTEST_IS_THREADSAFE
   15469 
   15470 TEST_F(VkLayerTest, InvalidSPIRVCodeSize) {
   15471     TEST_DESCRIPTION("Test that errors are produced for a spirv modules with invalid code sizes");
   15472 
   15473     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid SPIR-V header");
   15474 
   15475     ASSERT_NO_FATAL_FAILURE(Init());
   15476     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   15477 
   15478     VkShaderModule module;
   15479     VkShaderModuleCreateInfo moduleCreateInfo;
   15480     struct icd_spv_header spv;
   15481 
   15482     spv.magic = ICD_SPV_MAGIC;
   15483     spv.version = ICD_SPV_VERSION;
   15484     spv.gen_magic = 0;
   15485 
   15486     moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
   15487     moduleCreateInfo.pNext = NULL;
   15488     moduleCreateInfo.pCode = (const uint32_t *)&spv;
   15489     moduleCreateInfo.codeSize = 4;
   15490     moduleCreateInfo.flags = 0;
   15491     vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module);
   15492 
   15493     m_errorMonitor->VerifyFound();
   15494 
   15495     char const *vsSource =
   15496         "#version 450\n"
   15497         "\n"
   15498         "layout(location=0) out float x;\n"
   15499         "void main(){\n"
   15500         "   gl_Position = vec4(1);\n"
   15501         "   x = 0;\n"
   15502         "}\n";
   15503 
   15504     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_12a00ac0);
   15505     std::vector<unsigned int> shader;
   15506     VkShaderModuleCreateInfo module_create_info;
   15507     VkShaderModule shader_module;
   15508     module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
   15509     module_create_info.pNext = NULL;
   15510     this->GLSLtoSPV(VK_SHADER_STAGE_VERTEX_BIT, vsSource, shader);
   15511     module_create_info.pCode = shader.data();
   15512     // Introduce failure by making codeSize a non-multiple of 4
   15513     module_create_info.codeSize = shader.size() * sizeof(unsigned int) - 1;
   15514     module_create_info.flags = 0;
   15515     vkCreateShaderModule(m_device->handle(), &module_create_info, NULL, &shader_module);
   15516 
   15517     m_errorMonitor->VerifyFound();
   15518 }
   15519 
   15520 TEST_F(VkLayerTest, InvalidSPIRVMagic) {
   15521     TEST_DESCRIPTION("Test that an error is produced for a spirv module with a bad magic number");
   15522 
   15523     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid SPIR-V magic number");
   15524 
   15525     ASSERT_NO_FATAL_FAILURE(Init());
   15526     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   15527 
   15528     VkShaderModule module;
   15529     VkShaderModuleCreateInfo moduleCreateInfo;
   15530     struct icd_spv_header spv;
   15531 
   15532     spv.magic = (uint32_t)~ICD_SPV_MAGIC;
   15533     spv.version = ICD_SPV_VERSION;
   15534     spv.gen_magic = 0;
   15535 
   15536     moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
   15537     moduleCreateInfo.pNext = NULL;
   15538     moduleCreateInfo.pCode = (const uint32_t *)&spv;
   15539     moduleCreateInfo.codeSize = sizeof(spv) + 16;
   15540     moduleCreateInfo.flags = 0;
   15541     vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module);
   15542 
   15543     m_errorMonitor->VerifyFound();
   15544 }
   15545 
   15546 TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed) {
   15547     TEST_DESCRIPTION("Test that a warning is produced for a vertex output that is not consumed by the fragment stage");
   15548     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "not consumed by fragment shader");
   15549 
   15550     ASSERT_NO_FATAL_FAILURE(Init());
   15551     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   15552 
   15553     char const *vsSource =
   15554         "#version 450\n"
   15555         "\n"
   15556         "layout(location=0) out float x;\n"
   15557         "void main(){\n"
   15558         "   gl_Position = vec4(1);\n"
   15559         "   x = 0;\n"
   15560         "}\n";
   15561     char const *fsSource =
   15562         "#version 450\n"
   15563         "\n"
   15564         "layout(location=0) out vec4 color;\n"
   15565         "void main(){\n"
   15566         "   color = vec4(1);\n"
   15567         "}\n";
   15568 
   15569     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   15570     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   15571 
   15572     VkPipelineObj pipe(m_device);
   15573     pipe.AddDefaultColorAttachment();
   15574     pipe.AddShader(&vs);
   15575     pipe.AddShader(&fs);
   15576 
   15577     VkDescriptorSetObj descriptorSet(m_device);
   15578     descriptorSet.AppendDummy();
   15579     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   15580 
   15581     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   15582 
   15583     m_errorMonitor->VerifyFound();
   15584 }
   15585 
   15586 TEST_F(VkPositiveLayerTest, CreatePipelineComplexTypes) {
   15587     TEST_DESCRIPTION("Smoke test for complex types across VS/FS boundary");
   15588     ASSERT_NO_FATAL_FAILURE(Init());
   15589     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   15590 
   15591     if (!m_device->phy().features().tessellationShader) {
   15592         printf("             Device does not support tessellation shaders; skipped.\n");
   15593         return;
   15594     }
   15595 
   15596     m_errorMonitor->ExpectSuccess();
   15597 
   15598     char const *vsSource =
   15599         "#version 450\n"
   15600         "void main() {}";
   15601     char const *tcsSource =
   15602         "#version 450\n"
   15603         "layout(vertices=3) out;\n"
   15604         "struct S { int x; };\n"
   15605         "layout(location=2) patch out B { S s; } b;\n"
   15606         "void main() {\n"
   15607         "   gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
   15608         "   gl_TessLevelInner[0] = 1;\n"
   15609         "   b.s.x = 1;\n"
   15610         "}\n";
   15611 
   15612     char const *tesSource =
   15613         "#version 450\n"
   15614         "layout(triangles, equal_spacing, cw) in;\n"
   15615         "struct S { int x; };\n"
   15616         "layout(location=2) patch in B { S s; } b;\n"
   15617         "void main() { gl_Position = vec4(b.s.x); }\n";
   15618 
   15619     char const *fsSource =
   15620         "#version 450\n"
   15621         "layout(location=0) out vec4 c;\n"
   15622         "void main() { c = vec4(1); }\n";
   15623 
   15624     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   15625     VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
   15626     VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
   15627     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   15628 
   15629     VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
   15630                                                  VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
   15631 
   15632     VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
   15633 
   15634     VkPipelineObj pipe(m_device);
   15635 
   15636     pipe.AddDefaultColorAttachment();
   15637     pipe.AddShader(&vs);
   15638     pipe.AddShader(&tcs);
   15639     pipe.AddShader(&tes);
   15640     pipe.AddShader(&fs);
   15641     pipe.SetInputAssembly(&iasci);
   15642     pipe.SetTessellation(&tsci);
   15643 
   15644     VkDescriptorSetObj descriptorSet(m_device);
   15645     descriptorSet.AppendDummy();
   15646     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   15647 
   15648     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   15649 
   15650     m_errorMonitor->VerifyNotFound();
   15651 }
   15652 
   15653 TEST_F(VkLayerTest, CreatePipelineCheckShaderBadSpecialization) {
   15654     TEST_DESCRIPTION("Challenge core_validation with shader validation issues related to vkCreateGraphicsPipelines.");
   15655 
   15656     ASSERT_NO_FATAL_FAILURE(Init());
   15657     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   15658 
   15659     const char *bad_specialization_message =
   15660         "Specialization entry 0 (for constant id 0) references memory outside provided specialization data ";
   15661 
   15662     char const *vsSource =
   15663         "#version 450\n"
   15664         "\n"
   15665         "void main(){\n"
   15666         "   gl_Position = vec4(1);\n"
   15667         "}\n";
   15668 
   15669     char const *fsSource =
   15670         "#version 450\n"
   15671         "\n"
   15672         "layout (constant_id = 0) const float r = 0.0f;\n"
   15673         "layout(location = 0) out vec4 uFragColor;\n"
   15674         "void main(){\n"
   15675         "   uFragColor = vec4(r,1,0,1);\n"
   15676         "}\n";
   15677 
   15678     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   15679     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   15680 
   15681     const VkPipelineLayoutObj pipeline_layout(m_device);
   15682 
   15683     VkPipelineViewportStateCreateInfo vp_state_create_info = {};
   15684     vp_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
   15685     vp_state_create_info.viewportCount = 1;
   15686     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
   15687     vp_state_create_info.pViewports = &viewport;
   15688     vp_state_create_info.scissorCount = 1;
   15689 
   15690     VkDynamicState scissor_state = VK_DYNAMIC_STATE_SCISSOR;
   15691 
   15692     VkPipelineDynamicStateCreateInfo pipeline_dynamic_state_create_info = {};
   15693     pipeline_dynamic_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
   15694     pipeline_dynamic_state_create_info.dynamicStateCount = 1;
   15695     pipeline_dynamic_state_create_info.pDynamicStates = &scissor_state;
   15696 
   15697     VkPipelineShaderStageCreateInfo shader_stage_create_info[2] = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
   15698 
   15699     VkPipelineVertexInputStateCreateInfo vertex_input_create_info = {};
   15700     vertex_input_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
   15701 
   15702     VkPipelineInputAssemblyStateCreateInfo input_assembly_create_info = {};
   15703     input_assembly_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
   15704     input_assembly_create_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
   15705 
   15706     VkPipelineRasterizationStateCreateInfo rasterization_state_create_info = {};
   15707     rasterization_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
   15708     rasterization_state_create_info.pNext = nullptr;
   15709     rasterization_state_create_info.lineWidth = 1.0f;
   15710     rasterization_state_create_info.rasterizerDiscardEnable = true;
   15711 
   15712     VkPipelineColorBlendAttachmentState color_blend_attachment_state = {};
   15713     color_blend_attachment_state.blendEnable = VK_FALSE;
   15714     color_blend_attachment_state.colorWriteMask = 0xf;
   15715 
   15716     VkPipelineColorBlendStateCreateInfo color_blend_state_create_info = {};
   15717     color_blend_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
   15718     color_blend_state_create_info.attachmentCount = 1;
   15719     color_blend_state_create_info.pAttachments = &color_blend_attachment_state;
   15720 
   15721     VkGraphicsPipelineCreateInfo graphicspipe_create_info = {};
   15722     graphicspipe_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
   15723     graphicspipe_create_info.stageCount = 2;
   15724     graphicspipe_create_info.pStages = shader_stage_create_info;
   15725     graphicspipe_create_info.pVertexInputState = &vertex_input_create_info;
   15726     graphicspipe_create_info.pInputAssemblyState = &input_assembly_create_info;
   15727     graphicspipe_create_info.pViewportState = &vp_state_create_info;
   15728     graphicspipe_create_info.pRasterizationState = &rasterization_state_create_info;
   15729     graphicspipe_create_info.pColorBlendState = &color_blend_state_create_info;
   15730     graphicspipe_create_info.pDynamicState = &pipeline_dynamic_state_create_info;
   15731     graphicspipe_create_info.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
   15732     graphicspipe_create_info.layout = pipeline_layout.handle();
   15733     graphicspipe_create_info.renderPass = renderPass();
   15734 
   15735     VkPipelineCacheCreateInfo pipeline_cache_create_info = {};
   15736     pipeline_cache_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
   15737 
   15738     VkPipelineCache pipelineCache;
   15739     ASSERT_VK_SUCCESS(vkCreatePipelineCache(m_device->device(), &pipeline_cache_create_info, nullptr, &pipelineCache));
   15740 
   15741     // This structure maps constant ids to data locations.
   15742     const VkSpecializationMapEntry entry =
   15743         // id,  offset,                size
   15744         {0, 4, sizeof(uint32_t)};  // Challenge core validation by using a bogus offset.
   15745 
   15746     uint32_t data = 1;
   15747 
   15748     // Set up the info describing spec map and data
   15749     const VkSpecializationInfo specialization_info = {
   15750         1,
   15751         &entry,
   15752         1 * sizeof(float),
   15753         &data,
   15754     };
   15755     shader_stage_create_info[0].pSpecializationInfo = &specialization_info;
   15756 
   15757     VkPipeline pipeline;
   15758     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, bad_specialization_message);
   15759     vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &graphicspipe_create_info, nullptr, &pipeline);
   15760     m_errorMonitor->VerifyFound();
   15761 
   15762     vkDestroyPipelineCache(m_device->device(), pipelineCache, nullptr);
   15763 }
   15764 
   15765 TEST_F(VkLayerTest, CreatePipelineCheckShaderDescriptorTypeMismatch) {
   15766     TEST_DESCRIPTION("Challenge core_validation with shader validation issues related to vkCreateGraphicsPipelines.");
   15767 
   15768     ASSERT_NO_FATAL_FAILURE(Init());
   15769     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   15770 
   15771     const char *descriptor_type_mismatch_message = "Type mismatch on descriptor slot 0.0 (used as type ";
   15772 
   15773     OneOffDescriptorSet ds(m_device, {
   15774                                          {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
   15775                                      });
   15776 
   15777     char const *vsSource =
   15778         "#version 450\n"
   15779         "\n"
   15780         "layout (std140, set = 0, binding = 0) uniform buf {\n"
   15781         "    mat4 mvp;\n"
   15782         "} ubuf;\n"
   15783         "void main(){\n"
   15784         "   gl_Position = ubuf.mvp * vec4(1);\n"
   15785         "}\n";
   15786 
   15787     char const *fsSource =
   15788         "#version 450\n"
   15789         "\n"
   15790         "layout(location = 0) out vec4 uFragColor;\n"
   15791         "void main(){\n"
   15792         "   uFragColor = vec4(0,1,0,1);\n"
   15793         "}\n";
   15794 
   15795     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   15796     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   15797 
   15798     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
   15799 
   15800     VkPipelineObj pipe(m_device);
   15801     pipe.AddDefaultColorAttachment();
   15802     pipe.AddShader(&vs);
   15803     pipe.AddShader(&fs);
   15804 
   15805     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, descriptor_type_mismatch_message);
   15806     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   15807     m_errorMonitor->VerifyFound();
   15808 }
   15809 
   15810 TEST_F(VkLayerTest, CreatePipelineCheckShaderDescriptorNotAccessible) {
   15811     TEST_DESCRIPTION(
   15812         "Create a pipeline in which a descriptor used by a shader stage does not include that stage in its stageFlags.");
   15813 
   15814     ASSERT_NO_FATAL_FAILURE(Init());
   15815     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   15816 
   15817     const char *descriptor_not_accessible_message = "Shader uses descriptor slot 0.0 (used as type ";
   15818 
   15819     OneOffDescriptorSet ds(m_device, {
   15820                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT /*!*/, nullptr},
   15821                                      });
   15822 
   15823     char const *vsSource =
   15824         "#version 450\n"
   15825         "\n"
   15826         "layout (std140, set = 0, binding = 0) uniform buf {\n"
   15827         "    mat4 mvp;\n"
   15828         "} ubuf;\n"
   15829         "void main(){\n"
   15830         "   gl_Position = ubuf.mvp * vec4(1);\n"
   15831         "}\n";
   15832 
   15833     char const *fsSource =
   15834         "#version 450\n"
   15835         "\n"
   15836         "layout(location = 0) out vec4 uFragColor;\n"
   15837         "void main(){\n"
   15838         "   uFragColor = vec4(0,1,0,1);\n"
   15839         "}\n";
   15840 
   15841     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   15842     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   15843 
   15844     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
   15845 
   15846     VkPipelineObj pipe(m_device);
   15847     pipe.AddDefaultColorAttachment();
   15848     pipe.AddShader(&vs);
   15849     pipe.AddShader(&fs);
   15850 
   15851     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, descriptor_not_accessible_message);
   15852     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   15853     m_errorMonitor->VerifyFound();
   15854 }
   15855 
   15856 TEST_F(VkLayerTest, CreatePipelineCheckShaderPushConstantNotAccessible) {
   15857     TEST_DESCRIPTION(
   15858         "Create a graphics pipleine in which a push constant range containing a push constant block member is not accessible from "
   15859         "the current shader stage.");
   15860 
   15861     ASSERT_NO_FATAL_FAILURE(Init());
   15862     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   15863 
   15864     const char *push_constant_not_accessible_message =
   15865         "Push constant range covering variable starting at offset 0 not accessible from stage VK_SHADER_STAGE_VERTEX_BIT";
   15866 
   15867     char const *vsSource =
   15868         "#version 450\n"
   15869         "\n"
   15870         "layout(push_constant, std430) uniform foo { float x; } consts;\n"
   15871         "void main(){\n"
   15872         "   gl_Position = vec4(consts.x);\n"
   15873         "}\n";
   15874 
   15875     char const *fsSource =
   15876         "#version 450\n"
   15877         "\n"
   15878         "layout(location = 0) out vec4 uFragColor;\n"
   15879         "void main(){\n"
   15880         "   uFragColor = vec4(0,1,0,1);\n"
   15881         "}\n";
   15882 
   15883     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   15884     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   15885 
   15886     // Set up a push constant range
   15887     VkPushConstantRange push_constant_range = {};
   15888     // Set to the wrong stage to challenge core_validation
   15889     push_constant_range.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
   15890     push_constant_range.size = 4;
   15891 
   15892     const VkPipelineLayoutObj pipeline_layout(m_device, {}, {push_constant_range});
   15893 
   15894     VkPipelineObj pipe(m_device);
   15895     pipe.AddDefaultColorAttachment();
   15896     pipe.AddShader(&vs);
   15897     pipe.AddShader(&fs);
   15898 
   15899     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, push_constant_not_accessible_message);
   15900     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   15901     m_errorMonitor->VerifyFound();
   15902 }
   15903 
   15904 TEST_F(VkLayerTest, CreatePipelineCheckShaderNotEnabled) {
   15905     TEST_DESCRIPTION(
   15906         "Create a graphics pipeline in which a capability declared by the shader requires a feature not enabled on the device.");
   15907 
   15908     ASSERT_NO_FATAL_FAILURE(Init());
   15909     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   15910 
   15911     const char *feature_not_enabled_message =
   15912         "Shader requires VkPhysicalDeviceFeatures::shaderFloat64 but is not enabled on the device";
   15913 
   15914     // Some awkward steps are required to test with custom device features.
   15915     std::vector<const char *> device_extension_names;
   15916     auto features = m_device->phy().features();
   15917     // Disable support for 64 bit floats
   15918     features.shaderFloat64 = false;
   15919     // The sacrificial device object
   15920     VkDeviceObj test_device(0, gpu(), device_extension_names, &features);
   15921 
   15922     char const *vsSource =
   15923         "#version 450\n"
   15924         "\n"
   15925         "void main(){\n"
   15926         "   gl_Position = vec4(1);\n"
   15927         "}\n";
   15928     char const *fsSource =
   15929         "#version 450\n"
   15930         "\n"
   15931         "layout(location=0) out vec4 color;\n"
   15932         "void main(){\n"
   15933         "   dvec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
   15934         "   color = vec4(green);\n"
   15935         "}\n";
   15936 
   15937     VkShaderObj vs(&test_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   15938     VkShaderObj fs(&test_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   15939 
   15940     VkRenderpassObj render_pass(&test_device);
   15941 
   15942     VkPipelineObj pipe(&test_device);
   15943     pipe.AddDefaultColorAttachment();
   15944     pipe.AddShader(&vs);
   15945     pipe.AddShader(&fs);
   15946 
   15947     const VkPipelineLayoutObj pipeline_layout(&test_device);
   15948 
   15949     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, feature_not_enabled_message);
   15950     pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle());
   15951     m_errorMonitor->VerifyFound();
   15952 }
   15953 
   15954 TEST_F(VkLayerTest, CreateShaderModuleCheckBadCapability) {
   15955     TEST_DESCRIPTION("Create a shader in which a capability declared by the shader is not supported.");
   15956     // Note that this failure message comes from spirv-tools, specifically the validator.
   15957 
   15958     ASSERT_NO_FATAL_FAILURE(Init());
   15959     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   15960 
   15961     char const *vsSource =
   15962         "#version 450\n"
   15963         "\n"
   15964         "layout(xfb_buffer = 1) out;\n"
   15965         "void main(){\n"
   15966         "   gl_Position = vec4(1);\n"
   15967         "}\n";
   15968 
   15969     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Capability TransformFeedback is not allowed by Vulkan");
   15970 
   15971     std::vector<unsigned int> spv;
   15972     VkShaderModuleCreateInfo module_create_info;
   15973     VkShaderModule shader_module;
   15974     module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
   15975     module_create_info.pNext = NULL;
   15976     this->GLSLtoSPV(VK_SHADER_STAGE_VERTEX_BIT, vsSource, spv);
   15977     module_create_info.pCode = spv.data();
   15978     module_create_info.codeSize = spv.size() * sizeof(unsigned int);
   15979     module_create_info.flags = 0;
   15980 
   15981     vkCreateShaderModule(m_device->handle(), &module_create_info, NULL, &shader_module);
   15982 
   15983     m_errorMonitor->VerifyFound();
   15984 }
   15985 
   15986 TEST_F(VkPositiveLayerTest, CreatePipelineCheckShaderCapabilityExtension1of2) {
   15987     // This is a positive test, no errors expected
   15988     // Verifies the ability to deal with a shader that declares a non-unique SPIRV capability ID
   15989     TEST_DESCRIPTION("Create a shader in which uses a non-unique capability ID extension, 1 of 2");
   15990 
   15991     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   15992     if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME)) {
   15993         printf("             Extension %s not supported, skipping this pass. \n",
   15994                VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME);
   15995         return;
   15996     }
   15997     m_device_extension_names.push_back(VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME);
   15998     ASSERT_NO_FATAL_FAILURE(InitState());
   15999 
   16000     // These tests require that the device support multiViewport
   16001     if (!m_device->phy().features().multiViewport) {
   16002         printf("             Device does not support multiViewport, test skipped.\n");
   16003         return;
   16004     }
   16005     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   16006 
   16007     // Vertex shader using viewport array capability
   16008     char const *vsSource =
   16009         "#version 450\n"
   16010         "#extension GL_ARB_shader_viewport_layer_array : enable\n"
   16011         "void main() {\n"
   16012         "    gl_ViewportIndex = 1;\n"
   16013         "}\n";
   16014 
   16015     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   16016 
   16017     VkPipelineObj pipe(m_device);
   16018     pipe.AddDefaultColorAttachment();
   16019     pipe.AddShader(&vs);
   16020 
   16021     const VkPipelineLayoutObj pipe_layout(m_device, {});
   16022 
   16023     m_errorMonitor->ExpectSuccess();
   16024     pipe.CreateVKPipeline(pipe_layout.handle(), renderPass());
   16025     m_errorMonitor->VerifyNotFound();
   16026 }
   16027 
   16028 TEST_F(VkPositiveLayerTest, CreatePipelineCheckShaderCapabilityExtension2of2) {
   16029     // This is a positive test, no errors expected
   16030     // Verifies the ability to deal with a shader that declares a non-unique SPIRV capability ID
   16031     TEST_DESCRIPTION("Create a shader in which uses a non-unique capability ID extension, 2 of 2");
   16032 
   16033     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   16034     if (!DeviceExtensionSupported(gpu(), nullptr, VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME)) {
   16035         printf("             Extension %s not supported, skipping this pass. \n", VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME);
   16036         return;
   16037     }
   16038     m_device_extension_names.push_back(VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME);
   16039     ASSERT_NO_FATAL_FAILURE(InitState());
   16040 
   16041     // These tests require that the device support multiViewport
   16042     if (!m_device->phy().features().multiViewport) {
   16043         printf("             Device does not support multiViewport, test skipped.\n");
   16044         return;
   16045     }
   16046     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   16047 
   16048     // Vertex shader using viewport array capability
   16049     char const *vsSource =
   16050         "#version 450\n"
   16051         "#extension GL_ARB_shader_viewport_layer_array : enable\n"
   16052         "void main() {\n"
   16053         "    gl_ViewportIndex = 1;\n"
   16054         "}\n";
   16055 
   16056     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   16057 
   16058     VkPipelineObj pipe(m_device);
   16059     pipe.AddDefaultColorAttachment();
   16060     pipe.AddShader(&vs);
   16061 
   16062     const VkPipelineLayoutObj pipe_layout(m_device, {});
   16063 
   16064     m_errorMonitor->ExpectSuccess();
   16065     pipe.CreateVKPipeline(pipe_layout.handle(), renderPass());
   16066     m_errorMonitor->VerifyNotFound();
   16067 }
   16068 
   16069 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided) {
   16070     TEST_DESCRIPTION(
   16071         "Test that an error is produced for a fragment shader input which is not present in the outputs of the previous stage");
   16072 
   16073     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not written by vertex shader");
   16074 
   16075     ASSERT_NO_FATAL_FAILURE(Init());
   16076     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   16077 
   16078     char const *vsSource =
   16079         "#version 450\n"
   16080         "\n"
   16081         "void main(){\n"
   16082         "   gl_Position = vec4(1);\n"
   16083         "}\n";
   16084     char const *fsSource =
   16085         "#version 450\n"
   16086         "\n"
   16087         "layout(location=0) in float x;\n"
   16088         "layout(location=0) out vec4 color;\n"
   16089         "void main(){\n"
   16090         "   color = vec4(x);\n"
   16091         "}\n";
   16092 
   16093     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   16094     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   16095 
   16096     VkPipelineObj pipe(m_device);
   16097     pipe.AddDefaultColorAttachment();
   16098     pipe.AddShader(&vs);
   16099     pipe.AddShader(&fs);
   16100 
   16101     VkDescriptorSetObj descriptorSet(m_device);
   16102     descriptorSet.AppendDummy();
   16103     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   16104 
   16105     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16106 
   16107     m_errorMonitor->VerifyFound();
   16108 }
   16109 
   16110 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvidedInBlock) {
   16111     TEST_DESCRIPTION(
   16112         "Test that an error is produced for a fragment shader input within an interace block, which is not present in the outputs "
   16113         "of the previous stage.");
   16114     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not written by vertex shader");
   16115 
   16116     ASSERT_NO_FATAL_FAILURE(Init());
   16117     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   16118 
   16119     char const *vsSource =
   16120         "#version 450\n"
   16121         "\n"
   16122         "void main(){\n"
   16123         "   gl_Position = vec4(1);\n"
   16124         "}\n";
   16125     char const *fsSource =
   16126         "#version 450\n"
   16127         "\n"
   16128         "in block { layout(location=0) float x; } ins;\n"
   16129         "layout(location=0) out vec4 color;\n"
   16130         "void main(){\n"
   16131         "   color = vec4(ins.x);\n"
   16132         "}\n";
   16133 
   16134     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   16135     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   16136 
   16137     VkPipelineObj pipe(m_device);
   16138     pipe.AddDefaultColorAttachment();
   16139     pipe.AddShader(&vs);
   16140     pipe.AddShader(&fs);
   16141 
   16142     VkDescriptorSetObj descriptorSet(m_device);
   16143     descriptorSet.AppendDummy();
   16144     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   16145 
   16146     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16147 
   16148     m_errorMonitor->VerifyFound();
   16149 }
   16150 
   16151 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchArraySize) {
   16152     TEST_DESCRIPTION("Test that an error is produced for mismatched array sizes across the vertex->fragment shader interface");
   16153     m_errorMonitor->SetDesiredFailureMsg(
   16154         VK_DEBUG_REPORT_ERROR_BIT_EXT,
   16155         "Type mismatch on location 0.0: 'ptr to output arr[2] of float32' vs 'ptr to input arr[1] of float32'");
   16156 
   16157     ASSERT_NO_FATAL_FAILURE(Init());
   16158     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   16159 
   16160     char const *vsSource =
   16161         "#version 450\n"
   16162         "\n"
   16163         "layout(location=0) out float x[2];\n"
   16164         "void main(){\n"
   16165         "   x[0] = 0; x[1] = 0;\n"
   16166         "   gl_Position = vec4(1);\n"
   16167         "}\n";
   16168     char const *fsSource =
   16169         "#version 450\n"
   16170         "\n"
   16171         "layout(location=0) in float x[1];\n"
   16172         "layout(location=0) out vec4 color;\n"
   16173         "void main(){\n"
   16174         "   color = vec4(x[0]);\n"
   16175         "}\n";
   16176 
   16177     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   16178     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   16179 
   16180     VkPipelineObj pipe(m_device);
   16181     pipe.AddDefaultColorAttachment();
   16182     pipe.AddShader(&vs);
   16183     pipe.AddShader(&fs);
   16184 
   16185     VkDescriptorSetObj descriptorSet(m_device);
   16186     descriptorSet.AppendDummy();
   16187     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   16188 
   16189     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16190 
   16191     m_errorMonitor->VerifyFound();
   16192 }
   16193 
   16194 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch) {
   16195     TEST_DESCRIPTION("Test that an error is produced for mismatched types across the vertex->fragment shader interface");
   16196     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0");
   16197 
   16198     ASSERT_NO_FATAL_FAILURE(Init());
   16199     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   16200 
   16201     char const *vsSource =
   16202         "#version 450\n"
   16203         "\n"
   16204         "layout(location=0) out int x;\n"
   16205         "void main(){\n"
   16206         "   x = 0;\n"
   16207         "   gl_Position = vec4(1);\n"
   16208         "}\n";
   16209     char const *fsSource =
   16210         "#version 450\n"
   16211         "\n"
   16212         "layout(location=0) in float x;\n" /* VS writes int */
   16213         "layout(location=0) out vec4 color;\n"
   16214         "void main(){\n"
   16215         "   color = vec4(x);\n"
   16216         "}\n";
   16217 
   16218     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   16219     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   16220 
   16221     VkPipelineObj pipe(m_device);
   16222     pipe.AddDefaultColorAttachment();
   16223     pipe.AddShader(&vs);
   16224     pipe.AddShader(&fs);
   16225 
   16226     VkDescriptorSetObj descriptorSet(m_device);
   16227     descriptorSet.AppendDummy();
   16228     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   16229 
   16230     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16231 
   16232     m_errorMonitor->VerifyFound();
   16233 }
   16234 
   16235 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchInBlock) {
   16236     TEST_DESCRIPTION(
   16237         "Test that an error is produced for mismatched types across the vertex->fragment shader interface, when the variable is "
   16238         "contained within an interface block");
   16239     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0");
   16240 
   16241     ASSERT_NO_FATAL_FAILURE(Init());
   16242     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   16243 
   16244     char const *vsSource =
   16245         "#version 450\n"
   16246         "\n"
   16247         "out block { layout(location=0) int x; } outs;\n"
   16248         "void main(){\n"
   16249         "   outs.x = 0;\n"
   16250         "   gl_Position = vec4(1);\n"
   16251         "}\n";
   16252     char const *fsSource =
   16253         "#version 450\n"
   16254         "\n"
   16255         "in block { layout(location=0) float x; } ins;\n" /* VS writes int */
   16256         "layout(location=0) out vec4 color;\n"
   16257         "void main(){\n"
   16258         "   color = vec4(ins.x);\n"
   16259         "}\n";
   16260 
   16261     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   16262     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   16263 
   16264     VkPipelineObj pipe(m_device);
   16265     pipe.AddDefaultColorAttachment();
   16266     pipe.AddShader(&vs);
   16267     pipe.AddShader(&fs);
   16268 
   16269     VkDescriptorSetObj descriptorSet(m_device);
   16270     descriptorSet.AppendDummy();
   16271     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   16272 
   16273     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16274 
   16275     m_errorMonitor->VerifyFound();
   16276 }
   16277 
   16278 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByLocation) {
   16279     TEST_DESCRIPTION(
   16280         "Test that an error is produced for location mismatches across the vertex->fragment shader interface; This should manifest "
   16281         "as a not-written/not-consumed pair, but flushes out broken walking of the interfaces");
   16282     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0.0 which is not written by vertex shader");
   16283 
   16284     ASSERT_NO_FATAL_FAILURE(Init());
   16285     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   16286 
   16287     char const *vsSource =
   16288         "#version 450\n"
   16289         "\n"
   16290         "out block { layout(location=1) float x; } outs;\n"
   16291         "void main(){\n"
   16292         "   outs.x = 0;\n"
   16293         "   gl_Position = vec4(1);\n"
   16294         "}\n";
   16295     char const *fsSource =
   16296         "#version 450\n"
   16297         "\n"
   16298         "in block { layout(location=0) float x; } ins;\n"
   16299         "layout(location=0) out vec4 color;\n"
   16300         "void main(){\n"
   16301         "   color = vec4(ins.x);\n"
   16302         "}\n";
   16303 
   16304     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   16305     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   16306 
   16307     VkPipelineObj pipe(m_device);
   16308     pipe.AddDefaultColorAttachment();
   16309     pipe.AddShader(&vs);
   16310     pipe.AddShader(&fs);
   16311 
   16312     VkDescriptorSetObj descriptorSet(m_device);
   16313     descriptorSet.AppendDummy();
   16314     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   16315 
   16316     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16317 
   16318     m_errorMonitor->VerifyFound();
   16319 }
   16320 
   16321 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByComponent) {
   16322     TEST_DESCRIPTION(
   16323         "Test that an error is produced for component mismatches across the vertex->fragment shader interface. It's not enough to "
   16324         "have the same set of locations in use; matching is defined in terms of spirv variables.");
   16325     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0.1 which is not written by vertex shader");
   16326 
   16327     ASSERT_NO_FATAL_FAILURE(Init());
   16328     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   16329 
   16330     char const *vsSource =
   16331         "#version 450\n"
   16332         "\n"
   16333         "out block { layout(location=0, component=0) float x; } outs;\n"
   16334         "void main(){\n"
   16335         "   outs.x = 0;\n"
   16336         "   gl_Position = vec4(1);\n"
   16337         "}\n";
   16338     char const *fsSource =
   16339         "#version 450\n"
   16340         "\n"
   16341         "in block { layout(location=0, component=1) float x; } ins;\n"
   16342         "layout(location=0) out vec4 color;\n"
   16343         "void main(){\n"
   16344         "   color = vec4(ins.x);\n"
   16345         "}\n";
   16346 
   16347     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   16348     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   16349 
   16350     VkPipelineObj pipe(m_device);
   16351     pipe.AddDefaultColorAttachment();
   16352     pipe.AddShader(&vs);
   16353     pipe.AddShader(&fs);
   16354 
   16355     VkDescriptorSetObj descriptorSet(m_device);
   16356     descriptorSet.AppendDummy();
   16357     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   16358 
   16359     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16360 
   16361     m_errorMonitor->VerifyFound();
   16362 }
   16363 
   16364 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByPrecision) {
   16365     TEST_DESCRIPTION("Test that the RelaxedPrecision decoration is validated to match");
   16366 
   16367     ASSERT_NO_FATAL_FAILURE(Init());
   16368     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   16369 
   16370     char const *vsSource =
   16371         "#version 450\n"
   16372         "layout(location=0) out mediump float x;\n"
   16373         "void main() { gl_Position = vec4(0); x = 1.0; }\n";
   16374     char const *fsSource =
   16375         "#version 450\n"
   16376         "layout(location=0) in highp float x;\n"
   16377         "layout(location=0) out vec4 color;\n"
   16378         "void main() { color = vec4(x); }\n";
   16379 
   16380     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   16381     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   16382 
   16383     VkPipelineObj pipe(m_device);
   16384     pipe.AddDefaultColorAttachment();
   16385     pipe.AddShader(&vs);
   16386     pipe.AddShader(&fs);
   16387 
   16388     VkDescriptorSetObj descriptorSet(m_device);
   16389     descriptorSet.AppendDummy();
   16390     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   16391 
   16392     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "differ in precision");
   16393 
   16394     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16395 
   16396     m_errorMonitor->VerifyFound();
   16397 }
   16398 
   16399 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByPrecisionBlock) {
   16400     TEST_DESCRIPTION("Test that the RelaxedPrecision decoration is validated to match");
   16401 
   16402     ASSERT_NO_FATAL_FAILURE(Init());
   16403     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   16404 
   16405     char const *vsSource =
   16406         "#version 450\n"
   16407         "out block { layout(location=0) mediump float x; };\n"
   16408         "void main() { gl_Position = vec4(0); x = 1.0; }\n";
   16409     char const *fsSource =
   16410         "#version 450\n"
   16411         "in block { layout(location=0) highp float x; };\n"
   16412         "layout(location=0) out vec4 color;\n"
   16413         "void main() { color = vec4(x); }\n";
   16414 
   16415     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   16416     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   16417 
   16418     VkPipelineObj pipe(m_device);
   16419     pipe.AddDefaultColorAttachment();
   16420     pipe.AddShader(&vs);
   16421     pipe.AddShader(&fs);
   16422 
   16423     VkDescriptorSetObj descriptorSet(m_device);
   16424     descriptorSet.AppendDummy();
   16425     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   16426 
   16427     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "differ in precision");
   16428 
   16429     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16430 
   16431     m_errorMonitor->VerifyFound();
   16432 }
   16433 
   16434 TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed) {
   16435     TEST_DESCRIPTION("Test that a warning is produced for a vertex attribute which is not consumed by the vertex shader");
   16436     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by vertex shader");
   16437 
   16438     ASSERT_NO_FATAL_FAILURE(Init());
   16439     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   16440 
   16441     VkVertexInputBindingDescription input_binding;
   16442     memset(&input_binding, 0, sizeof(input_binding));
   16443 
   16444     VkVertexInputAttributeDescription input_attrib;
   16445     memset(&input_attrib, 0, sizeof(input_attrib));
   16446     input_attrib.format = VK_FORMAT_R32_SFLOAT;
   16447 
   16448     char const *vsSource =
   16449         "#version 450\n"
   16450         "\n"
   16451         "void main(){\n"
   16452         "   gl_Position = vec4(1);\n"
   16453         "}\n";
   16454     char const *fsSource =
   16455         "#version 450\n"
   16456         "\n"
   16457         "layout(location=0) out vec4 color;\n"
   16458         "void main(){\n"
   16459         "   color = vec4(1);\n"
   16460         "}\n";
   16461 
   16462     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   16463     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   16464 
   16465     VkPipelineObj pipe(m_device);
   16466     pipe.AddDefaultColorAttachment();
   16467     pipe.AddShader(&vs);
   16468     pipe.AddShader(&fs);
   16469 
   16470     pipe.AddVertexInputBindings(&input_binding, 1);
   16471     pipe.AddVertexInputAttribs(&input_attrib, 1);
   16472 
   16473     VkDescriptorSetObj descriptorSet(m_device);
   16474     descriptorSet.AppendDummy();
   16475     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   16476 
   16477     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16478 
   16479     m_errorMonitor->VerifyFound();
   16480 }
   16481 
   16482 TEST_F(VkLayerTest, CreatePipelineAttribLocationMismatch) {
   16483     TEST_DESCRIPTION(
   16484         "Test that a warning is produced for a location mismatch on vertex attributes. This flushes out bad behavior in the "
   16485         "interface walker");
   16486     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by vertex shader");
   16487 
   16488     ASSERT_NO_FATAL_FAILURE(Init());
   16489     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   16490 
   16491     VkVertexInputBindingDescription input_binding;
   16492     memset(&input_binding, 0, sizeof(input_binding));
   16493 
   16494     VkVertexInputAttributeDescription input_attrib;
   16495     memset(&input_attrib, 0, sizeof(input_attrib));
   16496     input_attrib.format = VK_FORMAT_R32_SFLOAT;
   16497 
   16498     char const *vsSource =
   16499         "#version 450\n"
   16500         "\n"
   16501         "layout(location=1) in float x;\n"
   16502         "void main(){\n"
   16503         "   gl_Position = vec4(x);\n"
   16504         "}\n";
   16505     char const *fsSource =
   16506         "#version 450\n"
   16507         "\n"
   16508         "layout(location=0) out vec4 color;\n"
   16509         "void main(){\n"
   16510         "   color = vec4(1);\n"
   16511         "}\n";
   16512 
   16513     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   16514     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   16515 
   16516     VkPipelineObj pipe(m_device);
   16517     pipe.AddDefaultColorAttachment();
   16518     pipe.AddShader(&vs);
   16519     pipe.AddShader(&fs);
   16520 
   16521     pipe.AddVertexInputBindings(&input_binding, 1);
   16522     pipe.AddVertexInputAttribs(&input_attrib, 1);
   16523 
   16524     VkDescriptorSetObj descriptorSet(m_device);
   16525     descriptorSet.AppendDummy();
   16526     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   16527 
   16528     m_errorMonitor->SetUnexpectedError("Vertex shader consumes input at location 1 but not provided");
   16529     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16530 
   16531     m_errorMonitor->VerifyFound();
   16532 }
   16533 
   16534 TEST_F(VkLayerTest, CreatePipelineAttribNotProvided) {
   16535     TEST_DESCRIPTION("Test that an error is produced for a vertex shader input which is not provided by a vertex attribute");
   16536     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   16537                                          "Vertex shader consumes input at location 0 but not provided");
   16538 
   16539     ASSERT_NO_FATAL_FAILURE(Init());
   16540     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   16541 
   16542     char const *vsSource =
   16543         "#version 450\n"
   16544         "\n"
   16545         "layout(location=0) in vec4 x;\n" /* not provided */
   16546         "void main(){\n"
   16547         "   gl_Position = x;\n"
   16548         "}\n";
   16549     char const *fsSource =
   16550         "#version 450\n"
   16551         "\n"
   16552         "layout(location=0) out vec4 color;\n"
   16553         "void main(){\n"
   16554         "   color = vec4(1);\n"
   16555         "}\n";
   16556 
   16557     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   16558     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   16559 
   16560     VkPipelineObj pipe(m_device);
   16561     pipe.AddDefaultColorAttachment();
   16562     pipe.AddShader(&vs);
   16563     pipe.AddShader(&fs);
   16564 
   16565     VkDescriptorSetObj descriptorSet(m_device);
   16566     descriptorSet.AppendDummy();
   16567     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   16568 
   16569     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16570 
   16571     m_errorMonitor->VerifyFound();
   16572 }
   16573 
   16574 TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch) {
   16575     TEST_DESCRIPTION(
   16576         "Test that an error is produced for a mismatch between the fundamental type (float/int/uint) of an attribute and the "
   16577         "vertex shader input that consumes it");
   16578     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0 does not match vertex shader input type");
   16579 
   16580     ASSERT_NO_FATAL_FAILURE(Init());
   16581     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   16582 
   16583     VkVertexInputBindingDescription input_binding;
   16584     memset(&input_binding, 0, sizeof(input_binding));
   16585 
   16586     VkVertexInputAttributeDescription input_attrib;
   16587     memset(&input_attrib, 0, sizeof(input_attrib));
   16588     input_attrib.format = VK_FORMAT_R32_SFLOAT;
   16589 
   16590     char const *vsSource =
   16591         "#version 450\n"
   16592         "\n"
   16593         "layout(location=0) in int x;\n" /* attrib provided float */
   16594         "void main(){\n"
   16595         "   gl_Position = vec4(x);\n"
   16596         "}\n";
   16597     char const *fsSource =
   16598         "#version 450\n"
   16599         "\n"
   16600         "layout(location=0) out vec4 color;\n"
   16601         "void main(){\n"
   16602         "   color = vec4(1);\n"
   16603         "}\n";
   16604 
   16605     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   16606     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   16607 
   16608     VkPipelineObj pipe(m_device);
   16609     pipe.AddDefaultColorAttachment();
   16610     pipe.AddShader(&vs);
   16611     pipe.AddShader(&fs);
   16612 
   16613     pipe.AddVertexInputBindings(&input_binding, 1);
   16614     pipe.AddVertexInputAttribs(&input_attrib, 1);
   16615 
   16616     VkDescriptorSetObj descriptorSet(m_device);
   16617     descriptorSet.AppendDummy();
   16618     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   16619 
   16620     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16621 
   16622     m_errorMonitor->VerifyFound();
   16623 }
   16624 
   16625 TEST_F(VkLayerTest, CreatePipelineDuplicateStage) {
   16626     TEST_DESCRIPTION("Test that an error is produced for a pipeline containing multiple shaders for the same stage");
   16627     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   16628                                          "Multiple shaders provided for stage VK_SHADER_STAGE_VERTEX_BIT");
   16629 
   16630     ASSERT_NO_FATAL_FAILURE(Init());
   16631     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   16632 
   16633     char const *vsSource =
   16634         "#version 450\n"
   16635         "\n"
   16636         "void main(){\n"
   16637         "   gl_Position = vec4(1);\n"
   16638         "}\n";
   16639     char const *fsSource =
   16640         "#version 450\n"
   16641         "\n"
   16642         "layout(location=0) out vec4 color;\n"
   16643         "void main(){\n"
   16644         "   color = vec4(1);\n"
   16645         "}\n";
   16646 
   16647     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   16648     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   16649 
   16650     VkPipelineObj pipe(m_device);
   16651     pipe.AddDefaultColorAttachment();
   16652     pipe.AddShader(&vs);
   16653     pipe.AddShader(&vs);  // intentionally duplicate vertex shader attachment
   16654     pipe.AddShader(&fs);
   16655 
   16656     VkDescriptorSetObj descriptorSet(m_device);
   16657     descriptorSet.AppendDummy();
   16658     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   16659 
   16660     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16661 
   16662     m_errorMonitor->VerifyFound();
   16663 }
   16664 
   16665 TEST_F(VkLayerTest, CreatePipelineMissingEntrypoint) {
   16666     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "No entrypoint found named `foo`");
   16667 
   16668     ASSERT_NO_FATAL_FAILURE(Init());
   16669     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   16670 
   16671     char const *vsSource =
   16672         "#version 450\n"
   16673         "void main(){\n"
   16674         "   gl_Position = vec4(0);\n"
   16675         "}\n";
   16676     char const *fsSource =
   16677         "#version 450\n"
   16678         "\n"
   16679         "layout(location=0) out vec4 color;\n"
   16680         "void main(){\n"
   16681         "   color = vec4(1);\n"
   16682         "}\n";
   16683 
   16684     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   16685     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this, "foo");
   16686 
   16687     VkPipelineObj pipe(m_device);
   16688     pipe.AddDefaultColorAttachment();
   16689     pipe.AddShader(&vs);
   16690     pipe.AddShader(&fs);
   16691 
   16692     VkDescriptorSetObj descriptorSet(m_device);
   16693     descriptorSet.AppendDummy();
   16694     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   16695 
   16696     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16697 
   16698     m_errorMonitor->VerifyFound();
   16699 }
   16700 
   16701 TEST_F(VkLayerTest, CreatePipelineDepthStencilRequired) {
   16702     m_errorMonitor->SetDesiredFailureMsg(
   16703         VK_DEBUG_REPORT_ERROR_BIT_EXT,
   16704         "pDepthStencilState is NULL when rasterization is enabled and subpass uses a depth/stencil attachment");
   16705 
   16706     ASSERT_NO_FATAL_FAILURE(Init());
   16707     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   16708 
   16709     char const *vsSource =
   16710         "#version 450\n"
   16711         "void main(){ gl_Position = vec4(0); }\n";
   16712     char const *fsSource =
   16713         "#version 450\n"
   16714         "\n"
   16715         "layout(location=0) out vec4 color;\n"
   16716         "void main(){\n"
   16717         "   color = vec4(1);\n"
   16718         "}\n";
   16719 
   16720     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   16721     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   16722 
   16723     VkPipelineObj pipe(m_device);
   16724     pipe.AddDefaultColorAttachment();
   16725     pipe.AddShader(&vs);
   16726     pipe.AddShader(&fs);
   16727 
   16728     VkDescriptorSetObj descriptorSet(m_device);
   16729     descriptorSet.AppendDummy();
   16730     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   16731 
   16732     VkAttachmentDescription attachments[] = {
   16733         {
   16734             0,
   16735             VK_FORMAT_B8G8R8A8_UNORM,
   16736             VK_SAMPLE_COUNT_1_BIT,
   16737             VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   16738             VK_ATTACHMENT_STORE_OP_DONT_CARE,
   16739             VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   16740             VK_ATTACHMENT_STORE_OP_DONT_CARE,
   16741             VK_IMAGE_LAYOUT_UNDEFINED,
   16742             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   16743         },
   16744         {
   16745             0,
   16746             VK_FORMAT_D16_UNORM,
   16747             VK_SAMPLE_COUNT_1_BIT,
   16748             VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   16749             VK_ATTACHMENT_STORE_OP_DONT_CARE,
   16750             VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   16751             VK_ATTACHMENT_STORE_OP_DONT_CARE,
   16752             VK_IMAGE_LAYOUT_UNDEFINED,
   16753             VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   16754         },
   16755     };
   16756     VkAttachmentReference refs[] = {
   16757         {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
   16758         {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL},
   16759     };
   16760     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &refs[0], nullptr, &refs[1], 0, nullptr};
   16761     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr};
   16762     VkRenderPass rp;
   16763     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   16764     ASSERT_VK_SUCCESS(err);
   16765 
   16766     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), rp);
   16767 
   16768     m_errorMonitor->VerifyFound();
   16769 
   16770     vkDestroyRenderPass(m_device->device(), rp, nullptr);
   16771 }
   16772 
   16773 TEST_F(VkLayerTest, CreatePipelineTessPatchDecorationMismatch) {
   16774     TEST_DESCRIPTION(
   16775         "Test that an error is produced for a variable output from the TCS without the patch decoration, but consumed in the TES "
   16776         "with the decoration.");
   16777     m_errorMonitor->SetDesiredFailureMsg(
   16778         VK_DEBUG_REPORT_ERROR_BIT_EXT,
   16779         "is per-vertex in tessellation control shader stage but per-patch in tessellation evaluation shader stage");
   16780 
   16781     ASSERT_NO_FATAL_FAILURE(Init());
   16782     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   16783 
   16784     if (!m_device->phy().features().tessellationShader) {
   16785         printf("             Device does not support tessellation shaders; skipped.\n");
   16786         return;
   16787     }
   16788 
   16789     char const *vsSource =
   16790         "#version 450\n"
   16791         "void main(){}\n";
   16792     char const *tcsSource =
   16793         "#version 450\n"
   16794         "layout(location=0) out int x[];\n"
   16795         "layout(vertices=3) out;\n"
   16796         "void main(){\n"
   16797         "   gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
   16798         "   gl_TessLevelInner[0] = 1;\n"
   16799         "   x[gl_InvocationID] = gl_InvocationID;\n"
   16800         "}\n";
   16801     char const *tesSource =
   16802         "#version 450\n"
   16803         "layout(triangles, equal_spacing, cw) in;\n"
   16804         "layout(location=0) patch in int x;\n"
   16805         "void main(){\n"
   16806         "   gl_Position.xyz = gl_TessCoord;\n"
   16807         "   gl_Position.w = x;\n"
   16808         "}\n";
   16809     char const *fsSource =
   16810         "#version 450\n"
   16811         "layout(location=0) out vec4 color;\n"
   16812         "void main(){\n"
   16813         "   color = vec4(1);\n"
   16814         "}\n";
   16815 
   16816     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   16817     VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
   16818     VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
   16819     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   16820 
   16821     VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
   16822                                                  VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
   16823 
   16824     VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
   16825 
   16826     VkPipelineObj pipe(m_device);
   16827     pipe.SetInputAssembly(&iasci);
   16828     pipe.SetTessellation(&tsci);
   16829     pipe.AddDefaultColorAttachment();
   16830     pipe.AddShader(&vs);
   16831     pipe.AddShader(&tcs);
   16832     pipe.AddShader(&tes);
   16833     pipe.AddShader(&fs);
   16834 
   16835     VkDescriptorSetObj descriptorSet(m_device);
   16836     descriptorSet.AppendDummy();
   16837     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   16838 
   16839     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16840 
   16841     m_errorMonitor->VerifyFound();
   16842 }
   16843 
   16844 TEST_F(VkLayerTest, CreatePipelineTessErrors) {
   16845     TEST_DESCRIPTION("Test various errors when creating a graphics pipeline with tessellation stages active.");
   16846 
   16847     ASSERT_NO_FATAL_FAILURE(Init());
   16848     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   16849 
   16850     if (!m_device->phy().features().tessellationShader) {
   16851         printf("             Device does not support tessellation shaders; skipped.\n");
   16852         return;
   16853     }
   16854 
   16855     char const *vsSource =
   16856         "#version 450\n"
   16857         "void main(){}\n";
   16858     char const *tcsSource =
   16859         "#version 450\n"
   16860         "layout(vertices=3) out;\n"
   16861         "void main(){\n"
   16862         "   gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
   16863         "   gl_TessLevelInner[0] = 1;\n"
   16864         "}\n";
   16865     char const *tesSource =
   16866         "#version 450\n"
   16867         "layout(triangles, equal_spacing, cw) in;\n"
   16868         "void main(){\n"
   16869         "   gl_Position.xyz = gl_TessCoord;\n"
   16870         "   gl_Position.w = 0;\n"
   16871         "}\n";
   16872     char const *fsSource =
   16873         "#version 450\n"
   16874         "layout(location=0) out vec4 color;\n"
   16875         "void main(){\n"
   16876         "   color = vec4(1);\n"
   16877         "}\n";
   16878 
   16879     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   16880     VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
   16881     VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
   16882     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   16883 
   16884     VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
   16885                                                  VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
   16886 
   16887     VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
   16888 
   16889     VkDescriptorSetObj descriptorSet(m_device);
   16890     descriptorSet.AppendDummy();
   16891     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   16892 
   16893     {
   16894         VkPipelineObj pipe(m_device);
   16895         VkPipelineInputAssemblyStateCreateInfo iasci_bad = iasci;
   16896         iasci_bad.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;  // otherwise we get a failure about invalid topology
   16897         pipe.SetInputAssembly(&iasci_bad);
   16898         pipe.AddDefaultColorAttachment();
   16899         pipe.AddShader(&vs);
   16900         pipe.AddShader(&fs);
   16901 
   16902         // Pass a tess control shader without a tess eval shader
   16903         pipe.AddShader(&tcs);
   16904         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_096005b2);
   16905         pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16906         m_errorMonitor->VerifyFound();
   16907     }
   16908 
   16909     {
   16910         VkPipelineObj pipe(m_device);
   16911         VkPipelineInputAssemblyStateCreateInfo iasci_bad = iasci;
   16912         iasci_bad.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;  // otherwise we get a failure about invalid topology
   16913         pipe.SetInputAssembly(&iasci_bad);
   16914         pipe.AddDefaultColorAttachment();
   16915         pipe.AddShader(&vs);
   16916         pipe.AddShader(&fs);
   16917 
   16918         // Pass a tess eval shader without a tess control shader
   16919         pipe.AddShader(&tes);
   16920         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_096005b4);
   16921         pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16922         m_errorMonitor->VerifyFound();
   16923     }
   16924 
   16925     {
   16926         VkPipelineObj pipe(m_device);
   16927         pipe.SetInputAssembly(&iasci);
   16928         pipe.AddDefaultColorAttachment();
   16929         pipe.AddShader(&vs);
   16930         pipe.AddShader(&fs);
   16931 
   16932         // Pass patch topology without tessellation shaders
   16933         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_096005c2);
   16934         pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16935         m_errorMonitor->VerifyFound();
   16936 
   16937         pipe.AddShader(&tcs);
   16938         pipe.AddShader(&tes);
   16939         // Pass a NULL pTessellationState (with active tessellation shader stages)
   16940         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_096005b6);
   16941         pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16942         m_errorMonitor->VerifyFound();
   16943 
   16944         // Pass an invalid pTessellationState (bad sType)
   16945         VkPipelineTessellationStateCreateInfo tsci_bad = tsci;
   16946         tsci_bad.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   16947         pipe.SetTessellation(&tsci_bad);
   16948         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1082b00b);
   16949         pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16950         m_errorMonitor->VerifyFound();
   16951         // Pass out-of-range patchControlPoints
   16952         tsci_bad = tsci;
   16953         tsci_bad.patchControlPoints = 0;
   16954         pipe.SetTessellation(&tsci);
   16955         pipe.SetTessellation(&tsci_bad);
   16956         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1080097c);
   16957         pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16958         m_errorMonitor->VerifyFound();
   16959         tsci_bad.patchControlPoints = m_device->props.limits.maxTessellationPatchSize + 1;
   16960         pipe.SetTessellation(&tsci_bad);
   16961         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1080097c);
   16962         pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16963         m_errorMonitor->VerifyFound();
   16964         pipe.SetTessellation(&tsci);
   16965 
   16966         // Pass an invalid primitive topology
   16967         VkPipelineInputAssemblyStateCreateInfo iasci_bad = iasci;
   16968         iasci_bad.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
   16969         pipe.SetInputAssembly(&iasci_bad);
   16970         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_096005c0);
   16971         pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   16972         m_errorMonitor->VerifyFound();
   16973         pipe.SetInputAssembly(&iasci);
   16974     }
   16975 }
   16976 
   16977 TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict) {
   16978     TEST_DESCRIPTION(
   16979         "Test that an error is produced for a vertex attribute setup where multiple bindings provide the same location");
   16980     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   16981                                          "Duplicate vertex input binding descriptions for binding 0");
   16982 
   16983     ASSERT_NO_FATAL_FAILURE(Init());
   16984     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   16985 
   16986     /* Two binding descriptions for binding 0 */
   16987     VkVertexInputBindingDescription input_bindings[2];
   16988     memset(input_bindings, 0, sizeof(input_bindings));
   16989 
   16990     VkVertexInputAttributeDescription input_attrib;
   16991     memset(&input_attrib, 0, sizeof(input_attrib));
   16992     input_attrib.format = VK_FORMAT_R32_SFLOAT;
   16993 
   16994     char const *vsSource =
   16995         "#version 450\n"
   16996         "\n"
   16997         "layout(location=0) in float x;\n" /* attrib provided float */
   16998         "void main(){\n"
   16999         "   gl_Position = vec4(x);\n"
   17000         "}\n";
   17001     char const *fsSource =
   17002         "#version 450\n"
   17003         "\n"
   17004         "layout(location=0) out vec4 color;\n"
   17005         "void main(){\n"
   17006         "   color = vec4(1);\n"
   17007         "}\n";
   17008 
   17009     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   17010     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   17011 
   17012     VkPipelineObj pipe(m_device);
   17013     pipe.AddDefaultColorAttachment();
   17014     pipe.AddShader(&vs);
   17015     pipe.AddShader(&fs);
   17016 
   17017     pipe.AddVertexInputBindings(input_bindings, 2);
   17018     pipe.AddVertexInputAttribs(&input_attrib, 1);
   17019 
   17020     VkDescriptorSetObj descriptorSet(m_device);
   17021     descriptorSet.AppendDummy();
   17022     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   17023 
   17024     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   17025 
   17026     m_errorMonitor->VerifyFound();
   17027 }
   17028 
   17029 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten) {
   17030     TEST_DESCRIPTION(
   17031         "Test that an error is produced for a fragment shader which does not provide an output for one of the pipeline's color "
   17032         "attachments");
   17033     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attachment 0 not written by fragment shader");
   17034 
   17035     ASSERT_NO_FATAL_FAILURE(Init());
   17036 
   17037     char const *vsSource =
   17038         "#version 450\n"
   17039         "\n"
   17040         "void main(){\n"
   17041         "   gl_Position = vec4(1);\n"
   17042         "}\n";
   17043     char const *fsSource =
   17044         "#version 450\n"
   17045         "\n"
   17046         "void main(){\n"
   17047         "}\n";
   17048 
   17049     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   17050     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   17051 
   17052     VkPipelineObj pipe(m_device);
   17053     pipe.AddShader(&vs);
   17054     pipe.AddShader(&fs);
   17055 
   17056     /* set up CB 0, not written */
   17057     pipe.AddDefaultColorAttachment();
   17058     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   17059 
   17060     VkDescriptorSetObj descriptorSet(m_device);
   17061     descriptorSet.AppendDummy();
   17062     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   17063 
   17064     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   17065 
   17066     m_errorMonitor->VerifyFound();
   17067 }
   17068 
   17069 TEST_F(VkPositiveLayerTest, CreatePipelineFragmentOutputNotWrittenButMasked) {
   17070     TEST_DESCRIPTION(
   17071         "Test that no error is produced when the fragment shader fails to declare an output, but the corresponding attachment's "
   17072         "write mask is 0.");
   17073     m_errorMonitor->ExpectSuccess();
   17074 
   17075     ASSERT_NO_FATAL_FAILURE(Init());
   17076 
   17077     char const *vsSource =
   17078         "#version 450\n"
   17079         "\n"
   17080         "void main(){\n"
   17081         "   gl_Position = vec4(1);\n"
   17082         "}\n";
   17083     char const *fsSource =
   17084         "#version 450\n"
   17085         "\n"
   17086         "void main(){\n"
   17087         "}\n";
   17088 
   17089     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   17090     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   17091 
   17092     VkPipelineObj pipe(m_device);
   17093     pipe.AddShader(&vs);
   17094     pipe.AddShader(&fs);
   17095 
   17096     /* set up CB 0, not written, but also masked */
   17097     pipe.AddDefaultColorAttachment(0);
   17098     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   17099 
   17100     VkDescriptorSetObj descriptorSet(m_device);
   17101     descriptorSet.AppendDummy();
   17102     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   17103 
   17104     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   17105 
   17106     m_errorMonitor->VerifyNotFound();
   17107 }
   17108 
   17109 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed) {
   17110     TEST_DESCRIPTION(
   17111         "Test that a warning is produced for a fragment shader which provides a spurious output with no matching attachment");
   17112     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
   17113                                          "fragment shader writes to output location 1 with no matching attachment");
   17114 
   17115     ASSERT_NO_FATAL_FAILURE(Init());
   17116 
   17117     char const *vsSource =
   17118         "#version 450\n"
   17119         "\n"
   17120         "void main(){\n"
   17121         "   gl_Position = vec4(1);\n"
   17122         "}\n";
   17123     char const *fsSource =
   17124         "#version 450\n"
   17125         "\n"
   17126         "layout(location=0) out vec4 x;\n"
   17127         "layout(location=1) out vec4 y;\n" /* no matching attachment for this */
   17128         "void main(){\n"
   17129         "   x = vec4(1);\n"
   17130         "   y = vec4(1);\n"
   17131         "}\n";
   17132 
   17133     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   17134     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   17135 
   17136     VkPipelineObj pipe(m_device);
   17137     pipe.AddShader(&vs);
   17138     pipe.AddShader(&fs);
   17139 
   17140     /* set up CB 0, not written */
   17141     pipe.AddDefaultColorAttachment();
   17142     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   17143     /* FS writes CB 1, but we don't configure it */
   17144 
   17145     VkDescriptorSetObj descriptorSet(m_device);
   17146     descriptorSet.AppendDummy();
   17147     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   17148 
   17149     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   17150 
   17151     m_errorMonitor->VerifyFound();
   17152 }
   17153 
   17154 TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch) {
   17155     TEST_DESCRIPTION(
   17156         "Test that an error is produced for a mismatch between the fundamental type of an fragment shader output variable, and the "
   17157         "format of the corresponding attachment");
   17158     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "does not match fragment shader output type");
   17159 
   17160     ASSERT_NO_FATAL_FAILURE(Init());
   17161 
   17162     char const *vsSource =
   17163         "#version 450\n"
   17164         "\n"
   17165         "void main(){\n"
   17166         "   gl_Position = vec4(1);\n"
   17167         "}\n";
   17168     char const *fsSource =
   17169         "#version 450\n"
   17170         "\n"
   17171         "layout(location=0) out ivec4 x;\n" /* not UNORM */
   17172         "void main(){\n"
   17173         "   x = ivec4(1);\n"
   17174         "}\n";
   17175 
   17176     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   17177     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   17178 
   17179     VkPipelineObj pipe(m_device);
   17180     pipe.AddShader(&vs);
   17181     pipe.AddShader(&fs);
   17182 
   17183     /* set up CB 0; type is UNORM by default */
   17184     pipe.AddDefaultColorAttachment();
   17185     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   17186 
   17187     VkDescriptorSetObj descriptorSet(m_device);
   17188     descriptorSet.AppendDummy();
   17189     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   17190 
   17191     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   17192 
   17193     m_errorMonitor->VerifyFound();
   17194 }
   17195 
   17196 TEST_F(VkLayerTest, CreatePipelineUniformBlockNotProvided) {
   17197     TEST_DESCRIPTION(
   17198         "Test that an error is produced for a shader consuming a uniform block which has no corresponding binding in the pipeline "
   17199         "layout");
   17200     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not declared in pipeline layout");
   17201 
   17202     ASSERT_NO_FATAL_FAILURE(Init());
   17203 
   17204     char const *vsSource =
   17205         "#version 450\n"
   17206         "\n"
   17207         "void main(){\n"
   17208         "   gl_Position = vec4(1);\n"
   17209         "}\n";
   17210     char const *fsSource =
   17211         "#version 450\n"
   17212         "\n"
   17213         "layout(location=0) out vec4 x;\n"
   17214         "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
   17215         "void main(){\n"
   17216         "   x = vec4(bar.y);\n"
   17217         "}\n";
   17218 
   17219     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   17220     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   17221 
   17222     VkPipelineObj pipe(m_device);
   17223     pipe.AddShader(&vs);
   17224     pipe.AddShader(&fs);
   17225 
   17226     /* set up CB 0; type is UNORM by default */
   17227     pipe.AddDefaultColorAttachment();
   17228     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   17229 
   17230     VkDescriptorSetObj descriptorSet(m_device);
   17231     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   17232 
   17233     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   17234 
   17235     m_errorMonitor->VerifyFound();
   17236 }
   17237 
   17238 TEST_F(VkLayerTest, CreatePipelinePushConstantsNotInLayout) {
   17239     TEST_DESCRIPTION(
   17240         "Test that an error is produced for a shader consuming push constants which are not provided in the pipeline layout");
   17241     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not declared in layout");
   17242 
   17243     ASSERT_NO_FATAL_FAILURE(Init());
   17244 
   17245     char const *vsSource =
   17246         "#version 450\n"
   17247         "\n"
   17248         "layout(push_constant, std430) uniform foo { float x; } consts;\n"
   17249         "void main(){\n"
   17250         "   gl_Position = vec4(consts.x);\n"
   17251         "}\n";
   17252     char const *fsSource =
   17253         "#version 450\n"
   17254         "\n"
   17255         "layout(location=0) out vec4 x;\n"
   17256         "void main(){\n"
   17257         "   x = vec4(1);\n"
   17258         "}\n";
   17259 
   17260     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   17261     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   17262 
   17263     VkPipelineObj pipe(m_device);
   17264     pipe.AddShader(&vs);
   17265     pipe.AddShader(&fs);
   17266 
   17267     /* set up CB 0; type is UNORM by default */
   17268     pipe.AddDefaultColorAttachment();
   17269     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   17270 
   17271     VkDescriptorSetObj descriptorSet(m_device);
   17272     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   17273 
   17274     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   17275 
   17276     /* should have generated an error -- no push constant ranges provided! */
   17277     m_errorMonitor->VerifyFound();
   17278 }
   17279 
   17280 TEST_F(VkLayerTest, CreatePipelineInputAttachmentMissing) {
   17281     TEST_DESCRIPTION(
   17282         "Test that an error is produced for a shader consuming an input attachment which is not included in the subpass "
   17283         "description");
   17284     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   17285                                          "consumes input attachment index 0 but not provided in subpass");
   17286 
   17287     ASSERT_NO_FATAL_FAILURE(Init());
   17288 
   17289     char const *vsSource =
   17290         "#version 450\n"
   17291         "\n"
   17292         "void main(){\n"
   17293         "    gl_Position = vec4(1);\n"
   17294         "}\n";
   17295     char const *fsSource =
   17296         "#version 450\n"
   17297         "\n"
   17298         "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
   17299         "layout(location=0) out vec4 color;\n"
   17300         "void main() {\n"
   17301         "   color = subpassLoad(x);\n"
   17302         "}\n";
   17303 
   17304     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   17305     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   17306 
   17307     VkPipelineObj pipe(m_device);
   17308     pipe.AddShader(&vs);
   17309     pipe.AddShader(&fs);
   17310     pipe.AddDefaultColorAttachment();
   17311     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   17312 
   17313     VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
   17314     const VkDescriptorSetLayoutObj dsl(m_device, {dslb});
   17315 
   17316     const VkPipelineLayoutObj pl(m_device, {&dsl});
   17317 
   17318     // error here.
   17319     pipe.CreateVKPipeline(pl.handle(), renderPass());
   17320 
   17321     m_errorMonitor->VerifyFound();
   17322 }
   17323 
   17324 TEST_F(VkLayerTest, CreatePipelineInputAttachmentTypeMismatch) {
   17325     TEST_DESCRIPTION(
   17326         "Test that an error is produced for a shader consuming an input attachment with a format having a different fundamental "
   17327         "type");
   17328     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   17329                                          "input attachment 0 format of VK_FORMAT_R8G8B8A8_UINT does not match");
   17330 
   17331     ASSERT_NO_FATAL_FAILURE(Init());
   17332 
   17333     char const *vsSource =
   17334         "#version 450\n"
   17335         "\n"
   17336         "void main(){\n"
   17337         "    gl_Position = vec4(1);\n"
   17338         "}\n";
   17339     char const *fsSource =
   17340         "#version 450\n"
   17341         "\n"
   17342         "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
   17343         "layout(location=0) out vec4 color;\n"
   17344         "void main() {\n"
   17345         "   color = subpassLoad(x);\n"
   17346         "}\n";
   17347 
   17348     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   17349     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   17350 
   17351     VkPipelineObj pipe(m_device);
   17352     pipe.AddShader(&vs);
   17353     pipe.AddShader(&fs);
   17354     pipe.AddDefaultColorAttachment();
   17355     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   17356 
   17357     VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
   17358     const VkDescriptorSetLayoutObj dsl(m_device, {dslb});
   17359 
   17360     const VkPipelineLayoutObj pl(m_device, {&dsl});
   17361 
   17362     VkAttachmentDescription descs[2] = {
   17363         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
   17364          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   17365          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
   17366         {0, VK_FORMAT_R8G8B8A8_UINT, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
   17367          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
   17368     };
   17369     VkAttachmentReference color = {
   17370         0,
   17371         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   17372     };
   17373     VkAttachmentReference input = {
   17374         1,
   17375         VK_IMAGE_LAYOUT_GENERAL,
   17376     };
   17377 
   17378     VkSubpassDescription sd = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr};
   17379 
   17380     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr};
   17381     VkRenderPass rp;
   17382     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   17383     ASSERT_VK_SUCCESS(err);
   17384 
   17385     // error here.
   17386     pipe.CreateVKPipeline(pl.handle(), rp);
   17387 
   17388     m_errorMonitor->VerifyFound();
   17389 
   17390     vkDestroyRenderPass(m_device->device(), rp, nullptr);
   17391 }
   17392 
   17393 TEST_F(VkLayerTest, CreatePipelineInputAttachmentMissingArray) {
   17394     TEST_DESCRIPTION(
   17395         "Test that an error is produced for a shader consuming an input attachment which is not included in the subpass "
   17396         "description -- array case");
   17397     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   17398                                          "consumes input attachment index 0 but not provided in subpass");
   17399 
   17400     ASSERT_NO_FATAL_FAILURE(Init());
   17401 
   17402     char const *vsSource =
   17403         "#version 450\n"
   17404         "\n"
   17405         "void main(){\n"
   17406         "    gl_Position = vec4(1);\n"
   17407         "}\n";
   17408     char const *fsSource =
   17409         "#version 450\n"
   17410         "\n"
   17411         "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput xs[1];\n"
   17412         "layout(location=0) out vec4 color;\n"
   17413         "void main() {\n"
   17414         "   color = subpassLoad(xs[0]);\n"
   17415         "}\n";
   17416 
   17417     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   17418     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   17419 
   17420     VkPipelineObj pipe(m_device);
   17421     pipe.AddShader(&vs);
   17422     pipe.AddShader(&fs);
   17423     pipe.AddDefaultColorAttachment();
   17424     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   17425 
   17426     VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
   17427     const VkDescriptorSetLayoutObj dsl(m_device, {dslb});
   17428 
   17429     const VkPipelineLayoutObj pl(m_device, {&dsl});
   17430 
   17431     // error here.
   17432     pipe.CreateVKPipeline(pl.handle(), renderPass());
   17433 
   17434     m_errorMonitor->VerifyFound();
   17435 }
   17436 
   17437 TEST_F(VkLayerTest, CreateComputePipelineMissingDescriptor) {
   17438     TEST_DESCRIPTION(
   17439         "Test that an error is produced for a compute pipeline consuming a descriptor which is not provided in the pipeline "
   17440         "layout");
   17441     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Shader uses descriptor slot 0.0");
   17442 
   17443     ASSERT_NO_FATAL_FAILURE(Init());
   17444 
   17445     char const *csSource =
   17446         "#version 450\n"
   17447         "\n"
   17448         "layout(local_size_x=1) in;\n"
   17449         "layout(set=0, binding=0) buffer block { vec4 x; };\n"
   17450         "void main(){\n"
   17451         "   x = vec4(1);\n"
   17452         "}\n";
   17453 
   17454     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
   17455 
   17456     VkDescriptorSetObj descriptorSet(m_device);
   17457     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   17458 
   17459     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
   17460                                         nullptr,
   17461                                         0,
   17462                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
   17463                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
   17464                                         descriptorSet.GetPipelineLayout(),
   17465                                         VK_NULL_HANDLE,
   17466                                         -1};
   17467 
   17468     VkPipeline pipe;
   17469     VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
   17470 
   17471     m_errorMonitor->VerifyFound();
   17472 
   17473     if (err == VK_SUCCESS) {
   17474         vkDestroyPipeline(m_device->device(), pipe, nullptr);
   17475     }
   17476 }
   17477 
   17478 TEST_F(VkLayerTest, CreateComputePipelineDescriptorTypeMismatch) {
   17479     TEST_DESCRIPTION("Test that an error is produced for a pipeline consuming a descriptor-backed resource of a mismatched type");
   17480     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   17481                                          "but descriptor of type VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER");
   17482 
   17483     ASSERT_NO_FATAL_FAILURE(Init());
   17484 
   17485     VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr};
   17486     const VkDescriptorSetLayoutObj dsl(m_device, {binding});
   17487 
   17488     const VkPipelineLayoutObj pl(m_device, {&dsl});
   17489 
   17490     char const *csSource =
   17491         "#version 450\n"
   17492         "\n"
   17493         "layout(local_size_x=1) in;\n"
   17494         "layout(set=0, binding=0) buffer block { vec4 x; };\n"
   17495         "void main() {\n"
   17496         "   x.x = 1.0f;\n"
   17497         "}\n";
   17498     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
   17499 
   17500     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
   17501                                         nullptr,
   17502                                         0,
   17503                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
   17504                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
   17505                                         pl.handle(),
   17506                                         VK_NULL_HANDLE,
   17507                                         -1};
   17508 
   17509     VkPipeline pipe;
   17510     VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
   17511 
   17512     m_errorMonitor->VerifyFound();
   17513 
   17514     if (err == VK_SUCCESS) {
   17515         vkDestroyPipeline(m_device->device(), pipe, nullptr);
   17516     }
   17517 }
   17518 
   17519 TEST_F(VkLayerTest, DrawTimeImageViewTypeMismatchWithPipeline) {
   17520     TEST_DESCRIPTION(
   17521         "Test that an error is produced when an image view type does not match the dimensionality declared in the shader");
   17522 
   17523     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "requires an image view of type VK_IMAGE_VIEW_TYPE_3D");
   17524 
   17525     ASSERT_NO_FATAL_FAILURE(Init());
   17526     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   17527 
   17528     char const *vsSource =
   17529         "#version 450\n"
   17530         "\n"
   17531         "void main() { gl_Position = vec4(0); }\n";
   17532     char const *fsSource =
   17533         "#version 450\n"
   17534         "\n"
   17535         "layout(set=0, binding=0) uniform sampler3D s;\n"
   17536         "layout(location=0) out vec4 color;\n"
   17537         "void main() {\n"
   17538         "   color = texture(s, vec3(0));\n"
   17539         "}\n";
   17540     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   17541     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   17542 
   17543     VkPipelineObj pipe(m_device);
   17544     pipe.AddShader(&vs);
   17545     pipe.AddShader(&fs);
   17546     pipe.AddDefaultColorAttachment();
   17547 
   17548     VkTextureObj texture(m_device, nullptr);
   17549     VkSamplerObj sampler(m_device);
   17550 
   17551     VkDescriptorSetObj descriptorSet(m_device);
   17552     descriptorSet.AppendSamplerTexture(&sampler, &texture);
   17553     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   17554 
   17555     VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   17556     ASSERT_VK_SUCCESS(err);
   17557 
   17558     m_commandBuffer->begin();
   17559     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   17560 
   17561     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   17562     m_commandBuffer->BindDescriptorSet(descriptorSet);
   17563 
   17564     VkViewport viewport = {0, 0, 16, 16, 0, 1};
   17565     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   17566     VkRect2D scissor = {{0, 0}, {16, 16}};
   17567     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
   17568 
   17569     // error produced here.
   17570     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
   17571 
   17572     m_errorMonitor->VerifyFound();
   17573 
   17574     m_commandBuffer->EndRenderPass();
   17575     m_commandBuffer->end();
   17576 }
   17577 
   17578 TEST_F(VkLayerTest, DrawTimeImageMultisampleMismatchWithPipeline) {
   17579     TEST_DESCRIPTION(
   17580         "Test that an error is produced when a multisampled images are consumed via singlesample images types in the shader, or "
   17581         "vice versa.");
   17582 
   17583     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "requires bound image to have multiple samples");
   17584 
   17585     ASSERT_NO_FATAL_FAILURE(Init());
   17586     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   17587 
   17588     char const *vsSource =
   17589         "#version 450\n"
   17590         "\n"
   17591         "void main() { gl_Position = vec4(0); }\n";
   17592     char const *fsSource =
   17593         "#version 450\n"
   17594         "\n"
   17595         "layout(set=0, binding=0) uniform sampler2DMS s;\n"
   17596         "layout(location=0) out vec4 color;\n"
   17597         "void main() {\n"
   17598         "   color = texelFetch(s, ivec2(0), 0);\n"
   17599         "}\n";
   17600     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   17601     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   17602 
   17603     VkPipelineObj pipe(m_device);
   17604     pipe.AddShader(&vs);
   17605     pipe.AddShader(&fs);
   17606     pipe.AddDefaultColorAttachment();
   17607 
   17608     VkTextureObj texture(m_device, nullptr);  // THIS LINE CAUSES CRASH ON MALI
   17609     VkSamplerObj sampler(m_device);
   17610 
   17611     VkDescriptorSetObj descriptorSet(m_device);
   17612     descriptorSet.AppendSamplerTexture(&sampler, &texture);
   17613     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   17614 
   17615     VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   17616     ASSERT_VK_SUCCESS(err);
   17617 
   17618     m_commandBuffer->begin();
   17619     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   17620 
   17621     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   17622     m_commandBuffer->BindDescriptorSet(descriptorSet);
   17623 
   17624     VkViewport viewport = {0, 0, 16, 16, 0, 1};
   17625     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   17626     VkRect2D scissor = {{0, 0}, {16, 16}};
   17627     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
   17628 
   17629     // error produced here.
   17630     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
   17631 
   17632     m_errorMonitor->VerifyFound();
   17633 
   17634     m_commandBuffer->EndRenderPass();
   17635     m_commandBuffer->end();
   17636 }
   17637 
   17638 TEST_F(VkLayerTest, CreateImageMinLimitsViolation) {
   17639     TEST_DESCRIPTION("Create invalid image with invalid parameters of zero.");
   17640 
   17641     ASSERT_NO_FATAL_FAILURE(Init());
   17642 
   17643     const VkFormat safe_format = VK_FORMAT_B8G8R8A8_UNORM;
   17644     const VkImageUsageFlags safe_usage = VK_IMAGE_USAGE_SAMPLED_BIT;
   17645 
   17646     VkImageCreateInfo info = {};
   17647     info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   17648     info.imageType = VK_IMAGE_TYPE_3D;
   17649     info.format = safe_format;
   17650     // extent to be set by tests
   17651     info.mipLevels = 1;
   17652     info.arrayLayers = 1;
   17653     info.samples = VK_SAMPLE_COUNT_1_BIT;
   17654     info.usage = safe_usage;
   17655 
   17656     enum Dimension { kWidth = 0x1, kHeight = 0x2, kDepth = 0x4 };
   17657 
   17658     for (underlying_type<Dimension>::type bad_dimensions = 0x1; bad_dimensions < 0x8; ++bad_dimensions) {
   17659         VkExtent3D extent = {1, 1, 1};
   17660 
   17661         if (bad_dimensions & kWidth) {
   17662             extent.width = 0;
   17663             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00760);
   17664         }
   17665 
   17666         if (bad_dimensions & kHeight) {
   17667             extent.height = 0;
   17668             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00762);
   17669         }
   17670 
   17671         if (bad_dimensions & kDepth) {
   17672             extent.depth = 0;
   17673             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00764);
   17674         }
   17675 
   17676         info.extent = extent;
   17677 
   17678         VkImage image;
   17679         vkCreateImage(m_device->device(), &info, NULL, &image);
   17680 
   17681         m_errorMonitor->VerifyFound();
   17682     }
   17683 
   17684     info.imageType = VK_IMAGE_TYPE_2D;
   17685     info.extent = {64, 64, 1};
   17686 
   17687     {
   17688         VkImageCreateInfo bad_info = info;
   17689         bad_info.mipLevels = 0;
   17690 
   17691         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00766);
   17692         VkImage image;
   17693         vkCreateImage(m_device->device(), &bad_info, NULL, &image);
   17694         m_errorMonitor->VerifyFound();
   17695     }
   17696 
   17697     {
   17698         VkImageCreateInfo bad_info = info;
   17699         bad_info.arrayLayers = 0;
   17700 
   17701         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00768);
   17702         VkImage image;
   17703         vkCreateImage(m_device->device(), &bad_info, NULL, &image);
   17704         m_errorMonitor->VerifyFound();
   17705     }
   17706 }
   17707 
   17708 TEST_F(VkLayerTest, AttachmentDescriptionUndefinedFormat) {
   17709     TEST_DESCRIPTION("Create a render pass with an attachment description format set to VK_FORMAT_UNDEFINED");
   17710 
   17711     ASSERT_NO_FATAL_FAILURE(Init());
   17712     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   17713 
   17714     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "format is VK_FORMAT_UNDEFINED");
   17715 
   17716     VkAttachmentReference color_attach = {};
   17717     color_attach.layout = VK_IMAGE_LAYOUT_GENERAL;
   17718     color_attach.attachment = 0;
   17719     VkSubpassDescription subpass = {};
   17720     subpass.colorAttachmentCount = 1;
   17721     subpass.pColorAttachments = &color_attach;
   17722 
   17723     VkRenderPassCreateInfo rpci = {};
   17724     rpci.subpassCount = 1;
   17725     rpci.pSubpasses = &subpass;
   17726     rpci.attachmentCount = 1;
   17727     VkAttachmentDescription attach_desc = {};
   17728     attach_desc.format = VK_FORMAT_UNDEFINED;
   17729     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
   17730     attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
   17731     rpci.pAttachments = &attach_desc;
   17732     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
   17733     VkRenderPass rp;
   17734     VkResult result = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
   17735 
   17736     m_errorMonitor->VerifyFound();
   17737 
   17738     if (result == VK_SUCCESS) {
   17739         vkDestroyRenderPass(m_device->device(), rp, NULL);
   17740     }
   17741 }
   17742 
   17743 TEST_F(VkLayerTest, AttachmentDescriptionInvalidFinalLayout) {
   17744     TEST_DESCRIPTION("VkAttachmentDescription's finalLayout must not be UNDEFINED or PREINITIALIZED");
   17745 
   17746     ASSERT_NO_FATAL_FAILURE(Init());
   17747 
   17748     VkAttachmentDescription attach_desc = {};
   17749     attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM;
   17750     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
   17751     attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
   17752     attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
   17753     attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
   17754     attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
   17755     attach_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   17756     attach_desc.finalLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   17757     VkAttachmentReference attach_ref = {};
   17758     attach_ref.attachment = 0;
   17759     attach_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   17760     VkSubpassDescription subpass = {};
   17761     subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
   17762     subpass.colorAttachmentCount = 1;
   17763     subpass.pColorAttachments = &attach_ref;
   17764     VkRenderPassCreateInfo rpci = {};
   17765     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
   17766     rpci.attachmentCount = 1;
   17767     rpci.pAttachments = &attach_desc;
   17768     rpci.subpassCount = 1;
   17769     rpci.pSubpasses = &subpass;
   17770     VkRenderPass rp = VK_NULL_HANDLE;
   17771 
   17772     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_00800696);
   17773     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
   17774     m_errorMonitor->VerifyFound();
   17775     if (rp != VK_NULL_HANDLE) {
   17776         vkDestroyRenderPass(m_device->device(), rp, NULL);
   17777     }
   17778 
   17779     attach_desc.finalLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
   17780     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_00800696);
   17781     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
   17782     m_errorMonitor->VerifyFound();
   17783     if (rp != VK_NULL_HANDLE) {
   17784         vkDestroyRenderPass(m_device->device(), rp, NULL);
   17785     }
   17786 }
   17787 
   17788 TEST_F(VkLayerTest, CreateImageViewNoMemoryBoundToImage) {
   17789     VkResult err;
   17790     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   17791                                          " used with no memory bound. Memory should be bound by calling vkBindImageMemory().");
   17792 
   17793     ASSERT_NO_FATAL_FAILURE(Init());
   17794 
   17795     // Create an image and try to create a view with no memory backing the image
   17796     VkImage image;
   17797 
   17798     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
   17799     const int32_t tex_width = 32;
   17800     const int32_t tex_height = 32;
   17801 
   17802     VkImageCreateInfo image_create_info = {};
   17803     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   17804     image_create_info.pNext = NULL;
   17805     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   17806     image_create_info.format = tex_format;
   17807     image_create_info.extent.width = tex_width;
   17808     image_create_info.extent.height = tex_height;
   17809     image_create_info.extent.depth = 1;
   17810     image_create_info.mipLevels = 1;
   17811     image_create_info.arrayLayers = 1;
   17812     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   17813     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
   17814     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
   17815     image_create_info.flags = 0;
   17816 
   17817     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
   17818     ASSERT_VK_SUCCESS(err);
   17819 
   17820     VkImageViewCreateInfo image_view_create_info = {};
   17821     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   17822     image_view_create_info.image = image;
   17823     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
   17824     image_view_create_info.format = tex_format;
   17825     image_view_create_info.subresourceRange.layerCount = 1;
   17826     image_view_create_info.subresourceRange.baseMipLevel = 0;
   17827     image_view_create_info.subresourceRange.levelCount = 1;
   17828     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   17829 
   17830     VkImageView view;
   17831     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
   17832 
   17833     m_errorMonitor->VerifyFound();
   17834     vkDestroyImage(m_device->device(), image, NULL);
   17835     // If last error is success, it still created the view, so delete it.
   17836     if (err == VK_SUCCESS) {
   17837         vkDestroyImageView(m_device->device(), view, NULL);
   17838     }
   17839 }
   17840 
   17841 TEST_F(VkLayerTest, InvalidImageViewAspect) {
   17842     TEST_DESCRIPTION("Create an image and try to create a view with an invalid aspectMask");
   17843     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a400c01);
   17844 
   17845     ASSERT_NO_FATAL_FAILURE(Init());
   17846 
   17847     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
   17848     VkImageObj image(m_device);
   17849     image.Init(32, 32, 1, tex_format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_LINEAR, 0);
   17850     ASSERT_TRUE(image.initialized());
   17851 
   17852     VkImageViewCreateInfo image_view_create_info = {};
   17853     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   17854     image_view_create_info.image = image.handle();
   17855     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
   17856     image_view_create_info.format = tex_format;
   17857     image_view_create_info.subresourceRange.baseMipLevel = 0;
   17858     image_view_create_info.subresourceRange.levelCount = 1;
   17859     image_view_create_info.subresourceRange.layerCount = 1;
   17860     // Cause an error by setting an invalid image aspect
   17861     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
   17862 
   17863     VkImageView view;
   17864     vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
   17865 
   17866     m_errorMonitor->VerifyFound();
   17867 }
   17868 
   17869 TEST_F(VkLayerTest, ExerciseGetImageSubresourceLayout) {
   17870     TEST_DESCRIPTION("Test vkGetImageSubresourceLayout() valid usages");
   17871 
   17872     ASSERT_NO_FATAL_FAILURE(Init());
   17873     VkSubresourceLayout subres_layout = {};
   17874 
   17875     // VU 00732: image must have been created with tiling equal to VK_IMAGE_TILING_LINEAR
   17876     {
   17877         const VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL;  // ERROR: violates VU 00732
   17878         VkImageObj img(m_device);
   17879         img.InitNoLayout(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, tiling);
   17880         ASSERT_TRUE(img.initialized());
   17881 
   17882         VkImageSubresource subres = {};
   17883         subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   17884         subres.mipLevel = 0;
   17885         subres.arrayLayer = 0;
   17886 
   17887         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_2a6007c8);
   17888         vkGetImageSubresourceLayout(m_device->device(), img.image(), &subres, &subres_layout);
   17889         m_errorMonitor->VerifyFound();
   17890     }
   17891 
   17892     // VU 00733: The aspectMask member of pSubresource must only have a single bit set
   17893     {
   17894         VkImageObj img(m_device);
   17895         img.InitNoLayout(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
   17896         ASSERT_TRUE(img.initialized());
   17897 
   17898         VkImageSubresource subres = {};
   17899         subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_METADATA_BIT;  // ERROR: triggers VU 00733
   17900         subres.mipLevel = 0;
   17901         subres.arrayLayer = 0;
   17902 
   17903         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_2a6007ca);
   17904         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a400c01);
   17905         vkGetImageSubresourceLayout(m_device->device(), img.image(), &subres, &subres_layout);
   17906         m_errorMonitor->VerifyFound();
   17907     }
   17908 
   17909     // 00739 mipLevel must be less than the mipLevels specified in VkImageCreateInfo when the image was created
   17910     {
   17911         VkImageObj img(m_device);
   17912         img.InitNoLayout(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
   17913         ASSERT_TRUE(img.initialized());
   17914 
   17915         VkImageSubresource subres = {};
   17916         subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   17917         subres.mipLevel = 1;  // ERROR: triggers VU 00739
   17918         subres.arrayLayer = 0;
   17919 
   17920         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a4007cc);
   17921         vkGetImageSubresourceLayout(m_device->device(), img.image(), &subres, &subres_layout);
   17922         m_errorMonitor->VerifyFound();
   17923     }
   17924 
   17925     // 00740 arrayLayer must be less than the arrayLayers specified in VkImageCreateInfo when the image was created
   17926     {
   17927         VkImageObj img(m_device);
   17928         img.InitNoLayout(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
   17929         ASSERT_TRUE(img.initialized());
   17930 
   17931         VkImageSubresource subres = {};
   17932         subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   17933         subres.mipLevel = 0;
   17934         subres.arrayLayer = 1;  // ERROR: triggers VU 00740
   17935 
   17936         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a4007ce);
   17937         vkGetImageSubresourceLayout(m_device->device(), img.image(), &subres, &subres_layout);
   17938         m_errorMonitor->VerifyFound();
   17939     }
   17940 }
   17941 
   17942 TEST_F(VkLayerTest, CopyImageLayerCountMismatch) {
   17943     VkResult err;
   17944     bool pass;
   17945 
   17946     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00118);
   17947 
   17948     ASSERT_NO_FATAL_FAILURE(Init());
   17949 
   17950     // Create two images of different types and try to copy between them
   17951     VkImage srcImage;
   17952     VkImage dstImage;
   17953     VkDeviceMemory srcMem;
   17954     VkDeviceMemory destMem;
   17955     VkMemoryRequirements memReqs;
   17956 
   17957     VkImageCreateInfo image_create_info = {};
   17958     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   17959     image_create_info.pNext = NULL;
   17960     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   17961     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
   17962     image_create_info.extent.width = 32;
   17963     image_create_info.extent.height = 32;
   17964     image_create_info.extent.depth = 1;
   17965     image_create_info.mipLevels = 1;
   17966     image_create_info.arrayLayers = 4;
   17967     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   17968     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   17969     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   17970     image_create_info.flags = 0;
   17971 
   17972     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
   17973     ASSERT_VK_SUCCESS(err);
   17974 
   17975     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   17976     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
   17977     ASSERT_VK_SUCCESS(err);
   17978 
   17979     // Allocate memory
   17980     VkMemoryAllocateInfo memAlloc = {};
   17981     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   17982     memAlloc.pNext = NULL;
   17983     memAlloc.allocationSize = 0;
   17984     memAlloc.memoryTypeIndex = 0;
   17985 
   17986     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
   17987     memAlloc.allocationSize = memReqs.size;
   17988     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
   17989     ASSERT_TRUE(pass);
   17990     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
   17991     ASSERT_VK_SUCCESS(err);
   17992 
   17993     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
   17994     memAlloc.allocationSize = memReqs.size;
   17995     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
   17996     ASSERT_VK_SUCCESS(err);
   17997     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
   17998     ASSERT_VK_SUCCESS(err);
   17999 
   18000     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
   18001     ASSERT_VK_SUCCESS(err);
   18002     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
   18003     ASSERT_VK_SUCCESS(err);
   18004 
   18005     m_commandBuffer->begin();
   18006     VkImageCopy copyRegion;
   18007     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   18008     copyRegion.srcSubresource.mipLevel = 0;
   18009     copyRegion.srcSubresource.baseArrayLayer = 0;
   18010     copyRegion.srcSubresource.layerCount = 1;
   18011     copyRegion.srcOffset.x = 0;
   18012     copyRegion.srcOffset.y = 0;
   18013     copyRegion.srcOffset.z = 0;
   18014     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   18015     copyRegion.dstSubresource.mipLevel = 0;
   18016     copyRegion.dstSubresource.baseArrayLayer = 0;
   18017     // Introduce failure by forcing the dst layerCount to differ from src
   18018     copyRegion.dstSubresource.layerCount = 3;
   18019     copyRegion.dstOffset.x = 0;
   18020     copyRegion.dstOffset.y = 0;
   18021     copyRegion.dstOffset.z = 0;
   18022     copyRegion.extent.width = 1;
   18023     copyRegion.extent.height = 1;
   18024     copyRegion.extent.depth = 1;
   18025     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
   18026     m_commandBuffer->end();
   18027 
   18028     m_errorMonitor->VerifyFound();
   18029 
   18030     vkDestroyImage(m_device->device(), srcImage, NULL);
   18031     vkDestroyImage(m_device->device(), dstImage, NULL);
   18032     vkFreeMemory(m_device->device(), srcMem, NULL);
   18033     vkFreeMemory(m_device->device(), destMem, NULL);
   18034 }
   18035 
   18036 TEST_F(VkLayerTest, ImageLayerUnsupportedFormat) {
   18037     TEST_DESCRIPTION("Creating images with unsuported formats ");
   18038 
   18039     ASSERT_NO_FATAL_FAILURE(Init());
   18040     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   18041 
   18042     // Create image with unsupported format - Expect FORMAT_UNSUPPORTED
   18043     VkImageCreateInfo image_create_info = {};
   18044     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   18045     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   18046     image_create_info.format = VK_FORMAT_UNDEFINED;
   18047     image_create_info.extent.width = 32;
   18048     image_create_info.extent.height = 32;
   18049     image_create_info.extent.depth = 1;
   18050     image_create_info.mipLevels = 1;
   18051     image_create_info.arrayLayers = 1;
   18052     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   18053     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   18054     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   18055 
   18056     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   18057                                          "vkCreateImage: VkFormat for image must not be VK_FORMAT_UNDEFINED");
   18058 
   18059     VkImage image;
   18060     vkCreateImage(m_device->handle(), &image_create_info, NULL, &image);
   18061     m_errorMonitor->VerifyFound();
   18062 
   18063     // Look for a format that is COMPLETELY unsupported with this hardware
   18064     VkFormat unsupported = VK_FORMAT_UNDEFINED;
   18065     for (int f = VK_FORMAT_BEGIN_RANGE; f <= VK_FORMAT_END_RANGE; f++) {
   18066         VkFormat format = static_cast<VkFormat>(f);
   18067         VkFormatProperties fProps = m_device->format_properties(format);
   18068         if (format != VK_FORMAT_UNDEFINED && fProps.linearTilingFeatures == 0 && fProps.optimalTilingFeatures == 0) {
   18069             unsupported = format;
   18070             break;
   18071         }
   18072     }
   18073 
   18074     if (unsupported != VK_FORMAT_UNDEFINED) {
   18075         image_create_info.format = unsupported;
   18076         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is an unsupported format");
   18077 
   18078         vkCreateImage(m_device->handle(), &image_create_info, NULL, &image);
   18079         m_errorMonitor->VerifyFound();
   18080     }
   18081 }
   18082 
   18083 TEST_F(VkLayerTest, CreateImageViewFormatMismatchUnrelated) {
   18084     TEST_DESCRIPTION("Create an image with a color format, then try to create a depth view of it");
   18085 
   18086     if (!EnableDeviceProfileLayer()) return;
   18087 
   18088     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   18089     ASSERT_NO_FATAL_FAILURE(InitState());
   18090 
   18091     // Load required functions
   18092     PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT =
   18093         (PFN_vkSetPhysicalDeviceFormatPropertiesEXT)vkGetInstanceProcAddr(instance(), "vkSetPhysicalDeviceFormatPropertiesEXT");
   18094     PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT =
   18095         (PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT)vkGetInstanceProcAddr(instance(),
   18096                                                                                   "vkGetOriginalPhysicalDeviceFormatPropertiesEXT");
   18097 
   18098     if (!(fpvkSetPhysicalDeviceFormatPropertiesEXT) || !(fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) {
   18099         printf("             Can't find device_profile_api functions; skipped.\n");
   18100         return;
   18101     }
   18102 
   18103     auto depth_format = FindSupportedDepthStencilFormat(gpu());
   18104     if (!depth_format) {
   18105         return;
   18106     }
   18107 
   18108     VkFormatProperties formatProps;
   18109 
   18110     fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), depth_format, &formatProps);
   18111     formatProps.optimalTilingFeatures |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
   18112     fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), depth_format, formatProps);
   18113 
   18114     VkImageObj image(m_device);
   18115     image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   18116     ASSERT_TRUE(image.initialized());
   18117 
   18118     VkImageView imgView;
   18119     VkImageViewCreateInfo imgViewInfo = {};
   18120     imgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   18121     imgViewInfo.image = image.handle();
   18122     imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
   18123     imgViewInfo.format = depth_format;
   18124     imgViewInfo.subresourceRange.layerCount = 1;
   18125     imgViewInfo.subresourceRange.baseMipLevel = 0;
   18126     imgViewInfo.subresourceRange.levelCount = 1;
   18127     imgViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   18128 
   18129     // Can't use depth format for view into color image - Expect INVALID_FORMAT
   18130     m_errorMonitor->SetDesiredFailureMsg(
   18131         VK_DEBUG_REPORT_ERROR_BIT_EXT,
   18132         "Formats MUST be IDENTICAL unless VK_IMAGE_CREATE_MUTABLE_FORMAT BIT was set on image creation.");
   18133     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
   18134     m_errorMonitor->VerifyFound();
   18135 }
   18136 
   18137 TEST_F(VkLayerTest, CreateImageViewNoMutableFormatBit) {
   18138     TEST_DESCRIPTION("Create an image view with a different format, when the image does not have MUTABLE_FORMAT bit");
   18139 
   18140     if (!EnableDeviceProfileLayer()) return;
   18141 
   18142     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   18143     ASSERT_NO_FATAL_FAILURE(InitState());
   18144 
   18145     PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr;
   18146     PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr;
   18147 
   18148     // Load required functions
   18149     if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) {
   18150         return;
   18151     }
   18152 
   18153     VkImageObj image(m_device);
   18154     image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   18155     ASSERT_TRUE(image.initialized());
   18156 
   18157     VkFormatProperties formatProps;
   18158 
   18159     fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_B8G8R8A8_UINT, &formatProps);
   18160     formatProps.optimalTilingFeatures |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
   18161     fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_B8G8R8A8_UINT, formatProps);
   18162 
   18163     VkImageView imgView;
   18164     VkImageViewCreateInfo imgViewInfo = {};
   18165     imgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   18166     imgViewInfo.image = image.handle();
   18167     imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
   18168     imgViewInfo.format = VK_FORMAT_B8G8R8A8_UINT;
   18169     imgViewInfo.subresourceRange.layerCount = 1;
   18170     imgViewInfo.subresourceRange.baseMipLevel = 0;
   18171     imgViewInfo.subresourceRange.levelCount = 1;
   18172     imgViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   18173 
   18174     // Same compatibility class but no MUTABLE_FORMAT bit - Expect
   18175     // VIEW_CREATE_ERROR
   18176     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac007f6);
   18177     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
   18178     m_errorMonitor->VerifyFound();
   18179 }
   18180 
   18181 TEST_F(VkLayerTest, CreateImageViewDifferentClass) {
   18182     TEST_DESCRIPTION("Passing bad parameters to CreateImageView");
   18183 
   18184     ASSERT_NO_FATAL_FAILURE(Init());
   18185 
   18186     if (!(m_device->format_properties(VK_FORMAT_R8_UINT).optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) {
   18187         printf("Device does not support R8_UINT as color attachment; skipped");
   18188         return;
   18189     }
   18190 
   18191     VkImageCreateInfo mutImgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
   18192                                     nullptr,
   18193                                     VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
   18194                                     VK_IMAGE_TYPE_2D,
   18195                                     VK_FORMAT_R8_UINT,
   18196                                     {128, 128, 1},
   18197                                     1,
   18198                                     1,
   18199                                     VK_SAMPLE_COUNT_1_BIT,
   18200                                     VK_IMAGE_TILING_OPTIMAL,
   18201                                     VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
   18202                                     VK_SHARING_MODE_EXCLUSIVE,
   18203                                     0,
   18204                                     nullptr,
   18205                                     VK_IMAGE_LAYOUT_UNDEFINED};
   18206     VkImageObj mutImage(m_device);
   18207     mutImage.init(&mutImgInfo);
   18208     ASSERT_TRUE(mutImage.initialized());
   18209 
   18210     VkImageView imgView;
   18211     VkImageViewCreateInfo imgViewInfo = {};
   18212     imgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   18213     imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
   18214     imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
   18215     imgViewInfo.subresourceRange.layerCount = 1;
   18216     imgViewInfo.subresourceRange.baseMipLevel = 0;
   18217     imgViewInfo.subresourceRange.levelCount = 1;
   18218     imgViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   18219     imgViewInfo.image = mutImage.handle();
   18220 
   18221     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac007f4);
   18222     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
   18223     m_errorMonitor->VerifyFound();
   18224 }
   18225 
   18226 TEST_F(VkLayerTest, CreateImageViewInvalidSubresourceRange) {
   18227     TEST_DESCRIPTION("Passing bad image subrange to CreateImageView");
   18228 
   18229     ASSERT_NO_FATAL_FAILURE(Init());
   18230 
   18231     VkImageObj image(m_device);
   18232     image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
   18233     ASSERT_TRUE(image.create_info().arrayLayers == 1);
   18234     ASSERT_TRUE(image.initialized());
   18235 
   18236     VkImageView img_view;
   18237     VkImageViewCreateInfo img_view_info_template = {};
   18238     img_view_info_template.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   18239     img_view_info_template.image = image.handle();
   18240     img_view_info_template.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
   18241     img_view_info_template.format = image.format();
   18242     // subresourceRange to be filled later for the purposes of this test
   18243     img_view_info_template.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   18244     img_view_info_template.subresourceRange.baseMipLevel = 0;
   18245     img_view_info_template.subresourceRange.levelCount = 0;
   18246     img_view_info_template.subresourceRange.baseArrayLayer = 0;
   18247     img_view_info_template.subresourceRange.layerCount = 0;
   18248 
   18249     // Try baseMipLevel >= image.mipLevels with VK_REMAINING_MIP_LEVELS
   18250     {
   18251         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac00b8c);
   18252         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, VK_REMAINING_MIP_LEVELS, 0, 1};
   18253         VkImageViewCreateInfo img_view_info = img_view_info_template;
   18254         img_view_info.subresourceRange = range;
   18255         vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view);
   18256         m_errorMonitor->VerifyFound();
   18257     }
   18258 
   18259     // Try baseMipLevel >= image.mipLevels without VK_REMAINING_MIP_LEVELS
   18260     {
   18261         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac00b8c);
   18262         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac00b8e);
   18263         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 0, 1};
   18264         VkImageViewCreateInfo img_view_info = img_view_info_template;
   18265         img_view_info.subresourceRange = range;
   18266         vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view);
   18267         m_errorMonitor->VerifyFound();
   18268     }
   18269 
   18270     // Try levelCount = 0
   18271     {
   18272         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac00b8e);
   18273         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 0, 1};
   18274         VkImageViewCreateInfo img_view_info = img_view_info_template;
   18275         img_view_info.subresourceRange = range;
   18276         vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view);
   18277         m_errorMonitor->VerifyFound();
   18278     }
   18279 
   18280     // Try baseMipLevel + levelCount > image.mipLevels
   18281     {
   18282         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac00b8e);
   18283         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 2, 0, 1};
   18284         VkImageViewCreateInfo img_view_info = img_view_info_template;
   18285         img_view_info.subresourceRange = range;
   18286         vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view);
   18287         m_errorMonitor->VerifyFound();
   18288     }
   18289 
   18290     // Try baseArrayLayer >= image.arrayLayers with VK_REMAINING_ARRAY_LAYERS
   18291     {
   18292         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac00b90);
   18293         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, VK_REMAINING_ARRAY_LAYERS};
   18294         VkImageViewCreateInfo img_view_info = img_view_info_template;
   18295         img_view_info.subresourceRange = range;
   18296         vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view);
   18297         m_errorMonitor->VerifyFound();
   18298     }
   18299 
   18300     // Try baseArrayLayer >= image.arrayLayers without VK_REMAINING_ARRAY_LAYERS
   18301     {
   18302         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac00b90);
   18303         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac00b92);
   18304         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, 1};
   18305         VkImageViewCreateInfo img_view_info = img_view_info_template;
   18306         img_view_info.subresourceRange = range;
   18307         vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view);
   18308         m_errorMonitor->VerifyFound();
   18309     }
   18310 
   18311     // Try layerCount = 0
   18312     {
   18313         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   18314                                              "vkCreateImageView: if pCreateInfo->viewType is VK_IMAGE_TYPE_2D_ARRAY, "
   18315                                              "pCreateInfo->subresourceRange.layerCount must be >= 1");
   18316         // TODO: The test environment aborts the Vulkan call in parameter_validation layer before VALIDATION_ERROR_0ac00b92 test
   18317         // m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac00b92);
   18318         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 0};
   18319         VkImageViewCreateInfo img_view_info = img_view_info_template;
   18320         img_view_info.subresourceRange = range;
   18321         vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view);
   18322         m_errorMonitor->VerifyFound();
   18323     }
   18324 
   18325     // Try baseArrayLayer + layerCount > image.arrayLayers
   18326     {
   18327         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac00b92);
   18328         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 2};
   18329         VkImageViewCreateInfo img_view_info = img_view_info_template;
   18330         img_view_info.subresourceRange = range;
   18331         vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view);
   18332         m_errorMonitor->VerifyFound();
   18333     }
   18334 }
   18335 
   18336 TEST_F(VkLayerTest, CompressedImageMipCopyTests) {
   18337     TEST_DESCRIPTION("Image/Buffer copies for higher mip levels");
   18338 
   18339     ASSERT_NO_FATAL_FAILURE(Init());
   18340 
   18341     VkPhysicalDeviceFeatures device_features = {};
   18342     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
   18343     VkFormat compressed_format = VK_FORMAT_UNDEFINED;
   18344     if (device_features.textureCompressionBC) {
   18345         compressed_format = VK_FORMAT_BC3_SRGB_BLOCK;
   18346     } else if (device_features.textureCompressionETC2) {
   18347         compressed_format = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
   18348     } else if (device_features.textureCompressionASTC_LDR) {
   18349         compressed_format = VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
   18350     } else {
   18351         printf("             No compressed formats supported - CompressedImageMipCopyTests skipped.\n");
   18352         return;
   18353     }
   18354 
   18355     VkImageCreateInfo ci;
   18356     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   18357     ci.pNext = NULL;
   18358     ci.flags = 0;
   18359     ci.imageType = VK_IMAGE_TYPE_2D;
   18360     ci.format = compressed_format;
   18361     ci.extent = {32, 32, 1};
   18362     ci.mipLevels = 6;
   18363     ci.arrayLayers = 1;
   18364     ci.samples = VK_SAMPLE_COUNT_1_BIT;
   18365     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
   18366     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   18367     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   18368     ci.queueFamilyIndexCount = 0;
   18369     ci.pQueueFamilyIndices = NULL;
   18370     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   18371 
   18372     VkImageObj image(m_device);
   18373     image.init(&ci);
   18374     ASSERT_TRUE(image.initialized());
   18375 
   18376     VkImageObj odd_image(m_device);
   18377     ci.extent = {31, 32, 1};  // Mips are [31,32] [15,16] [7,8] [3,4], [1,2] [1,1]
   18378     odd_image.init(&ci);
   18379     ASSERT_TRUE(odd_image.initialized());
   18380 
   18381     // Allocate buffers
   18382     VkMemoryPropertyFlags reqs = 0;
   18383     vk_testing::Buffer buffer_1024, buffer_64, buffer_16, buffer_8;
   18384     buffer_1024.init_as_src_and_dst(*m_device, 1024, reqs);
   18385     buffer_64.init_as_src_and_dst(*m_device, 64, reqs);
   18386     buffer_16.init_as_src_and_dst(*m_device, 16, reqs);
   18387     buffer_8.init_as_src_and_dst(*m_device, 8, reqs);
   18388 
   18389     VkBufferImageCopy region = {};
   18390     region.bufferRowLength = 0;
   18391     region.bufferImageHeight = 0;
   18392     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   18393     region.imageSubresource.layerCount = 1;
   18394     region.imageOffset = {0, 0, 0};
   18395     region.bufferOffset = 0;
   18396 
   18397     // start recording
   18398     m_commandBuffer->begin();
   18399 
   18400     // Mip level copies that work - 5 levels
   18401     m_errorMonitor->ExpectSuccess();
   18402 
   18403     // Mip 0 should fit in 1k buffer - 1k texels @ 1b each
   18404     region.imageExtent = {32, 32, 1};
   18405     region.imageSubresource.mipLevel = 0;
   18406     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_1024.handle(), 1, &region);
   18407     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_1024.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
   18408 
   18409     // Mip 2 should fit in 64b buffer - 64 texels @ 1b each
   18410     region.imageExtent = {8, 8, 1};
   18411     region.imageSubresource.mipLevel = 2;
   18412     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64.handle(), 1, &region);
   18413     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
   18414 
   18415     // Mip 3 should fit in 16b buffer - 16 texels @ 1b each
   18416     region.imageExtent = {4, 4, 1};
   18417     region.imageSubresource.mipLevel = 3;
   18418     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
   18419     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
   18420 
   18421     // Mip 4&5 should fit in 16b buffer with no complaint - 4 & 1 texels @ 1b each
   18422     region.imageExtent = {2, 2, 1};
   18423     region.imageSubresource.mipLevel = 4;
   18424     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
   18425     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
   18426 
   18427     region.imageExtent = {1, 1, 1};
   18428     region.imageSubresource.mipLevel = 5;
   18429     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
   18430     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
   18431     m_errorMonitor->VerifyNotFound();
   18432 
   18433     // Buffer must accomodate a full compressed block, regardless of texel count
   18434     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1920016e);
   18435     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_8.handle(), 1, &region);
   18436     m_errorMonitor->VerifyFound();
   18437     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18e00156);
   18438     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_8.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
   18439     m_errorMonitor->VerifyFound();
   18440 
   18441     // Copy width < compressed block size, but not the full mip width
   18442     region.imageExtent = {1, 2, 1};
   18443     region.imageSubresource.mipLevel = 4;
   18444     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0160019e);
   18445     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
   18446     m_errorMonitor->VerifyFound();
   18447     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0160019e);
   18448     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
   18449     m_errorMonitor->VerifyFound();
   18450 
   18451     // Copy height < compressed block size but not the full mip height
   18452     region.imageExtent = {2, 1, 1};
   18453     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_016001a0);
   18454     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
   18455     m_errorMonitor->VerifyFound();
   18456     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_016001a0);
   18457     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
   18458     m_errorMonitor->VerifyFound();
   18459 
   18460     // Offsets must be multiple of compressed block size
   18461     region.imageOffset = {1, 1, 0};
   18462     region.imageExtent = {1, 1, 1};
   18463     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0160019a);
   18464     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
   18465     m_errorMonitor->VerifyFound();
   18466     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0160019a);
   18467     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
   18468     m_errorMonitor->VerifyFound();
   18469 
   18470     // Offset + extent width = mip width - should succeed
   18471     region.imageOffset = {4, 4, 0};
   18472     region.imageExtent = {3, 4, 1};
   18473     region.imageSubresource.mipLevel = 2;
   18474     m_errorMonitor->ExpectSuccess();
   18475     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
   18476     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
   18477     m_errorMonitor->VerifyNotFound();
   18478 
   18479     // Offset + extent width > mip width, but still within the final compressed block - should succeed
   18480     region.imageExtent = {4, 4, 1};
   18481     m_errorMonitor->ExpectSuccess();
   18482     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
   18483     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
   18484     m_errorMonitor->VerifyNotFound();
   18485 
   18486     // Offset + extent width < mip width and not a multiple of block width - should fail
   18487     region.imageExtent = {3, 3, 1};
   18488     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_016001a0);
   18489     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
   18490     m_errorMonitor->VerifyFound();
   18491     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_016001a0);
   18492     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
   18493     m_errorMonitor->VerifyFound();
   18494 }
   18495 
   18496 TEST_F(VkLayerTest, ImageBufferCopyTests) {
   18497     TEST_DESCRIPTION("Image to buffer and buffer to image tests");
   18498 
   18499     ASSERT_NO_FATAL_FAILURE(Init());
   18500     VkFormatProperties format_props = m_device->format_properties(VK_FORMAT_D24_UNORM_S8_UINT);
   18501     if (!(format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
   18502         printf("             VK_FORMAT_D24_UNORM_S8_UINT not supported. Skipped.\n");
   18503         return;
   18504     }
   18505 
   18506     // Bail if any dimension of transfer granularity is 0.
   18507     auto index = m_device->graphics_queue_node_index_;
   18508     auto queue_family_properties = m_device->phy().queue_properties();
   18509     if ((queue_family_properties[index].minImageTransferGranularity.depth == 0) ||
   18510         (queue_family_properties[index].minImageTransferGranularity.width == 0) ||
   18511         (queue_family_properties[index].minImageTransferGranularity.height == 0)) {
   18512         printf("             Subresource copies are disallowed when xfer granularity (x|y|z) is 0. Skipped.\n");
   18513         return;
   18514     }
   18515 
   18516     VkImageObj image_64k(m_device);        // 128^2 texels, 64k
   18517     VkImageObj image_16k(m_device);        // 64^2 texels, 16k
   18518     VkImageObj image_16k_depth(m_device);  // 64^2 texels, depth, 16k
   18519     VkImageObj ds_image_4D_1S(m_device);   // 256^2 texels, 512kb (256k depth, 64k stencil, 192k pack)
   18520     VkImageObj ds_image_3D_1S(m_device);   // 256^2 texels, 256kb (192k depth, 64k stencil)
   18521     VkImageObj ds_image_2D(m_device);      // 256^2 texels, 128k (128k depth)
   18522     VkImageObj ds_image_1S(m_device);      // 256^2 texels, 64k (64k stencil)
   18523 
   18524     image_64k.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UINT,
   18525                    VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
   18526                    VK_IMAGE_TILING_OPTIMAL, 0);
   18527     image_16k.Init(64, 64, 1, VK_FORMAT_R8G8B8A8_UINT,
   18528                    VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
   18529                    VK_IMAGE_TILING_OPTIMAL, 0);
   18530     image_16k_depth.Init(64, 64, 1, VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
   18531                          VK_IMAGE_TILING_OPTIMAL, 0);
   18532     ASSERT_TRUE(image_64k.initialized());
   18533     ASSERT_TRUE(image_16k.initialized());
   18534     ASSERT_TRUE(image_16k_depth.initialized());
   18535 
   18536     // Verify all needed Depth/Stencil formats are supported
   18537     bool missing_ds_support = false;
   18538     VkFormatProperties props = {0, 0, 0};
   18539     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D32_SFLOAT_S8_UINT, &props);
   18540     missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
   18541     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D24_UNORM_S8_UINT, &props);
   18542     missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
   18543     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D16_UNORM, &props);
   18544     missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
   18545     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_S8_UINT, &props);
   18546     missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
   18547 
   18548     if (!missing_ds_support) {
   18549         ds_image_4D_1S.Init(
   18550             256, 256, 1, VK_FORMAT_D32_SFLOAT_S8_UINT,
   18551             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
   18552             VK_IMAGE_TILING_OPTIMAL, 0);
   18553         ASSERT_TRUE(ds_image_4D_1S.initialized());
   18554 
   18555         ds_image_3D_1S.Init(
   18556             256, 256, 1, VK_FORMAT_D24_UNORM_S8_UINT,
   18557             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
   18558             VK_IMAGE_TILING_OPTIMAL, 0);
   18559         ASSERT_TRUE(ds_image_3D_1S.initialized());
   18560 
   18561         ds_image_2D.Init(
   18562             256, 256, 1, VK_FORMAT_D16_UNORM,
   18563             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
   18564             VK_IMAGE_TILING_OPTIMAL, 0);
   18565         ASSERT_TRUE(ds_image_2D.initialized());
   18566 
   18567         ds_image_1S.Init(
   18568             256, 256, 1, VK_FORMAT_S8_UINT,
   18569             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
   18570             VK_IMAGE_TILING_OPTIMAL, 0);
   18571         ASSERT_TRUE(ds_image_1S.initialized());
   18572     }
   18573 
   18574     // Allocate buffers
   18575     vk_testing::Buffer buffer_256k, buffer_128k, buffer_64k, buffer_16k;
   18576     VkMemoryPropertyFlags reqs = 0;
   18577     buffer_256k.init_as_src_and_dst(*m_device, 262144, reqs);  // 256k
   18578     buffer_128k.init_as_src_and_dst(*m_device, 131072, reqs);  // 128k
   18579     buffer_64k.init_as_src_and_dst(*m_device, 65536, reqs);    // 64k
   18580     buffer_16k.init_as_src_and_dst(*m_device, 16384, reqs);    // 16k
   18581 
   18582     VkBufferImageCopy region = {};
   18583     region.bufferRowLength = 0;
   18584     region.bufferImageHeight = 0;
   18585     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   18586     region.imageSubresource.layerCount = 1;
   18587     region.imageOffset = {0, 0, 0};
   18588     region.imageExtent = {64, 64, 1};
   18589     region.bufferOffset = 0;
   18590 
   18591     // attempt copies before putting command buffer in recording state
   18592     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18e02413);
   18593     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
   18594     m_errorMonitor->VerifyFound();
   18595 
   18596     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19202413);
   18597     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1, &region);
   18598     m_errorMonitor->VerifyFound();
   18599 
   18600     // start recording
   18601     m_commandBuffer->begin();
   18602 
   18603     // successful copies
   18604     m_errorMonitor->ExpectSuccess();
   18605     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
   18606     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
   18607     region.imageOffset.x = 16;  // 16k copy, offset requires larger image
   18608     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
   18609     region.imageExtent.height = 78;  // > 16k copy requires larger buffer & image
   18610     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
   18611     region.imageOffset.x = 0;
   18612     region.imageExtent.height = 64;
   18613     region.bufferOffset = 256;  // 16k copy with buffer offset, requires larger buffer
   18614     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1, &region);
   18615     m_errorMonitor->VerifyNotFound();
   18616 
   18617     // image/buffer too small (extent too large) on copy to image
   18618     region.imageExtent = {65, 64, 1};
   18619     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18e00156);  // buffer too small
   18620     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
   18621     m_errorMonitor->VerifyFound();
   18622 
   18623     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18e00158);  // image too small
   18624     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
   18625     m_errorMonitor->VerifyFound();
   18626 
   18627     // image/buffer too small (offset) on copy to image
   18628     region.imageExtent = {64, 64, 1};
   18629     region.imageOffset = {0, 4, 0};
   18630     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18e00156);  // buffer too small
   18631     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
   18632     m_errorMonitor->VerifyFound();
   18633 
   18634     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18e00158);  // image too small
   18635     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
   18636     m_errorMonitor->VerifyFound();
   18637 
   18638     // image/buffer too small on copy to buffer
   18639     region.imageExtent = {64, 64, 1};
   18640     region.imageOffset = {0, 0, 0};
   18641     region.bufferOffset = 4;
   18642     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1920016e);  // buffer too small
   18643     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
   18644     m_errorMonitor->VerifyFound();
   18645 
   18646     region.imageExtent = {64, 65, 1};
   18647     region.bufferOffset = 0;
   18648     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1920016c);  // image too small
   18649     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1, &region);
   18650     m_errorMonitor->VerifyFound();
   18651 
   18652     // buffer size ok but rowlength causes loose packing
   18653     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1920016e);
   18654     region.imageExtent = {64, 64, 1};
   18655     region.bufferRowLength = 68;
   18656     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
   18657     m_errorMonitor->VerifyFound();
   18658 
   18659     // An extent with zero area should produce a warning, but no error
   18660     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_ERROR_BIT_EXT, "} has zero area");
   18661     region.imageExtent.width = 0;
   18662     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
   18663     m_errorMonitor->VerifyFound();
   18664 
   18665     // aspect bits
   18666     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_016001a8);  // more than 1 aspect bit set
   18667     region.imageExtent = {64, 64, 1};
   18668     region.bufferRowLength = 0;
   18669     region.bufferImageHeight = 0;
   18670     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
   18671     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_depth.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
   18672                            &region);
   18673     m_errorMonitor->VerifyFound();
   18674 
   18675     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_016001a6);  // mis-matched aspect
   18676     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
   18677     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
   18678     m_errorMonitor->VerifyFound();
   18679 
   18680     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_016001a6);  // different mis-matched aspect
   18681     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   18682     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_depth.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
   18683                            &region);
   18684     m_errorMonitor->VerifyFound();
   18685 
   18686     // Test Depth/Stencil copies
   18687     if (missing_ds_support) {
   18688         printf("             Depth / Stencil formats unsupported - skipping D/S tests.\n");
   18689     } else {
   18690         VkBufferImageCopy ds_region = {};
   18691         ds_region.bufferOffset = 0;
   18692         ds_region.bufferRowLength = 0;
   18693         ds_region.bufferImageHeight = 0;
   18694         ds_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
   18695         ds_region.imageSubresource.mipLevel = 0;
   18696         ds_region.imageSubresource.baseArrayLayer = 0;
   18697         ds_region.imageSubresource.layerCount = 1;
   18698         ds_region.imageOffset = {0, 0, 0};
   18699         ds_region.imageExtent = {256, 256, 1};
   18700 
   18701         // Depth copies that should succeed
   18702         m_errorMonitor->ExpectSuccess();  // Extract 4b depth per texel, pack into 256k buffer
   18703         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   18704                                buffer_256k.handle(), 1, &ds_region);
   18705         m_errorMonitor->VerifyNotFound();
   18706 
   18707         m_errorMonitor->ExpectSuccess();  // Extract 3b depth per texel, pack (loose) into 256k buffer
   18708         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   18709                                buffer_256k.handle(), 1, &ds_region);
   18710         m_errorMonitor->VerifyNotFound();
   18711 
   18712         m_errorMonitor->ExpectSuccess();  // Copy 2b depth per texel, into 128k buffer
   18713         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_2D.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   18714                                buffer_128k.handle(), 1, &ds_region);
   18715         m_errorMonitor->VerifyNotFound();
   18716 
   18717         // Depth copies that should fail
   18718         ds_region.bufferOffset = 4;
   18719         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   18720                                              VALIDATION_ERROR_1920016e);  // Extract 4b depth per texel, pack into 256k buffer
   18721         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   18722                                buffer_256k.handle(), 1, &ds_region);
   18723         m_errorMonitor->VerifyFound();
   18724 
   18725         m_errorMonitor->SetDesiredFailureMsg(
   18726             VK_DEBUG_REPORT_ERROR_BIT_EXT,
   18727             VALIDATION_ERROR_1920016e);  // Extract 3b depth per texel, pack (loose) into 256k buffer
   18728         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   18729                                buffer_256k.handle(), 1, &ds_region);
   18730         m_errorMonitor->VerifyFound();
   18731 
   18732         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   18733                                              VALIDATION_ERROR_1920016e);  // Copy 2b depth per texel, into 128k buffer
   18734         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_2D.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   18735                                buffer_128k.handle(), 1, &ds_region);
   18736         m_errorMonitor->VerifyFound();
   18737 
   18738         // Stencil copies that should succeed
   18739         ds_region.bufferOffset = 0;
   18740         ds_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
   18741         m_errorMonitor->ExpectSuccess();  // Extract 1b stencil per texel, pack into 64k buffer
   18742         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   18743                                buffer_64k.handle(), 1, &ds_region);
   18744         m_errorMonitor->VerifyNotFound();
   18745 
   18746         m_errorMonitor->ExpectSuccess();  // Extract 1b stencil per texel, pack into 64k buffer
   18747         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   18748                                buffer_64k.handle(), 1, &ds_region);
   18749         m_errorMonitor->VerifyNotFound();
   18750 
   18751         m_errorMonitor->ExpectSuccess();  // Copy 1b depth per texel, into 64k buffer
   18752         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   18753                                buffer_64k.handle(), 1, &ds_region);
   18754         m_errorMonitor->VerifyNotFound();
   18755 
   18756         // Stencil copies that should fail
   18757         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   18758                                              VALIDATION_ERROR_1920016e);  // Extract 1b stencil per texel, pack into 64k buffer
   18759         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   18760                                buffer_16k.handle(), 1, &ds_region);
   18761         m_errorMonitor->VerifyFound();
   18762 
   18763         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   18764                                              VALIDATION_ERROR_1920016e);  // Extract 1b stencil per texel, pack into 64k buffer
   18765         ds_region.bufferRowLength = 260;
   18766         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   18767                                buffer_64k.handle(), 1, &ds_region);
   18768         m_errorMonitor->VerifyFound();
   18769 
   18770         ds_region.bufferRowLength = 0;
   18771         ds_region.bufferOffset = 4;
   18772         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   18773                                              VALIDATION_ERROR_1920016e);  // Copy 1b depth per texel, into 64k buffer
   18774         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
   18775                                buffer_64k.handle(), 1, &ds_region);
   18776         m_errorMonitor->VerifyFound();
   18777     }
   18778 
   18779     // Test compressed formats, if supported
   18780     VkPhysicalDeviceFeatures device_features = {};
   18781     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
   18782     if (!(device_features.textureCompressionBC || device_features.textureCompressionETC2 ||
   18783           device_features.textureCompressionASTC_LDR)) {
   18784         printf("             No compressed formats supported - block compression tests skipped.\n");
   18785     } else {
   18786         VkImageObj image_16k_4x4comp(m_device);   // 128^2 texels as 32^2 compressed (4x4) blocks, 16k
   18787         VkImageObj image_NPOT_4x4comp(m_device);  // 130^2 texels as 33^2 compressed (4x4) blocks
   18788         if (device_features.textureCompressionBC) {
   18789             image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_BC3_SRGB_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL,
   18790                                    0);
   18791             image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_BC3_SRGB_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL,
   18792                                     0);
   18793         } else if (device_features.textureCompressionETC2) {
   18794             image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
   18795                                    VK_IMAGE_TILING_OPTIMAL, 0);
   18796             image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
   18797                                     VK_IMAGE_TILING_OPTIMAL, 0);
   18798         } else {
   18799             image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
   18800                                    VK_IMAGE_TILING_OPTIMAL, 0);
   18801             image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
   18802                                     VK_IMAGE_TILING_OPTIMAL, 0);
   18803         }
   18804         ASSERT_TRUE(image_16k_4x4comp.initialized());
   18805 
   18806         // Just fits
   18807         m_errorMonitor->ExpectSuccess();
   18808         region.imageExtent = {128, 128, 1};
   18809         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(),
   18810                                1, &region);
   18811         m_errorMonitor->VerifyNotFound();
   18812 
   18813         // with offset, too big for buffer
   18814         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1920016e);
   18815         region.bufferOffset = 16;
   18816         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(),
   18817                                1, &region);
   18818         m_errorMonitor->VerifyFound();
   18819         region.bufferOffset = 0;
   18820 
   18821         // extents that are not a multiple of compressed block size
   18822         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0160019e);
   18823         region.imageExtent.width = 66;
   18824         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(),
   18825                                1, &region);
   18826         m_errorMonitor->VerifyFound();
   18827         region.imageExtent.width = 128;
   18828 
   18829         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_016001a0);
   18830         region.imageExtent.height = 2;
   18831         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(),
   18832                                1, &region);
   18833         m_errorMonitor->VerifyFound();
   18834         region.imageExtent.height = 128;
   18835 
   18836         // TODO: All available compressed formats are 2D, with block depth of 1. Unable to provoke VU_01277.
   18837 
   18838         // non-multiple extents are allowed if at the far edge of a non-block-multiple image - these should pass
   18839         m_errorMonitor->ExpectSuccess();
   18840         region.imageExtent.width = 66;
   18841         region.imageOffset.x = 64;
   18842         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(),
   18843                                1, &region);
   18844         region.imageExtent.width = 16;
   18845         region.imageOffset.x = 0;
   18846         region.imageExtent.height = 2;
   18847         region.imageOffset.y = 128;
   18848         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(),
   18849                                1, &region);
   18850         m_errorMonitor->VerifyNotFound();
   18851         region.imageOffset = {0, 0, 0};
   18852 
   18853         // buffer offset must be a multiple of texel block size (16)
   18854         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0160019c);
   18855         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01600182);
   18856         region.imageExtent = {64, 64, 1};
   18857         region.bufferOffset = 24;
   18858         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(),
   18859                                1, &region);
   18860         m_errorMonitor->VerifyFound();
   18861 
   18862         // rowlength not a multiple of block width (4)
   18863         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01600196);
   18864         region.bufferOffset = 0;
   18865         region.bufferRowLength = 130;
   18866         region.bufferImageHeight = 0;
   18867         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(),
   18868                                1, &region);
   18869         m_errorMonitor->VerifyFound();
   18870 
   18871         // imageheight not a multiple of block height (4)
   18872         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01600198);
   18873         region.bufferRowLength = 0;
   18874         region.bufferImageHeight = 130;
   18875         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(),
   18876                                1, &region);
   18877         m_errorMonitor->VerifyFound();
   18878     }
   18879 }
   18880 
   18881 TEST_F(VkLayerTest, MiscImageLayerTests) {
   18882     TEST_DESCRIPTION("Image-related tests that don't belong elsewhere");
   18883 
   18884     ASSERT_NO_FATAL_FAILURE(Init());
   18885 
   18886     // TODO: Ideally we should check if a format is supported, before using it.
   18887     VkImageObj image(m_device);
   18888     image.Init(128, 128, 1, VK_FORMAT_R16G16B16A16_UINT, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);  // 64bpp
   18889     ASSERT_TRUE(image.initialized());
   18890     vk_testing::Buffer buffer;
   18891     VkMemoryPropertyFlags reqs = 0;
   18892     buffer.init_as_src(*m_device, 128 * 128 * 8, reqs);
   18893     VkBufferImageCopy region = {};
   18894     region.bufferRowLength = 128;
   18895     region.bufferImageHeight = 128;
   18896     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   18897     // layerCount can't be 0 - Expect MISMATCHED_IMAGE_ASPECT
   18898     region.imageSubresource.layerCount = 1;
   18899     region.imageExtent.height = 4;
   18900     region.imageExtent.width = 4;
   18901     region.imageExtent.depth = 1;
   18902 
   18903     VkImageObj image2(m_device);
   18904     image2.Init(128, 128, 1, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);  // 16bpp
   18905     ASSERT_TRUE(image2.initialized());
   18906     vk_testing::Buffer buffer2;
   18907     VkMemoryPropertyFlags reqs2 = 0;
   18908     buffer2.init_as_src(*m_device, 128 * 128 * 2, reqs2);
   18909     VkBufferImageCopy region2 = {};
   18910     region2.bufferRowLength = 128;
   18911     region2.bufferImageHeight = 128;
   18912     region2.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   18913     // layerCount can't be 0 - Expect MISMATCHED_IMAGE_ASPECT
   18914     region2.imageSubresource.layerCount = 1;
   18915     region2.imageExtent.height = 4;
   18916     region2.imageExtent.width = 4;
   18917     region2.imageExtent.depth = 1;
   18918     m_commandBuffer->begin();
   18919 
   18920     // Image must have offset.z of 0 and extent.depth of 1
   18921     // Introduce failure by setting imageExtent.depth to 0
   18922     region.imageExtent.depth = 0;
   18923     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01600192);
   18924     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
   18925                            &region);
   18926     m_errorMonitor->VerifyFound();
   18927 
   18928     region.imageExtent.depth = 1;
   18929 
   18930     // Image must have offset.z of 0 and extent.depth of 1
   18931     // Introduce failure by setting imageOffset.z to 4
   18932     // Note: Also (unavoidably) triggers 'region exceeds image' #1228
   18933     region.imageOffset.z = 4;
   18934     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01600192);
   18935     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18e00158);
   18936     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
   18937                            &region);
   18938     m_errorMonitor->VerifyFound();
   18939 
   18940     region.imageOffset.z = 0;
   18941     // BufferOffset must be a multiple of the calling command's VkImage parameter's texel size
   18942     // Introduce failure by setting bufferOffset to 1 and 1/2 texels
   18943     region.bufferOffset = 4;
   18944     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01600182);
   18945     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
   18946                            &region);
   18947     m_errorMonitor->VerifyFound();
   18948 
   18949     // BufferOffset must be a multiple of 4
   18950     // Introduce failure by setting bufferOffset to a value not divisible by 4
   18951     region2.bufferOffset = 6;
   18952     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01600184);
   18953     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer2.handle(), image2.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
   18954                            &region2);
   18955     m_errorMonitor->VerifyFound();
   18956 
   18957     // BufferRowLength must be 0, or greater than or equal to the width member of imageExtent
   18958     region.bufferOffset = 0;
   18959     region.imageExtent.height = 128;
   18960     region.imageExtent.width = 128;
   18961     // Introduce failure by setting bufferRowLength > 0 but less than width
   18962     region.bufferRowLength = 64;
   18963     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01600186);
   18964     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
   18965                            &region);
   18966     m_errorMonitor->VerifyFound();
   18967 
   18968     // BufferImageHeight must be 0, or greater than or equal to the height member of imageExtent
   18969     region.bufferRowLength = 128;
   18970     // Introduce failure by setting bufferRowHeight > 0 but less than height
   18971     region.bufferImageHeight = 64;
   18972     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01600188);
   18973     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
   18974                            &region);
   18975     m_errorMonitor->VerifyFound();
   18976 
   18977     region.bufferImageHeight = 128;
   18978     VkImageObj intImage1(m_device);
   18979     intImage1.Init(128, 128, 1, VK_FORMAT_R8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   18980     intImage1.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
   18981     VkImageObj intImage2(m_device);
   18982     intImage2.Init(128, 128, 1, VK_FORMAT_R8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   18983     intImage2.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
   18984     VkImageBlit blitRegion = {};
   18985     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   18986     blitRegion.srcSubresource.baseArrayLayer = 0;
   18987     blitRegion.srcSubresource.layerCount = 1;
   18988     blitRegion.srcSubresource.mipLevel = 0;
   18989     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   18990     blitRegion.dstSubresource.baseArrayLayer = 0;
   18991     blitRegion.dstSubresource.layerCount = 1;
   18992     blitRegion.dstSubresource.mipLevel = 0;
   18993     blitRegion.srcOffsets[0] = {128, 0, 0};
   18994     blitRegion.srcOffsets[1] = {128, 128, 1};
   18995     blitRegion.dstOffsets[0] = {0, 128, 0};
   18996     blitRegion.dstOffsets[1] = {128, 128, 1};
   18997 
   18998     // Look for NULL-blit warning
   18999     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
   19000                                          "vkCmdBlitImage: pRegions[0].srcOffsets specify a zero-volume area.");
   19001     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
   19002                                          "vkCmdBlitImage: pRegions[0].dstOffsets specify a zero-volume area.");
   19003     vkCmdBlitImage(m_commandBuffer->handle(), intImage1.handle(), intImage1.Layout(), intImage2.handle(), intImage2.Layout(), 1,
   19004                    &blitRegion, VK_FILTER_LINEAR);
   19005     m_errorMonitor->VerifyFound();
   19006 }
   19007 
   19008 TEST_F(VkLayerTest, ImageFormatLimits) {
   19009     TEST_DESCRIPTION("Exceed the limits of image format ");
   19010 
   19011     ASSERT_NO_FATAL_FAILURE(Init());
   19012 
   19013     VkFormat const format = VK_FORMAT_B8G8R8A8_UNORM;
   19014     {
   19015         VkFormatProperties properties;
   19016         vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), format, &properties);
   19017         if (properties.linearTilingFeatures == 0) {
   19018             printf("             Image format not supported; skipped.\n");
   19019             return;
   19020         }
   19021     }
   19022 
   19023     VkImageCreateInfo image_create_info = {};
   19024     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   19025     image_create_info.pNext = NULL;
   19026     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   19027     image_create_info.format = format;
   19028     image_create_info.extent.width = 32;
   19029     image_create_info.extent.height = 32;
   19030     image_create_info.extent.depth = 1;
   19031     image_create_info.mipLevels = 1;
   19032     image_create_info.arrayLayers = 1;
   19033     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   19034     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
   19035     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   19036     image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   19037     image_create_info.flags = 0;
   19038 
   19039     VkImage nullImg;
   19040     VkImageFormatProperties imgFmtProps;
   19041     VkResult err = vkGetPhysicalDeviceImageFormatProperties(gpu(), image_create_info.format, image_create_info.imageType,
   19042                                                             image_create_info.tiling, image_create_info.usage,
   19043                                                             image_create_info.flags, &imgFmtProps);
   19044     if (VK_SUCCESS != err) {
   19045         printf("             Image format not supported; skipped.\n");
   19046         return;
   19047     }
   19048 
   19049     VkPhysicalDeviceProperties device_props;
   19050     vkGetPhysicalDeviceProperties(gpu(), &device_props);
   19051     uint32_t max_width = std::max(imgFmtProps.maxExtent.width, device_props.limits.maxImageDimension2D);
   19052     if (max_width < UINT32_MAX) {
   19053         image_create_info.extent.width = max_width + 1;
   19054         // Expect INVALID_FORMAT_LIMITS_VIOLATION
   19055         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00770);
   19056         vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
   19057         m_errorMonitor->VerifyFound();
   19058         image_create_info.extent.width = 1;
   19059     }
   19060 
   19061     uint32_t maxDim = std::max({image_create_info.extent.width, image_create_info.extent.height, image_create_info.extent.depth});
   19062     // If max mip levels exceeds image extents, skip the max mip levels test
   19063     if ((imgFmtProps.maxMipLevels + 1) <= (floor(log2(maxDim)) + 1)) {
   19064         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e0077e);
   19065         image_create_info.mipLevels = imgFmtProps.maxMipLevels + 1;
   19066         // Expect INVALID_FORMAT_LIMITS_VIOLATION
   19067         vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
   19068         m_errorMonitor->VerifyFound();
   19069         image_create_info.mipLevels = 1;
   19070     }
   19071 
   19072     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00780);
   19073     image_create_info.arrayLayers = imgFmtProps.maxArrayLayers + 1;
   19074     // Expect INVALID_FORMAT_LIMITS_VIOLATION
   19075     vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
   19076     m_errorMonitor->VerifyFound();
   19077     image_create_info.arrayLayers = 1;
   19078 
   19079     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   19080     vkGetPhysicalDeviceImageFormatProperties(gpu(), image_create_info.format, image_create_info.imageType, image_create_info.tiling,
   19081                                              image_create_info.usage, image_create_info.flags, &imgFmtProps);
   19082     if (0 == (imgFmtProps.sampleCounts & VK_SAMPLE_COUNT_64_BIT)) {
   19083         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e0078e);
   19084         image_create_info.samples = VK_SAMPLE_COUNT_64_BIT;
   19085         // Expect INVALID_FORMAT_LIMITS_VIOLATION
   19086         vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
   19087         m_errorMonitor->VerifyFound();
   19088         image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
   19089         image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   19090     }
   19091 
   19092     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e0b801);
   19093     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e007c2);
   19094     image_create_info.initialLayout = VK_IMAGE_LAYOUT_MAX_ENUM;  // Not a legal layout value
   19095     vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg);
   19096     m_errorMonitor->VerifyFound();
   19097     image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   19098 }
   19099 
   19100 VkResult GPDIFPHelper(VkPhysicalDevice dev, VkImageCreateInfo *ci, VkImageFormatProperties *limits) {
   19101     return vkGetPhysicalDeviceImageFormatProperties(dev, ci->format, ci->imageType, ci->tiling, ci->usage, ci->flags, limits);
   19102 }
   19103 
   19104 TEST_F(VkLayerTest, ImageCreateInfoStructErrors) {
   19105     TEST_DESCRIPTION("Misc valid usage errors in vkImageCreateInfo struct");
   19106 
   19107     ASSERT_NO_FATAL_FAILURE(Init());
   19108 
   19109     VkFormat format = VK_FORMAT_B8G8R8A8_UNORM;
   19110     VkFormatProperties fmt_props;
   19111     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), format, &fmt_props);
   19112     if ((fmt_props.linearTilingFeatures == 0) || (fmt_props.optimalTilingFeatures == 0)) {
   19113         format = VK_FORMAT_R8G8B8A8_UNORM;
   19114         vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), format, &fmt_props);
   19115         if ((fmt_props.linearTilingFeatures == 0) || (fmt_props.optimalTilingFeatures == 0)) {
   19116             printf("             Image format not supported, test skipped.\n");
   19117             return;
   19118         }
   19119     }
   19120 
   19121     VkImage image;
   19122     VkImageCreateInfo image_ci = {};
   19123     image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   19124     image_ci.pNext = NULL;
   19125     image_ci.flags = 0;
   19126     image_ci.imageType = VK_IMAGE_TYPE_1D;
   19127     image_ci.format = format;
   19128     image_ci.extent = {64, 1, 1};
   19129     image_ci.mipLevels = 1;
   19130     image_ci.arrayLayers = 1;
   19131     image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
   19132     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
   19133     image_ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   19134     image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   19135 
   19136     VkImageFormatProperties img_limits = {};
   19137     const VkPhysicalDeviceLimits dev_limits = m_device->props.limits;
   19138 
   19139     // InitialLayout not VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREDEFINED
   19140     image_ci.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   19141     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e007c2);
   19142     vkCreateImage(m_device->handle(), &image_ci, NULL, &image);
   19143     m_errorMonitor->VerifyFound();
   19144     image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   19145 
   19146     // 1D with CUBE_COMPATIBLE
   19147     image_ci.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
   19148     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e0076a);
   19149     vkCreateImage(m_device->handle(), &image_ci, NULL, &image);
   19150     m_errorMonitor->VerifyFound();
   19151     image_ci.flags = 0;
   19152 
   19153     // 1D width
   19154     GPDIFPHelper(gpu(), &image_ci, &img_limits);
   19155     image_ci.extent.width = std::max(img_limits.maxExtent.width, dev_limits.maxImageDimension1D) + 1;
   19156     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e0076e);
   19157     vkCreateImage(m_device->handle(), &image_ci, NULL, &image);
   19158     m_errorMonitor->VerifyFound();
   19159 
   19160     // 2D CUBE_COMPATIBLE extents
   19161     image_ci.imageType = VK_IMAGE_TYPE_2D;
   19162     image_ci.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
   19163     GPDIFPHelper(gpu(), &image_ci, &img_limits);
   19164     uint32_t dim = std::max({img_limits.maxExtent.width, img_limits.maxExtent.height, dev_limits.maxImageDimensionCube}) + 1;
   19165     image_ci.extent = {dim, dim, 1};
   19166     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00772);
   19167     vkCreateImage(m_device->handle(), &image_ci, NULL, &image);
   19168     m_errorMonitor->VerifyFound();
   19169     image_ci.flags = 0;
   19170 
   19171     // 3D extents
   19172     image_ci.imageType = VK_IMAGE_TYPE_3D;
   19173     GPDIFPHelper(gpu(), &image_ci, &img_limits);
   19174     image_ci.extent = {(std::max(img_limits.maxExtent.width, dev_limits.maxImageDimension3D) + 1), 4, 4};
   19175     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00776);
   19176     vkCreateImage(m_device->handle(), &image_ci, NULL, &image);
   19177     m_errorMonitor->VerifyFound();
   19178     image_ci.extent = {4, (std::max(img_limits.maxExtent.height, dev_limits.maxImageDimension3D) + 1), 4};
   19179     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00776);
   19180     vkCreateImage(m_device->handle(), &image_ci, NULL, &image);
   19181     m_errorMonitor->VerifyFound();
   19182     image_ci.extent = {4, 4, (std::max(img_limits.maxExtent.depth, dev_limits.maxImageDimension3D) + 1)};
   19183     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00776);
   19184     vkCreateImage(m_device->handle(), &image_ci, NULL, &image);
   19185     m_errorMonitor->VerifyFound();
   19186 
   19187     // 3D arrayLayers
   19188     image_ci.extent = {4, 4, 4};
   19189     image_ci.arrayLayers = 2;
   19190     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00782);
   19191     vkCreateImage(m_device->handle(), &image_ci, NULL, &image);
   19192     m_errorMonitor->VerifyFound();
   19193     image_ci.arrayLayers = 1;
   19194 
   19195     // Multi-sample
   19196     image_ci.samples = VK_SAMPLE_COUNT_4_BIT;
   19197     image_ci.imageType = VK_IMAGE_TYPE_3D;
   19198     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00784);
   19199     vkCreateImage(m_device->handle(), &image_ci, NULL, &image);
   19200     m_errorMonitor->VerifyFound();
   19201     image_ci.imageType = VK_IMAGE_TYPE_2D;
   19202     image_ci.extent = {64, 64, 1};
   19203     image_ci.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
   19204     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00784);
   19205     vkCreateImage(m_device->handle(), &image_ci, NULL, &image);
   19206     m_errorMonitor->VerifyFound();
   19207     image_ci.flags = 0;
   19208     image_ci.tiling = VK_IMAGE_TILING_LINEAR;
   19209     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00784);
   19210     vkCreateImage(m_device->handle(), &image_ci, NULL, &image);
   19211     m_errorMonitor->VerifyFound();
   19212     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
   19213     image_ci.mipLevels = 7;
   19214     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00784);
   19215     vkCreateImage(m_device->handle(), &image_ci, NULL, &image);
   19216     m_errorMonitor->VerifyFound();
   19217     image_ci.mipLevels = 1;
   19218     image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
   19219 
   19220     // TRANSIENT with a non-attachment flag
   19221     image_ci.usage =
   19222         VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   19223     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00786);
   19224     vkCreateImage(m_device->handle(), &image_ci, NULL, &image);
   19225     m_errorMonitor->VerifyFound();
   19226 
   19227     // TRANSIENT without another attachment flag
   19228     image_ci.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
   19229     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e0078c);
   19230     vkCreateImage(m_device->handle(), &image_ci, NULL, &image);
   19231     m_errorMonitor->VerifyFound();
   19232 
   19233     // Frame buffer width
   19234     image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;  // (any attachment bit)
   19235     GPDIFPHelper(gpu(), &image_ci, &img_limits);
   19236     image_ci.extent.width = dev_limits.maxFramebufferWidth + 1;
   19237     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00788);
   19238     if (image_ci.extent.width > std::max(dev_limits.maxImageDimension2D, img_limits.maxExtent.width)) {
   19239         // Image/device limits are <= framebuffer limit - will also trip 770
   19240         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00770);
   19241     }
   19242     vkCreateImage(m_device->handle(), &image_ci, NULL, &image);
   19243     m_errorMonitor->VerifyFound();
   19244 
   19245     // Frame buffer height
   19246     image_ci.usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;  // (any attachment bit)
   19247     image_ci.extent.width = 64;
   19248     image_ci.extent.height = dev_limits.maxFramebufferHeight + 1;
   19249     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e0078a);
   19250     if (image_ci.extent.height > std::max(dev_limits.maxImageDimension2D, img_limits.maxExtent.height)) {
   19251         // Image/device limits are <= framebuffer limit - will also trip 770
   19252         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00770);
   19253     }
   19254     vkCreateImage(m_device->handle(), &image_ci, NULL, &image);
   19255     m_errorMonitor->VerifyFound();
   19256 
   19257     image_ci.format = VK_FORMAT_R8_SRGB;  // pick an 'unlikely' format
   19258     VkFormatProperties format_props;
   19259     vkGetPhysicalDeviceFormatProperties(gpu(), image_ci.format, &format_props);
   19260 
   19261     // Linear tiling with unsupported feature
   19262     image_ci.tiling = VK_IMAGE_TILING_LINEAR;
   19263     bool unsupported = (VK_ERROR_FORMAT_NOT_SUPPORTED == GPDIFPHelper(gpu(), &image_ci, &img_limits));
   19264     if (format_props.linearTilingFeatures && (0 == (format_props.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))) {
   19265         image_ci.tiling = VK_IMAGE_TILING_LINEAR;
   19266         image_ci.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
   19267         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e007a4);
   19268         if (unsupported) {
   19269             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00758);
   19270         }
   19271         vkCreateImage(m_device->handle(), &image_ci, NULL, &image);
   19272         m_errorMonitor->VerifyFound();
   19273     }
   19274     if (format_props.linearTilingFeatures && (0 == (format_props.linearTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))) {
   19275         image_ci.tiling = VK_IMAGE_TILING_LINEAR;
   19276         image_ci.usage = VK_IMAGE_USAGE_STORAGE_BIT;
   19277         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e007a6);
   19278         if (unsupported) {
   19279             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00758);
   19280         }
   19281         vkCreateImage(m_device->handle(), &image_ci, NULL, &image);
   19282         m_errorMonitor->VerifyFound();
   19283     }
   19284 
   19285     // Optimal tiling with unsupported feature
   19286     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
   19287     unsupported = (VK_ERROR_FORMAT_NOT_SUPPORTED == GPDIFPHelper(gpu(), &image_ci, &img_limits));
   19288     if (format_props.optimalTilingFeatures && (0 == (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))) {
   19289         image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
   19290         image_ci.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
   19291         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e007ae);
   19292         if (unsupported) {
   19293             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00758);
   19294         }
   19295         vkCreateImage(m_device->handle(), &image_ci, NULL, &image);
   19296         m_errorMonitor->VerifyFound();
   19297     }
   19298     if (format_props.optimalTilingFeatures && (0 == (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))) {
   19299         image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
   19300         image_ci.usage = VK_IMAGE_USAGE_STORAGE_BIT;
   19301         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e007b0);
   19302         if (unsupported) {
   19303             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00758);
   19304         }
   19305         vkCreateImage(m_device->handle(), &image_ci, NULL, &image);
   19306         m_errorMonitor->VerifyFound();
   19307     }
   19308 }
   19309 
   19310 TEST_F(VkLayerTest, CopyImageTypeExtentMismatch) {
   19311     // Image copy tests where format type and extents don't match
   19312     ASSERT_NO_FATAL_FAILURE(Init());
   19313 
   19314     VkImageCreateInfo ci;
   19315     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   19316     ci.pNext = NULL;
   19317     ci.flags = 0;
   19318     ci.imageType = VK_IMAGE_TYPE_1D;
   19319     ci.format = VK_FORMAT_R8G8B8A8_UNORM;
   19320     ci.extent = {32, 1, 1};
   19321     ci.mipLevels = 1;
   19322     ci.arrayLayers = 1;
   19323     ci.samples = VK_SAMPLE_COUNT_1_BIT;
   19324     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
   19325     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   19326     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   19327     ci.queueFamilyIndexCount = 0;
   19328     ci.pQueueFamilyIndices = NULL;
   19329     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   19330 
   19331     // Create 1D image
   19332     VkImageObj image_1D(m_device);
   19333     image_1D.init(&ci);
   19334     ASSERT_TRUE(image_1D.initialized());
   19335 
   19336     // 2D image
   19337     ci.imageType = VK_IMAGE_TYPE_2D;
   19338     ci.extent = {32, 32, 1};
   19339     VkImageObj image_2D(m_device);
   19340     image_2D.init(&ci);
   19341     ASSERT_TRUE(image_2D.initialized());
   19342 
   19343     // 3D image
   19344     ci.imageType = VK_IMAGE_TYPE_3D;
   19345     ci.extent = {32, 32, 8};
   19346     VkImageObj image_3D(m_device);
   19347     image_3D.init(&ci);
   19348     ASSERT_TRUE(image_3D.initialized());
   19349 
   19350     // 2D image array
   19351     ci.imageType = VK_IMAGE_TYPE_2D;
   19352     ci.extent = {32, 32, 1};
   19353     ci.arrayLayers = 8;
   19354     VkImageObj image_2D_array(m_device);
   19355     image_2D_array.init(&ci);
   19356     ASSERT_TRUE(image_2D_array.initialized());
   19357 
   19358     m_commandBuffer->begin();
   19359 
   19360     VkImageCopy copy_region;
   19361     copy_region.extent = {32, 1, 1};
   19362     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   19363     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   19364     copy_region.srcSubresource.mipLevel = 0;
   19365     copy_region.dstSubresource.mipLevel = 0;
   19366     copy_region.srcSubresource.baseArrayLayer = 0;
   19367     copy_region.dstSubresource.baseArrayLayer = 0;
   19368     copy_region.srcSubresource.layerCount = 1;
   19369     copy_region.dstSubresource.layerCount = 1;
   19370     copy_region.srcOffset = {0, 0, 0};
   19371     copy_region.dstOffset = {0, 0, 0};
   19372 
   19373     // Sanity check
   19374     m_errorMonitor->ExpectSuccess();
   19375     m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
   19376                                &copy_region);
   19377     m_errorMonitor->VerifyNotFound();
   19378 
   19379     // 1D texture w/ offset.y > 0. Source = VU 09c00124, dest = 09c00130
   19380     copy_region.srcOffset.y = 1;
   19381     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00124);
   19382     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00122);  // also y-dim overrun
   19383     m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
   19384                                &copy_region);
   19385     m_errorMonitor->VerifyFound();
   19386     copy_region.srcOffset.y = 0;
   19387     copy_region.dstOffset.y = 1;
   19388     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00130);
   19389     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0012e);  // also y-dim overrun
   19390     m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
   19391                                &copy_region);
   19392     m_errorMonitor->VerifyFound();
   19393     copy_region.dstOffset.y = 0;
   19394 
   19395     // 1D texture w/ extent.height > 1. Source = VU 09c00124, dest = 09c00130
   19396     copy_region.extent.height = 2;
   19397     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00124);
   19398     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00122);  // also y-dim overrun
   19399     m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
   19400                                &copy_region);
   19401     m_errorMonitor->VerifyFound();
   19402     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00130);
   19403     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0012e);  // also y-dim overrun
   19404     m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
   19405                                &copy_region);
   19406     m_errorMonitor->VerifyFound();
   19407     copy_region.extent.height = 1;
   19408 
   19409     // 2D texture w/ offset.z > 0. Source = VU 09c00128, dest = 09c00134
   19410     copy_region.extent = {16, 16, 1};
   19411     copy_region.srcOffset.z = 4;
   19412     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00128);
   19413     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00126);  // also z-dim overrun
   19414     m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
   19415                                &copy_region);
   19416     m_errorMonitor->VerifyFound();
   19417     copy_region.srcOffset.z = 0;
   19418     copy_region.dstOffset.z = 1;
   19419     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00134);
   19420     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00132);  // also z-dim overrun
   19421     m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
   19422                                &copy_region);
   19423     m_errorMonitor->VerifyFound();
   19424     copy_region.dstOffset.z = 0;
   19425 
   19426     // 2D texture w/ extent.depth > 1. Source = VU 09c00128, dest = 09c00134
   19427     copy_region.extent.depth = 8;
   19428     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00128);
   19429     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00126);  // also z-dim overrun
   19430     m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
   19431                                &copy_region);
   19432     m_errorMonitor->VerifyFound();
   19433     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00134);
   19434     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00132);  // also z-dim overrun
   19435     m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
   19436                                &copy_region);
   19437     m_errorMonitor->VerifyFound();
   19438     copy_region.extent.depth = 1;
   19439 
   19440     // 3D texture accessing an array layer other than 0. VU 09c0011a
   19441     copy_region.extent = {4, 4, 1};
   19442     copy_region.srcSubresource.baseArrayLayer = 1;
   19443     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0011a);
   19444     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   19445                                          VALIDATION_ERROR_0a600154);  // also triggers 'too many layers'
   19446     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   19447                                          VALIDATION_ERROR_09c0012a);  // and 'copy from layer not present'
   19448     m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
   19449                                &copy_region);
   19450     m_errorMonitor->VerifyFound();
   19451 
   19452     m_commandBuffer->end();
   19453 }
   19454 
   19455 TEST_F(VkLayerTest, CopyImageTypeExtentMismatchMaintenance1) {
   19456     // Image copy tests where format type and extents don't match and the Maintenance1 extension is enabled
   19457     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   19458     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
   19459         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
   19460     } else {
   19461         printf("             Maintenance1 extension cannot be enabled, test skipped.\n");
   19462         return;
   19463     }
   19464     ASSERT_NO_FATAL_FAILURE(InitState());
   19465 
   19466     VkImageCreateInfo ci;
   19467     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   19468     ci.pNext = NULL;
   19469     ci.flags = 0;
   19470     ci.imageType = VK_IMAGE_TYPE_1D;
   19471     ci.format = VK_FORMAT_R8G8B8A8_UNORM;
   19472     ci.extent = {32, 1, 1};
   19473     ci.mipLevels = 1;
   19474     ci.arrayLayers = 1;
   19475     ci.samples = VK_SAMPLE_COUNT_1_BIT;
   19476     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
   19477     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   19478     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   19479     ci.queueFamilyIndexCount = 0;
   19480     ci.pQueueFamilyIndices = NULL;
   19481     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   19482 
   19483     // Create 1D image
   19484     VkImageObj image_1D(m_device);
   19485     image_1D.init(&ci);
   19486     ASSERT_TRUE(image_1D.initialized());
   19487 
   19488     // 2D image
   19489     ci.imageType = VK_IMAGE_TYPE_2D;
   19490     ci.extent = {32, 32, 1};
   19491     VkImageObj image_2D(m_device);
   19492     image_2D.init(&ci);
   19493     ASSERT_TRUE(image_2D.initialized());
   19494 
   19495     // 3D image
   19496     ci.imageType = VK_IMAGE_TYPE_3D;
   19497     ci.extent = {32, 32, 8};
   19498     VkImageObj image_3D(m_device);
   19499     image_3D.init(&ci);
   19500     ASSERT_TRUE(image_3D.initialized());
   19501 
   19502     // 2D image array
   19503     ci.imageType = VK_IMAGE_TYPE_2D;
   19504     ci.extent = {32, 32, 1};
   19505     ci.arrayLayers = 8;
   19506     VkImageObj image_2D_array(m_device);
   19507     image_2D_array.init(&ci);
   19508     ASSERT_TRUE(image_2D_array.initialized());
   19509 
   19510     m_commandBuffer->begin();
   19511 
   19512     VkImageCopy copy_region;
   19513     copy_region.extent = {32, 1, 1};
   19514     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   19515     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   19516     copy_region.srcSubresource.mipLevel = 0;
   19517     copy_region.dstSubresource.mipLevel = 0;
   19518     copy_region.srcSubresource.baseArrayLayer = 0;
   19519     copy_region.dstSubresource.baseArrayLayer = 0;
   19520     copy_region.srcSubresource.layerCount = 1;
   19521     copy_region.dstSubresource.layerCount = 1;
   19522     copy_region.srcOffset = {0, 0, 0};
   19523     copy_region.dstOffset = {0, 0, 0};
   19524 
   19525     // Copy from layer not present - VU 09c0012a
   19526     // TODO: this VU is redundant with VU 0a600154. Gitlab issue 812 submitted to have it removed.
   19527     copy_region.srcSubresource.baseArrayLayer = 4;
   19528     copy_region.srcSubresource.layerCount = 6;
   19529     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0012a);
   19530     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a600154);
   19531     m_commandBuffer->CopyImage(image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
   19532                                &copy_region);
   19533     m_errorMonitor->VerifyFound();
   19534     copy_region.srcSubresource.baseArrayLayer = 0;
   19535     copy_region.srcSubresource.layerCount = 1;
   19536 
   19537     // Copy to layer not present - VU 09c00136
   19538     // TODO: this VU is redundant with 0a600154. Gitlab issue 812 submitted to have it removed.
   19539     copy_region.dstSubresource.baseArrayLayer = 1;
   19540     copy_region.dstSubresource.layerCount = 8;
   19541     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00136);
   19542     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a600154);
   19543     m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
   19544                                &copy_region);
   19545     m_errorMonitor->VerifyFound();
   19546     copy_region.dstSubresource.layerCount = 1;
   19547 
   19548     m_commandBuffer->end();
   19549 }
   19550 
   19551 TEST_F(VkLayerTest, CopyImageCompressedBlockAlignment) {
   19552     // Image copy tests on compressed images with block alignment errors
   19553 
   19554     ASSERT_NO_FATAL_FAILURE(Init());
   19555 
   19556     // Select a compressed format and verify support
   19557     VkPhysicalDeviceFeatures device_features = {};
   19558     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
   19559     VkFormat compressed_format = VK_FORMAT_UNDEFINED;
   19560     if (device_features.textureCompressionBC) {
   19561         compressed_format = VK_FORMAT_BC3_SRGB_BLOCK;
   19562     } else if (device_features.textureCompressionETC2) {
   19563         compressed_format = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
   19564     } else if (device_features.textureCompressionASTC_LDR) {
   19565         compressed_format = VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
   19566     }
   19567 
   19568     VkImageCreateInfo ci;
   19569     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   19570     ci.pNext = NULL;
   19571     ci.flags = 0;
   19572     ci.imageType = VK_IMAGE_TYPE_2D;
   19573     ci.format = compressed_format;
   19574     ci.extent = {64, 64, 1};
   19575     ci.mipLevels = 1;
   19576     ci.arrayLayers = 1;
   19577     ci.samples = VK_SAMPLE_COUNT_1_BIT;
   19578     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
   19579     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   19580     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   19581     ci.queueFamilyIndexCount = 0;
   19582     ci.pQueueFamilyIndices = NULL;
   19583     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   19584 
   19585     VkImageFormatProperties img_prop = {};
   19586     if (VK_SUCCESS != vkGetPhysicalDeviceImageFormatProperties(m_device->phy().handle(), ci.format, ci.imageType, ci.tiling,
   19587                                                                ci.usage, ci.flags, &img_prop)) {
   19588         printf("             No compressed formats supported - CopyImageCompressedBlockAlignment skipped.\n");
   19589         return;
   19590     }
   19591 
   19592     // Create images
   19593     VkImageObj image_1(m_device);
   19594     image_1.init(&ci);
   19595     ASSERT_TRUE(image_1.initialized());
   19596 
   19597     ci.extent = {62, 62, 1};  // slightly smaller and not divisible by block size
   19598     VkImageObj image_2(m_device);
   19599     image_2.init(&ci);
   19600     ASSERT_TRUE(image_2.initialized());
   19601 
   19602     m_commandBuffer->begin();
   19603 
   19604     VkImageCopy copy_region;
   19605     copy_region.extent = {48, 48, 1};
   19606     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   19607     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   19608     copy_region.srcSubresource.mipLevel = 0;
   19609     copy_region.dstSubresource.mipLevel = 0;
   19610     copy_region.srcSubresource.baseArrayLayer = 0;
   19611     copy_region.dstSubresource.baseArrayLayer = 0;
   19612     copy_region.srcSubresource.layerCount = 1;
   19613     copy_region.dstSubresource.layerCount = 1;
   19614     copy_region.srcOffset = {0, 0, 0};
   19615     copy_region.dstOffset = {0, 0, 0};
   19616 
   19617     // Sanity check
   19618     m_errorMonitor->ExpectSuccess();
   19619     m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
   19620     m_errorMonitor->VerifyNotFound();
   19621 
   19622     // Src, Dest offsets must be multiples of compressed block sizes {4, 4, 1}
   19623     // Image transfer granularity gets set to compressed block size, so an ITG error is also (unavoidably) triggered.
   19624     copy_region.srcOffset = {2, 4, 0};  // source width
   19625     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0013a);
   19626     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
   19627     m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
   19628     m_errorMonitor->VerifyFound();
   19629     copy_region.srcOffset = {12, 1, 0};  // source height
   19630     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0013a);
   19631     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
   19632     m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
   19633     m_errorMonitor->VerifyFound();
   19634     copy_region.srcOffset = {0, 0, 0};
   19635     copy_region.dstOffset = {1, 0, 0};  // dest width
   19636     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00144);
   19637     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
   19638     m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
   19639     m_errorMonitor->VerifyFound();
   19640     copy_region.dstOffset = {4, 1, 0};  // dest height
   19641     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00144);
   19642     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
   19643     m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
   19644     m_errorMonitor->VerifyFound();
   19645     copy_region.dstOffset = {0, 0, 0};
   19646 
   19647     // Copy extent must be multiples of compressed block sizes {4, 4, 1} if not full width/height
   19648     copy_region.extent = {62, 60, 1};  // source width
   19649     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0013c);
   19650     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
   19651     m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
   19652     m_errorMonitor->VerifyFound();
   19653     copy_region.extent = {60, 62, 1};  // source height
   19654     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0013e);
   19655     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
   19656     m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
   19657     m_errorMonitor->VerifyFound();
   19658     copy_region.extent = {62, 60, 1};  // dest width
   19659     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00146);
   19660     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
   19661     m_commandBuffer->CopyImage(image_2.image(), VK_IMAGE_LAYOUT_GENERAL, image_1.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
   19662     m_errorMonitor->VerifyFound();
   19663     copy_region.extent = {60, 62, 1};  // dest height
   19664     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00148);
   19665     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity");
   19666     m_commandBuffer->CopyImage(image_2.image(), VK_IMAGE_LAYOUT_GENERAL, image_1.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
   19667     m_errorMonitor->VerifyFound();
   19668 
   19669     // Note: VALIDATION_ERROR_09c00140 and VALIDATION_ERROR_09c0014a
   19670     //       VUs 01212 and 01217 should be tested here, if possible.  There are currently no supported compressed formats with
   19671     //       a block depth other than 1, so impossible to create a 'not a multiple' condiditon for depth.
   19672 
   19673     m_commandBuffer->end();
   19674 }
   19675 
   19676 TEST_F(VkLayerTest, CopyImageSrcSizeExceeded) {
   19677     // Image copy with source region specified greater than src image size
   19678     ASSERT_NO_FATAL_FAILURE(Init());
   19679 
   19680     // Create images with full mip chain
   19681     VkImageCreateInfo ci;
   19682     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   19683     ci.pNext = NULL;
   19684     ci.flags = 0;
   19685     ci.imageType = VK_IMAGE_TYPE_3D;
   19686     ci.format = VK_FORMAT_R8G8B8A8_UNORM;
   19687     ci.extent = {32, 32, 8};
   19688     ci.mipLevels = 6;
   19689     ci.arrayLayers = 1;
   19690     ci.samples = VK_SAMPLE_COUNT_1_BIT;
   19691     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
   19692     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   19693     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   19694     ci.queueFamilyIndexCount = 0;
   19695     ci.pQueueFamilyIndices = NULL;
   19696     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   19697 
   19698     VkImageObj src_image(m_device);
   19699     src_image.init(&ci);
   19700     ASSERT_TRUE(src_image.initialized());
   19701 
   19702     // Dest image with one more mip level
   19703     ci.extent = {64, 64, 16};
   19704     ci.mipLevels = 7;
   19705     ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   19706     VkImageObj dst_image(m_device);
   19707     dst_image.init(&ci);
   19708     ASSERT_TRUE(dst_image.initialized());
   19709 
   19710     m_commandBuffer->begin();
   19711 
   19712     VkImageCopy copy_region;
   19713     copy_region.extent = {32, 32, 8};
   19714     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   19715     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   19716     copy_region.srcSubresource.mipLevel = 0;
   19717     copy_region.dstSubresource.mipLevel = 0;
   19718     copy_region.srcSubresource.baseArrayLayer = 0;
   19719     copy_region.dstSubresource.baseArrayLayer = 0;
   19720     copy_region.srcSubresource.layerCount = 1;
   19721     copy_region.dstSubresource.layerCount = 1;
   19722     copy_region.srcOffset = {0, 0, 0};
   19723     copy_region.dstOffset = {0, 0, 0};
   19724 
   19725     m_errorMonitor->ExpectSuccess();
   19726     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
   19727                                &copy_region);
   19728     m_errorMonitor->VerifyNotFound();
   19729 
   19730     // Source exceeded in x-dim, VU 01202
   19731     copy_region.srcOffset.x = 4;
   19732     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   19733                                          VALIDATION_ERROR_190000f4);  // General "contained within" VU
   19734     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00120);
   19735     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
   19736                                &copy_region);
   19737     m_errorMonitor->VerifyFound();
   19738 
   19739     // Source exceeded in y-dim, VU 01203
   19740     copy_region.srcOffset.x = 0;
   19741     copy_region.extent.height = 48;
   19742     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_190000f4);
   19743     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00122);
   19744     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
   19745                                &copy_region);
   19746     m_errorMonitor->VerifyFound();
   19747 
   19748     // Source exceeded in z-dim, VU 01204
   19749     copy_region.extent = {4, 4, 4};
   19750     copy_region.srcSubresource.mipLevel = 2;
   19751     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_190000f4);
   19752     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00126);
   19753     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
   19754                                &copy_region);
   19755     m_errorMonitor->VerifyFound();
   19756 
   19757     m_commandBuffer->end();
   19758 }
   19759 
   19760 TEST_F(VkLayerTest, CopyImageDstSizeExceeded) {
   19761     // Image copy with dest region specified greater than dest image size
   19762     ASSERT_NO_FATAL_FAILURE(Init());
   19763 
   19764     // Create images with full mip chain
   19765     VkImageCreateInfo ci;
   19766     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   19767     ci.pNext = NULL;
   19768     ci.flags = 0;
   19769     ci.imageType = VK_IMAGE_TYPE_3D;
   19770     ci.format = VK_FORMAT_R8G8B8A8_UNORM;
   19771     ci.extent = {32, 32, 8};
   19772     ci.mipLevels = 6;
   19773     ci.arrayLayers = 1;
   19774     ci.samples = VK_SAMPLE_COUNT_1_BIT;
   19775     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
   19776     ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   19777     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   19778     ci.queueFamilyIndexCount = 0;
   19779     ci.pQueueFamilyIndices = NULL;
   19780     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   19781 
   19782     VkImageObj dst_image(m_device);
   19783     dst_image.init(&ci);
   19784     ASSERT_TRUE(dst_image.initialized());
   19785 
   19786     // Src image with one more mip level
   19787     ci.extent = {64, 64, 16};
   19788     ci.mipLevels = 7;
   19789     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   19790     VkImageObj src_image(m_device);
   19791     src_image.init(&ci);
   19792     ASSERT_TRUE(src_image.initialized());
   19793 
   19794     m_commandBuffer->begin();
   19795 
   19796     VkImageCopy copy_region;
   19797     copy_region.extent = {32, 32, 8};
   19798     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   19799     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   19800     copy_region.srcSubresource.mipLevel = 0;
   19801     copy_region.dstSubresource.mipLevel = 0;
   19802     copy_region.srcSubresource.baseArrayLayer = 0;
   19803     copy_region.dstSubresource.baseArrayLayer = 0;
   19804     copy_region.srcSubresource.layerCount = 1;
   19805     copy_region.dstSubresource.layerCount = 1;
   19806     copy_region.srcOffset = {0, 0, 0};
   19807     copy_region.dstOffset = {0, 0, 0};
   19808 
   19809     m_errorMonitor->ExpectSuccess();
   19810     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
   19811                                &copy_region);
   19812     m_errorMonitor->VerifyNotFound();
   19813 
   19814     // Dest exceeded in x-dim, VU 01205
   19815     copy_region.dstOffset.x = 4;
   19816     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   19817                                          VALIDATION_ERROR_190000f6);  // General "contained within" VU
   19818     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0012c);
   19819     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
   19820                                &copy_region);
   19821     m_errorMonitor->VerifyFound();
   19822 
   19823     // Dest exceeded in y-dim, VU 01206
   19824     copy_region.dstOffset.x = 0;
   19825     copy_region.extent.height = 48;
   19826     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_190000f6);
   19827     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0012e);
   19828     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
   19829                                &copy_region);
   19830     m_errorMonitor->VerifyFound();
   19831 
   19832     // Dest exceeded in z-dim, VU 01207
   19833     copy_region.extent = {4, 4, 4};
   19834     copy_region.dstSubresource.mipLevel = 2;
   19835     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_190000f6);
   19836     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00132);
   19837     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
   19838                                &copy_region);
   19839     m_errorMonitor->VerifyFound();
   19840 
   19841     m_commandBuffer->end();
   19842 }
   19843 
   19844 TEST_F(VkLayerTest, CopyImageFormatSizeMismatch) {
   19845     VkResult err;
   19846     bool pass;
   19847 
   19848     // Create color images with different format sizes and try to copy between them
   19849     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1900010e);
   19850 
   19851     ASSERT_NO_FATAL_FAILURE(Init());
   19852 
   19853     // Create two images of different types and try to copy between them
   19854     VkImage srcImage;
   19855     VkImage dstImage;
   19856     VkDeviceMemory srcMem;
   19857     VkDeviceMemory destMem;
   19858     VkMemoryRequirements memReqs;
   19859 
   19860     VkImageCreateInfo image_create_info = {};
   19861     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   19862     image_create_info.pNext = NULL;
   19863     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   19864     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
   19865     image_create_info.extent.width = 32;
   19866     image_create_info.extent.height = 32;
   19867     image_create_info.extent.depth = 1;
   19868     image_create_info.mipLevels = 1;
   19869     image_create_info.arrayLayers = 1;
   19870     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   19871     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
   19872     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   19873     image_create_info.flags = 0;
   19874 
   19875     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
   19876     ASSERT_VK_SUCCESS(err);
   19877 
   19878     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   19879     // Introduce failure by creating second image with a different-sized format.
   19880     image_create_info.format = VK_FORMAT_R5G5B5A1_UNORM_PACK16;
   19881     VkFormatProperties properties;
   19882     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), image_create_info.format, &properties);
   19883     if (properties.optimalTilingFeatures == 0) {
   19884         vkDestroyImage(m_device->device(), srcImage, NULL);
   19885         printf("             Image format not supported; skipped.\n");
   19886         return;
   19887     }
   19888 
   19889     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
   19890     ASSERT_VK_SUCCESS(err);
   19891 
   19892     // Allocate memory
   19893     VkMemoryAllocateInfo memAlloc = {};
   19894     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   19895     memAlloc.pNext = NULL;
   19896     memAlloc.allocationSize = 0;
   19897     memAlloc.memoryTypeIndex = 0;
   19898 
   19899     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
   19900     memAlloc.allocationSize = memReqs.size;
   19901     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
   19902     ASSERT_TRUE(pass);
   19903     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
   19904     ASSERT_VK_SUCCESS(err);
   19905 
   19906     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
   19907     memAlloc.allocationSize = memReqs.size;
   19908     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
   19909     ASSERT_TRUE(pass);
   19910     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
   19911     ASSERT_VK_SUCCESS(err);
   19912 
   19913     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
   19914     ASSERT_VK_SUCCESS(err);
   19915     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
   19916     ASSERT_VK_SUCCESS(err);
   19917 
   19918     m_commandBuffer->begin();
   19919     VkImageCopy copyRegion;
   19920     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   19921     copyRegion.srcSubresource.mipLevel = 0;
   19922     copyRegion.srcSubresource.baseArrayLayer = 0;
   19923     copyRegion.srcSubresource.layerCount = 0;
   19924     copyRegion.srcOffset.x = 0;
   19925     copyRegion.srcOffset.y = 0;
   19926     copyRegion.srcOffset.z = 0;
   19927     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   19928     copyRegion.dstSubresource.mipLevel = 0;
   19929     copyRegion.dstSubresource.baseArrayLayer = 0;
   19930     copyRegion.dstSubresource.layerCount = 0;
   19931     copyRegion.dstOffset.x = 0;
   19932     copyRegion.dstOffset.y = 0;
   19933     copyRegion.dstOffset.z = 0;
   19934     copyRegion.extent.width = 1;
   19935     copyRegion.extent.height = 1;
   19936     copyRegion.extent.depth = 1;
   19937     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
   19938     m_commandBuffer->end();
   19939 
   19940     m_errorMonitor->VerifyFound();
   19941 
   19942     vkDestroyImage(m_device->device(), srcImage, NULL);
   19943     vkDestroyImage(m_device->device(), dstImage, NULL);
   19944     vkFreeMemory(m_device->device(), srcMem, NULL);
   19945     vkFreeMemory(m_device->device(), destMem, NULL);
   19946 }
   19947 
   19948 TEST_F(VkLayerTest, CopyImageDepthStencilFormatMismatch) {
   19949     ASSERT_NO_FATAL_FAILURE(Init());
   19950     auto depth_format = FindSupportedDepthStencilFormat(gpu());
   19951     if (!depth_format) {
   19952         return;
   19953     }
   19954 
   19955     VkFormatProperties properties;
   19956     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D32_SFLOAT, &properties);
   19957     if (properties.optimalTilingFeatures == 0) {
   19958         printf("             Image format not supported; skipped.\n");
   19959         return;
   19960     }
   19961 
   19962     VkImageObj srcImage(m_device);
   19963     srcImage.Init(32, 32, 1, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL);
   19964     ASSERT_TRUE(srcImage.initialized());
   19965     VkImageObj dstImage(m_device);
   19966     dstImage.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
   19967     ASSERT_TRUE(dstImage.initialized());
   19968 
   19969     // Create two images of different types and try to copy between them
   19970 
   19971     m_commandBuffer->begin();
   19972     VkImageCopy copyRegion;
   19973     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
   19974     copyRegion.srcSubresource.mipLevel = 0;
   19975     copyRegion.srcSubresource.baseArrayLayer = 0;
   19976     copyRegion.srcSubresource.layerCount = 0;
   19977     copyRegion.srcOffset.x = 0;
   19978     copyRegion.srcOffset.y = 0;
   19979     copyRegion.srcOffset.z = 0;
   19980     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
   19981     copyRegion.dstSubresource.mipLevel = 0;
   19982     copyRegion.dstSubresource.baseArrayLayer = 0;
   19983     copyRegion.dstSubresource.layerCount = 0;
   19984     copyRegion.dstOffset.x = 0;
   19985     copyRegion.dstOffset.y = 0;
   19986     copyRegion.dstOffset.z = 0;
   19987     copyRegion.extent.width = 1;
   19988     copyRegion.extent.height = 1;
   19989     copyRegion.extent.depth = 1;
   19990 
   19991     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   19992                                          "vkCmdCopyImage called with unmatched source and dest image depth");
   19993     m_commandBuffer->CopyImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
   19994                                &copyRegion);
   19995     m_commandBuffer->end();
   19996 
   19997     m_errorMonitor->VerifyFound();
   19998 }
   19999 
   20000 TEST_F(VkLayerTest, CopyImageSampleCountMismatch) {
   20001     TEST_DESCRIPTION("Image copies with sample count mis-matches");
   20002 
   20003     ASSERT_NO_FATAL_FAILURE(Init());
   20004 
   20005     VkImageFormatProperties image_format_properties;
   20006     vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
   20007                                              VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
   20008                                              &image_format_properties);
   20009 
   20010     if ((0 == (VK_SAMPLE_COUNT_2_BIT & image_format_properties.sampleCounts)) ||
   20011         (0 == (VK_SAMPLE_COUNT_4_BIT & image_format_properties.sampleCounts))) {
   20012         printf("             Image multi-sample support not found; skipped.\n");
   20013         return;
   20014     }
   20015 
   20016     VkImageCreateInfo ci;
   20017     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   20018     ci.pNext = NULL;
   20019     ci.flags = 0;
   20020     ci.imageType = VK_IMAGE_TYPE_2D;
   20021     ci.format = VK_FORMAT_R8G8B8A8_UNORM;
   20022     ci.extent = {128, 128, 1};
   20023     ci.mipLevels = 1;
   20024     ci.arrayLayers = 1;
   20025     ci.samples = VK_SAMPLE_COUNT_1_BIT;
   20026     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
   20027     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   20028     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   20029     ci.queueFamilyIndexCount = 0;
   20030     ci.pQueueFamilyIndices = NULL;
   20031     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   20032 
   20033     VkImageObj image1(m_device);
   20034     image1.init(&ci);
   20035     ASSERT_TRUE(image1.initialized());
   20036 
   20037     ci.samples = VK_SAMPLE_COUNT_2_BIT;
   20038     VkImageObj image2(m_device);
   20039     image2.init(&ci);
   20040     ASSERT_TRUE(image2.initialized());
   20041 
   20042     ci.samples = VK_SAMPLE_COUNT_4_BIT;
   20043     VkImageObj image4(m_device);
   20044     image4.init(&ci);
   20045     ASSERT_TRUE(image4.initialized());
   20046 
   20047     m_commandBuffer->begin();
   20048 
   20049     VkImageCopy copyRegion;
   20050     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   20051     copyRegion.srcSubresource.mipLevel = 0;
   20052     copyRegion.srcSubresource.baseArrayLayer = 0;
   20053     copyRegion.srcSubresource.layerCount = 1;
   20054     copyRegion.srcOffset = {0, 0, 0};
   20055     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   20056     copyRegion.dstSubresource.mipLevel = 0;
   20057     copyRegion.dstSubresource.baseArrayLayer = 0;
   20058     copyRegion.dstSubresource.layerCount = 1;
   20059     copyRegion.dstOffset = {0, 0, 0};
   20060     copyRegion.extent = {128, 128, 1};
   20061 
   20062     // Copy a single sample image to/from a multi-sample image
   20063     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19000110);
   20064     vkCmdCopyImage(m_commandBuffer->handle(), image1.handle(), VK_IMAGE_LAYOUT_GENERAL, image4.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
   20065                    &copyRegion);
   20066     m_errorMonitor->VerifyFound();
   20067 
   20068     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19000110);
   20069     vkCmdCopyImage(m_commandBuffer->handle(), image2.handle(), VK_IMAGE_LAYOUT_GENERAL, image1.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
   20070                    &copyRegion);
   20071     m_errorMonitor->VerifyFound();
   20072 
   20073     // Copy between multi-sample images with different sample counts
   20074     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19000110);
   20075     vkCmdCopyImage(m_commandBuffer->handle(), image2.handle(), VK_IMAGE_LAYOUT_GENERAL, image4.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
   20076                    &copyRegion);
   20077     m_errorMonitor->VerifyFound();
   20078 
   20079     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19000110);
   20080     vkCmdCopyImage(m_commandBuffer->handle(), image4.handle(), VK_IMAGE_LAYOUT_GENERAL, image2.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
   20081                    &copyRegion);
   20082     m_errorMonitor->VerifyFound();
   20083 
   20084     m_commandBuffer->end();
   20085 }
   20086 
   20087 TEST_F(VkLayerTest, CopyImageAspectMismatch) {
   20088     TEST_DESCRIPTION("Image copies with aspect mask errors");
   20089     ASSERT_NO_FATAL_FAILURE(Init());
   20090     auto ds_format = FindSupportedDepthStencilFormat(gpu());
   20091     if (!ds_format) {
   20092         return;
   20093     }
   20094 
   20095     VkFormatProperties properties;
   20096     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D32_SFLOAT, &properties);
   20097     if (properties.optimalTilingFeatures == 0) {
   20098         printf("             Image format VK_FORMAT_D32_SFLOAT not supported; skipped.\n");
   20099         return;
   20100     }
   20101     VkImageObj color_image(m_device), ds_image(m_device), depth_image(m_device);
   20102     color_image.Init(128, 128, 1, VK_FORMAT_R32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
   20103     depth_image.Init(128, 128, 1, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
   20104                      VK_IMAGE_TILING_OPTIMAL, 0);
   20105     ds_image.Init(128, 128, 1, ds_format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
   20106                   VK_IMAGE_TILING_OPTIMAL, 0);
   20107     ASSERT_TRUE(color_image.initialized());
   20108     ASSERT_TRUE(depth_image.initialized());
   20109     ASSERT_TRUE(ds_image.initialized());
   20110 
   20111     VkImageCopy copyRegion;
   20112     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
   20113     copyRegion.srcSubresource.mipLevel = 0;
   20114     copyRegion.srcSubresource.baseArrayLayer = 0;
   20115     copyRegion.srcSubresource.layerCount = 1;
   20116     copyRegion.srcOffset = {0, 0, 0};
   20117     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
   20118     copyRegion.dstSubresource.mipLevel = 0;
   20119     copyRegion.dstSubresource.baseArrayLayer = 0;
   20120     copyRegion.dstSubresource.layerCount = 1;
   20121     copyRegion.dstOffset = {64, 0, 0};
   20122     copyRegion.extent = {64, 128, 1};
   20123 
   20124     // Submitting command before command buffer is in recording state
   20125     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   20126                                          "You must call vkBeginCommandBuffer");  // VALIDATION_ERROR_19002413);
   20127     vkCmdCopyImage(m_commandBuffer->handle(), depth_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(),
   20128                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
   20129     m_errorMonitor->VerifyFound();
   20130 
   20131     m_commandBuffer->begin();
   20132 
   20133     // Src and dest aspect masks don't match
   20134     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
   20135     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00112);
   20136     vkCmdCopyImage(m_commandBuffer->handle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, ds_image.handle(),
   20137                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
   20138     m_errorMonitor->VerifyFound();
   20139     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
   20140 
   20141     // Illegal combinations of aspect bits - VU 01221
   20142     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;  // color must be alone
   20143     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
   20144     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a60014e);
   20145     // These aspect/format mismatches are redundant but unavoidable here
   20146     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0011c);
   20147     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0011e);
   20148     vkCmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
   20149                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
   20150     m_errorMonitor->VerifyFound();
   20151     // Metadata aspect is illegal - VU 01222
   20152     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
   20153     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
   20154     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a600150);
   20155     // These aspect/format mismatches are redundant but unavoidable here
   20156     vkCmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
   20157                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
   20158     m_errorMonitor->VerifyFound();
   20159 
   20160     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
   20161     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
   20162 
   20163     // Aspect mask doesn't match source image format - VU 01200
   20164     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0011c);
   20165     // Again redundant but unavoidable when provoking vu01200 w/o vu01201
   20166     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "unmatched source and dest image depth/stencil formats");
   20167     vkCmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(),
   20168                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
   20169     m_errorMonitor->VerifyFound();
   20170 
   20171     // Aspect mask doesn't match dest image format - VU 01201
   20172     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   20173     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   20174     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0011e);
   20175     // Again redundant but unavoidable when provoking vu01201 w/o vu01200
   20176     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "unmatched source and dest image depth/stencil formats");
   20177     vkCmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(),
   20178                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
   20179     m_errorMonitor->VerifyFound();
   20180 
   20181     m_commandBuffer->end();
   20182 }
   20183 
   20184 TEST_F(VkLayerTest, ResolveImageLowSampleCount) {
   20185     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   20186                                          "vkCmdResolveImage called with source sample count less than 2.");
   20187 
   20188     ASSERT_NO_FATAL_FAILURE(Init());
   20189 
   20190     // Create two images of sample count 1 and try to Resolve between them
   20191 
   20192     VkImageCreateInfo image_create_info = {};
   20193     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   20194     image_create_info.pNext = NULL;
   20195     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   20196     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
   20197     image_create_info.extent.width = 32;
   20198     image_create_info.extent.height = 1;
   20199     image_create_info.extent.depth = 1;
   20200     image_create_info.mipLevels = 1;
   20201     image_create_info.arrayLayers = 1;
   20202     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   20203     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   20204     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   20205     image_create_info.flags = 0;
   20206 
   20207     VkImageObj srcImage(m_device);
   20208     srcImage.init(&image_create_info);
   20209     ASSERT_TRUE(srcImage.initialized());
   20210 
   20211     VkImageObj dstImage(m_device);
   20212     dstImage.init(&image_create_info);
   20213     ASSERT_TRUE(dstImage.initialized());
   20214 
   20215     m_commandBuffer->begin();
   20216     VkImageResolve resolveRegion;
   20217     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   20218     resolveRegion.srcSubresource.mipLevel = 0;
   20219     resolveRegion.srcSubresource.baseArrayLayer = 0;
   20220     resolveRegion.srcSubresource.layerCount = 1;
   20221     resolveRegion.srcOffset.x = 0;
   20222     resolveRegion.srcOffset.y = 0;
   20223     resolveRegion.srcOffset.z = 0;
   20224     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   20225     resolveRegion.dstSubresource.mipLevel = 0;
   20226     resolveRegion.dstSubresource.baseArrayLayer = 0;
   20227     resolveRegion.dstSubresource.layerCount = 1;
   20228     resolveRegion.dstOffset.x = 0;
   20229     resolveRegion.dstOffset.y = 0;
   20230     resolveRegion.dstOffset.z = 0;
   20231     resolveRegion.extent.width = 1;
   20232     resolveRegion.extent.height = 1;
   20233     resolveRegion.extent.depth = 1;
   20234     m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
   20235                                   &resolveRegion);
   20236     m_commandBuffer->end();
   20237 
   20238     m_errorMonitor->VerifyFound();
   20239 }
   20240 
   20241 TEST_F(VkLayerTest, ResolveImageHighSampleCount) {
   20242     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   20243                                          "vkCmdResolveImage called with dest sample count greater than 1.");
   20244 
   20245     ASSERT_NO_FATAL_FAILURE(Init());
   20246 
   20247     // Create two images of sample count 4 and try to Resolve between them
   20248 
   20249     VkImageCreateInfo image_create_info = {};
   20250     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   20251     image_create_info.pNext = NULL;
   20252     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   20253     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
   20254     image_create_info.extent.width = 32;
   20255     image_create_info.extent.height = 1;
   20256     image_create_info.extent.depth = 1;
   20257     image_create_info.mipLevels = 1;
   20258     image_create_info.arrayLayers = 1;
   20259     image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
   20260     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   20261     // Note: Some implementations expect color attachment usage for any
   20262     // multisample surface
   20263     image_create_info.usage =
   20264         VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
   20265     image_create_info.flags = 0;
   20266 
   20267     VkImageObj srcImage(m_device);
   20268     srcImage.init(&image_create_info);
   20269     ASSERT_TRUE(srcImage.initialized());
   20270 
   20271     VkImageObj dstImage(m_device);
   20272     dstImage.init(&image_create_info);
   20273     ASSERT_TRUE(dstImage.initialized());
   20274 
   20275     m_commandBuffer->begin();
   20276     // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
   20277     // VK_IMAGE_LAYOUT_UNDEFINED = 0,
   20278     // VK_IMAGE_LAYOUT_GENERAL = 1,
   20279     VkImageResolve resolveRegion;
   20280     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   20281     resolveRegion.srcSubresource.mipLevel = 0;
   20282     resolveRegion.srcSubresource.baseArrayLayer = 0;
   20283     resolveRegion.srcSubresource.layerCount = 1;
   20284     resolveRegion.srcOffset.x = 0;
   20285     resolveRegion.srcOffset.y = 0;
   20286     resolveRegion.srcOffset.z = 0;
   20287     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   20288     resolveRegion.dstSubresource.mipLevel = 0;
   20289     resolveRegion.dstSubresource.baseArrayLayer = 0;
   20290     resolveRegion.dstSubresource.layerCount = 1;
   20291     resolveRegion.dstOffset.x = 0;
   20292     resolveRegion.dstOffset.y = 0;
   20293     resolveRegion.dstOffset.z = 0;
   20294     resolveRegion.extent.width = 1;
   20295     resolveRegion.extent.height = 1;
   20296     resolveRegion.extent.depth = 1;
   20297     m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
   20298                                   &resolveRegion);
   20299     m_commandBuffer->end();
   20300 
   20301     m_errorMonitor->VerifyFound();
   20302 }
   20303 
   20304 TEST_F(VkLayerTest, ResolveImageFormatMismatch) {
   20305     VkResult err;
   20306     bool pass;
   20307 
   20308     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
   20309                                          "vkCmdResolveImage called with unmatched source and dest formats.");
   20310 
   20311     ASSERT_NO_FATAL_FAILURE(Init());
   20312 
   20313     // Create two images of different types and try to copy between them
   20314     VkImage srcImage;
   20315     VkImage dstImage;
   20316     VkDeviceMemory srcMem;
   20317     VkDeviceMemory destMem;
   20318     VkMemoryRequirements memReqs;
   20319 
   20320     VkImageCreateInfo image_create_info = {};
   20321     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   20322     image_create_info.pNext = NULL;
   20323     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   20324     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
   20325     image_create_info.extent.width = 32;
   20326     image_create_info.extent.height = 1;
   20327     image_create_info.extent.depth = 1;
   20328     image_create_info.mipLevels = 1;
   20329     image_create_info.arrayLayers = 1;
   20330     image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
   20331     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   20332     // Note: Some implementations expect color attachment usage for any
   20333     // multisample surface
   20334     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
   20335     image_create_info.flags = 0;
   20336 
   20337     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
   20338     ASSERT_VK_SUCCESS(err);
   20339 
   20340     // Set format to something other than source image
   20341     image_create_info.format = VK_FORMAT_R32_SFLOAT;
   20342     // Note: Some implementations expect color attachment usage for any
   20343     // multisample surface
   20344     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
   20345     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   20346 
   20347     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
   20348     ASSERT_VK_SUCCESS(err);
   20349 
   20350     // Allocate memory
   20351     VkMemoryAllocateInfo memAlloc = {};
   20352     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   20353     memAlloc.pNext = NULL;
   20354     memAlloc.allocationSize = 0;
   20355     memAlloc.memoryTypeIndex = 0;
   20356 
   20357     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
   20358     memAlloc.allocationSize = memReqs.size;
   20359     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
   20360     ASSERT_TRUE(pass);
   20361     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
   20362     ASSERT_VK_SUCCESS(err);
   20363 
   20364     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
   20365     memAlloc.allocationSize = memReqs.size;
   20366     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
   20367     ASSERT_TRUE(pass);
   20368     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
   20369     ASSERT_VK_SUCCESS(err);
   20370 
   20371     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
   20372     ASSERT_VK_SUCCESS(err);
   20373     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
   20374     ASSERT_VK_SUCCESS(err);
   20375 
   20376     m_commandBuffer->begin();
   20377     // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
   20378     // VK_IMAGE_LAYOUT_UNDEFINED = 0,
   20379     // VK_IMAGE_LAYOUT_GENERAL = 1,
   20380     VkImageResolve resolveRegion;
   20381     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   20382     resolveRegion.srcSubresource.mipLevel = 0;
   20383     resolveRegion.srcSubresource.baseArrayLayer = 0;
   20384     resolveRegion.srcSubresource.layerCount = 1;
   20385     resolveRegion.srcOffset.x = 0;
   20386     resolveRegion.srcOffset.y = 0;
   20387     resolveRegion.srcOffset.z = 0;
   20388     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   20389     resolveRegion.dstSubresource.mipLevel = 0;
   20390     resolveRegion.dstSubresource.baseArrayLayer = 0;
   20391     resolveRegion.dstSubresource.layerCount = 1;
   20392     resolveRegion.dstOffset.x = 0;
   20393     resolveRegion.dstOffset.y = 0;
   20394     resolveRegion.dstOffset.z = 0;
   20395     resolveRegion.extent.width = 1;
   20396     resolveRegion.extent.height = 1;
   20397     resolveRegion.extent.depth = 1;
   20398     m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
   20399     m_commandBuffer->end();
   20400 
   20401     m_errorMonitor->VerifyFound();
   20402 
   20403     vkDestroyImage(m_device->device(), srcImage, NULL);
   20404     vkDestroyImage(m_device->device(), dstImage, NULL);
   20405     vkFreeMemory(m_device->device(), srcMem, NULL);
   20406     vkFreeMemory(m_device->device(), destMem, NULL);
   20407 }
   20408 
   20409 TEST_F(VkLayerTest, ResolveImageTypeMismatch) {
   20410     VkResult err;
   20411     bool pass;
   20412 
   20413     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
   20414                                          "vkCmdResolveImage called with unmatched source and dest image types.");
   20415 
   20416     ASSERT_NO_FATAL_FAILURE(Init());
   20417 
   20418     // Create two images of different types and try to copy between them
   20419     VkImage srcImage;
   20420     VkImage dstImage;
   20421     VkDeviceMemory srcMem;
   20422     VkDeviceMemory destMem;
   20423     VkMemoryRequirements memReqs;
   20424 
   20425     VkImageCreateInfo image_create_info = {};
   20426     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   20427     image_create_info.pNext = NULL;
   20428     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   20429     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
   20430     image_create_info.extent.width = 32;
   20431     image_create_info.extent.height = 1;
   20432     image_create_info.extent.depth = 1;
   20433     image_create_info.mipLevels = 1;
   20434     image_create_info.arrayLayers = 1;
   20435     image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
   20436     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   20437     // Note: Some implementations expect color attachment usage for any
   20438     // multisample surface
   20439     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
   20440     image_create_info.flags = 0;
   20441 
   20442     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
   20443     ASSERT_VK_SUCCESS(err);
   20444 
   20445     image_create_info.imageType = VK_IMAGE_TYPE_1D;
   20446     // Note: Some implementations expect color attachment usage for any
   20447     // multisample surface
   20448     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
   20449     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   20450 
   20451     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
   20452     ASSERT_VK_SUCCESS(err);
   20453 
   20454     // Allocate memory
   20455     VkMemoryAllocateInfo memAlloc = {};
   20456     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   20457     memAlloc.pNext = NULL;
   20458     memAlloc.allocationSize = 0;
   20459     memAlloc.memoryTypeIndex = 0;
   20460 
   20461     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
   20462     memAlloc.allocationSize = memReqs.size;
   20463     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
   20464     ASSERT_TRUE(pass);
   20465     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
   20466     ASSERT_VK_SUCCESS(err);
   20467 
   20468     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
   20469     memAlloc.allocationSize = memReqs.size;
   20470     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
   20471     ASSERT_TRUE(pass);
   20472     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
   20473     ASSERT_VK_SUCCESS(err);
   20474 
   20475     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
   20476     ASSERT_VK_SUCCESS(err);
   20477     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
   20478     ASSERT_VK_SUCCESS(err);
   20479 
   20480     m_commandBuffer->begin();
   20481     // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
   20482     // VK_IMAGE_LAYOUT_UNDEFINED = 0,
   20483     // VK_IMAGE_LAYOUT_GENERAL = 1,
   20484     VkImageResolve resolveRegion;
   20485     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   20486     resolveRegion.srcSubresource.mipLevel = 0;
   20487     resolveRegion.srcSubresource.baseArrayLayer = 0;
   20488     resolveRegion.srcSubresource.layerCount = 1;
   20489     resolveRegion.srcOffset.x = 0;
   20490     resolveRegion.srcOffset.y = 0;
   20491     resolveRegion.srcOffset.z = 0;
   20492     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   20493     resolveRegion.dstSubresource.mipLevel = 0;
   20494     resolveRegion.dstSubresource.baseArrayLayer = 0;
   20495     resolveRegion.dstSubresource.layerCount = 1;
   20496     resolveRegion.dstOffset.x = 0;
   20497     resolveRegion.dstOffset.y = 0;
   20498     resolveRegion.dstOffset.z = 0;
   20499     resolveRegion.extent.width = 1;
   20500     resolveRegion.extent.height = 1;
   20501     resolveRegion.extent.depth = 1;
   20502     m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
   20503     m_commandBuffer->end();
   20504 
   20505     m_errorMonitor->VerifyFound();
   20506 
   20507     vkDestroyImage(m_device->device(), srcImage, NULL);
   20508     vkDestroyImage(m_device->device(), dstImage, NULL);
   20509     vkFreeMemory(m_device->device(), srcMem, NULL);
   20510     vkFreeMemory(m_device->device(), destMem, NULL);
   20511 }
   20512 
   20513 TEST_F(VkLayerTest, DepthStencilImageViewWithColorAspectBitError) {
   20514     // Create a single Image descriptor and cause it to first hit an error due
   20515     //  to using a DS format, then cause it to hit error due to COLOR_BIT not
   20516     //  set in aspect
   20517     // The image format check comes 2nd in validation so we trigger it first,
   20518     //  then when we cause aspect fail next, bad format check will be preempted
   20519     VkResult err;
   20520 
   20521     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   20522                                          "Combination depth/stencil image formats can have only the ");
   20523 
   20524     ASSERT_NO_FATAL_FAILURE(Init());
   20525     auto depth_format = FindSupportedDepthStencilFormat(gpu());
   20526     if (!depth_format) {
   20527         return;
   20528     }
   20529 
   20530     VkDescriptorPoolSize ds_type_count = {};
   20531     ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
   20532     ds_type_count.descriptorCount = 1;
   20533 
   20534     VkDescriptorPoolCreateInfo ds_pool_ci = {};
   20535     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
   20536     ds_pool_ci.pNext = NULL;
   20537     ds_pool_ci.maxSets = 1;
   20538     ds_pool_ci.poolSizeCount = 1;
   20539     ds_pool_ci.pPoolSizes = &ds_type_count;
   20540 
   20541     VkDescriptorPool ds_pool;
   20542     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
   20543     ASSERT_VK_SUCCESS(err);
   20544 
   20545     VkDescriptorSetLayoutBinding dsl_binding = {};
   20546     dsl_binding.binding = 0;
   20547     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
   20548     dsl_binding.descriptorCount = 1;
   20549     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
   20550     dsl_binding.pImmutableSamplers = NULL;
   20551 
   20552     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
   20553 
   20554     VkDescriptorSet descriptorSet;
   20555     VkDescriptorSetAllocateInfo alloc_info = {};
   20556     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
   20557     alloc_info.descriptorSetCount = 1;
   20558     alloc_info.descriptorPool = ds_pool;
   20559     alloc_info.pSetLayouts = &ds_layout.handle();
   20560     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
   20561     ASSERT_VK_SUCCESS(err);
   20562 
   20563     VkImage image_bad;
   20564     VkImage image_good;
   20565     // One bad format and one good format for Color attachment
   20566     const VkFormat tex_format_bad = depth_format;
   20567     const VkFormat tex_format_good = VK_FORMAT_B8G8R8A8_UNORM;
   20568     const int32_t tex_width = 32;
   20569     const int32_t tex_height = 32;
   20570 
   20571     VkImageCreateInfo image_create_info = {};
   20572     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   20573     image_create_info.pNext = NULL;
   20574     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   20575     image_create_info.format = tex_format_bad;
   20576     image_create_info.extent.width = tex_width;
   20577     image_create_info.extent.height = tex_height;
   20578     image_create_info.extent.depth = 1;
   20579     image_create_info.mipLevels = 1;
   20580     image_create_info.arrayLayers = 1;
   20581     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   20582     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   20583     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
   20584     image_create_info.flags = 0;
   20585 
   20586     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image_bad);
   20587     ASSERT_VK_SUCCESS(err);
   20588     image_create_info.format = tex_format_good;
   20589     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
   20590     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image_good);
   20591     ASSERT_VK_SUCCESS(err);
   20592 
   20593     // ---Bind image memory---
   20594     VkMemoryRequirements img_mem_reqs;
   20595     vkGetImageMemoryRequirements(m_device->device(), image_bad, &img_mem_reqs);
   20596     VkMemoryAllocateInfo image_alloc_info = {};
   20597     image_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   20598     image_alloc_info.pNext = NULL;
   20599     image_alloc_info.memoryTypeIndex = 0;
   20600     image_alloc_info.allocationSize = img_mem_reqs.size;
   20601     bool pass =
   20602         m_device->phy().set_memory_type(img_mem_reqs.memoryTypeBits, &image_alloc_info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
   20603     ASSERT_TRUE(pass);
   20604     VkDeviceMemory mem;
   20605     err = vkAllocateMemory(m_device->device(), &image_alloc_info, NULL, &mem);
   20606     ASSERT_VK_SUCCESS(err);
   20607     err = vkBindImageMemory(m_device->device(), image_bad, mem, 0);
   20608     ASSERT_VK_SUCCESS(err);
   20609     // -----------------------
   20610 
   20611     VkImageViewCreateInfo image_view_create_info = {};
   20612     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   20613     image_view_create_info.image = image_bad;
   20614     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
   20615     image_view_create_info.format = tex_format_bad;
   20616     image_view_create_info.subresourceRange.baseArrayLayer = 0;
   20617     image_view_create_info.subresourceRange.baseMipLevel = 0;
   20618     image_view_create_info.subresourceRange.layerCount = 1;
   20619     image_view_create_info.subresourceRange.levelCount = 1;
   20620     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
   20621 
   20622     VkImageView view;
   20623     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
   20624 
   20625     m_errorMonitor->VerifyFound();
   20626 
   20627     vkDestroyImage(m_device->device(), image_bad, NULL);
   20628     vkDestroyImage(m_device->device(), image_good, NULL);
   20629     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
   20630 
   20631     vkFreeMemory(m_device->device(), mem, NULL);
   20632 }
   20633 
   20634 TEST_F(VkLayerTest, ClearImageErrors) {
   20635     TEST_DESCRIPTION("Call ClearColorImage w/ a depth|stencil image and ClearDepthStencilImage with a color image.");
   20636 
   20637     ASSERT_NO_FATAL_FAILURE(Init());
   20638     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   20639 
   20640     m_commandBuffer->begin();
   20641 
   20642     // Color image
   20643     VkClearColorValue clear_color;
   20644     memset(clear_color.uint32, 0, sizeof(uint32_t) * 4);
   20645     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
   20646     const VkFormat color_format = VK_FORMAT_B8G8R8A8_UNORM;
   20647     const int32_t img_width = 32;
   20648     const int32_t img_height = 32;
   20649     VkImageCreateInfo image_create_info = {};
   20650     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   20651     image_create_info.pNext = NULL;
   20652     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   20653     image_create_info.format = color_format;
   20654     image_create_info.extent.width = img_width;
   20655     image_create_info.extent.height = img_height;
   20656     image_create_info.extent.depth = 1;
   20657     image_create_info.mipLevels = 1;
   20658     image_create_info.arrayLayers = 1;
   20659     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   20660     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
   20661 
   20662     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
   20663     vk_testing::Image color_image_no_transfer;
   20664     color_image_no_transfer.init(*m_device, image_create_info, reqs);
   20665 
   20666     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   20667     vk_testing::Image color_image;
   20668     color_image.init(*m_device, image_create_info, reqs);
   20669 
   20670     const VkImageSubresourceRange color_range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT);
   20671 
   20672     // Depth/Stencil image
   20673     VkClearDepthStencilValue clear_value = {0};
   20674     reqs = 0;  // don't need HOST_VISIBLE DS image
   20675     VkImageCreateInfo ds_image_create_info = vk_testing::Image::create_info();
   20676     ds_image_create_info.imageType = VK_IMAGE_TYPE_2D;
   20677     ds_image_create_info.format = VK_FORMAT_D16_UNORM;
   20678     ds_image_create_info.extent.width = 64;
   20679     ds_image_create_info.extent.height = 64;
   20680     ds_image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   20681     ds_image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   20682 
   20683     vk_testing::Image ds_image;
   20684     ds_image.init(*m_device, ds_image_create_info, reqs);
   20685 
   20686     const VkImageSubresourceRange ds_range = vk_testing::Image::subresource_range(ds_image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT);
   20687 
   20688     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearColorImage called with depth/stencil image.");
   20689 
   20690     vkCmdClearColorImage(m_commandBuffer->handle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &color_range);
   20691 
   20692     m_errorMonitor->VerifyFound();
   20693 
   20694     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   20695                                          "vkCmdClearColorImage called with image created without VK_IMAGE_USAGE_TRANSFER_DST_BIT");
   20696 
   20697     vkCmdClearColorImage(m_commandBuffer->handle(), color_image_no_transfer.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
   20698                          &color_range);
   20699 
   20700     m_errorMonitor->VerifyFound();
   20701 
   20702     // Call CmdClearDepthStencilImage with color image
   20703     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   20704                                          "vkCmdClearDepthStencilImage called without a depth/stencil image.");
   20705 
   20706     vkCmdClearDepthStencilImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_value,
   20707                                 1, &ds_range);
   20708 
   20709     m_errorMonitor->VerifyFound();
   20710 }
   20711 
   20712 TEST_F(VkLayerTest, CommandQueueFlags) {
   20713     TEST_DESCRIPTION(
   20714         "Allocate a command buffer on a queue that does not support graphics and try to issue a graphics-only command");
   20715 
   20716     ASSERT_NO_FATAL_FAILURE(Init());
   20717 
   20718     uint32_t queueFamilyIndex = m_device->QueueFamilyWithoutCapabilities(VK_QUEUE_GRAPHICS_BIT);
   20719     if (queueFamilyIndex == UINT32_MAX) {
   20720         printf("             Non-graphics queue family not found; skipped.\n");
   20721         return;
   20722     } else {
   20723         // Create command pool on a non-graphics queue
   20724         VkCommandPoolObj command_pool(m_device, queueFamilyIndex);
   20725 
   20726         // Setup command buffer on pool
   20727         VkCommandBufferObj command_buffer(m_device, &command_pool);
   20728         command_buffer.begin();
   20729 
   20730         // Issue a graphics only command
   20731         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1e002415);
   20732         VkViewport viewport = {0, 0, 16, 16, 0, 1};
   20733         command_buffer.SetViewport(0, 1, &viewport);
   20734         m_errorMonitor->VerifyFound();
   20735     }
   20736 }
   20737 
   20738 TEST_F(VkLayerTest, ExecuteUnrecordedSecondaryCB) {
   20739     TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a CB in the initial state");
   20740     ASSERT_NO_FATAL_FAILURE(Init());
   20741     VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
   20742     // never record secondary
   20743 
   20744     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b2000b2);
   20745     m_commandBuffer->begin();
   20746     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
   20747     m_errorMonitor->VerifyFound();
   20748     m_commandBuffer->end();
   20749 }
   20750 
   20751 TEST_F(VkLayerTest, ExecuteUnrecordedPrimaryCB) {
   20752     TEST_DESCRIPTION("Attempt vkQueueSubmit with a CB in the initial state");
   20753     ASSERT_NO_FATAL_FAILURE(Init());
   20754     // never record m_commandBuffer
   20755 
   20756     VkSubmitInfo si = {};
   20757     si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   20758     si.commandBufferCount = 1;
   20759     si.pCommandBuffers = &m_commandBuffer->handle();
   20760 
   20761     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_31a00090);
   20762     vkQueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE);
   20763     m_errorMonitor->VerifyFound();
   20764 }
   20765 
   20766 TEST_F(VkLayerTest, ExtensionNotEnabled) {
   20767     TEST_DESCRIPTION("Validate that using an API from an unenabled extension returns an error");
   20768 
   20769     // Do NOT enable VK_KHR_maintenance1
   20770     ASSERT_NO_FATAL_FAILURE(Init());
   20771     // Find address of extension API
   20772     PFN_vkTrimCommandPoolKHR vkTrimCommandPoolKHR =
   20773         (PFN_vkTrimCommandPoolKHR)vkGetDeviceProcAddr(m_device->handle(), "vkTrimCommandPoolKHR");
   20774     if (vkTrimCommandPoolKHR == nullptr) {
   20775         printf("             Maintenance1 not supported by device; skipped.\n");
   20776         return;
   20777     }
   20778     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   20779                                          "but its required extension VK_KHR_maintenance1 has not been enabled");
   20780     vkTrimCommandPoolKHR(m_device->handle(), m_commandPool->handle(), (VkCommandPoolTrimFlagsKHR)0);
   20781     m_errorMonitor->VerifyFound();
   20782 }
   20783 
   20784 TEST_F(VkLayerTest, Maintenance1AndNegativeViewport) {
   20785     TEST_DESCRIPTION("Attempt to enable AMD_negative_viewport_height and Maintenance1_KHR extension simultaneously");
   20786 
   20787     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   20788     if (!((DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) &&
   20789           (DeviceExtensionSupported(gpu(), nullptr, VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME)))) {
   20790         printf("             Maintenance1 and AMD_negative viewport height extensions not supported, skipping test\n");
   20791         return;
   20792     }
   20793     ASSERT_NO_FATAL_FAILURE(InitState());
   20794 
   20795     vk_testing::QueueCreateInfoArray queue_info(m_device->queue_props);
   20796     const char *extension_names[2] = {"VK_KHR_maintenance1", "VK_AMD_negative_viewport_height"};
   20797     VkDevice testDevice;
   20798     VkDeviceCreateInfo device_create_info = {};
   20799     auto features = m_device->phy().features();
   20800     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
   20801     device_create_info.pNext = NULL;
   20802     device_create_info.queueCreateInfoCount = queue_info.size();
   20803     device_create_info.pQueueCreateInfos = queue_info.data();
   20804     device_create_info.enabledLayerCount = 0;
   20805     device_create_info.ppEnabledLayerNames = NULL;
   20806     device_create_info.enabledExtensionCount = 2;
   20807     device_create_info.ppEnabledExtensionNames = (const char *const *)extension_names;
   20808     device_create_info.pEnabledFeatures = &features;
   20809 
   20810     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_056002ec);
   20811     // The following unexpected error is coming from the LunarG loader. Do not make it a desired message because platforms that do
   20812     // not use the LunarG loader (e.g. Android) will not see the message and the test will fail.
   20813     m_errorMonitor->SetUnexpectedError("Failed to create device chain.");
   20814     vkCreateDevice(gpu(), &device_create_info, NULL, &testDevice);
   20815     m_errorMonitor->VerifyFound();
   20816 }
   20817 
   20818 TEST_F(VkLayerTest, InvalidCreateDescriptorPool) {
   20819     TEST_DESCRIPTION("Attempt to create descriptor pool with invalid parameters");
   20820 
   20821     ASSERT_NO_FATAL_FAILURE(Init());
   20822 
   20823     const uint32_t default_descriptor_count = 1;
   20824     const VkDescriptorPoolSize dp_size_template{VK_DESCRIPTOR_TYPE_SAMPLER, default_descriptor_count};
   20825 
   20826     const VkDescriptorPoolCreateInfo dp_ci_template{VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
   20827                                                     nullptr,  // pNext
   20828                                                     0,        // flags
   20829                                                     1,        // maxSets
   20830                                                     1,        // poolSizeCount
   20831                                                     &dp_size_template};
   20832 
   20833     // try maxSets = 0
   20834     {
   20835         VkDescriptorPoolCreateInfo invalid_dp_ci = dp_ci_template;
   20836         invalid_dp_ci.maxSets = 0;  // invalid maxSets value
   20837 
   20838         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0480025a);
   20839         {
   20840             VkDescriptorPool pool;
   20841             vkCreateDescriptorPool(m_device->device(), &invalid_dp_ci, nullptr, &pool);
   20842         }
   20843         m_errorMonitor->VerifyFound();
   20844     }
   20845 
   20846     // try descriptorCount = 0
   20847     {
   20848         VkDescriptorPoolSize invalid_dp_size = dp_size_template;
   20849         invalid_dp_size.descriptorCount = 0;  // invalid descriptorCount value
   20850 
   20851         VkDescriptorPoolCreateInfo dp_ci = dp_ci_template;
   20852         dp_ci.pPoolSizes = &invalid_dp_size;
   20853 
   20854         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_04a0025c);
   20855         {
   20856             VkDescriptorPool pool;
   20857             vkCreateDescriptorPool(m_device->device(), &dp_ci, nullptr, &pool);
   20858         }
   20859         m_errorMonitor->VerifyFound();
   20860     }
   20861 }
   20862 
   20863 TEST_F(VkLayerTest, InvalidCreateBufferSize) {
   20864     TEST_DESCRIPTION("Attempt to create VkBuffer with size of zero");
   20865 
   20866     ASSERT_NO_FATAL_FAILURE(Init());
   20867 
   20868     VkBufferCreateInfo info = {};
   20869     info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   20870     info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
   20871 
   20872     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01400720);
   20873     info.size = 0;
   20874     VkBuffer buffer;
   20875     vkCreateBuffer(m_device->device(), &info, nullptr, &buffer);
   20876     m_errorMonitor->VerifyFound();
   20877 }
   20878 
   20879 //
   20880 // POSITIVE VALIDATION TESTS
   20881 //
   20882 // These tests do not expect to encounter ANY validation errors pass only if this is true
   20883 
   20884 TEST_F(VkPositiveLayerTest, UncompressedToCompressedImageCopy) {
   20885     TEST_DESCRIPTION("Image copies between compressed and uncompressed images");
   20886     ASSERT_NO_FATAL_FAILURE(Init());
   20887 
   20888     // Verify format support
   20889     // Size-compatible (64-bit) formats. Uncompressed is 64 bits per texel, compressed is 64 bits per 4x4 block (or 4bpt).
   20890     if (!ImageFormatAndFeaturesSupported(gpu(), VK_FORMAT_R16G16B16A16_UINT, VK_IMAGE_TILING_OPTIMAL,
   20891                                          VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR | VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR) ||
   20892         !ImageFormatAndFeaturesSupported(gpu(), VK_FORMAT_BC1_RGBA_SRGB_BLOCK, VK_IMAGE_TILING_OPTIMAL,
   20893                                          VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR | VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR)) {
   20894         printf("             Required formats/features not supported - UncompressedToCompressedImageCopy skipped.\n");
   20895         return;
   20896     }
   20897 
   20898     VkImageObj uncomp_10x10t_image(m_device);       // Size = 10 * 10 * 64 = 6400
   20899     VkImageObj comp_10x10b_40x40t_image(m_device);  // Size = 40 * 40 * 4  = 6400
   20900 
   20901     uncomp_10x10t_image.Init(10, 10, 1, VK_FORMAT_R16G16B16A16_UINT,
   20902                              VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
   20903     comp_10x10b_40x40t_image.Init(40, 40, 1, VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
   20904                                   VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
   20905 
   20906     if (!uncomp_10x10t_image.initialized() || !comp_10x10b_40x40t_image.initialized()) {
   20907         printf("             Unable to initialize surfaces - UncompressedToCompressedImageCopy skipped.\n");
   20908         return;
   20909     }
   20910 
   20911     // Both copies represent the same number of bytes. Bytes Per Texel = 1 for bc6, 16 for uncompressed
   20912     // Copy compressed to uncompressed
   20913     VkImageCopy copy_region = {};
   20914     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   20915     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   20916     copy_region.srcSubresource.mipLevel = 0;
   20917     copy_region.dstSubresource.mipLevel = 0;
   20918     copy_region.srcSubresource.baseArrayLayer = 0;
   20919     copy_region.dstSubresource.baseArrayLayer = 0;
   20920     copy_region.srcSubresource.layerCount = 1;
   20921     copy_region.dstSubresource.layerCount = 1;
   20922     copy_region.srcOffset = {0, 0, 0};
   20923     copy_region.dstOffset = {0, 0, 0};
   20924 
   20925     m_errorMonitor->ExpectSuccess();
   20926     m_commandBuffer->begin();
   20927 
   20928     // Copy from uncompressed to compressed
   20929     copy_region.extent = {10, 10, 1};  // Dimensions in (uncompressed) texels
   20930     vkCmdCopyImage(m_commandBuffer->handle(), uncomp_10x10t_image.handle(), VK_IMAGE_LAYOUT_GENERAL,
   20931                    comp_10x10b_40x40t_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
   20932 
   20933     // And from compressed to uncompressed
   20934     copy_region.extent = {40, 40, 1};  // Dimensions in (compressed) texels
   20935     vkCmdCopyImage(m_commandBuffer->handle(), comp_10x10b_40x40t_image.handle(), VK_IMAGE_LAYOUT_GENERAL,
   20936                    uncomp_10x10t_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
   20937 
   20938     m_errorMonitor->VerifyNotFound();
   20939     m_commandBuffer->end();
   20940 }
   20941 
   20942 TEST_F(VkPositiveLayerTest, DeleteDescriptorSetLayoutsBeforeDescriptorSets) {
   20943     TEST_DESCRIPTION("Create DSLayouts and DescriptorSets and then delete the DSLayouts before the DescriptorSets.");
   20944     ASSERT_NO_FATAL_FAILURE(Init());
   20945     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   20946     VkResult err;
   20947 
   20948     m_errorMonitor->ExpectSuccess();
   20949 
   20950     VkDescriptorPoolSize ds_type_count = {};
   20951     ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
   20952     ds_type_count.descriptorCount = 1;
   20953 
   20954     VkDescriptorPoolCreateInfo ds_pool_ci = {};
   20955     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
   20956     ds_pool_ci.pNext = NULL;
   20957     ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
   20958     ds_pool_ci.maxSets = 1;
   20959     ds_pool_ci.poolSizeCount = 1;
   20960     ds_pool_ci.pPoolSizes = &ds_type_count;
   20961 
   20962     VkDescriptorPool ds_pool_one;
   20963     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool_one);
   20964     ASSERT_VK_SUCCESS(err);
   20965 
   20966     VkDescriptorSetLayoutBinding dsl_binding = {};
   20967     dsl_binding.binding = 0;
   20968     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
   20969     dsl_binding.descriptorCount = 1;
   20970     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
   20971     dsl_binding.pImmutableSamplers = NULL;
   20972 
   20973     VkDescriptorSet descriptorSet;
   20974     {
   20975         const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
   20976 
   20977         VkDescriptorSetAllocateInfo alloc_info = {};
   20978         alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
   20979         alloc_info.descriptorSetCount = 1;
   20980         alloc_info.descriptorPool = ds_pool_one;
   20981         alloc_info.pSetLayouts = &ds_layout.handle();
   20982         err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
   20983         ASSERT_VK_SUCCESS(err);
   20984     }  // ds_layout destroyed
   20985     err = vkFreeDescriptorSets(m_device->device(), ds_pool_one, 1, &descriptorSet);
   20986 
   20987     vkDestroyDescriptorPool(m_device->device(), ds_pool_one, NULL);
   20988     m_errorMonitor->VerifyNotFound();
   20989 }
   20990 
   20991 TEST_F(VkPositiveLayerTest, CommandPoolDeleteWithReferences) {
   20992     TEST_DESCRIPTION("Ensure the validation layers bookkeeping tracks the implicit command buffer frees.");
   20993     ASSERT_NO_FATAL_FAILURE(Init());
   20994 
   20995     VkCommandPoolCreateInfo cmd_pool_info = {};
   20996     cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
   20997     cmd_pool_info.pNext = NULL;
   20998     cmd_pool_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
   20999     cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
   21000     cmd_pool_info.flags = 0;
   21001 
   21002     VkCommandPool secondary_cmd_pool;
   21003     VkResult res = vkCreateCommandPool(m_device->handle(), &cmd_pool_info, NULL, &secondary_cmd_pool);
   21004     ASSERT_VK_SUCCESS(res);
   21005 
   21006     VkCommandBufferAllocateInfo cmdalloc = vk_testing::CommandBuffer::create_info(secondary_cmd_pool);
   21007     cmdalloc.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
   21008 
   21009     VkCommandBuffer secondary_cmds;
   21010     res = vkAllocateCommandBuffers(m_device->handle(), &cmdalloc, &secondary_cmds);
   21011 
   21012     VkCommandBufferInheritanceInfo cmd_buf_inheritance_info = {};
   21013     cmd_buf_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
   21014     cmd_buf_inheritance_info.pNext = NULL;
   21015     cmd_buf_inheritance_info.renderPass = VK_NULL_HANDLE;
   21016     cmd_buf_inheritance_info.subpass = 0;
   21017     cmd_buf_inheritance_info.framebuffer = VK_NULL_HANDLE;
   21018     cmd_buf_inheritance_info.occlusionQueryEnable = VK_FALSE;
   21019     cmd_buf_inheritance_info.queryFlags = 0;
   21020     cmd_buf_inheritance_info.pipelineStatistics = 0;
   21021 
   21022     VkCommandBufferBeginInfo secondary_begin = {};
   21023     secondary_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   21024     secondary_begin.pNext = NULL;
   21025     secondary_begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
   21026     secondary_begin.pInheritanceInfo = &cmd_buf_inheritance_info;
   21027 
   21028     res = vkBeginCommandBuffer(secondary_cmds, &secondary_begin);
   21029     ASSERT_VK_SUCCESS(res);
   21030     vkEndCommandBuffer(secondary_cmds);
   21031 
   21032     m_commandBuffer->begin();
   21033     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_cmds);
   21034     m_commandBuffer->end();
   21035 
   21036     // DestroyCommandPool *implicitly* frees the command buffers allocated from it
   21037     vkDestroyCommandPool(m_device->handle(), secondary_cmd_pool, NULL);
   21038     // If bookkeeping has been lax, validating the reset will attempt to touch deleted data
   21039     res = vkResetCommandPool(m_device->handle(), m_commandPool->handle(), 0);
   21040     ASSERT_VK_SUCCESS(res);
   21041 }
   21042 
   21043 TEST_F(VkPositiveLayerTest, SecondaryCommandBufferClearColorAttachments) {
   21044     TEST_DESCRIPTION("Create a secondary command buffer and record a CmdClearAttachments call into it");
   21045     ASSERT_NO_FATAL_FAILURE(Init());
   21046     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   21047 
   21048     VkCommandBufferAllocateInfo command_buffer_allocate_info = {};
   21049     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
   21050     command_buffer_allocate_info.commandPool = m_commandPool->handle();
   21051     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
   21052     command_buffer_allocate_info.commandBufferCount = 1;
   21053 
   21054     VkCommandBuffer secondary_command_buffer;
   21055     ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer));
   21056     VkCommandBufferBeginInfo command_buffer_begin_info = {};
   21057     VkCommandBufferInheritanceInfo command_buffer_inheritance_info = {};
   21058     command_buffer_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
   21059     command_buffer_inheritance_info.renderPass = m_renderPass;
   21060     command_buffer_inheritance_info.framebuffer = m_framebuffer;
   21061 
   21062     command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   21063     command_buffer_begin_info.flags =
   21064         VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
   21065     command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info;
   21066 
   21067     vkBeginCommandBuffer(secondary_command_buffer, &command_buffer_begin_info);
   21068     VkClearAttachment color_attachment;
   21069     color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   21070     color_attachment.clearValue.color.float32[0] = 0;
   21071     color_attachment.clearValue.color.float32[1] = 0;
   21072     color_attachment.clearValue.color.float32[2] = 0;
   21073     color_attachment.clearValue.color.float32[3] = 0;
   21074     color_attachment.colorAttachment = 0;
   21075     VkClearRect clear_rect = {{{0, 0}, {32, 32}}};
   21076     vkCmdClearAttachments(secondary_command_buffer, 1, &color_attachment, 1, &clear_rect);
   21077 }
   21078 
   21079 TEST_F(VkPositiveLayerTest, SecondaryCommandBufferImageLayoutTransitions) {
   21080     TEST_DESCRIPTION("Perform an image layout transition in a secondary command buffer followed by a transition in the primary.");
   21081     VkResult err;
   21082     m_errorMonitor->ExpectSuccess();
   21083     ASSERT_NO_FATAL_FAILURE(Init());
   21084     auto depth_format = FindSupportedDepthStencilFormat(gpu());
   21085     if (!depth_format) {
   21086         return;
   21087     }
   21088     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   21089     // Allocate a secondary and primary cmd buffer
   21090     VkCommandBufferAllocateInfo command_buffer_allocate_info = {};
   21091     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
   21092     command_buffer_allocate_info.commandPool = m_commandPool->handle();
   21093     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
   21094     command_buffer_allocate_info.commandBufferCount = 1;
   21095 
   21096     VkCommandBuffer secondary_command_buffer;
   21097     ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer));
   21098     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
   21099     VkCommandBuffer primary_command_buffer;
   21100     ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &primary_command_buffer));
   21101     VkCommandBufferBeginInfo command_buffer_begin_info = {};
   21102     VkCommandBufferInheritanceInfo command_buffer_inheritance_info = {};
   21103     command_buffer_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
   21104     command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   21105     command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
   21106     command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info;
   21107 
   21108     err = vkBeginCommandBuffer(secondary_command_buffer, &command_buffer_begin_info);
   21109     ASSERT_VK_SUCCESS(err);
   21110     VkImageObj image(m_device);
   21111     image.Init(128, 128, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   21112     ASSERT_TRUE(image.initialized());
   21113     VkImageMemoryBarrier img_barrier = {};
   21114     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
   21115     img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
   21116     img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
   21117     img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   21118     img_barrier.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
   21119     img_barrier.image = image.handle();
   21120     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   21121     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   21122     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
   21123     img_barrier.subresourceRange.baseArrayLayer = 0;
   21124     img_barrier.subresourceRange.baseMipLevel = 0;
   21125     img_barrier.subresourceRange.layerCount = 1;
   21126     img_barrier.subresourceRange.levelCount = 1;
   21127     vkCmdPipelineBarrier(secondary_command_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr,
   21128                          0, nullptr, 1, &img_barrier);
   21129     err = vkEndCommandBuffer(secondary_command_buffer);
   21130     ASSERT_VK_SUCCESS(err);
   21131 
   21132     // Now update primary cmd buffer to execute secondary and transitions image
   21133     command_buffer_begin_info.pInheritanceInfo = nullptr;
   21134     err = vkBeginCommandBuffer(primary_command_buffer, &command_buffer_begin_info);
   21135     ASSERT_VK_SUCCESS(err);
   21136     vkCmdExecuteCommands(primary_command_buffer, 1, &secondary_command_buffer);
   21137     VkImageMemoryBarrier img_barrier2 = {};
   21138     img_barrier2.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
   21139     img_barrier2.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
   21140     img_barrier2.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
   21141     img_barrier2.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
   21142     img_barrier2.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
   21143     img_barrier2.image = image.handle();
   21144     img_barrier2.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   21145     img_barrier2.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   21146     img_barrier2.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
   21147     img_barrier2.subresourceRange.baseArrayLayer = 0;
   21148     img_barrier2.subresourceRange.baseMipLevel = 0;
   21149     img_barrier2.subresourceRange.layerCount = 1;
   21150     img_barrier2.subresourceRange.levelCount = 1;
   21151     vkCmdPipelineBarrier(primary_command_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 0,
   21152                          nullptr, 1, &img_barrier2);
   21153     err = vkEndCommandBuffer(primary_command_buffer);
   21154     ASSERT_VK_SUCCESS(err);
   21155     VkSubmitInfo submit_info = {};
   21156     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   21157     submit_info.commandBufferCount = 1;
   21158     submit_info.pCommandBuffers = &primary_command_buffer;
   21159     err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   21160     ASSERT_VK_SUCCESS(err);
   21161     m_errorMonitor->VerifyNotFound();
   21162     err = vkDeviceWaitIdle(m_device->device());
   21163     ASSERT_VK_SUCCESS(err);
   21164     vkFreeCommandBuffers(m_device->device(), m_commandPool->handle(), 1, &secondary_command_buffer);
   21165     vkFreeCommandBuffers(m_device->device(), m_commandPool->handle(), 1, &primary_command_buffer);
   21166 }
   21167 
   21168 // This is a positive test. No failures are expected.
   21169 TEST_F(VkPositiveLayerTest, IgnoreUnrelatedDescriptor) {
   21170     TEST_DESCRIPTION(
   21171         "Ensure that the vkUpdateDescriptorSets validation code is ignoring VkWriteDescriptorSet members that are not related to "
   21172         "the descriptor type specified by VkWriteDescriptorSet::descriptorType.  Correct validation behavior will result in the "
   21173         "test running to completion without validation errors.");
   21174 
   21175     const uintptr_t invalid_ptr = 0xcdcdcdcd;
   21176 
   21177     ASSERT_NO_FATAL_FAILURE(Init());
   21178 
   21179     // Image Case
   21180     {
   21181         m_errorMonitor->ExpectSuccess();
   21182 
   21183         VkImageObj image(m_device);
   21184         image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   21185 
   21186         VkImageView view = image.targetView(VK_FORMAT_B8G8R8A8_UNORM);
   21187 
   21188         OneOffDescriptorSet ds(m_device, {
   21189                                              {0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr},
   21190                                          });
   21191 
   21192         VkDescriptorImageInfo image_info = {};
   21193         image_info.imageView = view;
   21194         image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
   21195 
   21196         VkWriteDescriptorSet descriptor_write;
   21197         memset(&descriptor_write, 0, sizeof(descriptor_write));
   21198         descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   21199         descriptor_write.dstSet = ds.set_;
   21200         descriptor_write.dstBinding = 0;
   21201         descriptor_write.descriptorCount = 1;
   21202         descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
   21203         descriptor_write.pImageInfo = &image_info;
   21204 
   21205         // Set pBufferInfo and pTexelBufferView to invalid values, which should
   21206         // be
   21207         //  ignored for descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE.
   21208         // This will most likely produce a crash if the parameter_validation
   21209         // layer
   21210         // does not correctly ignore pBufferInfo.
   21211         descriptor_write.pBufferInfo = reinterpret_cast<const VkDescriptorBufferInfo *>(invalid_ptr);
   21212         descriptor_write.pTexelBufferView = reinterpret_cast<const VkBufferView *>(invalid_ptr);
   21213 
   21214         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   21215 
   21216         m_errorMonitor->VerifyNotFound();
   21217     }
   21218 
   21219     // Buffer Case
   21220     {
   21221         m_errorMonitor->ExpectSuccess();
   21222 
   21223         VkBuffer buffer;
   21224         uint32_t queue_family_index = 0;
   21225         VkBufferCreateInfo buffer_create_info = {};
   21226         buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   21227         buffer_create_info.size = 1024;
   21228         buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
   21229         buffer_create_info.queueFamilyIndexCount = 1;
   21230         buffer_create_info.pQueueFamilyIndices = &queue_family_index;
   21231 
   21232         VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
   21233         ASSERT_VK_SUCCESS(err);
   21234 
   21235         VkMemoryRequirements memory_reqs;
   21236         VkDeviceMemory buffer_memory;
   21237         bool pass;
   21238         VkMemoryAllocateInfo memory_info = {};
   21239         memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   21240         memory_info.pNext = NULL;
   21241         memory_info.allocationSize = 0;
   21242         memory_info.memoryTypeIndex = 0;
   21243 
   21244         vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
   21245         memory_info.allocationSize = memory_reqs.size;
   21246         pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
   21247         ASSERT_TRUE(pass);
   21248 
   21249         err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
   21250         ASSERT_VK_SUCCESS(err);
   21251         err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
   21252         ASSERT_VK_SUCCESS(err);
   21253 
   21254         OneOffDescriptorSet ds(m_device, {
   21255                                              {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
   21256                                          });
   21257 
   21258         VkDescriptorBufferInfo buffer_info = {};
   21259         buffer_info.buffer = buffer;
   21260         buffer_info.offset = 0;
   21261         buffer_info.range = 1024;
   21262 
   21263         VkWriteDescriptorSet descriptor_write;
   21264         memset(&descriptor_write, 0, sizeof(descriptor_write));
   21265         descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   21266         descriptor_write.dstSet = ds.set_;
   21267         descriptor_write.dstBinding = 0;
   21268         descriptor_write.descriptorCount = 1;
   21269         descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   21270         descriptor_write.pBufferInfo = &buffer_info;
   21271 
   21272         // Set pImageInfo and pTexelBufferView to invalid values, which should
   21273         // be
   21274         //  ignored for descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER.
   21275         // This will most likely produce a crash if the parameter_validation
   21276         // layer
   21277         // does not correctly ignore pImageInfo.
   21278         descriptor_write.pImageInfo = reinterpret_cast<const VkDescriptorImageInfo *>(invalid_ptr);
   21279         descriptor_write.pTexelBufferView = reinterpret_cast<const VkBufferView *>(invalid_ptr);
   21280 
   21281         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   21282 
   21283         m_errorMonitor->VerifyNotFound();
   21284 
   21285         vkDestroyBuffer(m_device->device(), buffer, NULL);
   21286         vkFreeMemory(m_device->device(), buffer_memory, NULL);
   21287     }
   21288 
   21289     // Texel Buffer Case
   21290     {
   21291         m_errorMonitor->ExpectSuccess();
   21292 
   21293         VkBuffer buffer;
   21294         uint32_t queue_family_index = 0;
   21295         VkBufferCreateInfo buffer_create_info = {};
   21296         buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   21297         buffer_create_info.size = 1024;
   21298         buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
   21299         buffer_create_info.queueFamilyIndexCount = 1;
   21300         buffer_create_info.pQueueFamilyIndices = &queue_family_index;
   21301 
   21302         VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
   21303         ASSERT_VK_SUCCESS(err);
   21304 
   21305         VkMemoryRequirements memory_reqs;
   21306         VkDeviceMemory buffer_memory;
   21307         bool pass;
   21308         VkMemoryAllocateInfo memory_info = {};
   21309         memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   21310         memory_info.pNext = NULL;
   21311         memory_info.allocationSize = 0;
   21312         memory_info.memoryTypeIndex = 0;
   21313 
   21314         vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
   21315         memory_info.allocationSize = memory_reqs.size;
   21316         pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
   21317         ASSERT_TRUE(pass);
   21318 
   21319         err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
   21320         ASSERT_VK_SUCCESS(err);
   21321         err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
   21322         ASSERT_VK_SUCCESS(err);
   21323 
   21324         VkBufferViewCreateInfo buff_view_ci = {};
   21325         buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
   21326         buff_view_ci.buffer = buffer;
   21327         buff_view_ci.format = VK_FORMAT_R8_UNORM;
   21328         buff_view_ci.range = VK_WHOLE_SIZE;
   21329         VkBufferView buffer_view;
   21330         err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buffer_view);
   21331 
   21332         OneOffDescriptorSet ds(m_device, {
   21333                                              {0, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
   21334                                          });
   21335 
   21336         VkWriteDescriptorSet descriptor_write;
   21337         memset(&descriptor_write, 0, sizeof(descriptor_write));
   21338         descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   21339         descriptor_write.dstSet = ds.set_;
   21340         descriptor_write.dstBinding = 0;
   21341         descriptor_write.descriptorCount = 1;
   21342         descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
   21343         descriptor_write.pTexelBufferView = &buffer_view;
   21344 
   21345         // Set pImageInfo and pBufferInfo to invalid values, which should be
   21346         //  ignored for descriptorType ==
   21347         //  VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER.
   21348         // This will most likely produce a crash if the parameter_validation
   21349         // layer
   21350         // does not correctly ignore pImageInfo and pBufferInfo.
   21351         descriptor_write.pImageInfo = reinterpret_cast<const VkDescriptorImageInfo *>(invalid_ptr);
   21352         descriptor_write.pBufferInfo = reinterpret_cast<const VkDescriptorBufferInfo *>(invalid_ptr);
   21353 
   21354         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   21355 
   21356         m_errorMonitor->VerifyNotFound();
   21357 
   21358         vkDestroyBufferView(m_device->device(), buffer_view, NULL);
   21359         vkDestroyBuffer(m_device->device(), buffer, NULL);
   21360         vkFreeMemory(m_device->device(), buffer_memory, NULL);
   21361     }
   21362 }
   21363 
   21364 TEST_F(VkPositiveLayerTest, ImmutableSamplerOnlyDescriptor) {
   21365     TEST_DESCRIPTION("Bind a DescriptorSet with only an immutable samplerand make sure that we don't warn for no update.");
   21366 
   21367     ASSERT_NO_FATAL_FAILURE(Init());
   21368     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   21369 
   21370     OneOffDescriptorSet ds(m_device, {
   21371                                          {0, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
   21372                                      });
   21373 
   21374     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
   21375     VkSampler sampler;
   21376     VkResult err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
   21377     ASSERT_VK_SUCCESS(err);
   21378 
   21379     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
   21380 
   21381     m_errorMonitor->ExpectSuccess();
   21382     m_commandBuffer->begin();
   21383     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   21384 
   21385     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &ds.set_, 0,
   21386                             nullptr);
   21387     m_errorMonitor->VerifyNotFound();
   21388 
   21389     vkDestroySampler(m_device->device(), sampler, NULL);
   21390 }
   21391 
   21392 TEST_F(VkLayerTest, DuplicateDescriptorBinding) {
   21393     TEST_DESCRIPTION("Create a descriptor set layout with a duplicate binding number.");
   21394 
   21395     ASSERT_NO_FATAL_FAILURE(Init());
   21396     // Create layout where two binding #s are "1"
   21397     static const uint32_t NUM_BINDINGS = 3;
   21398     VkDescriptorSetLayoutBinding dsl_binding[NUM_BINDINGS] = {};
   21399     dsl_binding[0].binding = 1;
   21400     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   21401     dsl_binding[0].descriptorCount = 1;
   21402     dsl_binding[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
   21403     dsl_binding[0].pImmutableSamplers = NULL;
   21404     dsl_binding[1].binding = 0;
   21405     dsl_binding[1].descriptorCount = 1;
   21406     dsl_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   21407     dsl_binding[1].descriptorCount = 1;
   21408     dsl_binding[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
   21409     dsl_binding[1].pImmutableSamplers = NULL;
   21410     dsl_binding[2].binding = 1;  // Duplicate binding should cause error
   21411     dsl_binding[2].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   21412     dsl_binding[2].descriptorCount = 1;
   21413     dsl_binding[2].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
   21414     dsl_binding[2].pImmutableSamplers = NULL;
   21415 
   21416     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
   21417     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
   21418     ds_layout_ci.pNext = NULL;
   21419     ds_layout_ci.bindingCount = NUM_BINDINGS;
   21420     ds_layout_ci.pBindings = dsl_binding;
   21421     VkDescriptorSetLayout ds_layout;
   21422     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0500022e);
   21423     vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
   21424     m_errorMonitor->VerifyFound();
   21425 }
   21426 
   21427 TEST_F(VkLayerTest, InvalidPushDescriptorSetLayout) {
   21428     TEST_DESCRIPTION("Create a push descriptor set layout with invalid bindings.");
   21429 
   21430     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
   21431         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
   21432     } else {
   21433         printf("             Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n");
   21434         return;
   21435     }
   21436 
   21437     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   21438     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
   21439         m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
   21440     } else {
   21441         printf("             %s Extension not supported, skipping tests\n", VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
   21442         return;
   21443     }
   21444 
   21445     ASSERT_NO_FATAL_FAILURE(InitState());
   21446 
   21447     // Find address of extension call and make the call
   21448     PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR =
   21449         (PFN_vkGetPhysicalDeviceProperties2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceProperties2KHR");
   21450     assert(vkGetPhysicalDeviceProperties2KHR != nullptr);
   21451 
   21452     // Get the push descriptor limits
   21453     auto push_descriptor_prop = lvl_init_struct<VkPhysicalDevicePushDescriptorPropertiesKHR>();
   21454     auto prop2 = lvl_init_struct<VkPhysicalDeviceProperties2KHR>(&push_descriptor_prop);
   21455     vkGetPhysicalDeviceProperties2KHR(m_device->phy().handle(), &prop2);
   21456 
   21457     VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
   21458 
   21459     auto ds_layout_ci = lvl_init_struct<VkDescriptorSetLayoutCreateInfo>();
   21460     ds_layout_ci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
   21461     ds_layout_ci.bindingCount = 1;
   21462     ds_layout_ci.pBindings = &binding;
   21463 
   21464     // Note that as binding is referenced in ds_layout_ci, it is effectively in the closure by reference as well.
   21465     auto test_create_ds_layout = [&ds_layout_ci, this](UNIQUE_VALIDATION_ERROR_CODE error) {
   21466         VkDescriptorSetLayout ds_layout = VK_NULL_HANDLE;
   21467         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error);
   21468         vkCreateDescriptorSetLayout(m_device->handle(), &ds_layout_ci, nullptr, &ds_layout);
   21469         m_errorMonitor->VerifyFound();
   21470         vkDestroyDescriptorSetLayout(m_device->handle(), ds_layout, nullptr);
   21471     };
   21472 
   21473     // Starting with the initial VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC type set above..
   21474     test_create_ds_layout(VALIDATION_ERROR_05000230);
   21475 
   21476     binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
   21477     test_create_ds_layout(VALIDATION_ERROR_05000230);  // This is the same VUID as above, just a second error condition.
   21478 
   21479     if (!(push_descriptor_prop.maxPushDescriptors == std::numeric_limits<uint32_t>::max())) {
   21480         binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
   21481         binding.descriptorCount = push_descriptor_prop.maxPushDescriptors + 1;
   21482         test_create_ds_layout(VALIDATION_ERROR_05000232);
   21483     } else {
   21484         printf("             maxPushDescriptors is set to maxiumum unit32_t value, skipping 'out of range test'.\n");
   21485     }
   21486 }
   21487 
   21488 TEST_F(VkLayerTest, PushDescriptorSetLayoutWithoutExtension) {
   21489     TEST_DESCRIPTION("Create a push descriptor set layout without loading the needed extension.");
   21490     ASSERT_NO_FATAL_FAILURE(Init());
   21491 
   21492     VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
   21493 
   21494     auto ds_layout_ci = lvl_init_struct<VkDescriptorSetLayoutCreateInfo>();
   21495     ds_layout_ci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
   21496     ds_layout_ci.bindingCount = 1;
   21497     ds_layout_ci.pBindings = &binding;
   21498 
   21499     std::string error = "Attemped to use VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR in ";
   21500     error = error + "VkDescriptorSetLayoutCreateInfo::flags but its required extension ";
   21501     error = error + VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME;
   21502     error = error + " has not been enabled.";
   21503 
   21504     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error.c_str());
   21505     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_05000232);
   21506     VkDescriptorSetLayout ds_layout = VK_NULL_HANDLE;
   21507     vkCreateDescriptorSetLayout(m_device->handle(), &ds_layout_ci, nullptr, &ds_layout);
   21508     m_errorMonitor->VerifyFound();
   21509     vkDestroyDescriptorSetLayout(m_device->handle(), ds_layout, nullptr);
   21510 }
   21511 
   21512 TEST_F(VkLayerTest, AllocatePushDescriptorSet) {
   21513     TEST_DESCRIPTION("Attempt to allocate a push descriptor set.");
   21514     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
   21515         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
   21516     } else {
   21517         printf("             %s Extension not supported, skipping tests\n", VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
   21518         return;
   21519     }
   21520 
   21521     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   21522     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
   21523         m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
   21524     } else {
   21525         printf("             %s Extension not supported, skipping tests\n", VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
   21526         return;
   21527     }
   21528     ASSERT_NO_FATAL_FAILURE(InitState());
   21529 
   21530     VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
   21531     auto ds_layout_ci = lvl_init_struct<VkDescriptorSetLayoutCreateInfo>();
   21532     ds_layout_ci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
   21533     ds_layout_ci.bindingCount = 1;
   21534     ds_layout_ci.pBindings = &binding;
   21535     VkDescriptorSetLayout ds_layout = VK_NULL_HANDLE;
   21536     VkResult err = vkCreateDescriptorSetLayout(m_device->handle(), &ds_layout_ci, nullptr, &ds_layout);
   21537     ASSERT_VK_SUCCESS(err);
   21538 
   21539     VkDescriptorPoolSize pool_size = {binding.descriptorType, binding.descriptorCount};
   21540     auto dspci = lvl_init_struct<VkDescriptorPoolCreateInfo>();
   21541     dspci.poolSizeCount = 1;
   21542     dspci.pPoolSizes = &pool_size;
   21543     dspci.maxSets = 1;
   21544     VkDescriptorPool pool;
   21545     err = vkCreateDescriptorPool(m_device->handle(), &dspci, nullptr, &pool);
   21546     ASSERT_VK_SUCCESS(err);
   21547 
   21548     auto ds_alloc_info = lvl_init_struct<VkDescriptorSetAllocateInfo>();
   21549     ds_alloc_info.descriptorPool = pool;
   21550     ds_alloc_info.descriptorSetCount = 1;
   21551     ds_alloc_info.pSetLayouts = &ds_layout;
   21552 
   21553     VkDescriptorSet ds = VK_NULL_HANDLE;
   21554     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_04c00268);
   21555     vkAllocateDescriptorSets(m_device->handle(), &ds_alloc_info, &ds);
   21556     m_errorMonitor->VerifyFound();
   21557 
   21558     vkDestroyDescriptorPool(m_device->handle(), pool, nullptr);
   21559     vkDestroyDescriptorSetLayout(m_device->handle(), ds_layout, nullptr);
   21560 }
   21561 
   21562 TEST_F(VkLayerTest, PushDescriptorSetCmdPushBadArgs) {
   21563     TEST_DESCRIPTION("Attempt to push a push descriptor set with incorrect arguments.");
   21564     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
   21565         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
   21566     } else {
   21567         printf("             %s Extension not supported, skipping tests\n", VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
   21568         return;
   21569     }
   21570 
   21571     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   21572     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
   21573         m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
   21574     } else {
   21575         printf("             %s Extension not supported, skipping tests\n", VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
   21576         return;
   21577     }
   21578     ASSERT_NO_FATAL_FAILURE(InitState());
   21579 
   21580     // Create ordinary and push descriptor set layout
   21581     VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
   21582     const VkDescriptorSetLayoutObj ds_layout(m_device, {binding});
   21583     ASSERT_TRUE(ds_layout.initialized());
   21584     const VkDescriptorSetLayoutObj push_ds_layout(m_device, {binding}, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
   21585     ASSERT_TRUE(push_ds_layout.initialized());
   21586 
   21587     // Now use the descriptor set layouts to create a pipeline layout
   21588     const VkPipelineLayoutObj pipeline_layout(m_device, {&push_ds_layout, &ds_layout});
   21589     ASSERT_TRUE(pipeline_layout.initialized());
   21590 
   21591     // Create a descriptor to push
   21592     const uint32_t buffer_data[4] = {4, 5, 6, 7};
   21593     VkConstantBufferObj buffer_obj(m_device, sizeof(buffer_data), &buffer_data);
   21594     ASSERT_TRUE(buffer_obj.initialized());
   21595 
   21596     // Create a "write" struct, noting that the buffer_info cannot be a temporary arg (the return from write_descriptor_set
   21597     // references its data), and the DescriptorSet() can be temporary, because the value is ignored
   21598     VkDescriptorBufferInfo buffer_info = {buffer_obj.handle(), 0, VK_WHOLE_SIZE};
   21599 
   21600     VkWriteDescriptorSet descriptor_write = vk_testing::Device::write_descriptor_set(
   21601         vk_testing::DescriptorSet(), 0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &buffer_info);
   21602 
   21603     // Find address of extension call and make the call
   21604     PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR =
   21605         (PFN_vkCmdPushDescriptorSetKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR");
   21606     ASSERT_TRUE(vkCmdPushDescriptorSetKHR != nullptr);
   21607 
   21608     // Section 1: Queue family matching/capabilities.
   21609     // Create command pool on a non-graphics queue
   21610     const uint32_t no_gfx_qfi = m_device->QueueFamilyMatching(VK_QUEUE_COMPUTE_BIT, VK_QUEUE_GRAPHICS_BIT);
   21611     const uint32_t transfer_only_qfi =
   21612         m_device->QueueFamilyMatching(VK_QUEUE_TRANSFER_BIT, (VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT));
   21613     if ((UINT32_MAX == transfer_only_qfi) && (UINT32_MAX == no_gfx_qfi)) {
   21614         printf("             No compute or transfer only queue family, skipping bindpoint and queue tests.");
   21615     } else {
   21616         const uint32_t err_qfi = (UINT32_MAX == no_gfx_qfi) ? transfer_only_qfi : no_gfx_qfi;
   21617 
   21618         VkCommandPoolObj command_pool(m_device, err_qfi);
   21619         ASSERT_TRUE(command_pool.initialized());
   21620         VkCommandBufferObj command_buffer(m_device, &command_pool);
   21621         ASSERT_TRUE(command_buffer.initialized());
   21622         command_buffer.begin();
   21623 
   21624         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1be002d6);
   21625         if (err_qfi == transfer_only_qfi) {
   21626             // This as this queue neither supports the gfx or compute bindpoints, we'll get two errors
   21627             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1be02415);
   21628         }
   21629         vkCmdPushDescriptorSetKHR(command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
   21630                                   &descriptor_write);
   21631         m_errorMonitor->VerifyFound();
   21632         command_buffer.end();
   21633 
   21634         // If we succeed in testing only one condition above, we need to test the other below.
   21635         if ((UINT32_MAX != transfer_only_qfi) && (err_qfi != transfer_only_qfi)) {
   21636             // Need to test the neither compute/gfx supported case separately.
   21637             VkCommandPoolObj tran_command_pool(m_device, transfer_only_qfi);
   21638             ASSERT_TRUE(tran_command_pool.initialized());
   21639             VkCommandBufferObj tran_command_buffer(m_device, &tran_command_pool);
   21640             ASSERT_TRUE(tran_command_buffer.initialized());
   21641             tran_command_buffer.begin();
   21642 
   21643             // We can't avoid getting *both* errors in this case
   21644             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1be002d6);
   21645             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1be02415);
   21646             vkCmdPushDescriptorSetKHR(tran_command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
   21647                                       &descriptor_write);
   21648             m_errorMonitor->VerifyFound();
   21649             tran_command_buffer.end();
   21650         }
   21651     }
   21652 
   21653     // Push to the non-push binding
   21654     m_commandBuffer->begin();
   21655     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1be002da);
   21656     vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 1, 1,
   21657                               &descriptor_write);
   21658     m_errorMonitor->VerifyFound();
   21659 
   21660     // Specify set out of bounds
   21661     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1be002d8);
   21662     vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 2, 1,
   21663                               &descriptor_write);
   21664     m_errorMonitor->VerifyFound();
   21665     m_commandBuffer->end();
   21666 
   21667     // This is a test for VUID-vkCmdPushDescriptorSetKHR-commandBuffer-recording
   21668     // TODO: Add VALIDATION_ERROR_ code support to core_validation::ValidateCmd
   21669     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
   21670                                          "You must call vkBeginCommandBuffer() before this call to vkCmdPushDescriptorSetKHR()");
   21671     vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
   21672                               &descriptor_write);
   21673     m_errorMonitor->VerifyFound();
   21674 }
   21675 
   21676 TEST_F(VkLayerTest, ViewportBoundsCheckingWithNVHExtensionEnabled) {
   21677     TEST_DESCRIPTION("Verify errors are detected on misuse of SetViewport with a negative viewport extension enabled.");
   21678 
   21679     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   21680 
   21681     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
   21682         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
   21683     } else {
   21684         printf("             Maintenance1 Extension not supported, skipping tests\n");
   21685         return;
   21686     }
   21687     ASSERT_NO_FATAL_FAILURE(InitState());
   21688     const VkPhysicalDeviceLimits &limits = m_device->props.limits;
   21689 
   21690     m_commandBuffer->begin();
   21691     {
   21692         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1500099a);
   21693         VkViewport viewport = {0, 0, 16, -(static_cast<float>(limits.maxViewportDimensions[1] + 1)), 0, 1};
   21694         vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   21695         m_errorMonitor->VerifyFound();
   21696     }
   21697     m_commandBuffer->end();
   21698 }
   21699 
   21700 TEST_F(VkLayerTest, ViewportAndScissorBoundsChecking) {
   21701     TEST_DESCRIPTION("Verify errors are detected on misuse of SetViewport and SetScissor.");
   21702 
   21703     ASSERT_NO_FATAL_FAILURE(Init());
   21704 
   21705     m_commandBuffer->begin();
   21706 
   21707     const VkPhysicalDeviceLimits &limits = m_device->props.limits;
   21708 
   21709     {
   21710         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15000996);
   21711         VkViewport viewport = {0, 0, static_cast<float>(limits.maxViewportDimensions[0] + 1), 16, 0, 1};
   21712         vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   21713         m_errorMonitor->VerifyFound();
   21714     }
   21715 
   21716     {
   21717         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15000998);
   21718         VkViewport viewport = {0, 0, 16, static_cast<float>(limits.maxViewportDimensions[1] + 1), 0, 1};
   21719         vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   21720         m_errorMonitor->VerifyFound();
   21721     }
   21722 
   21723     {
   21724         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1500099e);
   21725         VkViewport viewport = {limits.viewportBoundsRange[0] - 1, 0, 16, 16, 0, 1};
   21726         vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   21727         m_errorMonitor->VerifyFound();
   21728     }
   21729 
   21730     {
   21731         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1500099e);
   21732         VkViewport viewport = {0, limits.viewportBoundsRange[0] - 1, 16, 16, 0, 1};
   21733         vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   21734         m_errorMonitor->VerifyFound();
   21735     }
   21736 
   21737     {
   21738         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_150009a0);
   21739         VkViewport viewport = {limits.viewportBoundsRange[1], 0, 16, 16, 0, 1};
   21740         vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   21741         m_errorMonitor->VerifyFound();
   21742     }
   21743 
   21744     {
   21745         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_150009a2);
   21746         VkViewport viewport = {0, limits.viewportBoundsRange[1], 16, 16, 0, 1};
   21747         vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
   21748         m_errorMonitor->VerifyFound();
   21749     }
   21750 
   21751     {
   21752         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1d8004a6);
   21753         VkRect2D scissor = {{-1, 0}, {16, 16}};
   21754         vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
   21755         m_errorMonitor->VerifyFound();
   21756     }
   21757 
   21758     {
   21759         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1d8004a6);
   21760         VkRect2D scissor = {{0, -2}, {16, 16}};
   21761         vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
   21762         m_errorMonitor->VerifyFound();
   21763     }
   21764 
   21765     {
   21766         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1d8004a8);
   21767         VkRect2D scissor = {{100, 100}, {INT_MAX, 16}};
   21768         vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
   21769         m_errorMonitor->VerifyFound();
   21770     }
   21771 
   21772     {
   21773         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1d8004aa);
   21774         VkRect2D scissor = {{100, 100}, {16, INT_MAX}};
   21775         vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
   21776         m_errorMonitor->VerifyFound();
   21777     }
   21778 
   21779     m_commandBuffer->end();
   21780 }
   21781 
   21782 // This is a positive test. No failures are expected.
   21783 TEST_F(VkPositiveLayerTest, EmptyDescriptorUpdateTest) {
   21784     TEST_DESCRIPTION("Update last descriptor in a set that includes an empty binding");
   21785     VkResult err;
   21786 
   21787     ASSERT_NO_FATAL_FAILURE(Init());
   21788     m_errorMonitor->ExpectSuccess();
   21789 
   21790     // Create layout with two uniform buffer descriptors w/ empty binding between them
   21791     OneOffDescriptorSet ds(m_device, {
   21792                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
   21793                                          {1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0 /*!*/, 0, nullptr},
   21794                                          {2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
   21795                                      });
   21796 
   21797     // Create a buffer to be used for update
   21798     VkBufferCreateInfo buff_ci = {};
   21799     buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   21800     buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
   21801     buff_ci.size = 256;
   21802     buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   21803     VkBuffer buffer;
   21804     err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
   21805     ASSERT_VK_SUCCESS(err);
   21806     // Have to bind memory to buffer before descriptor update
   21807     VkMemoryAllocateInfo mem_alloc = {};
   21808     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   21809     mem_alloc.pNext = NULL;
   21810     mem_alloc.allocationSize = 512;  // one allocation for both buffers
   21811     mem_alloc.memoryTypeIndex = 0;
   21812 
   21813     VkMemoryRequirements mem_reqs;
   21814     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
   21815     bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
   21816     if (!pass) {
   21817         vkDestroyBuffer(m_device->device(), buffer, NULL);
   21818         return;
   21819     }
   21820     // Make sure allocation is sufficiently large to accommodate buffer requirements
   21821     if (mem_reqs.size > mem_alloc.allocationSize) {
   21822         mem_alloc.allocationSize = mem_reqs.size;
   21823     }
   21824 
   21825     VkDeviceMemory mem;
   21826     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
   21827     ASSERT_VK_SUCCESS(err);
   21828     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
   21829     ASSERT_VK_SUCCESS(err);
   21830 
   21831     // Only update the descriptor at binding 2
   21832     VkDescriptorBufferInfo buff_info = {};
   21833     buff_info.buffer = buffer;
   21834     buff_info.offset = 0;
   21835     buff_info.range = VK_WHOLE_SIZE;
   21836     VkWriteDescriptorSet descriptor_write = {};
   21837     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   21838     descriptor_write.dstBinding = 2;
   21839     descriptor_write.descriptorCount = 1;
   21840     descriptor_write.pTexelBufferView = nullptr;
   21841     descriptor_write.pBufferInfo = &buff_info;
   21842     descriptor_write.pImageInfo = nullptr;
   21843     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   21844     descriptor_write.dstSet = ds.set_;
   21845 
   21846     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   21847 
   21848     m_errorMonitor->VerifyNotFound();
   21849     // Cleanup
   21850     vkFreeMemory(m_device->device(), mem, NULL);
   21851     vkDestroyBuffer(m_device->device(), buffer, NULL);
   21852 }
   21853 
   21854 TEST_F(VkLayerTest, MultiplePushDescriptorSets) {
   21855     TEST_DESCRIPTION("Verify an error message for multiple push descriptor sets.");
   21856 
   21857     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
   21858         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
   21859     } else {
   21860         printf("             Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n");
   21861         return;
   21862     }
   21863     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   21864     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
   21865         m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
   21866     } else {
   21867         printf("             Push Descriptors Extension not supported, skipping tests\n");
   21868         return;
   21869     }
   21870     ASSERT_NO_FATAL_FAILURE(InitState());
   21871 
   21872     VkDescriptorSetLayoutBinding dsl_binding = {};
   21873     dsl_binding.binding = 0;
   21874     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   21875     dsl_binding.descriptorCount = 1;
   21876     dsl_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
   21877     dsl_binding.pImmutableSamplers = NULL;
   21878 
   21879     const unsigned int descriptor_set_layout_count = 2;
   21880     std::vector<VkDescriptorSetLayoutObj> ds_layouts;
   21881     for (uint32_t i = 0; i < descriptor_set_layout_count; ++i) {
   21882         dsl_binding.binding = i;
   21883         ds_layouts.emplace_back(m_device, std::vector<VkDescriptorSetLayoutBinding>(1, dsl_binding),
   21884                                 VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
   21885     }
   21886     const auto &ds_vk_layouts = MakeVkHandles<VkDescriptorSetLayout>(ds_layouts);
   21887 
   21888     VkPipelineLayout pipeline_layout;
   21889     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
   21890     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
   21891     pipeline_layout_ci.pNext = NULL;
   21892     pipeline_layout_ci.pushConstantRangeCount = 0;
   21893     pipeline_layout_ci.pPushConstantRanges = NULL;
   21894     pipeline_layout_ci.setLayoutCount = ds_vk_layouts.size();
   21895     pipeline_layout_ci.pSetLayouts = ds_vk_layouts.data();
   21896 
   21897     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe0024a);
   21898     vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
   21899     m_errorMonitor->VerifyFound();
   21900 }
   21901 
   21902 // This is a positive test. No failures are expected.
   21903 TEST_F(VkPositiveLayerTest, PushDescriptorNullDstSetTest) {
   21904     TEST_DESCRIPTION("Use null dstSet in CmdPushDescriptorSetKHR");
   21905 
   21906     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
   21907         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
   21908     } else {
   21909         printf("             Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n");
   21910         return;
   21911     }
   21912     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   21913     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
   21914         m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
   21915     } else {
   21916         printf("             Push Descriptors Extension not supported, skipping tests\n");
   21917         return;
   21918     }
   21919     ASSERT_NO_FATAL_FAILURE(InitState());
   21920     m_errorMonitor->ExpectSuccess();
   21921 
   21922     VkDescriptorSetLayoutBinding dsl_binding = {};
   21923     dsl_binding.binding = 2;
   21924     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   21925     dsl_binding.descriptorCount = 1;
   21926     dsl_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
   21927     dsl_binding.pImmutableSamplers = NULL;
   21928 
   21929     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding}, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
   21930 
   21931     // Now use the descriptor layout to create a pipeline layout
   21932     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout});
   21933 
   21934     static const float vbo_data[3] = {1.f, 0.f, 1.f};
   21935     VkConstantBufferObj vbo(m_device, sizeof(vbo_data), (const void *)&vbo_data);
   21936 
   21937     VkDescriptorBufferInfo buff_info;
   21938     buff_info.buffer = vbo.handle();
   21939     buff_info.offset = 0;
   21940     buff_info.range = sizeof(vbo_data);
   21941     VkWriteDescriptorSet descriptor_write = {};
   21942     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   21943     descriptor_write.dstBinding = 2;
   21944     descriptor_write.descriptorCount = 1;
   21945     descriptor_write.pTexelBufferView = nullptr;
   21946     descriptor_write.pBufferInfo = &buff_info;
   21947     descriptor_write.pImageInfo = nullptr;
   21948     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   21949     descriptor_write.dstSet = 0;  // Should not cause a validation error
   21950 
   21951     // Find address of extension call and make the call
   21952     PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR =
   21953         (PFN_vkCmdPushDescriptorSetKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR");
   21954     assert(vkCmdPushDescriptorSetKHR != nullptr);
   21955     m_commandBuffer->begin();
   21956     vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
   21957                               &descriptor_write);
   21958 
   21959     m_errorMonitor->VerifyNotFound();
   21960 }
   21961 
   21962 // This is a positive test. No failures are expected.
   21963 TEST_F(VkPositiveLayerTest, PushDescriptorUnboundSetTest) {
   21964     TEST_DESCRIPTION("Ensure that no validation errors are produced for not bound push descriptor sets");
   21965     VkResult err;
   21966     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
   21967         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
   21968     } else {
   21969         printf("             Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n");
   21970         return;
   21971     }
   21972     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   21973     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
   21974         m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
   21975     } else {
   21976         printf("             Push Descriptors Extension not supported, skipping tests\n");
   21977         return;
   21978     }
   21979     ASSERT_NO_FATAL_FAILURE(InitState());
   21980     ASSERT_NO_FATAL_FAILURE(InitViewport());
   21981     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   21982     m_errorMonitor->ExpectSuccess();
   21983 
   21984     VkDescriptorPoolSize ds_type_count = {};
   21985     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   21986     ds_type_count.descriptorCount = 1;
   21987 
   21988     VkDescriptorPoolCreateInfo ds_pool_ci = {};
   21989     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
   21990     ds_pool_ci.pNext = NULL;
   21991     ds_pool_ci.maxSets = 1;
   21992     ds_pool_ci.poolSizeCount = 1;
   21993     ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
   21994     ds_pool_ci.pPoolSizes = &ds_type_count;
   21995 
   21996     VkDescriptorPool ds_pool;
   21997     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
   21998     ASSERT_VK_SUCCESS(err);
   21999 
   22000     // Create descriptor set layout
   22001     VkDescriptorSetLayoutBinding dsl_binding = {};
   22002     dsl_binding.binding = 2;
   22003     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   22004     dsl_binding.descriptorCount = 1;
   22005     dsl_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
   22006     dsl_binding.pImmutableSamplers = NULL;
   22007 
   22008     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
   22009 
   22010     // Create push descriptor set layout
   22011     const VkDescriptorSetLayoutObj push_ds_layout(m_device, {dsl_binding}, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
   22012 
   22013     // Allocate descriptor set
   22014     VkDescriptorSetAllocateInfo alloc_info = {};
   22015     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
   22016     alloc_info.pNext = NULL;
   22017     alloc_info.descriptorPool = ds_pool;
   22018     alloc_info.descriptorSetCount = 1;
   22019     alloc_info.pSetLayouts = &ds_layout.handle();
   22020     VkDescriptorSet descriptor_set;
   22021     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
   22022     ASSERT_VK_SUCCESS(err);
   22023 
   22024     // Now use the descriptor layouts to create a pipeline layout
   22025     const VkPipelineLayoutObj pipeline_layout(m_device, {&push_ds_layout, &ds_layout});
   22026 
   22027     // Create PSO
   22028     char const *vsSource =
   22029         "#version 450\n"
   22030         "\n"
   22031         "void main(){\n"
   22032         "   gl_Position = vec4(1);\n"
   22033         "}\n";
   22034     char const *fsSource =
   22035         "#version 450\n"
   22036         "\n"
   22037         "layout(location=0) out vec4 x;\n"
   22038         "layout(set=0) layout(binding=2) uniform foo1 { float x; } bar1;\n"
   22039         "layout(set=1) layout(binding=2) uniform foo2 { float y; } bar2;\n"
   22040         "void main(){\n"
   22041         "   x = vec4(bar1.x) + vec4(bar2.y);\n"
   22042         "}\n";
   22043     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   22044     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   22045     VkPipelineObj pipe(m_device);
   22046     pipe.SetViewport(m_viewports);
   22047     pipe.SetScissor(m_scissors);
   22048     pipe.AddShader(&vs);
   22049     pipe.AddShader(&fs);
   22050     pipe.AddDefaultColorAttachment();
   22051     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   22052 
   22053     static const float bo_data[1] = {1.f};
   22054     VkConstantBufferObj buffer(m_device, sizeof(bo_data), (const void *)&bo_data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
   22055 
   22056     // Update descriptor set
   22057     VkDescriptorBufferInfo buff_info;
   22058     buff_info.buffer = buffer.handle();
   22059     buff_info.offset = 0;
   22060     buff_info.range = sizeof(bo_data);
   22061     VkWriteDescriptorSet descriptor_write = {};
   22062     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   22063     descriptor_write.dstBinding = 2;
   22064     descriptor_write.descriptorCount = 1;
   22065     descriptor_write.pTexelBufferView = nullptr;
   22066     descriptor_write.pBufferInfo = &buff_info;
   22067     descriptor_write.pImageInfo = nullptr;
   22068     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
   22069     descriptor_write.dstSet = descriptor_set;
   22070     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   22071 
   22072     PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR =
   22073         (PFN_vkCmdPushDescriptorSetKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR");
   22074     assert(vkCmdPushDescriptorSetKHR != nullptr);
   22075 
   22076     m_commandBuffer->begin();
   22077     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   22078     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   22079 
   22080     // Push descriptors and bind descriptor set
   22081     vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
   22082                               &descriptor_write);
   22083     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 1, 1,
   22084                             &descriptor_set, 0, NULL);
   22085 
   22086     // No errors should be generated.
   22087     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
   22088 
   22089     m_errorMonitor->VerifyNotFound();
   22090     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
   22091 }
   22092 
   22093 // This is a positive test. No failures are expected.
   22094 TEST_F(VkPositiveLayerTest, TestAliasedMemoryTracking) {
   22095     VkResult err;
   22096     bool pass;
   22097 
   22098     TEST_DESCRIPTION(
   22099         "Create a buffer, allocate memory, bind memory, destroy the buffer, create an image, and bind the same memory to it");
   22100 
   22101     m_errorMonitor->ExpectSuccess();
   22102 
   22103     ASSERT_NO_FATAL_FAILURE(Init());
   22104 
   22105     VkBuffer buffer;
   22106     VkImage image;
   22107     VkDeviceMemory mem;
   22108     VkMemoryRequirements mem_reqs;
   22109 
   22110     VkBufferCreateInfo buf_info = {};
   22111     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   22112     buf_info.pNext = NULL;
   22113     buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
   22114     buf_info.size = 256;
   22115     buf_info.queueFamilyIndexCount = 0;
   22116     buf_info.pQueueFamilyIndices = NULL;
   22117     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   22118     buf_info.flags = 0;
   22119     err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
   22120     ASSERT_VK_SUCCESS(err);
   22121 
   22122     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
   22123 
   22124     VkMemoryAllocateInfo alloc_info = {};
   22125     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   22126     alloc_info.pNext = NULL;
   22127     alloc_info.memoryTypeIndex = 0;
   22128 
   22129     // Ensure memory is big enough for both bindings
   22130     alloc_info.allocationSize = 0x10000;
   22131 
   22132     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
   22133     if (!pass) {
   22134         vkDestroyBuffer(m_device->device(), buffer, NULL);
   22135         return;
   22136     }
   22137 
   22138     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
   22139     ASSERT_VK_SUCCESS(err);
   22140 
   22141     uint8_t *pData;
   22142     err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData);
   22143     ASSERT_VK_SUCCESS(err);
   22144 
   22145     memset(pData, 0xCADECADE, static_cast<size_t>(mem_reqs.size));
   22146 
   22147     vkUnmapMemory(m_device->device(), mem);
   22148 
   22149     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
   22150     ASSERT_VK_SUCCESS(err);
   22151 
   22152     // NOW, destroy the buffer. Obviously, the resource no longer occupies this
   22153     // memory. In fact, it was never used by the GPU.
   22154     // Just be be sure, wait for idle.
   22155     vkDestroyBuffer(m_device->device(), buffer, NULL);
   22156     vkDeviceWaitIdle(m_device->device());
   22157 
   22158     // Use optimal as some platforms report linear support but then fail image creation
   22159     VkImageTiling image_tiling = VK_IMAGE_TILING_OPTIMAL;
   22160     VkImageFormatProperties image_format_properties;
   22161     vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, image_tiling,
   22162                                              VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0, &image_format_properties);
   22163     if (image_format_properties.maxExtent.width == 0) {
   22164         printf("             Image format not supported; skipped.\n");
   22165         vkFreeMemory(m_device->device(), mem, NULL);
   22166         return;
   22167     }
   22168     VkImageCreateInfo image_create_info = {};
   22169     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   22170     image_create_info.pNext = NULL;
   22171     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   22172     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
   22173     image_create_info.extent.width = 64;
   22174     image_create_info.extent.height = 64;
   22175     image_create_info.extent.depth = 1;
   22176     image_create_info.mipLevels = 1;
   22177     image_create_info.arrayLayers = 1;
   22178     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   22179     image_create_info.tiling = image_tiling;
   22180     image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
   22181     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   22182     image_create_info.queueFamilyIndexCount = 0;
   22183     image_create_info.pQueueFamilyIndices = NULL;
   22184     image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   22185     image_create_info.flags = 0;
   22186 
   22187     /* Create a mappable image.  It will be the texture if linear images are ok
   22188      * to be textures or it will be the staging image if they are not.
   22189      */
   22190     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
   22191     ASSERT_VK_SUCCESS(err);
   22192 
   22193     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
   22194 
   22195     VkMemoryAllocateInfo mem_alloc = {};
   22196     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   22197     mem_alloc.pNext = NULL;
   22198     mem_alloc.allocationSize = 0;
   22199     mem_alloc.memoryTypeIndex = 0;
   22200     mem_alloc.allocationSize = mem_reqs.size;
   22201 
   22202     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
   22203     if (!pass) {
   22204         vkFreeMemory(m_device->device(), mem, NULL);
   22205         vkDestroyImage(m_device->device(), image, NULL);
   22206         return;
   22207     }
   22208 
   22209     // VALIDATION FAILURE:
   22210     err = vkBindImageMemory(m_device->device(), image, mem, 0);
   22211     ASSERT_VK_SUCCESS(err);
   22212 
   22213     m_errorMonitor->VerifyNotFound();
   22214 
   22215     vkFreeMemory(m_device->device(), mem, NULL);
   22216     vkDestroyImage(m_device->device(), image, NULL);
   22217 }
   22218 
   22219 // This is a positive test. No failures are expected.
   22220 TEST_F(VkPositiveLayerTest, TestDestroyFreeNullHandles) {
   22221     VkResult err;
   22222 
   22223     TEST_DESCRIPTION("Call all applicable destroy and free routines with NULL handles, expecting no validation errors");
   22224 
   22225     m_errorMonitor->ExpectSuccess();
   22226 
   22227     ASSERT_NO_FATAL_FAILURE(Init());
   22228     vkDestroyBuffer(m_device->device(), VK_NULL_HANDLE, NULL);
   22229     vkDestroyBufferView(m_device->device(), VK_NULL_HANDLE, NULL);
   22230     vkDestroyCommandPool(m_device->device(), VK_NULL_HANDLE, NULL);
   22231     vkDestroyDescriptorPool(m_device->device(), VK_NULL_HANDLE, NULL);
   22232     vkDestroyDescriptorSetLayout(m_device->device(), VK_NULL_HANDLE, NULL);
   22233     vkDestroyDevice(VK_NULL_HANDLE, NULL);
   22234     vkDestroyEvent(m_device->device(), VK_NULL_HANDLE, NULL);
   22235     vkDestroyFence(m_device->device(), VK_NULL_HANDLE, NULL);
   22236     vkDestroyFramebuffer(m_device->device(), VK_NULL_HANDLE, NULL);
   22237     vkDestroyImage(m_device->device(), VK_NULL_HANDLE, NULL);
   22238     vkDestroyImageView(m_device->device(), VK_NULL_HANDLE, NULL);
   22239     vkDestroyInstance(VK_NULL_HANDLE, NULL);
   22240     vkDestroyPipeline(m_device->device(), VK_NULL_HANDLE, NULL);
   22241     vkDestroyPipelineCache(m_device->device(), VK_NULL_HANDLE, NULL);
   22242     vkDestroyPipelineLayout(m_device->device(), VK_NULL_HANDLE, NULL);
   22243     vkDestroyQueryPool(m_device->device(), VK_NULL_HANDLE, NULL);
   22244     vkDestroyRenderPass(m_device->device(), VK_NULL_HANDLE, NULL);
   22245     vkDestroySampler(m_device->device(), VK_NULL_HANDLE, NULL);
   22246     vkDestroySemaphore(m_device->device(), VK_NULL_HANDLE, NULL);
   22247     vkDestroyShaderModule(m_device->device(), VK_NULL_HANDLE, NULL);
   22248 
   22249     VkCommandPool command_pool;
   22250     VkCommandPoolCreateInfo pool_create_info{};
   22251     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
   22252     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
   22253     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
   22254     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
   22255     VkCommandBuffer command_buffers[3] = {};
   22256     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
   22257     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
   22258     command_buffer_allocate_info.commandPool = command_pool;
   22259     command_buffer_allocate_info.commandBufferCount = 1;
   22260     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
   22261     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffers[1]);
   22262     vkFreeCommandBuffers(m_device->device(), command_pool, 3, command_buffers);
   22263     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
   22264 
   22265     VkDescriptorPoolSize ds_type_count = {};
   22266     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
   22267     ds_type_count.descriptorCount = 1;
   22268 
   22269     VkDescriptorPoolCreateInfo ds_pool_ci = {};
   22270     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
   22271     ds_pool_ci.pNext = NULL;
   22272     ds_pool_ci.maxSets = 1;
   22273     ds_pool_ci.poolSizeCount = 1;
   22274     ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
   22275     ds_pool_ci.pPoolSizes = &ds_type_count;
   22276 
   22277     VkDescriptorPool ds_pool;
   22278     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
   22279     ASSERT_VK_SUCCESS(err);
   22280 
   22281     VkDescriptorSetLayoutBinding dsl_binding = {};
   22282     dsl_binding.binding = 2;
   22283     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
   22284     dsl_binding.descriptorCount = 1;
   22285     dsl_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
   22286     dsl_binding.pImmutableSamplers = NULL;
   22287 
   22288     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
   22289 
   22290     VkDescriptorSet descriptor_sets[3] = {};
   22291     VkDescriptorSetAllocateInfo alloc_info = {};
   22292     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
   22293     alloc_info.descriptorSetCount = 1;
   22294     alloc_info.descriptorPool = ds_pool;
   22295     alloc_info.pSetLayouts = &ds_layout.handle();
   22296     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_sets[1]);
   22297     ASSERT_VK_SUCCESS(err);
   22298     vkFreeDescriptorSets(m_device->device(), ds_pool, 3, descriptor_sets);
   22299     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
   22300 
   22301     vkFreeMemory(m_device->device(), VK_NULL_HANDLE, NULL);
   22302 
   22303     m_errorMonitor->VerifyNotFound();
   22304 }
   22305 
   22306 TEST_F(VkPositiveLayerTest, QueueSubmitSemaphoresAndLayoutTracking) {
   22307     TEST_DESCRIPTION("Submit multiple command buffers with chained semaphore signals and layout transitions");
   22308 
   22309     m_errorMonitor->ExpectSuccess();
   22310 
   22311     ASSERT_NO_FATAL_FAILURE(Init());
   22312     VkCommandBuffer cmd_bufs[4];
   22313     VkCommandBufferAllocateInfo alloc_info;
   22314     alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
   22315     alloc_info.pNext = NULL;
   22316     alloc_info.commandBufferCount = 4;
   22317     alloc_info.commandPool = m_commandPool->handle();
   22318     alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
   22319     vkAllocateCommandBuffers(m_device->device(), &alloc_info, cmd_bufs);
   22320     VkImageObj image(m_device);
   22321     image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM,
   22322                (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT),
   22323                VK_IMAGE_TILING_OPTIMAL, 0);
   22324     ASSERT_TRUE(image.initialized());
   22325     VkCommandBufferBeginInfo cb_binfo;
   22326     cb_binfo.pNext = NULL;
   22327     cb_binfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   22328     cb_binfo.pInheritanceInfo = VK_NULL_HANDLE;
   22329     cb_binfo.flags = 0;
   22330     // Use 4 command buffers, each with an image layout transition, ColorAO->General->ColorAO->TransferSrc->TransferDst
   22331     vkBeginCommandBuffer(cmd_bufs[0], &cb_binfo);
   22332     VkImageMemoryBarrier img_barrier = {};
   22333     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
   22334     img_barrier.pNext = NULL;
   22335     img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
   22336     img_barrier.dstAccessMask = VK_ACCESS_HOST_WRITE_BIT;
   22337     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   22338     img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
   22339     img_barrier.image = image.handle();
   22340     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   22341     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   22342     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   22343     img_barrier.subresourceRange.baseArrayLayer = 0;
   22344     img_barrier.subresourceRange.baseMipLevel = 0;
   22345     img_barrier.subresourceRange.layerCount = 1;
   22346     img_barrier.subresourceRange.levelCount = 1;
   22347     vkCmdPipelineBarrier(cmd_bufs[0], VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, nullptr, 0, nullptr, 1,
   22348                          &img_barrier);
   22349     vkEndCommandBuffer(cmd_bufs[0]);
   22350     vkBeginCommandBuffer(cmd_bufs[1], &cb_binfo);
   22351     img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
   22352     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   22353     vkCmdPipelineBarrier(cmd_bufs[1], VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, nullptr, 0, nullptr, 1,
   22354                          &img_barrier);
   22355     vkEndCommandBuffer(cmd_bufs[1]);
   22356     vkBeginCommandBuffer(cmd_bufs[2], &cb_binfo);
   22357     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   22358     img_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   22359     vkCmdPipelineBarrier(cmd_bufs[2], VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, nullptr, 0, nullptr, 1,
   22360                          &img_barrier);
   22361     vkEndCommandBuffer(cmd_bufs[2]);
   22362     vkBeginCommandBuffer(cmd_bufs[3], &cb_binfo);
   22363     img_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   22364     img_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   22365     vkCmdPipelineBarrier(cmd_bufs[3], VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, nullptr, 0, nullptr, 1,
   22366                          &img_barrier);
   22367     vkEndCommandBuffer(cmd_bufs[3]);
   22368 
   22369     // Submit 4 command buffers in 3 submits, with submits 2 and 3 waiting for semaphores from submits 1 and 2
   22370     VkSemaphore semaphore1, semaphore2;
   22371     VkSemaphoreCreateInfo semaphore_create_info{};
   22372     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
   22373     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore1);
   22374     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore2);
   22375     VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
   22376     VkSubmitInfo submit_info[3];
   22377     submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   22378     submit_info[0].pNext = nullptr;
   22379     submit_info[0].commandBufferCount = 1;
   22380     submit_info[0].pCommandBuffers = &cmd_bufs[0];
   22381     submit_info[0].signalSemaphoreCount = 1;
   22382     submit_info[0].pSignalSemaphores = &semaphore1;
   22383     submit_info[0].waitSemaphoreCount = 0;
   22384     submit_info[0].pWaitDstStageMask = nullptr;
   22385     submit_info[0].pWaitDstStageMask = flags;
   22386     submit_info[1].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   22387     submit_info[1].pNext = nullptr;
   22388     submit_info[1].commandBufferCount = 1;
   22389     submit_info[1].pCommandBuffers = &cmd_bufs[1];
   22390     submit_info[1].waitSemaphoreCount = 1;
   22391     submit_info[1].pWaitSemaphores = &semaphore1;
   22392     submit_info[1].signalSemaphoreCount = 1;
   22393     submit_info[1].pSignalSemaphores = &semaphore2;
   22394     submit_info[1].pWaitDstStageMask = flags;
   22395     submit_info[2].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   22396     submit_info[2].pNext = nullptr;
   22397     submit_info[2].commandBufferCount = 2;
   22398     submit_info[2].pCommandBuffers = &cmd_bufs[2];
   22399     submit_info[2].waitSemaphoreCount = 1;
   22400     submit_info[2].pWaitSemaphores = &semaphore2;
   22401     submit_info[2].signalSemaphoreCount = 0;
   22402     submit_info[2].pSignalSemaphores = nullptr;
   22403     submit_info[2].pWaitDstStageMask = flags;
   22404     vkQueueSubmit(m_device->m_queue, 3, submit_info, VK_NULL_HANDLE);
   22405     vkQueueWaitIdle(m_device->m_queue);
   22406 
   22407     vkDestroySemaphore(m_device->device(), semaphore1, NULL);
   22408     vkDestroySemaphore(m_device->device(), semaphore2, NULL);
   22409     m_errorMonitor->VerifyNotFound();
   22410 }
   22411 
   22412 TEST_F(VkPositiveLayerTest, DynamicOffsetWithInactiveBinding) {
   22413     // Create a descriptorSet w/ dynamic descriptors where 1 binding is inactive
   22414     // We previously had a bug where dynamic offset of inactive bindings was still being used
   22415     VkResult err;
   22416     m_errorMonitor->ExpectSuccess();
   22417 
   22418     ASSERT_NO_FATAL_FAILURE(Init());
   22419     ASSERT_NO_FATAL_FAILURE(InitViewport());
   22420     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   22421 
   22422     OneOffDescriptorSet ds(m_device, {
   22423                                          {2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
   22424                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
   22425                                          {1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
   22426                                      });
   22427 
   22428     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
   22429 
   22430     // Create two buffers to update the descriptors with
   22431     // The first will be 2k and used for bindings 0 & 1, the second is 1k for binding 2
   22432     uint32_t qfi = 0;
   22433     VkBufferCreateInfo buffCI = {};
   22434     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   22435     buffCI.size = 2048;
   22436     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
   22437     buffCI.queueFamilyIndexCount = 1;
   22438     buffCI.pQueueFamilyIndices = &qfi;
   22439 
   22440     VkBuffer dyub1;
   22441     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub1);
   22442     ASSERT_VK_SUCCESS(err);
   22443     // buffer2
   22444     buffCI.size = 1024;
   22445     VkBuffer dyub2;
   22446     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub2);
   22447     ASSERT_VK_SUCCESS(err);
   22448     // Allocate memory and bind to buffers
   22449     VkMemoryAllocateInfo mem_alloc[2] = {};
   22450     mem_alloc[0].sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   22451     mem_alloc[0].pNext = NULL;
   22452     mem_alloc[0].memoryTypeIndex = 0;
   22453     mem_alloc[1].sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   22454     mem_alloc[1].pNext = NULL;
   22455     mem_alloc[1].memoryTypeIndex = 0;
   22456 
   22457     VkMemoryRequirements mem_reqs1;
   22458     vkGetBufferMemoryRequirements(m_device->device(), dyub1, &mem_reqs1);
   22459     VkMemoryRequirements mem_reqs2;
   22460     vkGetBufferMemoryRequirements(m_device->device(), dyub2, &mem_reqs2);
   22461     mem_alloc[0].allocationSize = mem_reqs1.size;
   22462     bool pass = m_device->phy().set_memory_type(mem_reqs1.memoryTypeBits, &mem_alloc[0], 0);
   22463     mem_alloc[1].allocationSize = mem_reqs2.size;
   22464     pass &= m_device->phy().set_memory_type(mem_reqs2.memoryTypeBits, &mem_alloc[1], 0);
   22465     if (!pass) {
   22466         vkDestroyBuffer(m_device->device(), dyub1, NULL);
   22467         vkDestroyBuffer(m_device->device(), dyub2, NULL);
   22468         return;
   22469     }
   22470 
   22471     VkDeviceMemory mem1;
   22472     err = vkAllocateMemory(m_device->device(), &mem_alloc[0], NULL, &mem1);
   22473     ASSERT_VK_SUCCESS(err);
   22474     err = vkBindBufferMemory(m_device->device(), dyub1, mem1, 0);
   22475     ASSERT_VK_SUCCESS(err);
   22476     VkDeviceMemory mem2;
   22477     err = vkAllocateMemory(m_device->device(), &mem_alloc[1], NULL, &mem2);
   22478     ASSERT_VK_SUCCESS(err);
   22479     err = vkBindBufferMemory(m_device->device(), dyub2, mem2, 0);
   22480     ASSERT_VK_SUCCESS(err);
   22481     // Update descriptors
   22482     const uint32_t BINDING_COUNT = 3;
   22483     VkDescriptorBufferInfo buff_info[BINDING_COUNT] = {};
   22484     buff_info[0].buffer = dyub1;
   22485     buff_info[0].offset = 0;
   22486     buff_info[0].range = 256;
   22487     buff_info[1].buffer = dyub1;
   22488     buff_info[1].offset = 256;
   22489     buff_info[1].range = 512;
   22490     buff_info[2].buffer = dyub2;
   22491     buff_info[2].offset = 0;
   22492     buff_info[2].range = 512;
   22493 
   22494     VkWriteDescriptorSet descriptor_write;
   22495     memset(&descriptor_write, 0, sizeof(descriptor_write));
   22496     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
   22497     descriptor_write.dstSet = ds.set_;
   22498     descriptor_write.dstBinding = 0;
   22499     descriptor_write.descriptorCount = BINDING_COUNT;
   22500     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
   22501     descriptor_write.pBufferInfo = buff_info;
   22502 
   22503     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
   22504 
   22505     m_commandBuffer->begin();
   22506     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
   22507 
   22508     // Create PSO to be used for draw-time errors below
   22509     char const *vsSource =
   22510         "#version 450\n"
   22511         "\n"
   22512         "void main(){\n"
   22513         "   gl_Position = vec4(1);\n"
   22514         "}\n";
   22515     char const *fsSource =
   22516         "#version 450\n"
   22517         "\n"
   22518         "layout(location=0) out vec4 x;\n"
   22519         "layout(set=0) layout(binding=0) uniform foo1 { int x; int y; } bar1;\n"
   22520         "layout(set=0) layout(binding=2) uniform foo2 { int x; int y; } bar2;\n"
   22521         "void main(){\n"
   22522         "   x = vec4(bar1.y) + vec4(bar2.y);\n"
   22523         "}\n";
   22524     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   22525     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   22526     VkPipelineObj pipe(m_device);
   22527     pipe.SetViewport(m_viewports);
   22528     pipe.SetScissor(m_scissors);
   22529     pipe.AddShader(&vs);
   22530     pipe.AddShader(&fs);
   22531     pipe.AddDefaultColorAttachment();
   22532     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
   22533 
   22534     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
   22535     // This update should succeed, but offset of inactive binding 1 oversteps binding 2 buffer size
   22536     //   we used to have a bug in this case.
   22537     uint32_t dyn_off[BINDING_COUNT] = {0, 1024, 256};
   22538     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &ds.set_,
   22539                             BINDING_COUNT, dyn_off);
   22540     m_commandBuffer->Draw(1, 0, 0, 0);
   22541     m_errorMonitor->VerifyNotFound();
   22542 
   22543     vkDestroyBuffer(m_device->device(), dyub1, NULL);
   22544     vkDestroyBuffer(m_device->device(), dyub2, NULL);
   22545     vkFreeMemory(m_device->device(), mem1, NULL);
   22546     vkFreeMemory(m_device->device(), mem2, NULL);
   22547 }
   22548 
   22549 TEST_F(VkPositiveLayerTest, NonCoherentMemoryMapping) {
   22550     TEST_DESCRIPTION(
   22551         "Ensure that validations handling of non-coherent memory mapping while using VK_WHOLE_SIZE does not cause access "
   22552         "violations");
   22553     VkResult err;
   22554     uint8_t *pData;
   22555     ASSERT_NO_FATAL_FAILURE(Init());
   22556 
   22557     VkDeviceMemory mem;
   22558     VkMemoryRequirements mem_reqs;
   22559     mem_reqs.memoryTypeBits = 0xFFFFFFFF;
   22560     const VkDeviceSize atom_size = m_device->props.limits.nonCoherentAtomSize;
   22561     VkMemoryAllocateInfo alloc_info = {};
   22562     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   22563     alloc_info.pNext = NULL;
   22564     alloc_info.memoryTypeIndex = 0;
   22565 
   22566     static const VkDeviceSize allocation_size = 32 * atom_size;
   22567     alloc_info.allocationSize = allocation_size;
   22568 
   22569     // Find a memory configurations WITHOUT a COHERENT bit, otherwise exit
   22570     bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
   22571                                                 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
   22572     if (!pass) {
   22573         pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info,
   22574                                                VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
   22575                                                VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
   22576         if (!pass) {
   22577             pass = m_device->phy().set_memory_type(
   22578                 mem_reqs.memoryTypeBits, &alloc_info,
   22579                 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
   22580                 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
   22581             if (!pass) {
   22582                 return;
   22583             }
   22584         }
   22585     }
   22586 
   22587     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
   22588     ASSERT_VK_SUCCESS(err);
   22589 
   22590     // Map/Flush/Invalidate using WHOLE_SIZE and zero offsets and entire mapped range
   22591     m_errorMonitor->ExpectSuccess();
   22592     err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, (void **)&pData);
   22593     ASSERT_VK_SUCCESS(err);
   22594     VkMappedMemoryRange mmr = {};
   22595     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
   22596     mmr.memory = mem;
   22597     mmr.offset = 0;
   22598     mmr.size = VK_WHOLE_SIZE;
   22599     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
   22600     ASSERT_VK_SUCCESS(err);
   22601     err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr);
   22602     ASSERT_VK_SUCCESS(err);
   22603     m_errorMonitor->VerifyNotFound();
   22604     vkUnmapMemory(m_device->device(), mem);
   22605 
   22606     // Map/Flush/Invalidate using WHOLE_SIZE and an offset and entire mapped range
   22607     m_errorMonitor->ExpectSuccess();
   22608     err = vkMapMemory(m_device->device(), mem, 5 * atom_size, VK_WHOLE_SIZE, 0, (void **)&pData);
   22609     ASSERT_VK_SUCCESS(err);
   22610     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
   22611     mmr.memory = mem;
   22612     mmr.offset = 6 * atom_size;
   22613     mmr.size = VK_WHOLE_SIZE;
   22614     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
   22615     ASSERT_VK_SUCCESS(err);
   22616     err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr);
   22617     ASSERT_VK_SUCCESS(err);
   22618     m_errorMonitor->VerifyNotFound();
   22619     vkUnmapMemory(m_device->device(), mem);
   22620 
   22621     // Map with offset and size
   22622     // Flush/Invalidate subrange of mapped area with offset and size
   22623     m_errorMonitor->ExpectSuccess();
   22624     err = vkMapMemory(m_device->device(), mem, 3 * atom_size, 9 * atom_size, 0, (void **)&pData);
   22625     ASSERT_VK_SUCCESS(err);
   22626     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
   22627     mmr.memory = mem;
   22628     mmr.offset = 4 * atom_size;
   22629     mmr.size = 2 * atom_size;
   22630     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
   22631     ASSERT_VK_SUCCESS(err);
   22632     err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr);
   22633     ASSERT_VK_SUCCESS(err);
   22634     m_errorMonitor->VerifyNotFound();
   22635     vkUnmapMemory(m_device->device(), mem);
   22636 
   22637     // Map without offset and flush WHOLE_SIZE with two separate offsets
   22638     m_errorMonitor->ExpectSuccess();
   22639     err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, (void **)&pData);
   22640     ASSERT_VK_SUCCESS(err);
   22641     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
   22642     mmr.memory = mem;
   22643     mmr.offset = allocation_size - (4 * atom_size);
   22644     mmr.size = VK_WHOLE_SIZE;
   22645     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
   22646     ASSERT_VK_SUCCESS(err);
   22647     mmr.offset = allocation_size - (6 * atom_size);
   22648     mmr.size = VK_WHOLE_SIZE;
   22649     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
   22650     ASSERT_VK_SUCCESS(err);
   22651     m_errorMonitor->VerifyNotFound();
   22652     vkUnmapMemory(m_device->device(), mem);
   22653 
   22654     vkFreeMemory(m_device->device(), mem, NULL);
   22655 }
   22656 
   22657 // This is a positive test. We used to expect error in this case but spec now allows it
   22658 TEST_F(VkPositiveLayerTest, ResetUnsignaledFence) {
   22659     m_errorMonitor->ExpectSuccess();
   22660     vk_testing::Fence testFence;
   22661     VkFenceCreateInfo fenceInfo = {};
   22662     fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
   22663     fenceInfo.pNext = NULL;
   22664 
   22665     ASSERT_NO_FATAL_FAILURE(Init());
   22666     testFence.init(*m_device, fenceInfo);
   22667     VkFence fences[1] = {testFence.handle()};
   22668     VkResult result = vkResetFences(m_device->device(), 1, fences);
   22669     ASSERT_VK_SUCCESS(result);
   22670 
   22671     m_errorMonitor->VerifyNotFound();
   22672 }
   22673 
   22674 TEST_F(VkPositiveLayerTest, CommandBufferSimultaneousUseSync) {
   22675     m_errorMonitor->ExpectSuccess();
   22676 
   22677     ASSERT_NO_FATAL_FAILURE(Init());
   22678     VkResult err;
   22679 
   22680     // Record (empty!) command buffer that can be submitted multiple times
   22681     // simultaneously.
   22682     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
   22683                                      VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, nullptr};
   22684     m_commandBuffer->begin(&cbbi);
   22685     m_commandBuffer->end();
   22686 
   22687     VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
   22688     VkFence fence;
   22689     err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
   22690     ASSERT_VK_SUCCESS(err);
   22691 
   22692     VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
   22693     VkSemaphore s1, s2;
   22694     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s1);
   22695     ASSERT_VK_SUCCESS(err);
   22696     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s2);
   22697     ASSERT_VK_SUCCESS(err);
   22698 
   22699     // Submit CB once signaling s1, with fence so we can roll forward to its retirement.
   22700     VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &m_commandBuffer->handle(), 1, &s1};
   22701     err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
   22702     ASSERT_VK_SUCCESS(err);
   22703 
   22704     // Submit CB again, signaling s2.
   22705     si.pSignalSemaphores = &s2;
   22706     err = vkQueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE);
   22707     ASSERT_VK_SUCCESS(err);
   22708 
   22709     // Wait for fence.
   22710     err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
   22711     ASSERT_VK_SUCCESS(err);
   22712 
   22713     // CB is still in flight from second submission, but semaphore s1 is no
   22714     // longer in flight. delete it.
   22715     vkDestroySemaphore(m_device->device(), s1, nullptr);
   22716 
   22717     m_errorMonitor->VerifyNotFound();
   22718 
   22719     // Force device idle and clean up remaining objects
   22720     vkDeviceWaitIdle(m_device->device());
   22721     vkDestroySemaphore(m_device->device(), s2, nullptr);
   22722     vkDestroyFence(m_device->device(), fence, nullptr);
   22723 }
   22724 
   22725 TEST_F(VkPositiveLayerTest, FenceCreateSignaledWaitHandling) {
   22726     m_errorMonitor->ExpectSuccess();
   22727 
   22728     ASSERT_NO_FATAL_FAILURE(Init());
   22729     VkResult err;
   22730 
   22731     // A fence created signaled
   22732     VkFenceCreateInfo fci1 = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, VK_FENCE_CREATE_SIGNALED_BIT};
   22733     VkFence f1;
   22734     err = vkCreateFence(m_device->device(), &fci1, nullptr, &f1);
   22735     ASSERT_VK_SUCCESS(err);
   22736 
   22737     // A fence created not
   22738     VkFenceCreateInfo fci2 = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
   22739     VkFence f2;
   22740     err = vkCreateFence(m_device->device(), &fci2, nullptr, &f2);
   22741     ASSERT_VK_SUCCESS(err);
   22742 
   22743     // Submit the unsignaled fence
   22744     VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 0, nullptr, 0, nullptr};
   22745     err = vkQueueSubmit(m_device->m_queue, 1, &si, f2);
   22746 
   22747     // Wait on both fences, with signaled first.
   22748     VkFence fences[] = {f1, f2};
   22749     vkWaitForFences(m_device->device(), 2, fences, VK_TRUE, UINT64_MAX);
   22750 
   22751     // Should have both retired!
   22752     vkDestroyFence(m_device->device(), f1, nullptr);
   22753     vkDestroyFence(m_device->device(), f2, nullptr);
   22754 
   22755     m_errorMonitor->VerifyNotFound();
   22756 }
   22757 
   22758 TEST_F(VkPositiveLayerTest, CreateImageViewFollowsParameterCompatibilityRequirements) {
   22759     TEST_DESCRIPTION("Verify that creating an ImageView with valid usage does not generate validation errors.");
   22760 
   22761     ASSERT_NO_FATAL_FAILURE(Init());
   22762 
   22763     m_errorMonitor->ExpectSuccess();
   22764 
   22765     VkImageCreateInfo imgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
   22766                                  nullptr,
   22767                                  VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
   22768                                  VK_IMAGE_TYPE_2D,
   22769                                  VK_FORMAT_R8G8B8A8_UNORM,
   22770                                  {128, 128, 1},
   22771                                  1,
   22772                                  1,
   22773                                  VK_SAMPLE_COUNT_1_BIT,
   22774                                  VK_IMAGE_TILING_OPTIMAL,
   22775                                  VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
   22776                                  VK_SHARING_MODE_EXCLUSIVE,
   22777                                  0,
   22778                                  nullptr,
   22779                                  VK_IMAGE_LAYOUT_UNDEFINED};
   22780     VkImageObj image(m_device);
   22781     image.init(&imgInfo);
   22782     ASSERT_TRUE(image.initialized());
   22783     VkImageView imageView;
   22784     VkImageViewCreateInfo ivci = {};
   22785     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   22786     ivci.image = image.handle();
   22787     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
   22788     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
   22789     ivci.subresourceRange.layerCount = 1;
   22790     ivci.subresourceRange.baseMipLevel = 0;
   22791     ivci.subresourceRange.levelCount = 1;
   22792     ivci.subresourceRange.baseArrayLayer = 0;
   22793     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   22794 
   22795     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
   22796     m_errorMonitor->VerifyNotFound();
   22797     vkDestroyImageView(m_device->device(), imageView, NULL);
   22798 }
   22799 
   22800 TEST_F(VkPositiveLayerTest, ValidUsage) {
   22801     TEST_DESCRIPTION("Verify that creating an image view from an image with valid usage doesn't generate validation errors");
   22802 
   22803     ASSERT_NO_FATAL_FAILURE(Init());
   22804 
   22805     m_errorMonitor->ExpectSuccess();
   22806     // Verify that we can create a view with usage INPUT_ATTACHMENT
   22807     VkImageObj image(m_device);
   22808     image.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   22809     ASSERT_TRUE(image.initialized());
   22810     VkImageView imageView;
   22811     VkImageViewCreateInfo ivci = {};
   22812     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
   22813     ivci.image = image.handle();
   22814     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
   22815     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
   22816     ivci.subresourceRange.layerCount = 1;
   22817     ivci.subresourceRange.baseMipLevel = 0;
   22818     ivci.subresourceRange.levelCount = 1;
   22819     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   22820 
   22821     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
   22822     m_errorMonitor->VerifyNotFound();
   22823     vkDestroyImageView(m_device->device(), imageView, NULL);
   22824 }
   22825 
   22826 // This is a positive test. No failures are expected.
   22827 TEST_F(VkPositiveLayerTest, BindSparse) {
   22828     TEST_DESCRIPTION("Bind 2 memory ranges to one image using vkQueueBindSparse, destroy the image and then free the memory");
   22829 
   22830     ASSERT_NO_FATAL_FAILURE(Init());
   22831 
   22832     auto index = m_device->graphics_queue_node_index_;
   22833     if (!(m_device->queue_props[index].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT)) return;
   22834     if (!m_device->phy().features().sparseBinding) return;
   22835 
   22836     m_errorMonitor->ExpectSuccess();
   22837 
   22838     VkImage image;
   22839     VkImageCreateInfo image_create_info = {};
   22840     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
   22841     image_create_info.pNext = NULL;
   22842     image_create_info.imageType = VK_IMAGE_TYPE_2D;
   22843     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
   22844     image_create_info.extent.width = 64;
   22845     image_create_info.extent.height = 64;
   22846     image_create_info.extent.depth = 1;
   22847     image_create_info.mipLevels = 1;
   22848     image_create_info.arrayLayers = 1;
   22849     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
   22850     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
   22851     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   22852     image_create_info.flags = VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
   22853     VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
   22854     ASSERT_VK_SUCCESS(err);
   22855 
   22856     VkMemoryRequirements memory_reqs;
   22857     VkDeviceMemory memory_one, memory_two;
   22858     bool pass;
   22859     VkMemoryAllocateInfo memory_info = {};
   22860     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   22861     memory_info.pNext = NULL;
   22862     memory_info.allocationSize = 0;
   22863     memory_info.memoryTypeIndex = 0;
   22864     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
   22865     // Find an image big enough to allow sparse mapping of 2 memory regions
   22866     // Increase the image size until it is at least twice the
   22867     // size of the required alignment, to ensure we can bind both
   22868     // allocated memory blocks to the image on aligned offsets.
   22869     while (memory_reqs.size < (memory_reqs.alignment * 2)) {
   22870         vkDestroyImage(m_device->device(), image, nullptr);
   22871         image_create_info.extent.width *= 2;
   22872         image_create_info.extent.height *= 2;
   22873         err = vkCreateImage(m_device->device(), &image_create_info, nullptr, &image);
   22874         ASSERT_VK_SUCCESS(err);
   22875         vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
   22876     }
   22877     // Allocate 2 memory regions of minimum alignment size, bind one at 0, the other
   22878     // at the end of the first
   22879     memory_info.allocationSize = memory_reqs.alignment;
   22880     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
   22881     ASSERT_TRUE(pass);
   22882     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &memory_one);
   22883     ASSERT_VK_SUCCESS(err);
   22884     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &memory_two);
   22885     ASSERT_VK_SUCCESS(err);
   22886     VkSparseMemoryBind binds[2];
   22887     binds[0].flags = 0;
   22888     binds[0].memory = memory_one;
   22889     binds[0].memoryOffset = 0;
   22890     binds[0].resourceOffset = 0;
   22891     binds[0].size = memory_info.allocationSize;
   22892     binds[1].flags = 0;
   22893     binds[1].memory = memory_two;
   22894     binds[1].memoryOffset = 0;
   22895     binds[1].resourceOffset = memory_info.allocationSize;
   22896     binds[1].size = memory_info.allocationSize;
   22897 
   22898     VkSparseImageOpaqueMemoryBindInfo opaqueBindInfo;
   22899     opaqueBindInfo.image = image;
   22900     opaqueBindInfo.bindCount = 2;
   22901     opaqueBindInfo.pBinds = binds;
   22902 
   22903     VkFence fence = VK_NULL_HANDLE;
   22904     VkBindSparseInfo bindSparseInfo = {};
   22905     bindSparseInfo.sType = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO;
   22906     bindSparseInfo.imageOpaqueBindCount = 1;
   22907     bindSparseInfo.pImageOpaqueBinds = &opaqueBindInfo;
   22908 
   22909     vkQueueBindSparse(m_device->m_queue, 1, &bindSparseInfo, fence);
   22910     vkQueueWaitIdle(m_device->m_queue);
   22911     vkDestroyImage(m_device->device(), image, NULL);
   22912     vkFreeMemory(m_device->device(), memory_one, NULL);
   22913     vkFreeMemory(m_device->device(), memory_two, NULL);
   22914     m_errorMonitor->VerifyNotFound();
   22915 }
   22916 
   22917 TEST_F(VkPositiveLayerTest, RenderPassInitialLayoutUndefined) {
   22918     TEST_DESCRIPTION(
   22919         "Ensure that CmdBeginRenderPass with an attachment's initialLayout of VK_IMAGE_LAYOUT_UNDEFINED works when the command "
   22920         "buffer has prior knowledge of that attachment's layout.");
   22921 
   22922     m_errorMonitor->ExpectSuccess();
   22923 
   22924     ASSERT_NO_FATAL_FAILURE(Init());
   22925 
   22926     // A renderpass with one color attachment.
   22927     VkAttachmentDescription attachment = {0,
   22928                                           VK_FORMAT_R8G8B8A8_UNORM,
   22929                                           VK_SAMPLE_COUNT_1_BIT,
   22930                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   22931                                           VK_ATTACHMENT_STORE_OP_STORE,
   22932                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   22933                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
   22934                                           VK_IMAGE_LAYOUT_UNDEFINED,
   22935                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
   22936 
   22937     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
   22938 
   22939     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
   22940 
   22941     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
   22942 
   22943     VkRenderPass rp;
   22944     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   22945     ASSERT_VK_SUCCESS(err);
   22946 
   22947     // A compatible framebuffer.
   22948     VkImageObj image(m_device);
   22949     image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   22950     ASSERT_TRUE(image.initialized());
   22951 
   22952     VkImageViewCreateInfo ivci = {
   22953         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
   22954         nullptr,
   22955         0,
   22956         image.handle(),
   22957         VK_IMAGE_VIEW_TYPE_2D,
   22958         VK_FORMAT_R8G8B8A8_UNORM,
   22959         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
   22960          VK_COMPONENT_SWIZZLE_IDENTITY},
   22961         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
   22962     };
   22963     VkImageView view;
   22964     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
   22965     ASSERT_VK_SUCCESS(err);
   22966 
   22967     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
   22968     VkFramebuffer fb;
   22969     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
   22970     ASSERT_VK_SUCCESS(err);
   22971 
   22972     // Record a single command buffer which uses this renderpass twice. The
   22973     // bug is triggered at the beginning of the second renderpass, when the
   22974     // command buffer already has a layout recorded for the attachment.
   22975     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
   22976     m_commandBuffer->begin();
   22977     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
   22978     vkCmdEndRenderPass(m_commandBuffer->handle());
   22979     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
   22980 
   22981     m_errorMonitor->VerifyNotFound();
   22982 
   22983     vkCmdEndRenderPass(m_commandBuffer->handle());
   22984     m_commandBuffer->end();
   22985 
   22986     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
   22987     vkDestroyRenderPass(m_device->device(), rp, nullptr);
   22988     vkDestroyImageView(m_device->device(), view, nullptr);
   22989 }
   22990 
   22991 TEST_F(VkPositiveLayerTest, FramebufferBindingDestroyCommandPool) {
   22992     TEST_DESCRIPTION(
   22993         "This test should pass. Create a Framebuffer and command buffer, bind them together, then destroy command pool and "
   22994         "framebuffer and verify there are no errors.");
   22995 
   22996     m_errorMonitor->ExpectSuccess();
   22997 
   22998     ASSERT_NO_FATAL_FAILURE(Init());
   22999 
   23000     // A renderpass with one color attachment.
   23001     VkAttachmentDescription attachment = {0,
   23002                                           VK_FORMAT_R8G8B8A8_UNORM,
   23003                                           VK_SAMPLE_COUNT_1_BIT,
   23004                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   23005                                           VK_ATTACHMENT_STORE_OP_STORE,
   23006                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   23007                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
   23008                                           VK_IMAGE_LAYOUT_UNDEFINED,
   23009                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
   23010 
   23011     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
   23012 
   23013     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
   23014 
   23015     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
   23016 
   23017     VkRenderPass rp;
   23018     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   23019     ASSERT_VK_SUCCESS(err);
   23020 
   23021     // A compatible framebuffer.
   23022     VkImageObj image(m_device);
   23023     image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   23024     ASSERT_TRUE(image.initialized());
   23025 
   23026     VkImageView view = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
   23027 
   23028     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
   23029     VkFramebuffer fb;
   23030     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
   23031     ASSERT_VK_SUCCESS(err);
   23032 
   23033     // Explicitly create a command buffer to bind the FB to so that we can then
   23034     //  destroy the command pool in order to implicitly free command buffer
   23035     VkCommandPool command_pool;
   23036     VkCommandPoolCreateInfo pool_create_info{};
   23037     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
   23038     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
   23039     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
   23040     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
   23041 
   23042     VkCommandBuffer command_buffer;
   23043     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
   23044     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
   23045     command_buffer_allocate_info.commandPool = command_pool;
   23046     command_buffer_allocate_info.commandBufferCount = 1;
   23047     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
   23048     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
   23049 
   23050     // Begin our cmd buffer with renderpass using our framebuffer
   23051     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
   23052     VkCommandBufferBeginInfo begin_info{};
   23053     begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   23054     vkBeginCommandBuffer(command_buffer, &begin_info);
   23055 
   23056     vkCmdBeginRenderPass(command_buffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
   23057     vkCmdEndRenderPass(command_buffer);
   23058     vkEndCommandBuffer(command_buffer);
   23059     // Destroy command pool to implicitly free command buffer
   23060     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
   23061     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
   23062     vkDestroyRenderPass(m_device->device(), rp, nullptr);
   23063     m_errorMonitor->VerifyNotFound();
   23064 }
   23065 
   23066 TEST_F(VkPositiveLayerTest, RenderPassSubpassZeroTransitionsApplied) {
   23067     TEST_DESCRIPTION("Ensure that CmdBeginRenderPass applies the layout transitions for the first subpass");
   23068 
   23069     m_errorMonitor->ExpectSuccess();
   23070 
   23071     ASSERT_NO_FATAL_FAILURE(Init());
   23072 
   23073     // A renderpass with one color attachment.
   23074     VkAttachmentDescription attachment = {0,
   23075                                           VK_FORMAT_R8G8B8A8_UNORM,
   23076                                           VK_SAMPLE_COUNT_1_BIT,
   23077                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   23078                                           VK_ATTACHMENT_STORE_OP_STORE,
   23079                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   23080                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
   23081                                           VK_IMAGE_LAYOUT_UNDEFINED,
   23082                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
   23083 
   23084     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
   23085 
   23086     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
   23087 
   23088     VkSubpassDependency dep = {0,
   23089                                0,
   23090                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   23091                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   23092                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   23093                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   23094                                VK_DEPENDENCY_BY_REGION_BIT};
   23095 
   23096     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep};
   23097 
   23098     VkResult err;
   23099     VkRenderPass rp;
   23100     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   23101     ASSERT_VK_SUCCESS(err);
   23102 
   23103     // A compatible framebuffer.
   23104     VkImageObj image(m_device);
   23105     image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   23106     ASSERT_TRUE(image.initialized());
   23107 
   23108     VkImageView view = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
   23109 
   23110     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
   23111     VkFramebuffer fb;
   23112     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
   23113     ASSERT_VK_SUCCESS(err);
   23114 
   23115     // Record a single command buffer which issues a pipeline barrier w/
   23116     // image memory barrier for the attachment. This detects the previously
   23117     // missing tracking of the subpass layout by throwing a validation error
   23118     // if it doesn't occur.
   23119     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
   23120     m_commandBuffer->begin();
   23121     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
   23122 
   23123     VkImageMemoryBarrier imb = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
   23124                                 nullptr,
   23125                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   23126                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   23127                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   23128                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   23129                                 VK_QUEUE_FAMILY_IGNORED,
   23130                                 VK_QUEUE_FAMILY_IGNORED,
   23131                                 image.handle(),
   23132                                 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};
   23133     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   23134                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
   23135                          &imb);
   23136 
   23137     vkCmdEndRenderPass(m_commandBuffer->handle());
   23138     m_errorMonitor->VerifyNotFound();
   23139     m_commandBuffer->end();
   23140 
   23141     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
   23142     vkDestroyRenderPass(m_device->device(), rp, nullptr);
   23143 }
   23144 
   23145 TEST_F(VkPositiveLayerTest, DepthStencilLayoutTransitionForDepthOnlyImageview) {
   23146     TEST_DESCRIPTION(
   23147         "Validate that when an imageView of a depth/stencil image is used as a depth/stencil framebuffer attachment, the "
   23148         "aspectMask is ignored and both depth and stencil image subresources are used.");
   23149 
   23150     ASSERT_NO_FATAL_FAILURE(Init());
   23151     VkFormatProperties format_properties;
   23152     vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_D32_SFLOAT_S8_UINT, &format_properties);
   23153     if (!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
   23154         return;
   23155     }
   23156 
   23157     m_errorMonitor->ExpectSuccess();
   23158 
   23159     VkAttachmentDescription attachment = {0,
   23160                                           VK_FORMAT_D32_SFLOAT_S8_UINT,
   23161                                           VK_SAMPLE_COUNT_1_BIT,
   23162                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   23163                                           VK_ATTACHMENT_STORE_OP_STORE,
   23164                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   23165                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
   23166                                           VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
   23167                                           VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
   23168 
   23169     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
   23170 
   23171     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &att_ref, 0, nullptr};
   23172 
   23173     VkSubpassDependency dep = {0,
   23174                                0,
   23175                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   23176                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
   23177                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   23178                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
   23179                                VK_DEPENDENCY_BY_REGION_BIT};
   23180 
   23181     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep};
   23182 
   23183     VkResult err;
   23184     VkRenderPass rp;
   23185     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   23186     ASSERT_VK_SUCCESS(err);
   23187 
   23188     VkImageObj image(m_device);
   23189     image.InitNoLayout(32, 32, 1, VK_FORMAT_D32_SFLOAT_S8_UINT,
   23190                        0x26,  // usage
   23191                        VK_IMAGE_TILING_OPTIMAL, 0);
   23192     ASSERT_TRUE(image.initialized());
   23193     image.SetLayout(0x6, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
   23194 
   23195     VkImageViewCreateInfo ivci = {
   23196         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
   23197         nullptr,
   23198         0,
   23199         image.handle(),
   23200         VK_IMAGE_VIEW_TYPE_2D,
   23201         VK_FORMAT_D32_SFLOAT_S8_UINT,
   23202         {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
   23203         {0x2, 0, 1, 0, 1},
   23204     };
   23205     VkImageView view;
   23206     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
   23207     ASSERT_VK_SUCCESS(err);
   23208 
   23209     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
   23210     VkFramebuffer fb;
   23211     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
   23212     ASSERT_VK_SUCCESS(err);
   23213 
   23214     m_commandBuffer->begin();
   23215 
   23216     VkImageMemoryBarrier imb = {};
   23217     imb.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
   23218     imb.pNext = nullptr;
   23219     imb.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
   23220     imb.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
   23221     imb.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
   23222     imb.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
   23223     imb.srcQueueFamilyIndex = 0;
   23224     imb.dstQueueFamilyIndex = 0;
   23225     imb.image = image.handle();
   23226     imb.subresourceRange.aspectMask = 0x6;
   23227     imb.subresourceRange.baseMipLevel = 0;
   23228     imb.subresourceRange.levelCount = 0x1;
   23229     imb.subresourceRange.baseArrayLayer = 0;
   23230     imb.subresourceRange.layerCount = 0x1;
   23231 
   23232     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
   23233                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &imb);
   23234 
   23235     m_commandBuffer->end();
   23236     m_commandBuffer->QueueCommandBuffer(false);
   23237     m_errorMonitor->VerifyNotFound();
   23238 
   23239     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
   23240     vkDestroyRenderPass(m_device->device(), rp, nullptr);
   23241     vkDestroyImageView(m_device->device(), view, nullptr);
   23242 }
   23243 
   23244 TEST_F(VkPositiveLayerTest, RenderPassTransitionsAttachmentUnused) {
   23245     TEST_DESCRIPTION(
   23246         "Ensure that layout transitions work correctly without errors, when an attachment reference is VK_ATTACHMENT_UNUSED");
   23247 
   23248     m_errorMonitor->ExpectSuccess();
   23249 
   23250     ASSERT_NO_FATAL_FAILURE(Init());
   23251 
   23252     // A renderpass with no attachments
   23253     VkAttachmentReference att_ref = {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
   23254 
   23255     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
   23256 
   23257     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, &subpass, 0, nullptr};
   23258 
   23259     VkRenderPass rp;
   23260     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   23261     ASSERT_VK_SUCCESS(err);
   23262 
   23263     // A compatible framebuffer.
   23264     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 32, 32, 1};
   23265     VkFramebuffer fb;
   23266     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
   23267     ASSERT_VK_SUCCESS(err);
   23268 
   23269     // Record a command buffer which just begins and ends the renderpass. The
   23270     // bug manifests in BeginRenderPass.
   23271     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
   23272     m_commandBuffer->begin();
   23273     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
   23274     vkCmdEndRenderPass(m_commandBuffer->handle());
   23275     m_errorMonitor->VerifyNotFound();
   23276     m_commandBuffer->end();
   23277 
   23278     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
   23279     vkDestroyRenderPass(m_device->device(), rp, nullptr);
   23280 }
   23281 
   23282 // This is a positive test. No errors are expected.
   23283 TEST_F(VkPositiveLayerTest, StencilLoadOp) {
   23284     TEST_DESCRIPTION("Create a stencil-only attachment with a LOAD_OP set to CLEAR. stencil[Load|Store]Op used to be ignored.");
   23285     VkResult result = VK_SUCCESS;
   23286     ASSERT_NO_FATAL_FAILURE(Init());
   23287     auto depth_format = FindSupportedDepthStencilFormat(gpu());
   23288     if (!depth_format) {
   23289         printf("             No Depth + Stencil format found. Skipped.\n");
   23290         return;
   23291     }
   23292     VkImageFormatProperties formatProps;
   23293     vkGetPhysicalDeviceImageFormatProperties(gpu(), depth_format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
   23294                                              VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
   23295                                              &formatProps);
   23296     if (formatProps.maxExtent.width < 100 || formatProps.maxExtent.height < 100) {
   23297         return;
   23298     }
   23299 
   23300     VkFormat depth_stencil_fmt = depth_format;
   23301     m_depthStencil->Init(m_device, 100, 100, depth_stencil_fmt,
   23302                          VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
   23303     VkAttachmentDescription att = {};
   23304     VkAttachmentReference ref = {};
   23305     att.format = depth_stencil_fmt;
   23306     att.samples = VK_SAMPLE_COUNT_1_BIT;
   23307     att.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
   23308     att.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
   23309     att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
   23310     att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
   23311     att.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
   23312     att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
   23313 
   23314     VkClearValue clear;
   23315     clear.depthStencil.depth = 1.0;
   23316     clear.depthStencil.stencil = 0;
   23317     ref.attachment = 0;
   23318     ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
   23319 
   23320     VkSubpassDescription subpass = {};
   23321     subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
   23322     subpass.flags = 0;
   23323     subpass.inputAttachmentCount = 0;
   23324     subpass.pInputAttachments = NULL;
   23325     subpass.colorAttachmentCount = 0;
   23326     subpass.pColorAttachments = NULL;
   23327     subpass.pResolveAttachments = NULL;
   23328     subpass.pDepthStencilAttachment = &ref;
   23329     subpass.preserveAttachmentCount = 0;
   23330     subpass.pPreserveAttachments = NULL;
   23331 
   23332     VkRenderPass rp;
   23333     VkRenderPassCreateInfo rp_info = {};
   23334     rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
   23335     rp_info.attachmentCount = 1;
   23336     rp_info.pAttachments = &att;
   23337     rp_info.subpassCount = 1;
   23338     rp_info.pSubpasses = &subpass;
   23339     result = vkCreateRenderPass(device(), &rp_info, NULL, &rp);
   23340     ASSERT_VK_SUCCESS(result);
   23341 
   23342     VkImageView *depthView = m_depthStencil->BindInfo();
   23343     VkFramebufferCreateInfo fb_info = {};
   23344     fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
   23345     fb_info.pNext = NULL;
   23346     fb_info.renderPass = rp;
   23347     fb_info.attachmentCount = 1;
   23348     fb_info.pAttachments = depthView;
   23349     fb_info.width = 100;
   23350     fb_info.height = 100;
   23351     fb_info.layers = 1;
   23352     VkFramebuffer fb;
   23353     result = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
   23354     ASSERT_VK_SUCCESS(result);
   23355 
   23356     VkRenderPassBeginInfo rpbinfo = {};
   23357     rpbinfo.clearValueCount = 1;
   23358     rpbinfo.pClearValues = &clear;
   23359     rpbinfo.pNext = NULL;
   23360     rpbinfo.renderPass = rp;
   23361     rpbinfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
   23362     rpbinfo.renderArea.extent.width = 100;
   23363     rpbinfo.renderArea.extent.height = 100;
   23364     rpbinfo.renderArea.offset.x = 0;
   23365     rpbinfo.renderArea.offset.y = 0;
   23366     rpbinfo.framebuffer = fb;
   23367 
   23368     VkFence fence = {};
   23369     VkFenceCreateInfo fence_ci = {};
   23370     fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
   23371     fence_ci.pNext = nullptr;
   23372     fence_ci.flags = 0;
   23373     result = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fence);
   23374     ASSERT_VK_SUCCESS(result);
   23375 
   23376     m_commandBuffer->begin();
   23377     m_commandBuffer->BeginRenderPass(rpbinfo);
   23378     m_commandBuffer->EndRenderPass();
   23379     m_commandBuffer->end();
   23380     m_commandBuffer->QueueCommandBuffer(fence);
   23381 
   23382     VkImageObj destImage(m_device);
   23383     destImage.Init(100, 100, 1, depth_stencil_fmt, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
   23384                    VK_IMAGE_TILING_OPTIMAL, 0);
   23385     VkImageMemoryBarrier barrier = {};
   23386     VkImageSubresourceRange range;
   23387     barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
   23388     barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
   23389     barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
   23390     barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
   23391     barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
   23392     barrier.image = m_depthStencil->handle();
   23393     range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
   23394     range.baseMipLevel = 0;
   23395     range.levelCount = 1;
   23396     range.baseArrayLayer = 0;
   23397     range.layerCount = 1;
   23398     barrier.subresourceRange = range;
   23399     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
   23400     VkCommandBufferObj cmdbuf(m_device, m_commandPool);
   23401     cmdbuf.begin();
   23402     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
   23403                            &barrier);
   23404     barrier.srcAccessMask = 0;
   23405     barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   23406     barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
   23407     barrier.image = destImage.handle();
   23408     barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
   23409     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
   23410                            &barrier);
   23411     VkImageCopy cregion;
   23412     cregion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
   23413     cregion.srcSubresource.mipLevel = 0;
   23414     cregion.srcSubresource.baseArrayLayer = 0;
   23415     cregion.srcSubresource.layerCount = 1;
   23416     cregion.srcOffset.x = 0;
   23417     cregion.srcOffset.y = 0;
   23418     cregion.srcOffset.z = 0;
   23419     cregion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
   23420     cregion.dstSubresource.mipLevel = 0;
   23421     cregion.dstSubresource.baseArrayLayer = 0;
   23422     cregion.dstSubresource.layerCount = 1;
   23423     cregion.dstOffset.x = 0;
   23424     cregion.dstOffset.y = 0;
   23425     cregion.dstOffset.z = 0;
   23426     cregion.extent.width = 100;
   23427     cregion.extent.height = 100;
   23428     cregion.extent.depth = 1;
   23429     cmdbuf.CopyImage(m_depthStencil->handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, destImage.handle(),
   23430                      VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cregion);
   23431     cmdbuf.end();
   23432 
   23433     VkSubmitInfo submit_info;
   23434     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   23435     submit_info.pNext = NULL;
   23436     submit_info.waitSemaphoreCount = 0;
   23437     submit_info.pWaitSemaphores = NULL;
   23438     submit_info.pWaitDstStageMask = NULL;
   23439     submit_info.commandBufferCount = 1;
   23440     submit_info.pCommandBuffers = &cmdbuf.handle();
   23441     submit_info.signalSemaphoreCount = 0;
   23442     submit_info.pSignalSemaphores = NULL;
   23443 
   23444     m_errorMonitor->ExpectSuccess();
   23445     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   23446     m_errorMonitor->VerifyNotFound();
   23447 
   23448     vkQueueWaitIdle(m_device->m_queue);
   23449     vkDestroyFence(m_device->device(), fence, nullptr);
   23450     vkDestroyRenderPass(m_device->device(), rp, nullptr);
   23451     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
   23452 }
   23453 
   23454 // This is a positive test.  No errors should be generated.
   23455 TEST_F(VkPositiveLayerTest, BarrierLayoutToImageUsage) {
   23456     TEST_DESCRIPTION("Ensure barriers' new and old VkImageLayout are compatible with their images' VkImageUsageFlags");
   23457 
   23458     m_errorMonitor->ExpectSuccess();
   23459 
   23460     ASSERT_NO_FATAL_FAILURE(Init());
   23461     auto depth_format = FindSupportedDepthStencilFormat(gpu());
   23462     if (!depth_format) {
   23463         printf("             No Depth + Stencil format found. Skipped.\n");
   23464         return;
   23465     }
   23466     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   23467 
   23468     VkImageMemoryBarrier img_barrier = {};
   23469     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
   23470     img_barrier.pNext = NULL;
   23471     img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
   23472     img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
   23473     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   23474     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   23475     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   23476     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   23477     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   23478     img_barrier.subresourceRange.baseArrayLayer = 0;
   23479     img_barrier.subresourceRange.baseMipLevel = 0;
   23480     img_barrier.subresourceRange.layerCount = 1;
   23481     img_barrier.subresourceRange.levelCount = 1;
   23482 
   23483     {
   23484         VkImageObj img_color(m_device);
   23485         img_color.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
   23486         ASSERT_TRUE(img_color.initialized());
   23487 
   23488         VkImageObj img_ds1(m_device);
   23489         img_ds1.Init(128, 128, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
   23490         ASSERT_TRUE(img_ds1.initialized());
   23491 
   23492         VkImageObj img_ds2(m_device);
   23493         img_ds2.Init(128, 128, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
   23494         ASSERT_TRUE(img_ds2.initialized());
   23495 
   23496         VkImageObj img_xfer_src(m_device);
   23497         img_xfer_src.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL);
   23498         ASSERT_TRUE(img_xfer_src.initialized());
   23499 
   23500         VkImageObj img_xfer_dst(m_device);
   23501         img_xfer_dst.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
   23502         ASSERT_TRUE(img_xfer_dst.initialized());
   23503 
   23504         VkImageObj img_sampled(m_device);
   23505         img_sampled.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL);
   23506         ASSERT_TRUE(img_sampled.initialized());
   23507 
   23508         VkImageObj img_input(m_device);
   23509         img_input.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
   23510         ASSERT_TRUE(img_input.initialized());
   23511 
   23512         const struct {
   23513             VkImageObj &image_obj;
   23514             VkImageLayout old_layout;
   23515             VkImageLayout new_layout;
   23516         } buffer_layouts[] = {
   23517             // clang-format off
   23518             {img_color,    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,         VK_IMAGE_LAYOUT_GENERAL},
   23519             {img_ds1,      VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL},
   23520             {img_ds2,      VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,  VK_IMAGE_LAYOUT_GENERAL},
   23521             {img_sampled,  VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,         VK_IMAGE_LAYOUT_GENERAL},
   23522             {img_input,    VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,         VK_IMAGE_LAYOUT_GENERAL},
   23523             {img_xfer_src, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,             VK_IMAGE_LAYOUT_GENERAL},
   23524             {img_xfer_dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,             VK_IMAGE_LAYOUT_GENERAL},
   23525             // clang-format on
   23526         };
   23527         const uint32_t layout_count = sizeof(buffer_layouts) / sizeof(buffer_layouts[0]);
   23528 
   23529         m_commandBuffer->begin();
   23530         for (uint32_t i = 0; i < layout_count; ++i) {
   23531             img_barrier.image = buffer_layouts[i].image_obj.handle();
   23532             const VkImageUsageFlags usage = buffer_layouts[i].image_obj.usage();
   23533             img_barrier.subresourceRange.aspectMask = (usage == VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
   23534                                                           ? (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)
   23535                                                           : VK_IMAGE_ASPECT_COLOR_BIT;
   23536 
   23537             img_barrier.oldLayout = buffer_layouts[i].old_layout;
   23538             img_barrier.newLayout = buffer_layouts[i].new_layout;
   23539             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
   23540                                  nullptr, 0, nullptr, 1, &img_barrier);
   23541 
   23542             img_barrier.oldLayout = buffer_layouts[i].new_layout;
   23543             img_barrier.newLayout = buffer_layouts[i].old_layout;
   23544             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
   23545                                  nullptr, 0, nullptr, 1, &img_barrier);
   23546         }
   23547         m_commandBuffer->end();
   23548 
   23549         img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
   23550         img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
   23551     }
   23552     m_errorMonitor->VerifyNotFound();
   23553 }
   23554 
   23555 // This is a positive test.  No errors should be generated.
   23556 TEST_F(VkPositiveLayerTest, WaitEventThenSet) {
   23557     TEST_DESCRIPTION("Wait on a event then set it after the wait has been submitted.");
   23558 
   23559     m_errorMonitor->ExpectSuccess();
   23560     ASSERT_NO_FATAL_FAILURE(Init());
   23561 
   23562     VkEvent event;
   23563     VkEventCreateInfo event_create_info{};
   23564     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
   23565     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
   23566 
   23567     VkCommandPool command_pool;
   23568     VkCommandPoolCreateInfo pool_create_info{};
   23569     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
   23570     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
   23571     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
   23572     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
   23573 
   23574     VkCommandBuffer command_buffer;
   23575     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
   23576     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
   23577     command_buffer_allocate_info.commandPool = command_pool;
   23578     command_buffer_allocate_info.commandBufferCount = 1;
   23579     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
   23580     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
   23581 
   23582     VkQueue queue = VK_NULL_HANDLE;
   23583     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
   23584 
   23585     {
   23586         VkCommandBufferBeginInfo begin_info{};
   23587         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   23588         vkBeginCommandBuffer(command_buffer, &begin_info);
   23589 
   23590         vkCmdWaitEvents(command_buffer, 1, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0,
   23591                         nullptr, 0, nullptr);
   23592         vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
   23593         vkEndCommandBuffer(command_buffer);
   23594     }
   23595     {
   23596         VkSubmitInfo submit_info{};
   23597         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   23598         submit_info.commandBufferCount = 1;
   23599         submit_info.pCommandBuffers = &command_buffer;
   23600         submit_info.signalSemaphoreCount = 0;
   23601         submit_info.pSignalSemaphores = nullptr;
   23602         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
   23603     }
   23604     { vkSetEvent(m_device->device(), event); }
   23605 
   23606     vkQueueWaitIdle(queue);
   23607 
   23608     vkDestroyEvent(m_device->device(), event, nullptr);
   23609     vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
   23610     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
   23611 
   23612     m_errorMonitor->VerifyNotFound();
   23613 }
   23614 // This is a positive test.  No errors should be generated.
   23615 TEST_F(VkPositiveLayerTest, QueryAndCopySecondaryCommandBuffers) {
   23616     TEST_DESCRIPTION("Issue a query on a secondary command buffer and copy it on a primary.");
   23617 
   23618     ASSERT_NO_FATAL_FAILURE(Init());
   23619     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) return;
   23620 
   23621     m_errorMonitor->ExpectSuccess();
   23622 
   23623     VkQueryPool query_pool;
   23624     VkQueryPoolCreateInfo query_pool_create_info{};
   23625     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
   23626     query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
   23627     query_pool_create_info.queryCount = 1;
   23628     vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
   23629 
   23630     VkCommandPoolObj command_pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
   23631     VkCommandBufferObj primary_buffer(m_device, &command_pool);
   23632     VkCommandBufferObj secondary_buffer(m_device, &command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
   23633 
   23634     VkQueue queue = VK_NULL_HANDLE;
   23635     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
   23636 
   23637     uint32_t qfi = 0;
   23638     VkBufferCreateInfo buff_create_info = {};
   23639     buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   23640     buff_create_info.size = 1024;
   23641     buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
   23642     buff_create_info.queueFamilyIndexCount = 1;
   23643     buff_create_info.pQueueFamilyIndices = &qfi;
   23644 
   23645     VkResult err;
   23646     VkBuffer buffer;
   23647     err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer);
   23648     ASSERT_VK_SUCCESS(err);
   23649 
   23650     VkMemoryRequirements memReqs;
   23651     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
   23652     VkMemoryAllocateInfo mem_alloc = {};
   23653     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   23654     mem_alloc.pNext = NULL;
   23655     mem_alloc.allocationSize = memReqs.size;
   23656     mem_alloc.memoryTypeIndex = 0;
   23657     bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
   23658     if (!pass) {
   23659         vkDestroyBuffer(m_device->device(), buffer, NULL);
   23660         return;
   23661     }
   23662 
   23663     VkDeviceMemory mem;
   23664     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
   23665     ASSERT_VK_SUCCESS(err);
   23666     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
   23667     ASSERT_VK_SUCCESS(err);
   23668 
   23669     VkCommandBufferInheritanceInfo hinfo = {};
   23670     hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
   23671     hinfo.renderPass = VK_NULL_HANDLE;
   23672     hinfo.subpass = 0;
   23673     hinfo.framebuffer = VK_NULL_HANDLE;
   23674     hinfo.occlusionQueryEnable = VK_FALSE;
   23675     hinfo.queryFlags = 0;
   23676     hinfo.pipelineStatistics = 0;
   23677 
   23678     {
   23679         VkCommandBufferBeginInfo begin_info{};
   23680         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   23681         begin_info.pInheritanceInfo = &hinfo;
   23682         secondary_buffer.begin(&begin_info);
   23683         vkCmdResetQueryPool(secondary_buffer.handle(), query_pool, 0, 1);
   23684         vkCmdWriteTimestamp(secondary_buffer.handle(), VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
   23685         secondary_buffer.end();
   23686 
   23687         primary_buffer.begin();
   23688         vkCmdExecuteCommands(primary_buffer.handle(), 1, &secondary_buffer.handle());
   23689         vkCmdCopyQueryPoolResults(primary_buffer.handle(), query_pool, 0, 1, buffer, 0, 0, 0);
   23690         primary_buffer.end();
   23691     }
   23692 
   23693     primary_buffer.QueueCommandBuffer();
   23694     vkQueueWaitIdle(queue);
   23695 
   23696     vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
   23697     vkDestroyBuffer(m_device->device(), buffer, NULL);
   23698     vkFreeMemory(m_device->device(), mem, NULL);
   23699 
   23700     m_errorMonitor->VerifyNotFound();
   23701 }
   23702 
   23703 // This is a positive test.  No errors should be generated.
   23704 TEST_F(VkPositiveLayerTest, QueryAndCopyMultipleCommandBuffers) {
   23705     TEST_DESCRIPTION("Issue a query and copy from it on a second command buffer.");
   23706 
   23707     ASSERT_NO_FATAL_FAILURE(Init());
   23708     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) return;
   23709 
   23710     m_errorMonitor->ExpectSuccess();
   23711 
   23712     VkQueryPool query_pool;
   23713     VkQueryPoolCreateInfo query_pool_create_info{};
   23714     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
   23715     query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
   23716     query_pool_create_info.queryCount = 1;
   23717     vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
   23718 
   23719     VkCommandPool command_pool;
   23720     VkCommandPoolCreateInfo pool_create_info{};
   23721     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
   23722     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
   23723     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
   23724     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
   23725 
   23726     VkCommandBuffer command_buffer[2];
   23727     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
   23728     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
   23729     command_buffer_allocate_info.commandPool = command_pool;
   23730     command_buffer_allocate_info.commandBufferCount = 2;
   23731     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
   23732     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
   23733 
   23734     VkQueue queue = VK_NULL_HANDLE;
   23735     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
   23736 
   23737     uint32_t qfi = 0;
   23738     VkBufferCreateInfo buff_create_info = {};
   23739     buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   23740     buff_create_info.size = 1024;
   23741     buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
   23742     buff_create_info.queueFamilyIndexCount = 1;
   23743     buff_create_info.pQueueFamilyIndices = &qfi;
   23744 
   23745     VkResult err;
   23746     VkBuffer buffer;
   23747     err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer);
   23748     ASSERT_VK_SUCCESS(err);
   23749 
   23750     VkMemoryRequirements memReqs;
   23751     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
   23752     VkMemoryAllocateInfo mem_alloc = {};
   23753     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   23754     mem_alloc.pNext = NULL;
   23755     mem_alloc.allocationSize = memReqs.size;
   23756     mem_alloc.memoryTypeIndex = 0;
   23757     bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
   23758     if (!pass) {
   23759         vkDestroyBuffer(m_device->device(), buffer, NULL);
   23760         return;
   23761     }
   23762 
   23763     VkDeviceMemory mem;
   23764     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
   23765     ASSERT_VK_SUCCESS(err);
   23766     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
   23767     ASSERT_VK_SUCCESS(err);
   23768 
   23769     {
   23770         VkCommandBufferBeginInfo begin_info{};
   23771         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   23772         vkBeginCommandBuffer(command_buffer[0], &begin_info);
   23773 
   23774         vkCmdResetQueryPool(command_buffer[0], query_pool, 0, 1);
   23775         vkCmdWriteTimestamp(command_buffer[0], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
   23776 
   23777         vkEndCommandBuffer(command_buffer[0]);
   23778 
   23779         vkBeginCommandBuffer(command_buffer[1], &begin_info);
   23780 
   23781         vkCmdCopyQueryPoolResults(command_buffer[1], query_pool, 0, 1, buffer, 0, 0, 0);
   23782 
   23783         vkEndCommandBuffer(command_buffer[1]);
   23784     }
   23785     {
   23786         VkSubmitInfo submit_info{};
   23787         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   23788         submit_info.commandBufferCount = 2;
   23789         submit_info.pCommandBuffers = command_buffer;
   23790         submit_info.signalSemaphoreCount = 0;
   23791         submit_info.pSignalSemaphores = nullptr;
   23792         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
   23793     }
   23794 
   23795     vkQueueWaitIdle(queue);
   23796 
   23797     vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
   23798     vkFreeCommandBuffers(m_device->device(), command_pool, 2, command_buffer);
   23799     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
   23800     vkDestroyBuffer(m_device->device(), buffer, NULL);
   23801     vkFreeMemory(m_device->device(), mem, NULL);
   23802 
   23803     m_errorMonitor->VerifyNotFound();
   23804 }
   23805 
   23806 TEST_F(VkLayerTest, ResetEventThenSet) {
   23807     TEST_DESCRIPTION("Reset an event then set it after the reset has been submitted.");
   23808 
   23809     ASSERT_NO_FATAL_FAILURE(Init());
   23810     VkEvent event;
   23811     VkEventCreateInfo event_create_info{};
   23812     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
   23813     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
   23814 
   23815     VkCommandPool command_pool;
   23816     VkCommandPoolCreateInfo pool_create_info{};
   23817     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
   23818     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
   23819     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
   23820     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
   23821 
   23822     VkCommandBuffer command_buffer;
   23823     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
   23824     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
   23825     command_buffer_allocate_info.commandPool = command_pool;
   23826     command_buffer_allocate_info.commandBufferCount = 1;
   23827     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
   23828     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
   23829 
   23830     VkQueue queue = VK_NULL_HANDLE;
   23831     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
   23832 
   23833     {
   23834         VkCommandBufferBeginInfo begin_info{};
   23835         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   23836         vkBeginCommandBuffer(command_buffer, &begin_info);
   23837 
   23838         vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
   23839         vkEndCommandBuffer(command_buffer);
   23840     }
   23841     {
   23842         VkSubmitInfo submit_info{};
   23843         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   23844         submit_info.commandBufferCount = 1;
   23845         submit_info.pCommandBuffers = &command_buffer;
   23846         submit_info.signalSemaphoreCount = 0;
   23847         submit_info.pSignalSemaphores = nullptr;
   23848         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
   23849     }
   23850     {
   23851         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is already in use by a command buffer.");
   23852         vkSetEvent(m_device->device(), event);
   23853         m_errorMonitor->VerifyFound();
   23854     }
   23855 
   23856     vkQueueWaitIdle(queue);
   23857 
   23858     vkDestroyEvent(m_device->device(), event, nullptr);
   23859     vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
   23860     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
   23861 }
   23862 
   23863 // This is a positive test.  No errors should be generated.
   23864 TEST_F(VkPositiveLayerTest, TwoFencesThreeFrames) {
   23865     TEST_DESCRIPTION(
   23866         "Two command buffers with two separate fences are each run through a Submit & WaitForFences cycle 3 times. This previously "
   23867         "revealed a bug so running this positive test to prevent a regression.");
   23868     m_errorMonitor->ExpectSuccess();
   23869 
   23870     ASSERT_NO_FATAL_FAILURE(Init());
   23871     VkQueue queue = VK_NULL_HANDLE;
   23872     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
   23873 
   23874     static const uint32_t NUM_OBJECTS = 2;
   23875     static const uint32_t NUM_FRAMES = 3;
   23876     VkCommandBuffer cmd_buffers[NUM_OBJECTS] = {};
   23877     VkFence fences[NUM_OBJECTS] = {};
   23878 
   23879     VkCommandPool cmd_pool;
   23880     VkCommandPoolCreateInfo cmd_pool_ci = {};
   23881     cmd_pool_ci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
   23882     cmd_pool_ci.queueFamilyIndex = m_device->graphics_queue_node_index_;
   23883     cmd_pool_ci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
   23884     VkResult err = vkCreateCommandPool(m_device->device(), &cmd_pool_ci, nullptr, &cmd_pool);
   23885     ASSERT_VK_SUCCESS(err);
   23886 
   23887     VkCommandBufferAllocateInfo cmd_buf_info = {};
   23888     cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
   23889     cmd_buf_info.commandPool = cmd_pool;
   23890     cmd_buf_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
   23891     cmd_buf_info.commandBufferCount = 1;
   23892 
   23893     VkFenceCreateInfo fence_ci = {};
   23894     fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
   23895     fence_ci.pNext = nullptr;
   23896     fence_ci.flags = 0;
   23897 
   23898     for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
   23899         err = vkAllocateCommandBuffers(m_device->device(), &cmd_buf_info, &cmd_buffers[i]);
   23900         ASSERT_VK_SUCCESS(err);
   23901         err = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fences[i]);
   23902         ASSERT_VK_SUCCESS(err);
   23903     }
   23904 
   23905     for (uint32_t frame = 0; frame < NUM_FRAMES; ++frame) {
   23906         for (uint32_t obj = 0; obj < NUM_OBJECTS; ++obj) {
   23907             // Create empty cmd buffer
   23908             VkCommandBufferBeginInfo cmdBufBeginDesc = {};
   23909             cmdBufBeginDesc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   23910 
   23911             err = vkBeginCommandBuffer(cmd_buffers[obj], &cmdBufBeginDesc);
   23912             ASSERT_VK_SUCCESS(err);
   23913             err = vkEndCommandBuffer(cmd_buffers[obj]);
   23914             ASSERT_VK_SUCCESS(err);
   23915 
   23916             VkSubmitInfo submit_info = {};
   23917             submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   23918             submit_info.commandBufferCount = 1;
   23919             submit_info.pCommandBuffers = &cmd_buffers[obj];
   23920             // Submit cmd buffer and wait for fence
   23921             err = vkQueueSubmit(queue, 1, &submit_info, fences[obj]);
   23922             ASSERT_VK_SUCCESS(err);
   23923             err = vkWaitForFences(m_device->device(), 1, &fences[obj], VK_TRUE, UINT64_MAX);
   23924             ASSERT_VK_SUCCESS(err);
   23925             err = vkResetFences(m_device->device(), 1, &fences[obj]);
   23926             ASSERT_VK_SUCCESS(err);
   23927         }
   23928     }
   23929     m_errorMonitor->VerifyNotFound();
   23930     vkDestroyCommandPool(m_device->device(), cmd_pool, NULL);
   23931     for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
   23932         vkDestroyFence(m_device->device(), fences[i], nullptr);
   23933     }
   23934 }
   23935 // This is a positive test.  No errors should be generated.
   23936 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWI) {
   23937     TEST_DESCRIPTION(
   23938         "Two command buffers, each in a separate QueueSubmit call submitted on separate queues followed by a QueueWaitIdle.");
   23939 
   23940     ASSERT_NO_FATAL_FAILURE(Init());
   23941     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) return;
   23942 
   23943     m_errorMonitor->ExpectSuccess();
   23944 
   23945     VkSemaphore semaphore;
   23946     VkSemaphoreCreateInfo semaphore_create_info{};
   23947     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
   23948     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
   23949 
   23950     VkCommandPool command_pool;
   23951     VkCommandPoolCreateInfo pool_create_info{};
   23952     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
   23953     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
   23954     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
   23955     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
   23956 
   23957     VkCommandBuffer command_buffer[2];
   23958     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
   23959     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
   23960     command_buffer_allocate_info.commandPool = command_pool;
   23961     command_buffer_allocate_info.commandBufferCount = 2;
   23962     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
   23963     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
   23964 
   23965     VkQueue queue = VK_NULL_HANDLE;
   23966     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
   23967 
   23968     {
   23969         VkCommandBufferBeginInfo begin_info{};
   23970         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   23971         vkBeginCommandBuffer(command_buffer[0], &begin_info);
   23972 
   23973         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
   23974                              nullptr, 0, nullptr, 0, nullptr);
   23975 
   23976         VkViewport viewport{};
   23977         viewport.maxDepth = 1.0f;
   23978         viewport.minDepth = 0.0f;
   23979         viewport.width = 512;
   23980         viewport.height = 512;
   23981         viewport.x = 0;
   23982         viewport.y = 0;
   23983         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
   23984         vkEndCommandBuffer(command_buffer[0]);
   23985     }
   23986     {
   23987         VkCommandBufferBeginInfo begin_info{};
   23988         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   23989         vkBeginCommandBuffer(command_buffer[1], &begin_info);
   23990 
   23991         VkViewport viewport{};
   23992         viewport.maxDepth = 1.0f;
   23993         viewport.minDepth = 0.0f;
   23994         viewport.width = 512;
   23995         viewport.height = 512;
   23996         viewport.x = 0;
   23997         viewport.y = 0;
   23998         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
   23999         vkEndCommandBuffer(command_buffer[1]);
   24000     }
   24001     {
   24002         VkSubmitInfo submit_info{};
   24003         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   24004         submit_info.commandBufferCount = 1;
   24005         submit_info.pCommandBuffers = &command_buffer[0];
   24006         submit_info.signalSemaphoreCount = 1;
   24007         submit_info.pSignalSemaphores = &semaphore;
   24008         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
   24009     }
   24010     {
   24011         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
   24012         VkSubmitInfo submit_info{};
   24013         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   24014         submit_info.commandBufferCount = 1;
   24015         submit_info.pCommandBuffers = &command_buffer[1];
   24016         submit_info.waitSemaphoreCount = 1;
   24017         submit_info.pWaitSemaphores = &semaphore;
   24018         submit_info.pWaitDstStageMask = flags;
   24019         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   24020     }
   24021 
   24022     vkQueueWaitIdle(m_device->m_queue);
   24023 
   24024     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
   24025     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
   24026     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
   24027 
   24028     m_errorMonitor->VerifyNotFound();
   24029 }
   24030 
   24031 // This is a positive test.  No errors should be generated.
   24032 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWIFence) {
   24033     TEST_DESCRIPTION(
   24034         "Two command buffers, each in a separate QueueSubmit call submitted on separate queues, the second having a fencefollowed "
   24035         "by a QueueWaitIdle.");
   24036 
   24037     ASSERT_NO_FATAL_FAILURE(Init());
   24038     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) return;
   24039 
   24040     m_errorMonitor->ExpectSuccess();
   24041 
   24042     VkFence fence;
   24043     VkFenceCreateInfo fence_create_info{};
   24044     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
   24045     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
   24046 
   24047     VkSemaphore semaphore;
   24048     VkSemaphoreCreateInfo semaphore_create_info{};
   24049     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
   24050     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
   24051 
   24052     VkCommandPool command_pool;
   24053     VkCommandPoolCreateInfo pool_create_info{};
   24054     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
   24055     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
   24056     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
   24057     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
   24058 
   24059     VkCommandBuffer command_buffer[2];
   24060     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
   24061     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
   24062     command_buffer_allocate_info.commandPool = command_pool;
   24063     command_buffer_allocate_info.commandBufferCount = 2;
   24064     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
   24065     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
   24066 
   24067     VkQueue queue = VK_NULL_HANDLE;
   24068     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
   24069 
   24070     {
   24071         VkCommandBufferBeginInfo begin_info{};
   24072         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   24073         vkBeginCommandBuffer(command_buffer[0], &begin_info);
   24074 
   24075         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
   24076                              nullptr, 0, nullptr, 0, nullptr);
   24077 
   24078         VkViewport viewport{};
   24079         viewport.maxDepth = 1.0f;
   24080         viewport.minDepth = 0.0f;
   24081         viewport.width = 512;
   24082         viewport.height = 512;
   24083         viewport.x = 0;
   24084         viewport.y = 0;
   24085         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
   24086         vkEndCommandBuffer(command_buffer[0]);
   24087     }
   24088     {
   24089         VkCommandBufferBeginInfo begin_info{};
   24090         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   24091         vkBeginCommandBuffer(command_buffer[1], &begin_info);
   24092 
   24093         VkViewport viewport{};
   24094         viewport.maxDepth = 1.0f;
   24095         viewport.minDepth = 0.0f;
   24096         viewport.width = 512;
   24097         viewport.height = 512;
   24098         viewport.x = 0;
   24099         viewport.y = 0;
   24100         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
   24101         vkEndCommandBuffer(command_buffer[1]);
   24102     }
   24103     {
   24104         VkSubmitInfo submit_info{};
   24105         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   24106         submit_info.commandBufferCount = 1;
   24107         submit_info.pCommandBuffers = &command_buffer[0];
   24108         submit_info.signalSemaphoreCount = 1;
   24109         submit_info.pSignalSemaphores = &semaphore;
   24110         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
   24111     }
   24112     {
   24113         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
   24114         VkSubmitInfo submit_info{};
   24115         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   24116         submit_info.commandBufferCount = 1;
   24117         submit_info.pCommandBuffers = &command_buffer[1];
   24118         submit_info.waitSemaphoreCount = 1;
   24119         submit_info.pWaitSemaphores = &semaphore;
   24120         submit_info.pWaitDstStageMask = flags;
   24121         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
   24122     }
   24123 
   24124     vkQueueWaitIdle(m_device->m_queue);
   24125 
   24126     vkDestroyFence(m_device->device(), fence, nullptr);
   24127     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
   24128     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
   24129     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
   24130 
   24131     m_errorMonitor->VerifyNotFound();
   24132 }
   24133 
   24134 // This is a positive test.  No errors should be generated.
   24135 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceTwoWFF) {
   24136     TEST_DESCRIPTION(
   24137         "Two command buffers, each in a separate QueueSubmit call submitted on separate queues, the second having a fencefollowed "
   24138         "by two consecutive WaitForFences calls on the same fence.");
   24139 
   24140     ASSERT_NO_FATAL_FAILURE(Init());
   24141     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) return;
   24142 
   24143     m_errorMonitor->ExpectSuccess();
   24144 
   24145     VkFence fence;
   24146     VkFenceCreateInfo fence_create_info{};
   24147     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
   24148     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
   24149 
   24150     VkSemaphore semaphore;
   24151     VkSemaphoreCreateInfo semaphore_create_info{};
   24152     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
   24153     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
   24154 
   24155     VkCommandPool command_pool;
   24156     VkCommandPoolCreateInfo pool_create_info{};
   24157     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
   24158     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
   24159     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
   24160     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
   24161 
   24162     VkCommandBuffer command_buffer[2];
   24163     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
   24164     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
   24165     command_buffer_allocate_info.commandPool = command_pool;
   24166     command_buffer_allocate_info.commandBufferCount = 2;
   24167     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
   24168     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
   24169 
   24170     VkQueue queue = VK_NULL_HANDLE;
   24171     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
   24172 
   24173     {
   24174         VkCommandBufferBeginInfo begin_info{};
   24175         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   24176         vkBeginCommandBuffer(command_buffer[0], &begin_info);
   24177 
   24178         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
   24179                              nullptr, 0, nullptr, 0, nullptr);
   24180 
   24181         VkViewport viewport{};
   24182         viewport.maxDepth = 1.0f;
   24183         viewport.minDepth = 0.0f;
   24184         viewport.width = 512;
   24185         viewport.height = 512;
   24186         viewport.x = 0;
   24187         viewport.y = 0;
   24188         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
   24189         vkEndCommandBuffer(command_buffer[0]);
   24190     }
   24191     {
   24192         VkCommandBufferBeginInfo begin_info{};
   24193         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   24194         vkBeginCommandBuffer(command_buffer[1], &begin_info);
   24195 
   24196         VkViewport viewport{};
   24197         viewport.maxDepth = 1.0f;
   24198         viewport.minDepth = 0.0f;
   24199         viewport.width = 512;
   24200         viewport.height = 512;
   24201         viewport.x = 0;
   24202         viewport.y = 0;
   24203         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
   24204         vkEndCommandBuffer(command_buffer[1]);
   24205     }
   24206     {
   24207         VkSubmitInfo submit_info{};
   24208         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   24209         submit_info.commandBufferCount = 1;
   24210         submit_info.pCommandBuffers = &command_buffer[0];
   24211         submit_info.signalSemaphoreCount = 1;
   24212         submit_info.pSignalSemaphores = &semaphore;
   24213         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
   24214     }
   24215     {
   24216         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
   24217         VkSubmitInfo submit_info{};
   24218         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   24219         submit_info.commandBufferCount = 1;
   24220         submit_info.pCommandBuffers = &command_buffer[1];
   24221         submit_info.waitSemaphoreCount = 1;
   24222         submit_info.pWaitSemaphores = &semaphore;
   24223         submit_info.pWaitDstStageMask = flags;
   24224         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
   24225     }
   24226 
   24227     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
   24228     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
   24229 
   24230     vkDestroyFence(m_device->device(), fence, nullptr);
   24231     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
   24232     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
   24233     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
   24234 
   24235     m_errorMonitor->VerifyNotFound();
   24236 }
   24237 
   24238 TEST_F(VkPositiveLayerTest, TwoQueuesEnsureCorrectRetirementWithWorkStolen) {
   24239     ASSERT_NO_FATAL_FAILURE(Init());
   24240     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
   24241         printf("             Test requires two queues, skipping\n");
   24242         return;
   24243     }
   24244 
   24245     VkResult err;
   24246 
   24247     m_errorMonitor->ExpectSuccess();
   24248 
   24249     VkQueue q0 = m_device->m_queue;
   24250     VkQueue q1 = nullptr;
   24251     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &q1);
   24252     ASSERT_NE(q1, nullptr);
   24253 
   24254     // An (empty) command buffer. We must have work in the first submission --
   24255     // the layer treats unfenced work differently from fenced work.
   24256     VkCommandPoolCreateInfo cpci = {VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, nullptr, 0, 0};
   24257     VkCommandPool pool;
   24258     err = vkCreateCommandPool(m_device->device(), &cpci, nullptr, &pool);
   24259     ASSERT_VK_SUCCESS(err);
   24260     VkCommandBufferAllocateInfo cbai = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, nullptr, pool,
   24261                                         VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1};
   24262     VkCommandBuffer cb;
   24263     err = vkAllocateCommandBuffers(m_device->device(), &cbai, &cb);
   24264     ASSERT_VK_SUCCESS(err);
   24265     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, nullptr};
   24266     err = vkBeginCommandBuffer(cb, &cbbi);
   24267     ASSERT_VK_SUCCESS(err);
   24268     err = vkEndCommandBuffer(cb);
   24269     ASSERT_VK_SUCCESS(err);
   24270 
   24271     // A semaphore
   24272     VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
   24273     VkSemaphore s;
   24274     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s);
   24275     ASSERT_VK_SUCCESS(err);
   24276 
   24277     // First submission, to q0
   24278     VkSubmitInfo s0 = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &cb, 1, &s};
   24279 
   24280     err = vkQueueSubmit(q0, 1, &s0, VK_NULL_HANDLE);
   24281     ASSERT_VK_SUCCESS(err);
   24282 
   24283     // Second submission, to q1, waiting on s
   24284     VkFlags waitmask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;  // doesn't really matter what this value is.
   24285     VkSubmitInfo s1 = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &s, &waitmask, 0, nullptr, 0, nullptr};
   24286 
   24287     err = vkQueueSubmit(q1, 1, &s1, VK_NULL_HANDLE);
   24288     ASSERT_VK_SUCCESS(err);
   24289 
   24290     // Wait for q0 idle
   24291     err = vkQueueWaitIdle(q0);
   24292     ASSERT_VK_SUCCESS(err);
   24293 
   24294     // Command buffer should have been completed (it was on q0); reset the pool.
   24295     vkFreeCommandBuffers(m_device->device(), pool, 1, &cb);
   24296 
   24297     m_errorMonitor->VerifyNotFound();
   24298 
   24299     // Force device completely idle and clean up resources
   24300     vkDeviceWaitIdle(m_device->device());
   24301     vkDestroyCommandPool(m_device->device(), pool, nullptr);
   24302     vkDestroySemaphore(m_device->device(), s, nullptr);
   24303 }
   24304 
   24305 // This is a positive test.  No errors should be generated.
   24306 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFence) {
   24307     TEST_DESCRIPTION(
   24308         "Two command buffers, each in a separate QueueSubmit call submitted on separate queues, the second having a fence, "
   24309         "followed by a WaitForFences call.");
   24310 
   24311     ASSERT_NO_FATAL_FAILURE(Init());
   24312     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) return;
   24313 
   24314     m_errorMonitor->ExpectSuccess();
   24315 
   24316     VkFence fence;
   24317     VkFenceCreateInfo fence_create_info{};
   24318     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
   24319     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
   24320 
   24321     VkSemaphore semaphore;
   24322     VkSemaphoreCreateInfo semaphore_create_info{};
   24323     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
   24324     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
   24325 
   24326     VkCommandPool command_pool;
   24327     VkCommandPoolCreateInfo pool_create_info{};
   24328     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
   24329     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
   24330     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
   24331     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
   24332 
   24333     VkCommandBuffer command_buffer[2];
   24334     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
   24335     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
   24336     command_buffer_allocate_info.commandPool = command_pool;
   24337     command_buffer_allocate_info.commandBufferCount = 2;
   24338     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
   24339     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
   24340 
   24341     VkQueue queue = VK_NULL_HANDLE;
   24342     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
   24343 
   24344     {
   24345         VkCommandBufferBeginInfo begin_info{};
   24346         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   24347         vkBeginCommandBuffer(command_buffer[0], &begin_info);
   24348 
   24349         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
   24350                              nullptr, 0, nullptr, 0, nullptr);
   24351 
   24352         VkViewport viewport{};
   24353         viewport.maxDepth = 1.0f;
   24354         viewport.minDepth = 0.0f;
   24355         viewport.width = 512;
   24356         viewport.height = 512;
   24357         viewport.x = 0;
   24358         viewport.y = 0;
   24359         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
   24360         vkEndCommandBuffer(command_buffer[0]);
   24361     }
   24362     {
   24363         VkCommandBufferBeginInfo begin_info{};
   24364         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   24365         vkBeginCommandBuffer(command_buffer[1], &begin_info);
   24366 
   24367         VkViewport viewport{};
   24368         viewport.maxDepth = 1.0f;
   24369         viewport.minDepth = 0.0f;
   24370         viewport.width = 512;
   24371         viewport.height = 512;
   24372         viewport.x = 0;
   24373         viewport.y = 0;
   24374         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
   24375         vkEndCommandBuffer(command_buffer[1]);
   24376     }
   24377     {
   24378         VkSubmitInfo submit_info{};
   24379         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   24380         submit_info.commandBufferCount = 1;
   24381         submit_info.pCommandBuffers = &command_buffer[0];
   24382         submit_info.signalSemaphoreCount = 1;
   24383         submit_info.pSignalSemaphores = &semaphore;
   24384         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
   24385     }
   24386     {
   24387         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
   24388         VkSubmitInfo submit_info{};
   24389         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   24390         submit_info.commandBufferCount = 1;
   24391         submit_info.pCommandBuffers = &command_buffer[1];
   24392         submit_info.waitSemaphoreCount = 1;
   24393         submit_info.pWaitSemaphores = &semaphore;
   24394         submit_info.pWaitDstStageMask = flags;
   24395         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
   24396     }
   24397 
   24398     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
   24399 
   24400     vkDestroyFence(m_device->device(), fence, nullptr);
   24401     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
   24402     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
   24403     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
   24404 
   24405     m_errorMonitor->VerifyNotFound();
   24406 }
   24407 
   24408 // This is a positive test.  No errors should be generated.
   24409 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsOneQueueWithSemaphoreAndOneFence) {
   24410     TEST_DESCRIPTION(
   24411         "Two command buffers, each in a separate QueueSubmit call on the same queue, sharing a signal/wait semaphore, the second "
   24412         "having a fence, followed by a WaitForFences call.");
   24413 
   24414     m_errorMonitor->ExpectSuccess();
   24415 
   24416     ASSERT_NO_FATAL_FAILURE(Init());
   24417     VkFence fence;
   24418     VkFenceCreateInfo fence_create_info{};
   24419     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
   24420     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
   24421 
   24422     VkSemaphore semaphore;
   24423     VkSemaphoreCreateInfo semaphore_create_info{};
   24424     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
   24425     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
   24426 
   24427     VkCommandPool command_pool;
   24428     VkCommandPoolCreateInfo pool_create_info{};
   24429     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
   24430     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
   24431     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
   24432     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
   24433 
   24434     VkCommandBuffer command_buffer[2];
   24435     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
   24436     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
   24437     command_buffer_allocate_info.commandPool = command_pool;
   24438     command_buffer_allocate_info.commandBufferCount = 2;
   24439     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
   24440     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
   24441 
   24442     {
   24443         VkCommandBufferBeginInfo begin_info{};
   24444         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   24445         vkBeginCommandBuffer(command_buffer[0], &begin_info);
   24446 
   24447         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
   24448                              nullptr, 0, nullptr, 0, nullptr);
   24449 
   24450         VkViewport viewport{};
   24451         viewport.maxDepth = 1.0f;
   24452         viewport.minDepth = 0.0f;
   24453         viewport.width = 512;
   24454         viewport.height = 512;
   24455         viewport.x = 0;
   24456         viewport.y = 0;
   24457         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
   24458         vkEndCommandBuffer(command_buffer[0]);
   24459     }
   24460     {
   24461         VkCommandBufferBeginInfo begin_info{};
   24462         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   24463         vkBeginCommandBuffer(command_buffer[1], &begin_info);
   24464 
   24465         VkViewport viewport{};
   24466         viewport.maxDepth = 1.0f;
   24467         viewport.minDepth = 0.0f;
   24468         viewport.width = 512;
   24469         viewport.height = 512;
   24470         viewport.x = 0;
   24471         viewport.y = 0;
   24472         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
   24473         vkEndCommandBuffer(command_buffer[1]);
   24474     }
   24475     {
   24476         VkSubmitInfo submit_info{};
   24477         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   24478         submit_info.commandBufferCount = 1;
   24479         submit_info.pCommandBuffers = &command_buffer[0];
   24480         submit_info.signalSemaphoreCount = 1;
   24481         submit_info.pSignalSemaphores = &semaphore;
   24482         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   24483     }
   24484     {
   24485         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
   24486         VkSubmitInfo submit_info{};
   24487         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   24488         submit_info.commandBufferCount = 1;
   24489         submit_info.pCommandBuffers = &command_buffer[1];
   24490         submit_info.waitSemaphoreCount = 1;
   24491         submit_info.pWaitSemaphores = &semaphore;
   24492         submit_info.pWaitDstStageMask = flags;
   24493         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
   24494     }
   24495 
   24496     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
   24497 
   24498     vkDestroyFence(m_device->device(), fence, nullptr);
   24499     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
   24500     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
   24501     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
   24502 
   24503     m_errorMonitor->VerifyNotFound();
   24504 }
   24505 
   24506 // This is a positive test.  No errors should be generated.
   24507 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsOneQueueNullQueueSubmitWithFence) {
   24508     TEST_DESCRIPTION(
   24509         "Two command buffers, each in a separate QueueSubmit call on the same queue, no fences, followed by a third QueueSubmit "
   24510         "with NO SubmitInfos but with a fence, followed by a WaitForFences call.");
   24511 
   24512     m_errorMonitor->ExpectSuccess();
   24513 
   24514     ASSERT_NO_FATAL_FAILURE(Init());
   24515     VkFence fence;
   24516     VkFenceCreateInfo fence_create_info{};
   24517     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
   24518     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
   24519 
   24520     VkCommandPool command_pool;
   24521     VkCommandPoolCreateInfo pool_create_info{};
   24522     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
   24523     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
   24524     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
   24525     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
   24526 
   24527     VkCommandBuffer command_buffer[2];
   24528     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
   24529     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
   24530     command_buffer_allocate_info.commandPool = command_pool;
   24531     command_buffer_allocate_info.commandBufferCount = 2;
   24532     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
   24533     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
   24534 
   24535     {
   24536         VkCommandBufferBeginInfo begin_info{};
   24537         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   24538         vkBeginCommandBuffer(command_buffer[0], &begin_info);
   24539 
   24540         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
   24541                              nullptr, 0, nullptr, 0, nullptr);
   24542 
   24543         VkViewport viewport{};
   24544         viewport.maxDepth = 1.0f;
   24545         viewport.minDepth = 0.0f;
   24546         viewport.width = 512;
   24547         viewport.height = 512;
   24548         viewport.x = 0;
   24549         viewport.y = 0;
   24550         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
   24551         vkEndCommandBuffer(command_buffer[0]);
   24552     }
   24553     {
   24554         VkCommandBufferBeginInfo begin_info{};
   24555         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   24556         vkBeginCommandBuffer(command_buffer[1], &begin_info);
   24557 
   24558         VkViewport viewport{};
   24559         viewport.maxDepth = 1.0f;
   24560         viewport.minDepth = 0.0f;
   24561         viewport.width = 512;
   24562         viewport.height = 512;
   24563         viewport.x = 0;
   24564         viewport.y = 0;
   24565         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
   24566         vkEndCommandBuffer(command_buffer[1]);
   24567     }
   24568     {
   24569         VkSubmitInfo submit_info{};
   24570         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   24571         submit_info.commandBufferCount = 1;
   24572         submit_info.pCommandBuffers = &command_buffer[0];
   24573         submit_info.signalSemaphoreCount = 0;
   24574         submit_info.pSignalSemaphores = VK_NULL_HANDLE;
   24575         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   24576     }
   24577     {
   24578         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
   24579         VkSubmitInfo submit_info{};
   24580         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   24581         submit_info.commandBufferCount = 1;
   24582         submit_info.pCommandBuffers = &command_buffer[1];
   24583         submit_info.waitSemaphoreCount = 0;
   24584         submit_info.pWaitSemaphores = VK_NULL_HANDLE;
   24585         submit_info.pWaitDstStageMask = flags;
   24586         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   24587     }
   24588 
   24589     vkQueueSubmit(m_device->m_queue, 0, NULL, fence);
   24590 
   24591     VkResult err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
   24592     ASSERT_VK_SUCCESS(err);
   24593 
   24594     vkDestroyFence(m_device->device(), fence, nullptr);
   24595     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
   24596     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
   24597 
   24598     m_errorMonitor->VerifyNotFound();
   24599 }
   24600 
   24601 // This is a positive test.  No errors should be generated.
   24602 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsOneQueueOneFence) {
   24603     TEST_DESCRIPTION(
   24604         "Two command buffers, each in a separate QueueSubmit call on the same queue, the second having a fence, followed by a "
   24605         "WaitForFences call.");
   24606 
   24607     m_errorMonitor->ExpectSuccess();
   24608 
   24609     ASSERT_NO_FATAL_FAILURE(Init());
   24610     VkFence fence;
   24611     VkFenceCreateInfo fence_create_info{};
   24612     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
   24613     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
   24614 
   24615     VkCommandPool command_pool;
   24616     VkCommandPoolCreateInfo pool_create_info{};
   24617     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
   24618     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
   24619     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
   24620     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
   24621 
   24622     VkCommandBuffer command_buffer[2];
   24623     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
   24624     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
   24625     command_buffer_allocate_info.commandPool = command_pool;
   24626     command_buffer_allocate_info.commandBufferCount = 2;
   24627     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
   24628     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
   24629 
   24630     {
   24631         VkCommandBufferBeginInfo begin_info{};
   24632         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   24633         vkBeginCommandBuffer(command_buffer[0], &begin_info);
   24634 
   24635         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
   24636                              nullptr, 0, nullptr, 0, nullptr);
   24637 
   24638         VkViewport viewport{};
   24639         viewport.maxDepth = 1.0f;
   24640         viewport.minDepth = 0.0f;
   24641         viewport.width = 512;
   24642         viewport.height = 512;
   24643         viewport.x = 0;
   24644         viewport.y = 0;
   24645         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
   24646         vkEndCommandBuffer(command_buffer[0]);
   24647     }
   24648     {
   24649         VkCommandBufferBeginInfo begin_info{};
   24650         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   24651         vkBeginCommandBuffer(command_buffer[1], &begin_info);
   24652 
   24653         VkViewport viewport{};
   24654         viewport.maxDepth = 1.0f;
   24655         viewport.minDepth = 0.0f;
   24656         viewport.width = 512;
   24657         viewport.height = 512;
   24658         viewport.x = 0;
   24659         viewport.y = 0;
   24660         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
   24661         vkEndCommandBuffer(command_buffer[1]);
   24662     }
   24663     {
   24664         VkSubmitInfo submit_info{};
   24665         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   24666         submit_info.commandBufferCount = 1;
   24667         submit_info.pCommandBuffers = &command_buffer[0];
   24668         submit_info.signalSemaphoreCount = 0;
   24669         submit_info.pSignalSemaphores = VK_NULL_HANDLE;
   24670         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
   24671     }
   24672     {
   24673         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
   24674         VkSubmitInfo submit_info{};
   24675         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   24676         submit_info.commandBufferCount = 1;
   24677         submit_info.pCommandBuffers = &command_buffer[1];
   24678         submit_info.waitSemaphoreCount = 0;
   24679         submit_info.pWaitSemaphores = VK_NULL_HANDLE;
   24680         submit_info.pWaitDstStageMask = flags;
   24681         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
   24682     }
   24683 
   24684     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
   24685 
   24686     vkDestroyFence(m_device->device(), fence, nullptr);
   24687     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
   24688     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
   24689 
   24690     m_errorMonitor->VerifyNotFound();
   24691 }
   24692 
   24693 // This is a positive test.  No errors should be generated.
   24694 TEST_F(VkPositiveLayerTest, TwoSubmitInfosWithSemaphoreOneQueueSubmitsOneFence) {
   24695     TEST_DESCRIPTION(
   24696         "Two command buffers each in a separate SubmitInfo sent in a single QueueSubmit call followed by a WaitForFences call.");
   24697     ASSERT_NO_FATAL_FAILURE(Init());
   24698 
   24699     m_errorMonitor->ExpectSuccess();
   24700 
   24701     VkFence fence;
   24702     VkFenceCreateInfo fence_create_info{};
   24703     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
   24704     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
   24705 
   24706     VkSemaphore semaphore;
   24707     VkSemaphoreCreateInfo semaphore_create_info{};
   24708     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
   24709     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
   24710 
   24711     VkCommandPool command_pool;
   24712     VkCommandPoolCreateInfo pool_create_info{};
   24713     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
   24714     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
   24715     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
   24716     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
   24717 
   24718     VkCommandBuffer command_buffer[2];
   24719     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
   24720     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
   24721     command_buffer_allocate_info.commandPool = command_pool;
   24722     command_buffer_allocate_info.commandBufferCount = 2;
   24723     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
   24724     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
   24725 
   24726     {
   24727         VkCommandBufferBeginInfo begin_info{};
   24728         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   24729         vkBeginCommandBuffer(command_buffer[0], &begin_info);
   24730 
   24731         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
   24732                              nullptr, 0, nullptr, 0, nullptr);
   24733 
   24734         VkViewport viewport{};
   24735         viewport.maxDepth = 1.0f;
   24736         viewport.minDepth = 0.0f;
   24737         viewport.width = 512;
   24738         viewport.height = 512;
   24739         viewport.x = 0;
   24740         viewport.y = 0;
   24741         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
   24742         vkEndCommandBuffer(command_buffer[0]);
   24743     }
   24744     {
   24745         VkCommandBufferBeginInfo begin_info{};
   24746         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
   24747         vkBeginCommandBuffer(command_buffer[1], &begin_info);
   24748 
   24749         VkViewport viewport{};
   24750         viewport.maxDepth = 1.0f;
   24751         viewport.minDepth = 0.0f;
   24752         viewport.width = 512;
   24753         viewport.height = 512;
   24754         viewport.x = 0;
   24755         viewport.y = 0;
   24756         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
   24757         vkEndCommandBuffer(command_buffer[1]);
   24758     }
   24759     {
   24760         VkSubmitInfo submit_info[2];
   24761         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
   24762 
   24763         submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   24764         submit_info[0].pNext = NULL;
   24765         submit_info[0].commandBufferCount = 1;
   24766         submit_info[0].pCommandBuffers = &command_buffer[0];
   24767         submit_info[0].signalSemaphoreCount = 1;
   24768         submit_info[0].pSignalSemaphores = &semaphore;
   24769         submit_info[0].waitSemaphoreCount = 0;
   24770         submit_info[0].pWaitSemaphores = NULL;
   24771         submit_info[0].pWaitDstStageMask = 0;
   24772 
   24773         submit_info[1].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   24774         submit_info[1].pNext = NULL;
   24775         submit_info[1].commandBufferCount = 1;
   24776         submit_info[1].pCommandBuffers = &command_buffer[1];
   24777         submit_info[1].waitSemaphoreCount = 1;
   24778         submit_info[1].pWaitSemaphores = &semaphore;
   24779         submit_info[1].pWaitDstStageMask = flags;
   24780         submit_info[1].signalSemaphoreCount = 0;
   24781         submit_info[1].pSignalSemaphores = NULL;
   24782         vkQueueSubmit(m_device->m_queue, 2, &submit_info[0], fence);
   24783     }
   24784 
   24785     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
   24786 
   24787     vkDestroyFence(m_device->device(), fence, nullptr);
   24788     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
   24789     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
   24790     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
   24791 
   24792     m_errorMonitor->VerifyNotFound();
   24793 }
   24794 
   24795 TEST_F(VkPositiveLayerTest, RenderPassSecondaryCommandBuffersMultipleTimes) {
   24796     m_errorMonitor->ExpectSuccess();
   24797 
   24798     ASSERT_NO_FATAL_FAILURE(Init());
   24799     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   24800 
   24801     m_commandBuffer->begin();
   24802 
   24803     vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
   24804     vkCmdEndRenderPass(m_commandBuffer->handle());
   24805     m_errorMonitor->VerifyNotFound();
   24806     vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
   24807     m_errorMonitor->VerifyNotFound();
   24808     vkCmdEndRenderPass(m_commandBuffer->handle());
   24809     m_errorMonitor->VerifyNotFound();
   24810 
   24811     m_commandBuffer->end();
   24812     m_errorMonitor->VerifyNotFound();
   24813 }
   24814 
   24815 TEST_F(VkPositiveLayerTest, ValidRenderPassAttachmentLayoutWithLoadOp) {
   24816     TEST_DESCRIPTION(
   24817         "Positive test where we create a renderpass with an attachment that uses LOAD_OP_CLEAR, the first subpass has a valid "
   24818         "layout, and a second subpass then uses a valid *READ_ONLY* layout.");
   24819     m_errorMonitor->ExpectSuccess();
   24820     ASSERT_NO_FATAL_FAILURE(Init());
   24821     auto depth_format = FindSupportedDepthStencilFormat(gpu());
   24822     if (!depth_format) {
   24823         printf("             No Depth + Stencil format found. Skipped.\n");
   24824         return;
   24825     }
   24826 
   24827     VkAttachmentReference attach[2] = {};
   24828     attach[0].attachment = 0;
   24829     attach[0].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
   24830     attach[1].attachment = 0;
   24831     attach[1].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
   24832     VkSubpassDescription subpasses[2] = {};
   24833     // First subpass clears DS attach on load
   24834     subpasses[0].pDepthStencilAttachment = &attach[0];
   24835     // 2nd subpass reads in DS as input attachment
   24836     subpasses[1].inputAttachmentCount = 1;
   24837     subpasses[1].pInputAttachments = &attach[1];
   24838     VkAttachmentDescription attach_desc = {};
   24839     attach_desc.format = depth_format;
   24840     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
   24841     attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
   24842     attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
   24843     attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
   24844     attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
   24845     attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
   24846     attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
   24847     VkRenderPassCreateInfo rpci = {};
   24848     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
   24849     rpci.attachmentCount = 1;
   24850     rpci.pAttachments = &attach_desc;
   24851     rpci.subpassCount = 2;
   24852     rpci.pSubpasses = subpasses;
   24853 
   24854     // Now create RenderPass and verify no errors
   24855     VkRenderPass rp;
   24856     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
   24857     m_errorMonitor->VerifyNotFound();
   24858 
   24859     vkDestroyRenderPass(m_device->device(), rp, NULL);
   24860 }
   24861 
   24862 TEST_F(VkPositiveLayerTest, RenderPassDepthStencilLayoutTransition) {
   24863     TEST_DESCRIPTION(
   24864         "Create a render pass with depth-stencil attachment where layout transition from UNDEFINED TO DS_READ_ONLY_OPTIMAL is set "
   24865         "by render pass and verify that transition has correctly occurred at queue submit time with no validation errors.");
   24866 
   24867     ASSERT_NO_FATAL_FAILURE(Init());
   24868     auto depth_format = FindSupportedDepthStencilFormat(gpu());
   24869     if (!depth_format) {
   24870         printf("             No Depth + Stencil format found. Skipped.\n");
   24871         return;
   24872     }
   24873     VkImageFormatProperties format_props;
   24874     vkGetPhysicalDeviceImageFormatProperties(gpu(), depth_format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
   24875                                              VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 0, &format_props);
   24876     if (format_props.maxExtent.width < 32 || format_props.maxExtent.height < 32) {
   24877         printf("Depth extent too small, RenderPassDepthStencilLayoutTransition skipped.\n");
   24878         return;
   24879     }
   24880 
   24881     m_errorMonitor->ExpectSuccess();
   24882     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   24883 
   24884     // A renderpass with one depth/stencil attachment.
   24885     VkAttachmentDescription attachment = {0,
   24886                                           depth_format,
   24887                                           VK_SAMPLE_COUNT_1_BIT,
   24888                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   24889                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
   24890                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
   24891                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
   24892                                           VK_IMAGE_LAYOUT_UNDEFINED,
   24893                                           VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
   24894 
   24895     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
   24896 
   24897     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &att_ref, 0, nullptr};
   24898 
   24899     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
   24900 
   24901     VkRenderPass rp;
   24902     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   24903     ASSERT_VK_SUCCESS(err);
   24904     // A compatible ds image.
   24905     VkImageObj image(m_device);
   24906     image.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
   24907     ASSERT_TRUE(image.initialized());
   24908 
   24909     VkImageViewCreateInfo ivci = {
   24910         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
   24911         nullptr,
   24912         0,
   24913         image.handle(),
   24914         VK_IMAGE_VIEW_TYPE_2D,
   24915         depth_format,
   24916         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
   24917          VK_COMPONENT_SWIZZLE_IDENTITY},
   24918         {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 1, 0, 1},
   24919     };
   24920     VkImageView view;
   24921     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
   24922     ASSERT_VK_SUCCESS(err);
   24923 
   24924     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
   24925     VkFramebuffer fb;
   24926     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
   24927     ASSERT_VK_SUCCESS(err);
   24928 
   24929     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
   24930     m_commandBuffer->begin();
   24931     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
   24932     vkCmdEndRenderPass(m_commandBuffer->handle());
   24933     m_commandBuffer->end();
   24934     m_commandBuffer->QueueCommandBuffer(false);
   24935     m_errorMonitor->VerifyNotFound();
   24936 
   24937     // Cleanup
   24938     vkDestroyImageView(m_device->device(), view, NULL);
   24939     vkDestroyRenderPass(m_device->device(), rp, NULL);
   24940     vkDestroyFramebuffer(m_device->device(), fb, NULL);
   24941 }
   24942 
   24943 TEST_F(VkPositiveLayerTest, CreatePipelineAttribMatrixType) {
   24944     TEST_DESCRIPTION("Test that pipeline validation accepts matrices passed as vertex attributes");
   24945     m_errorMonitor->ExpectSuccess();
   24946 
   24947     ASSERT_NO_FATAL_FAILURE(Init());
   24948     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   24949 
   24950     VkVertexInputBindingDescription input_binding;
   24951     memset(&input_binding, 0, sizeof(input_binding));
   24952 
   24953     VkVertexInputAttributeDescription input_attribs[2];
   24954     memset(input_attribs, 0, sizeof(input_attribs));
   24955 
   24956     for (int i = 0; i < 2; i++) {
   24957         input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
   24958         input_attribs[i].location = i;
   24959     }
   24960 
   24961     char const *vsSource =
   24962         "#version 450\n"
   24963         "\n"
   24964         "layout(location=0) in mat2x4 x;\n"
   24965         "void main(){\n"
   24966         "   gl_Position = x[0] + x[1];\n"
   24967         "}\n";
   24968     char const *fsSource =
   24969         "#version 450\n"
   24970         "\n"
   24971         "layout(location=0) out vec4 color;\n"
   24972         "void main(){\n"
   24973         "   color = vec4(1);\n"
   24974         "}\n";
   24975 
   24976     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   24977     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   24978 
   24979     VkPipelineObj pipe(m_device);
   24980     pipe.AddDefaultColorAttachment();
   24981     pipe.AddShader(&vs);
   24982     pipe.AddShader(&fs);
   24983 
   24984     pipe.AddVertexInputBindings(&input_binding, 1);
   24985     pipe.AddVertexInputAttribs(input_attribs, 2);
   24986 
   24987     VkDescriptorSetObj descriptorSet(m_device);
   24988     descriptorSet.AppendDummy();
   24989     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   24990 
   24991     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   24992 
   24993     /* expect success */
   24994     m_errorMonitor->VerifyNotFound();
   24995 }
   24996 
   24997 TEST_F(VkPositiveLayerTest, CreatePipelineAttribArrayType) {
   24998     m_errorMonitor->ExpectSuccess();
   24999 
   25000     ASSERT_NO_FATAL_FAILURE(Init());
   25001     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   25002 
   25003     VkVertexInputBindingDescription input_binding;
   25004     memset(&input_binding, 0, sizeof(input_binding));
   25005 
   25006     VkVertexInputAttributeDescription input_attribs[2];
   25007     memset(input_attribs, 0, sizeof(input_attribs));
   25008 
   25009     for (int i = 0; i < 2; i++) {
   25010         input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
   25011         input_attribs[i].location = i;
   25012     }
   25013 
   25014     char const *vsSource =
   25015         "#version 450\n"
   25016         "\n"
   25017         "layout(location=0) in vec4 x[2];\n"
   25018         "void main(){\n"
   25019         "   gl_Position = x[0] + x[1];\n"
   25020         "}\n";
   25021     char const *fsSource =
   25022         "#version 450\n"
   25023         "\n"
   25024         "layout(location=0) out vec4 color;\n"
   25025         "void main(){\n"
   25026         "   color = vec4(1);\n"
   25027         "}\n";
   25028 
   25029     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   25030     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   25031 
   25032     VkPipelineObj pipe(m_device);
   25033     pipe.AddDefaultColorAttachment();
   25034     pipe.AddShader(&vs);
   25035     pipe.AddShader(&fs);
   25036 
   25037     pipe.AddVertexInputBindings(&input_binding, 1);
   25038     pipe.AddVertexInputAttribs(input_attribs, 2);
   25039 
   25040     VkDescriptorSetObj descriptorSet(m_device);
   25041     descriptorSet.AppendDummy();
   25042     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   25043 
   25044     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   25045 
   25046     m_errorMonitor->VerifyNotFound();
   25047 }
   25048 
   25049 TEST_F(VkPositiveLayerTest, CreatePipelineAttribComponents) {
   25050     TEST_DESCRIPTION(
   25051         "Test that pipeline validation accepts consuming a vertex attribute through multiple vertex shader inputs, each consuming "
   25052         "a different subset of the components.");
   25053     m_errorMonitor->ExpectSuccess();
   25054 
   25055     ASSERT_NO_FATAL_FAILURE(Init());
   25056     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   25057 
   25058     VkVertexInputBindingDescription input_binding;
   25059     memset(&input_binding, 0, sizeof(input_binding));
   25060 
   25061     VkVertexInputAttributeDescription input_attribs[3];
   25062     memset(input_attribs, 0, sizeof(input_attribs));
   25063 
   25064     for (int i = 0; i < 3; i++) {
   25065         input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
   25066         input_attribs[i].location = i;
   25067     }
   25068 
   25069     char const *vsSource =
   25070         "#version 450\n"
   25071         "\n"
   25072         "layout(location=0) in vec4 x;\n"
   25073         "layout(location=1) in vec3 y1;\n"
   25074         "layout(location=1, component=3) in float y2;\n"
   25075         "layout(location=2) in vec4 z;\n"
   25076         "void main(){\n"
   25077         "   gl_Position = x + vec4(y1, y2) + z;\n"
   25078         "}\n";
   25079     char const *fsSource =
   25080         "#version 450\n"
   25081         "\n"
   25082         "layout(location=0) out vec4 color;\n"
   25083         "void main(){\n"
   25084         "   color = vec4(1);\n"
   25085         "}\n";
   25086 
   25087     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   25088     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   25089 
   25090     VkPipelineObj pipe(m_device);
   25091     pipe.AddDefaultColorAttachment();
   25092     pipe.AddShader(&vs);
   25093     pipe.AddShader(&fs);
   25094 
   25095     pipe.AddVertexInputBindings(&input_binding, 1);
   25096     pipe.AddVertexInputAttribs(input_attribs, 3);
   25097 
   25098     VkDescriptorSetObj descriptorSet(m_device);
   25099     descriptorSet.AppendDummy();
   25100     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   25101 
   25102     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   25103 
   25104     m_errorMonitor->VerifyNotFound();
   25105 }
   25106 
   25107 TEST_F(VkPositiveLayerTest, CreatePipelineSimplePositive) {
   25108     m_errorMonitor->ExpectSuccess();
   25109 
   25110     ASSERT_NO_FATAL_FAILURE(Init());
   25111     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   25112 
   25113     char const *vsSource =
   25114         "#version 450\n"
   25115         "void main(){\n"
   25116         "   gl_Position = vec4(0);\n"
   25117         "}\n";
   25118     char const *fsSource =
   25119         "#version 450\n"
   25120         "\n"
   25121         "layout(location=0) out vec4 color;\n"
   25122         "void main(){\n"
   25123         "   color = vec4(1);\n"
   25124         "}\n";
   25125 
   25126     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   25127     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   25128 
   25129     VkPipelineObj pipe(m_device);
   25130     pipe.AddDefaultColorAttachment();
   25131     pipe.AddShader(&vs);
   25132     pipe.AddShader(&fs);
   25133 
   25134     VkDescriptorSetObj descriptorSet(m_device);
   25135     descriptorSet.AppendDummy();
   25136     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   25137 
   25138     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   25139 
   25140     m_errorMonitor->VerifyNotFound();
   25141 }
   25142 
   25143 TEST_F(VkPositiveLayerTest, CreatePipelineRelaxedTypeMatch) {
   25144     TEST_DESCRIPTION(
   25145         "Test that pipeline validation accepts the relaxed type matching rules set out in 14.1.3: fundamental type must match, and "
   25146         "producer side must have at least as many components");
   25147     m_errorMonitor->ExpectSuccess();
   25148 
   25149     // VK 1.0.8 Specification, 14.1.3 "Additionally,..." block
   25150 
   25151     ASSERT_NO_FATAL_FAILURE(Init());
   25152     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   25153 
   25154     char const *vsSource =
   25155         "#version 450\n"
   25156         "layout(location=0) out vec3 x;\n"
   25157         "layout(location=1) out ivec3 y;\n"
   25158         "layout(location=2) out vec3 z;\n"
   25159         "void main(){\n"
   25160         "   gl_Position = vec4(0);\n"
   25161         "   x = vec3(0); y = ivec3(0); z = vec3(0);\n"
   25162         "}\n";
   25163     char const *fsSource =
   25164         "#version 450\n"
   25165         "\n"
   25166         "layout(location=0) out vec4 color;\n"
   25167         "layout(location=0) in float x;\n"
   25168         "layout(location=1) flat in int y;\n"
   25169         "layout(location=2) in vec2 z;\n"
   25170         "void main(){\n"
   25171         "   color = vec4(1 + x + y + z.x);\n"
   25172         "}\n";
   25173 
   25174     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   25175     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   25176 
   25177     VkPipelineObj pipe(m_device);
   25178     pipe.AddDefaultColorAttachment();
   25179     pipe.AddShader(&vs);
   25180     pipe.AddShader(&fs);
   25181 
   25182     VkDescriptorSetObj descriptorSet(m_device);
   25183     descriptorSet.AppendDummy();
   25184     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   25185 
   25186     VkResult err = VK_SUCCESS;
   25187     err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   25188     ASSERT_VK_SUCCESS(err);
   25189 
   25190     m_errorMonitor->VerifyNotFound();
   25191 }
   25192 
   25193 TEST_F(VkPositiveLayerTest, CreatePipelineTessPerVertex) {
   25194     TEST_DESCRIPTION("Test that pipeline validation accepts per-vertex variables passed between the TCS and TES stages");
   25195     m_errorMonitor->ExpectSuccess();
   25196 
   25197     ASSERT_NO_FATAL_FAILURE(Init());
   25198     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   25199 
   25200     if (!m_device->phy().features().tessellationShader) {
   25201         printf("             Device does not support tessellation shaders; skipped.\n");
   25202         return;
   25203     }
   25204 
   25205     char const *vsSource =
   25206         "#version 450\n"
   25207         "void main(){}\n";
   25208     char const *tcsSource =
   25209         "#version 450\n"
   25210         "layout(location=0) out int x[];\n"
   25211         "layout(vertices=3) out;\n"
   25212         "void main(){\n"
   25213         "   gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
   25214         "   gl_TessLevelInner[0] = 1;\n"
   25215         "   x[gl_InvocationID] = gl_InvocationID;\n"
   25216         "}\n";
   25217     char const *tesSource =
   25218         "#version 450\n"
   25219         "layout(triangles, equal_spacing, cw) in;\n"
   25220         "layout(location=0) in int x[];\n"
   25221         "void main(){\n"
   25222         "   gl_Position.xyz = gl_TessCoord;\n"
   25223         "   gl_Position.w = x[0] + x[1] + x[2];\n"
   25224         "}\n";
   25225     char const *fsSource =
   25226         "#version 450\n"
   25227         "layout(location=0) out vec4 color;\n"
   25228         "void main(){\n"
   25229         "   color = vec4(1);\n"
   25230         "}\n";
   25231 
   25232     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   25233     VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
   25234     VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
   25235     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   25236 
   25237     VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
   25238                                                  VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
   25239 
   25240     VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
   25241 
   25242     VkPipelineObj pipe(m_device);
   25243     pipe.SetInputAssembly(&iasci);
   25244     pipe.SetTessellation(&tsci);
   25245     pipe.AddDefaultColorAttachment();
   25246     pipe.AddShader(&vs);
   25247     pipe.AddShader(&tcs);
   25248     pipe.AddShader(&tes);
   25249     pipe.AddShader(&fs);
   25250 
   25251     VkDescriptorSetObj descriptorSet(m_device);
   25252     descriptorSet.AppendDummy();
   25253     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   25254 
   25255     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   25256 
   25257     m_errorMonitor->VerifyNotFound();
   25258 }
   25259 
   25260 TEST_F(VkPositiveLayerTest, CreatePipelineGeometryInputBlockPositive) {
   25261     TEST_DESCRIPTION(
   25262         "Test that pipeline validation accepts a user-defined interface block passed into the geometry shader. This is interesting "
   25263         "because the 'extra' array level is not present on the member type, but on the block instance.");
   25264     m_errorMonitor->ExpectSuccess();
   25265 
   25266     ASSERT_NO_FATAL_FAILURE(Init());
   25267     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   25268 
   25269     if (!m_device->phy().features().geometryShader) {
   25270         printf("             Device does not support geometry shaders; skipped.\n");
   25271         return;
   25272     }
   25273 
   25274     char const *vsSource =
   25275         "#version 450\n"
   25276         "layout(location=0) out VertexData { vec4 x; } vs_out;\n"
   25277         "void main(){\n"
   25278         "   vs_out.x = vec4(1);\n"
   25279         "}\n";
   25280     char const *gsSource =
   25281         "#version 450\n"
   25282         "layout(triangles) in;\n"
   25283         "layout(triangle_strip, max_vertices=3) out;\n"
   25284         "layout(location=0) in VertexData { vec4 x; } gs_in[];\n"
   25285         "void main() {\n"
   25286         "   gl_Position = gs_in[0].x;\n"
   25287         "   EmitVertex();\n"
   25288         "}\n";
   25289     char const *fsSource =
   25290         "#version 450\n"
   25291         "layout(location=0) out vec4 color;\n"
   25292         "void main(){\n"
   25293         "   color = vec4(1);\n"
   25294         "}\n";
   25295 
   25296     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   25297     VkShaderObj gs(m_device, gsSource, VK_SHADER_STAGE_GEOMETRY_BIT, this);
   25298     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   25299 
   25300     VkPipelineObj pipe(m_device);
   25301     pipe.AddDefaultColorAttachment();
   25302     pipe.AddShader(&vs);
   25303     pipe.AddShader(&gs);
   25304     pipe.AddShader(&fs);
   25305 
   25306     VkDescriptorSetObj descriptorSet(m_device);
   25307     descriptorSet.AppendDummy();
   25308     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   25309 
   25310     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   25311 
   25312     m_errorMonitor->VerifyNotFound();
   25313 }
   25314 
   25315 TEST_F(VkPositiveLayerTest, CreatePipeline64BitAttributesPositive) {
   25316     TEST_DESCRIPTION(
   25317         "Test that pipeline validation accepts basic use of 64bit vertex attributes. This is interesting because they consume "
   25318         "multiple locations.");
   25319     m_errorMonitor->ExpectSuccess();
   25320 
   25321     if (!EnableDeviceProfileLayer()) return;
   25322 
   25323     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   25324     ASSERT_NO_FATAL_FAILURE(InitState());
   25325     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   25326 
   25327     if (!m_device->phy().features().shaderFloat64) {
   25328         printf("             Device does not support 64bit vertex attributes; skipped.\n");
   25329         return;
   25330     }
   25331     // Set 64bit format to support VTX Buffer feature
   25332     PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr;
   25333     PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr;
   25334 
   25335     // Load required functions
   25336     if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) {
   25337         return;
   25338     }
   25339     VkFormatProperties format_props;
   25340     fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R64G64B64A64_SFLOAT, &format_props);
   25341     format_props.bufferFeatures |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;
   25342     fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R64G64B64A64_SFLOAT, format_props);
   25343 
   25344     VkVertexInputBindingDescription input_bindings[1];
   25345     memset(input_bindings, 0, sizeof(input_bindings));
   25346 
   25347     VkVertexInputAttributeDescription input_attribs[4];
   25348     memset(input_attribs, 0, sizeof(input_attribs));
   25349     input_attribs[0].location = 0;
   25350     input_attribs[0].offset = 0;
   25351     input_attribs[0].format = VK_FORMAT_R64G64B64A64_SFLOAT;
   25352     input_attribs[1].location = 2;
   25353     input_attribs[1].offset = 32;
   25354     input_attribs[1].format = VK_FORMAT_R64G64B64A64_SFLOAT;
   25355     input_attribs[2].location = 4;
   25356     input_attribs[2].offset = 64;
   25357     input_attribs[2].format = VK_FORMAT_R64G64B64A64_SFLOAT;
   25358     input_attribs[3].location = 6;
   25359     input_attribs[3].offset = 96;
   25360     input_attribs[3].format = VK_FORMAT_R64G64B64A64_SFLOAT;
   25361 
   25362     char const *vsSource =
   25363         "#version 450\n"
   25364         "\n"
   25365         "layout(location=0) in dmat4 x;\n"
   25366         "void main(){\n"
   25367         "   gl_Position = vec4(x[0][0]);\n"
   25368         "}\n";
   25369     char const *fsSource =
   25370         "#version 450\n"
   25371         "\n"
   25372         "layout(location=0) out vec4 color;\n"
   25373         "void main(){\n"
   25374         "   color = vec4(1);\n"
   25375         "}\n";
   25376 
   25377     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   25378     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   25379 
   25380     VkPipelineObj pipe(m_device);
   25381     pipe.AddDefaultColorAttachment();
   25382     pipe.AddShader(&vs);
   25383     pipe.AddShader(&fs);
   25384 
   25385     pipe.AddVertexInputBindings(input_bindings, 1);
   25386     pipe.AddVertexInputAttribs(input_attribs, 4);
   25387 
   25388     VkDescriptorSetObj descriptorSet(m_device);
   25389     descriptorSet.AppendDummy();
   25390     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   25391 
   25392     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
   25393 
   25394     m_errorMonitor->VerifyNotFound();
   25395 }
   25396 
   25397 TEST_F(VkPositiveLayerTest, CreatePipelineInputAttachmentPositive) {
   25398     TEST_DESCRIPTION("Positive test for a correctly matched input attachment");
   25399     m_errorMonitor->ExpectSuccess();
   25400 
   25401     ASSERT_NO_FATAL_FAILURE(Init());
   25402 
   25403     char const *vsSource =
   25404         "#version 450\n"
   25405         "\n"
   25406         "void main(){\n"
   25407         "    gl_Position = vec4(1);\n"
   25408         "}\n";
   25409     char const *fsSource =
   25410         "#version 450\n"
   25411         "\n"
   25412         "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
   25413         "layout(location=0) out vec4 color;\n"
   25414         "void main() {\n"
   25415         "   color = subpassLoad(x);\n"
   25416         "}\n";
   25417 
   25418     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
   25419     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   25420 
   25421     VkPipelineObj pipe(m_device);
   25422     pipe.AddShader(&vs);
   25423     pipe.AddShader(&fs);
   25424     pipe.AddDefaultColorAttachment();
   25425     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   25426 
   25427     VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
   25428     const VkDescriptorSetLayoutObj dsl(m_device, {dslb});
   25429     const VkPipelineLayoutObj pl(m_device, {&dsl});
   25430 
   25431     VkAttachmentDescription descs[2] = {
   25432         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
   25433          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   25434          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
   25435         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
   25436          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
   25437     };
   25438     VkAttachmentReference color = {
   25439         0,
   25440         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
   25441     };
   25442     VkAttachmentReference input = {
   25443         1,
   25444         VK_IMAGE_LAYOUT_GENERAL,
   25445     };
   25446 
   25447     VkSubpassDescription sd = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr};
   25448 
   25449     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr};
   25450     VkRenderPass rp;
   25451     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
   25452     ASSERT_VK_SUCCESS(err);
   25453 
   25454     // should be OK. would go wrong here if it's going to...
   25455     pipe.CreateVKPipeline(pl.handle(), rp);
   25456 
   25457     m_errorMonitor->VerifyNotFound();
   25458 
   25459     vkDestroyRenderPass(m_device->device(), rp, nullptr);
   25460 }
   25461 
   25462 TEST_F(VkPositiveLayerTest, CreateComputePipelineMissingDescriptorUnusedPositive) {
   25463     TEST_DESCRIPTION(
   25464         "Test that pipeline validation accepts a compute pipeline which declares a descriptor-backed resource which is not "
   25465         "provided, but the shader does not statically use it. This is interesting because it requires compute pipelines to have a "
   25466         "proper descriptor use walk, which they didn't for some time.");
   25467     m_errorMonitor->ExpectSuccess();
   25468 
   25469     ASSERT_NO_FATAL_FAILURE(Init());
   25470 
   25471     char const *csSource =
   25472         "#version 450\n"
   25473         "\n"
   25474         "layout(local_size_x=1) in;\n"
   25475         "layout(set=0, binding=0) buffer block { vec4 x; };\n"
   25476         "void main(){\n"
   25477         "   // x is not used.\n"
   25478         "}\n";
   25479 
   25480     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
   25481 
   25482     VkDescriptorSetObj descriptorSet(m_device);
   25483     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
   25484 
   25485     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
   25486                                         nullptr,
   25487                                         0,
   25488                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
   25489                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
   25490                                         descriptorSet.GetPipelineLayout(),
   25491                                         VK_NULL_HANDLE,
   25492                                         -1};
   25493 
   25494     VkPipeline pipe;
   25495     VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
   25496 
   25497     m_errorMonitor->VerifyNotFound();
   25498 
   25499     if (err == VK_SUCCESS) {
   25500         vkDestroyPipeline(m_device->device(), pipe, nullptr);
   25501     }
   25502 }
   25503 
   25504 TEST_F(VkPositiveLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsSampler) {
   25505     TEST_DESCRIPTION(
   25506         "Test that pipeline validation accepts a shader consuming only the sampler portion of a combined image + sampler");
   25507     m_errorMonitor->ExpectSuccess();
   25508 
   25509     ASSERT_NO_FATAL_FAILURE(Init());
   25510 
   25511     std::vector<VkDescriptorSetLayoutBinding> bindings = {
   25512         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
   25513         {1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
   25514         {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
   25515     };
   25516 
   25517     const VkDescriptorSetLayoutObj dsl(m_device, bindings);
   25518     const VkPipelineLayoutObj pl(m_device, {&dsl});
   25519 
   25520     char const *csSource =
   25521         "#version 450\n"
   25522         "\n"
   25523         "layout(local_size_x=1) in;\n"
   25524         "layout(set=0, binding=0) uniform sampler s;\n"
   25525         "layout(set=0, binding=1) uniform texture2D t;\n"
   25526         "layout(set=0, binding=2) buffer block { vec4 x; };\n"
   25527         "void main() {\n"
   25528         "   x = texture(sampler2D(t, s), vec2(0));\n"
   25529         "}\n";
   25530     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
   25531 
   25532     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
   25533                                         nullptr,
   25534                                         0,
   25535                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
   25536                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
   25537                                         pl.handle(),
   25538                                         VK_NULL_HANDLE,
   25539                                         -1};
   25540 
   25541     VkPipeline pipe;
   25542     VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
   25543 
   25544     m_errorMonitor->VerifyNotFound();
   25545 
   25546     if (err == VK_SUCCESS) {
   25547         vkDestroyPipeline(m_device->device(), pipe, nullptr);
   25548     }
   25549 }
   25550 
   25551 TEST_F(VkPositiveLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsImage) {
   25552     TEST_DESCRIPTION(
   25553         "Test that pipeline validation accepts a shader consuming only the image portion of a combined image + sampler");
   25554     m_errorMonitor->ExpectSuccess();
   25555 
   25556     ASSERT_NO_FATAL_FAILURE(Init());
   25557 
   25558     std::vector<VkDescriptorSetLayoutBinding> bindings = {
   25559         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
   25560         {1, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
   25561         {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
   25562     };
   25563 
   25564     const VkDescriptorSetLayoutObj dsl(m_device, bindings);
   25565     const VkPipelineLayoutObj pl(m_device, {&dsl});
   25566 
   25567     char const *csSource =
   25568         "#version 450\n"
   25569         "\n"
   25570         "layout(local_size_x=1) in;\n"
   25571         "layout(set=0, binding=0) uniform texture2D t;\n"
   25572         "layout(set=0, binding=1) uniform sampler s;\n"
   25573         "layout(set=0, binding=2) buffer block { vec4 x; };\n"
   25574         "void main() {\n"
   25575         "   x = texture(sampler2D(t, s), vec2(0));\n"
   25576         "}\n";
   25577     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
   25578 
   25579     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
   25580                                         nullptr,
   25581                                         0,
   25582                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
   25583                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
   25584                                         pl.handle(),
   25585                                         VK_NULL_HANDLE,
   25586                                         -1};
   25587 
   25588     VkPipeline pipe;
   25589     VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
   25590 
   25591     m_errorMonitor->VerifyNotFound();
   25592 
   25593     if (err == VK_SUCCESS) {
   25594         vkDestroyPipeline(m_device->device(), pipe, nullptr);
   25595     }
   25596 }
   25597 
   25598 TEST_F(VkPositiveLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsBoth) {
   25599     TEST_DESCRIPTION(
   25600         "Test that pipeline validation accepts a shader consuming both the sampler and the image of a combined image+sampler but "
   25601         "via separate variables");
   25602     m_errorMonitor->ExpectSuccess();
   25603 
   25604     ASSERT_NO_FATAL_FAILURE(Init());
   25605 
   25606     std::vector<VkDescriptorSetLayoutBinding> bindings = {
   25607         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
   25608         {1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
   25609     };
   25610 
   25611     const VkDescriptorSetLayoutObj dsl(m_device, bindings);
   25612     const VkPipelineLayoutObj pl(m_device, {&dsl});
   25613 
   25614     char const *csSource =
   25615         "#version 450\n"
   25616         "\n"
   25617         "layout(local_size_x=1) in;\n"
   25618         "layout(set=0, binding=0) uniform texture2D t;\n"
   25619         "layout(set=0, binding=0) uniform sampler s;  // both binding 0!\n"
   25620         "layout(set=0, binding=1) buffer block { vec4 x; };\n"
   25621         "void main() {\n"
   25622         "   x = texture(sampler2D(t, s), vec2(0));\n"
   25623         "}\n";
   25624     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
   25625 
   25626     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
   25627                                         nullptr,
   25628                                         0,
   25629                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
   25630                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
   25631                                         pl.handle(),
   25632                                         VK_NULL_HANDLE,
   25633                                         -1};
   25634 
   25635     VkPipeline pipe;
   25636     VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
   25637 
   25638     m_errorMonitor->VerifyNotFound();
   25639 
   25640     if (err == VK_SUCCESS) {
   25641         vkDestroyPipeline(m_device->device(), pipe, nullptr);
   25642     }
   25643 }
   25644 
   25645 TEST_F(VkPositiveLayerTest, CreateDescriptorSetBindingWithIgnoredSamplers) {
   25646     TEST_DESCRIPTION("Test that layers conditionally do ignore the pImmutableSamplers on vkCreateDescriptorSetLayout");
   25647 
   25648     bool prop2_found = false;
   25649     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
   25650         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
   25651         prop2_found = true;
   25652     } else {
   25653         printf("             %s Extension not supported, skipping push descriptor sub-tests\n",
   25654                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
   25655     }
   25656 
   25657     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   25658     bool push_descriptor_found = false;
   25659     if (prop2_found && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
   25660         m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
   25661         push_descriptor_found = true;
   25662     } else {
   25663         printf("             %s Extension not supported, skipping push descriptor sub-tests\n",
   25664                VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
   25665     }
   25666 
   25667     ASSERT_NO_FATAL_FAILURE(InitState());
   25668     const uint64_t fake_address_64 = 0xCDCDCDCDCDCDCDCD;
   25669     const uint64_t fake_address_32 = 0xCDCDCDCD;
   25670     const void *fake_pointer =
   25671         sizeof(void *) == 8 ? reinterpret_cast<void *>(fake_address_64) : reinterpret_cast<void *>(fake_address_32);
   25672     const VkSampler *hopefully_undereferencable_pointer = reinterpret_cast<const VkSampler *>(fake_pointer);
   25673 
   25674     // regular descriptors
   25675     m_errorMonitor->ExpectSuccess();
   25676     {
   25677         const VkDescriptorSetLayoutBinding non_sampler_bindings[] = {
   25678             {0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
   25679             {1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
   25680             {2, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
   25681             {3, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
   25682             {4, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
   25683             {5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
   25684             {6, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
   25685             {7, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
   25686             {8, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
   25687         };
   25688         const VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0,
   25689                                                        static_cast<uint32_t>(size(non_sampler_bindings)), non_sampler_bindings};
   25690         VkDescriptorSetLayout dsl;
   25691         const VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
   25692         ASSERT_VK_SUCCESS(err);
   25693         vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
   25694     }
   25695     m_errorMonitor->VerifyNotFound();
   25696 
   25697     if (push_descriptor_found) {
   25698         // push descriptors
   25699         m_errorMonitor->ExpectSuccess();
   25700         {
   25701             const VkDescriptorSetLayoutBinding non_sampler_bindings[] = {
   25702                 {0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
   25703                 {1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
   25704                 {2, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
   25705                 {3, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
   25706                 {4, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
   25707                 {5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
   25708                 {6, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
   25709             };
   25710             const VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr,
   25711                                                            VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
   25712                                                            static_cast<uint32_t>(size(non_sampler_bindings)), non_sampler_bindings};
   25713             VkDescriptorSetLayout dsl;
   25714             const VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
   25715             ASSERT_VK_SUCCESS(err);
   25716             vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
   25717         }
   25718         m_errorMonitor->VerifyNotFound();
   25719     }
   25720 }
   25721 
   25722 TEST_F(VkPositiveLayerTest, Maintenance1Tests) {
   25723     TEST_DESCRIPTION("Validate various special cases for the Maintenance1_KHR extension");
   25724 
   25725     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   25726     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
   25727         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
   25728     } else {
   25729         printf("             Maintenance1 Extension not supported, skipping tests\n");
   25730         return;
   25731     }
   25732     ASSERT_NO_FATAL_FAILURE(InitState());
   25733 
   25734     m_errorMonitor->ExpectSuccess();
   25735 
   25736     VkCommandBufferObj cmd_buf(m_device, m_commandPool);
   25737     cmd_buf.begin();
   25738     // Set Negative height, should give error if Maintenance 1 is not enabled
   25739     VkViewport viewport = {0, 0, 16, -16, 0, 1};
   25740     vkCmdSetViewport(cmd_buf.handle(), 0, 1, &viewport);
   25741     cmd_buf.end();
   25742 
   25743     m_errorMonitor->VerifyNotFound();
   25744 }
   25745 
   25746 TEST_F(VkLayerTest, DuplicateValidPNextStructures) {
   25747     TEST_DESCRIPTION("Create a pNext chain containing valid strutures, but with a duplicate structure type");
   25748 
   25749     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   25750     if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME)) {
   25751         m_device_extension_names.push_back(VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME);
   25752     } else {
   25753         printf("             VK_NV_dedicated_allocation extension not supported, skipping test\n");
   25754         return;
   25755     }
   25756     ASSERT_NO_FATAL_FAILURE(InitState());
   25757 
   25758     // Create two pNext structures which by themselves would be valid
   25759     VkDedicatedAllocationBufferCreateInfoNV dedicated_buffer_create_info = {};
   25760     VkDedicatedAllocationBufferCreateInfoNV dedicated_buffer_create_info_2 = {};
   25761     dedicated_buffer_create_info.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV;
   25762     dedicated_buffer_create_info.pNext = &dedicated_buffer_create_info_2;
   25763     dedicated_buffer_create_info.dedicatedAllocation = VK_TRUE;
   25764 
   25765     dedicated_buffer_create_info_2.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV;
   25766     dedicated_buffer_create_info_2.pNext = nullptr;
   25767     dedicated_buffer_create_info_2.dedicatedAllocation = VK_TRUE;
   25768 
   25769     uint32_t queue_family_index = 0;
   25770     VkBufferCreateInfo buffer_create_info = {};
   25771     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   25772     buffer_create_info.pNext = &dedicated_buffer_create_info;
   25773     buffer_create_info.size = 1024;
   25774     buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
   25775     buffer_create_info.queueFamilyIndexCount = 1;
   25776     buffer_create_info.pQueueFamilyIndices = &queue_family_index;
   25777 
   25778     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "chain contains duplicate structure types");
   25779     VkBuffer buffer;
   25780     vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
   25781     m_errorMonitor->VerifyFound();
   25782 }
   25783 
   25784 TEST_F(VkPositiveLayerTest, ValidStructPNext) {
   25785     TEST_DESCRIPTION("Verify that a valid pNext value is handled correctly");
   25786 
   25787     // Positive test to check parameter_validation and unique_objects support for NV_dedicated_allocation
   25788     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   25789     if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME)) {
   25790         m_device_extension_names.push_back(VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME);
   25791     } else {
   25792         printf("             VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME Extension not supported, skipping test\n");
   25793         return;
   25794     }
   25795     ASSERT_NO_FATAL_FAILURE(InitState());
   25796 
   25797     m_errorMonitor->ExpectSuccess();
   25798 
   25799     VkDedicatedAllocationBufferCreateInfoNV dedicated_buffer_create_info = {};
   25800     dedicated_buffer_create_info.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV;
   25801     dedicated_buffer_create_info.pNext = nullptr;
   25802     dedicated_buffer_create_info.dedicatedAllocation = VK_TRUE;
   25803 
   25804     uint32_t queue_family_index = 0;
   25805     VkBufferCreateInfo buffer_create_info = {};
   25806     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
   25807     buffer_create_info.pNext = &dedicated_buffer_create_info;
   25808     buffer_create_info.size = 1024;
   25809     buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
   25810     buffer_create_info.queueFamilyIndexCount = 1;
   25811     buffer_create_info.pQueueFamilyIndices = &queue_family_index;
   25812 
   25813     VkBuffer buffer;
   25814     VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
   25815     ASSERT_VK_SUCCESS(err);
   25816 
   25817     VkMemoryRequirements memory_reqs;
   25818     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
   25819 
   25820     VkDedicatedAllocationMemoryAllocateInfoNV dedicated_memory_info = {};
   25821     dedicated_memory_info.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV;
   25822     dedicated_memory_info.pNext = nullptr;
   25823     dedicated_memory_info.buffer = buffer;
   25824     dedicated_memory_info.image = VK_NULL_HANDLE;
   25825 
   25826     VkMemoryAllocateInfo memory_info = {};
   25827     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
   25828     memory_info.pNext = &dedicated_memory_info;
   25829     memory_info.allocationSize = memory_reqs.size;
   25830 
   25831     bool pass;
   25832     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
   25833     ASSERT_TRUE(pass);
   25834 
   25835     VkDeviceMemory buffer_memory;
   25836     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
   25837     ASSERT_VK_SUCCESS(err);
   25838 
   25839     err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
   25840     ASSERT_VK_SUCCESS(err);
   25841 
   25842     vkDestroyBuffer(m_device->device(), buffer, NULL);
   25843     vkFreeMemory(m_device->device(), buffer_memory, NULL);
   25844 
   25845     m_errorMonitor->VerifyNotFound();
   25846 }
   25847 
   25848 TEST_F(VkPositiveLayerTest, PSOPolygonModeValid) {
   25849     TEST_DESCRIPTION("Verify that using a solid polygon fill mode works correctly.");
   25850 
   25851     ASSERT_NO_FATAL_FAILURE(Init());
   25852     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   25853 
   25854     std::vector<const char *> device_extension_names;
   25855     auto features = m_device->phy().features();
   25856     // Artificially disable support for non-solid fill modes
   25857     features.fillModeNonSolid = false;
   25858     // The sacrificial device object
   25859     VkDeviceObj test_device(0, gpu(), device_extension_names, &features);
   25860 
   25861     VkRenderpassObj render_pass(&test_device);
   25862 
   25863     const VkPipelineLayoutObj pipeline_layout(&test_device);
   25864 
   25865     VkPipelineRasterizationStateCreateInfo rs_ci = {};
   25866     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
   25867     rs_ci.pNext = nullptr;
   25868     rs_ci.lineWidth = 1.0f;
   25869     rs_ci.rasterizerDiscardEnable = true;
   25870 
   25871     VkShaderObj vs(&test_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   25872     VkShaderObj fs(&test_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   25873 
   25874     // Set polygonMode=FILL. No error is expected
   25875     m_errorMonitor->ExpectSuccess();
   25876     {
   25877         VkPipelineObj pipe(&test_device);
   25878         pipe.AddShader(&vs);
   25879         pipe.AddShader(&fs);
   25880         pipe.AddDefaultColorAttachment();
   25881         // Set polygonMode to a good value
   25882         rs_ci.polygonMode = VK_POLYGON_MODE_FILL;
   25883         pipe.SetRasterization(&rs_ci);
   25884         pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle());
   25885     }
   25886     m_errorMonitor->VerifyNotFound();
   25887 }
   25888 
   25889 TEST_F(VkPositiveLayerTest, LongSemaphoreChain) {
   25890     m_errorMonitor->ExpectSuccess();
   25891 
   25892     ASSERT_NO_FATAL_FAILURE(Init());
   25893     VkResult err;
   25894 
   25895     std::vector<VkSemaphore> semaphores;
   25896 
   25897     const int chainLength = 32768;
   25898     VkPipelineStageFlags flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
   25899 
   25900     for (int i = 0; i < chainLength; i++) {
   25901         VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
   25902         VkSemaphore semaphore;
   25903         err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &semaphore);
   25904         ASSERT_VK_SUCCESS(err);
   25905 
   25906         semaphores.push_back(semaphore);
   25907 
   25908         VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO,
   25909                            nullptr,
   25910                            semaphores.size() > 1 ? 1u : 0u,
   25911                            semaphores.size() > 1 ? &semaphores[semaphores.size() - 2] : nullptr,
   25912                            &flags,
   25913                            0,
   25914                            nullptr,
   25915                            1,
   25916                            &semaphores[semaphores.size() - 1]};
   25917         err = vkQueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE);
   25918         ASSERT_VK_SUCCESS(err);
   25919     }
   25920 
   25921     VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
   25922     VkFence fence;
   25923     err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
   25924     ASSERT_VK_SUCCESS(err);
   25925     VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &semaphores.back(), &flags, 0, nullptr, 0, nullptr};
   25926     err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
   25927     ASSERT_VK_SUCCESS(err);
   25928 
   25929     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
   25930 
   25931     for (auto semaphore : semaphores) vkDestroySemaphore(m_device->device(), semaphore, nullptr);
   25932 
   25933     vkDestroyFence(m_device->device(), fence, nullptr);
   25934 
   25935     m_errorMonitor->VerifyNotFound();
   25936 }
   25937 
   25938 TEST_F(VkPositiveLayerTest, ExternalSemaphore) {
   25939 #ifdef _WIN32
   25940     const auto extension_name = VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME;
   25941     const auto handle_type = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR;
   25942 #else
   25943     const auto extension_name = VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME;
   25944     const auto handle_type = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
   25945 #endif
   25946     // Check for external semaphore instance extensions
   25947     if (InstanceExtensionSupported(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME)) {
   25948         m_instance_extension_names.push_back(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
   25949         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
   25950     } else {
   25951         printf("             External semaphore extension not supported, skipping test\n");
   25952         return;
   25953     }
   25954     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   25955 
   25956     // Check for external semaphore device extensions
   25957     if (DeviceExtensionSupported(gpu(), nullptr, extension_name)) {
   25958         m_device_extension_names.push_back(extension_name);
   25959         m_device_extension_names.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
   25960     } else {
   25961         printf("             External semaphore extension not supported, skipping test\n");
   25962         return;
   25963     }
   25964     ASSERT_NO_FATAL_FAILURE(InitState());
   25965 
   25966     // Check for external semaphore import and export capability
   25967     VkPhysicalDeviceExternalSemaphoreInfoKHR esi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR, nullptr,
   25968                                                     handle_type};
   25969     VkExternalSemaphorePropertiesKHR esp = {VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR, nullptr};
   25970     auto vkGetPhysicalDeviceExternalSemaphorePropertiesKHR =
   25971         (PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)vkGetInstanceProcAddr(
   25972             instance(), "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR");
   25973     vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(gpu(), &esi, &esp);
   25974 
   25975     if (!(esp.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR) ||
   25976         !(esp.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR)) {
   25977         printf("             External semaphore does not support importing and exporting, skipping test\n");
   25978         return;
   25979     }
   25980 
   25981     VkResult err;
   25982     m_errorMonitor->ExpectSuccess();
   25983 
   25984     // Create a semaphore to export payload from
   25985     VkExportSemaphoreCreateInfoKHR esci = {VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR, nullptr, handle_type};
   25986     VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &esci, 0};
   25987 
   25988     VkSemaphore export_semaphore;
   25989     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &export_semaphore);
   25990     ASSERT_VK_SUCCESS(err);
   25991 
   25992     // Create a semaphore to import payload into
   25993     sci.pNext = nullptr;
   25994     VkSemaphore import_semaphore;
   25995     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &import_semaphore);
   25996     ASSERT_VK_SUCCESS(err);
   25997 
   25998 #ifdef _WIN32
   25999     // Export semaphore payload to an opaque handle
   26000     HANDLE handle = nullptr;
   26001     VkSemaphoreGetWin32HandleInfoKHR ghi = {VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR, nullptr, export_semaphore,
   26002                                             handle_type};
   26003     auto vkGetSemaphoreWin32HandleKHR =
   26004         (PFN_vkGetSemaphoreWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetSemaphoreWin32HandleKHR");
   26005     err = vkGetSemaphoreWin32HandleKHR(m_device->device(), &ghi, &handle);
   26006     ASSERT_VK_SUCCESS(err);
   26007 
   26008     // Import opaque handle exported above
   26009     VkImportSemaphoreWin32HandleInfoKHR ihi = {
   26010         VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR, nullptr, import_semaphore, 0, handle_type, handle, nullptr};
   26011     auto vkImportSemaphoreWin32HandleKHR =
   26012         (PFN_vkImportSemaphoreWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportSemaphoreWin32HandleKHR");
   26013     err = vkImportSemaphoreWin32HandleKHR(m_device->device(), &ihi);
   26014     ASSERT_VK_SUCCESS(err);
   26015 #else
   26016     // Export semaphore payload to an opaque handle
   26017     int fd = 0;
   26018     VkSemaphoreGetFdInfoKHR ghi = {VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR, nullptr, export_semaphore, handle_type};
   26019     auto vkGetSemaphoreFdKHR = (PFN_vkGetSemaphoreFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetSemaphoreFdKHR");
   26020     err = vkGetSemaphoreFdKHR(m_device->device(), &ghi, &fd);
   26021     ASSERT_VK_SUCCESS(err);
   26022 
   26023     // Import opaque handle exported above
   26024     VkImportSemaphoreFdInfoKHR ihi = {
   26025         VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR, nullptr, import_semaphore, 0, handle_type, fd};
   26026     auto vkImportSemaphoreFdKHR = (PFN_vkImportSemaphoreFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportSemaphoreFdKHR");
   26027     err = vkImportSemaphoreFdKHR(m_device->device(), &ihi);
   26028     ASSERT_VK_SUCCESS(err);
   26029 #endif
   26030 
   26031     // Signal the exported semaphore and wait on the imported semaphore
   26032     VkPipelineStageFlags flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
   26033     VkSubmitInfo si[] = {
   26034         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, &flags, 0, nullptr, 1, &export_semaphore},
   26035         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &import_semaphore, &flags, 0, nullptr, 0, nullptr},
   26036         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, &flags, 0, nullptr, 1, &export_semaphore},
   26037         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &import_semaphore, &flags, 0, nullptr, 0, nullptr},
   26038     };
   26039     err = vkQueueSubmit(m_device->m_queue, 4, si, VK_NULL_HANDLE);
   26040     ASSERT_VK_SUCCESS(err);
   26041 
   26042     if (m_device->phy().features().sparseBinding) {
   26043         // Signal the imported semaphore and wait on the exported semaphore
   26044         VkBindSparseInfo bi[] = {
   26045             {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 1, &import_semaphore},
   26046             {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 1, &export_semaphore, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr},
   26047             {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 1, &import_semaphore},
   26048             {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 1, &export_semaphore, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr},
   26049         };
   26050         err = vkQueueBindSparse(m_device->m_queue, 4, bi, VK_NULL_HANDLE);
   26051         ASSERT_VK_SUCCESS(err);
   26052     }
   26053 
   26054     // Cleanup
   26055     err = vkQueueWaitIdle(m_device->m_queue);
   26056     ASSERT_VK_SUCCESS(err);
   26057     vkDestroySemaphore(m_device->device(), export_semaphore, nullptr);
   26058     vkDestroySemaphore(m_device->device(), import_semaphore, nullptr);
   26059 
   26060     m_errorMonitor->VerifyNotFound();
   26061 }
   26062 
   26063 TEST_F(VkPositiveLayerTest, ExternalFence) {
   26064 #ifdef _WIN32
   26065     const auto extension_name = VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME;
   26066     const auto handle_type = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
   26067 #else
   26068     const auto extension_name = VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME;
   26069     const auto handle_type = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
   26070 #endif
   26071     // Check for external fence instance extensions
   26072     if (InstanceExtensionSupported(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME)) {
   26073         m_instance_extension_names.push_back(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME);
   26074         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
   26075     } else {
   26076         printf("             External fence extension not supported, skipping test\n");
   26077         return;
   26078     }
   26079     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   26080 
   26081     // Check for external fence device extensions
   26082     if (DeviceExtensionSupported(gpu(), nullptr, extension_name)) {
   26083         m_device_extension_names.push_back(extension_name);
   26084         m_device_extension_names.push_back(VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME);
   26085     } else {
   26086         printf("             External fence extension not supported, skipping test\n");
   26087         return;
   26088     }
   26089     ASSERT_NO_FATAL_FAILURE(InitState());
   26090 
   26091     // Check for external fence import and export capability
   26092     VkPhysicalDeviceExternalFenceInfoKHR efi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR, nullptr, handle_type};
   26093     VkExternalFencePropertiesKHR efp = {VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR, nullptr};
   26094     auto vkGetPhysicalDeviceExternalFencePropertiesKHR = (PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR)vkGetInstanceProcAddr(
   26095         instance(), "vkGetPhysicalDeviceExternalFencePropertiesKHR");
   26096     vkGetPhysicalDeviceExternalFencePropertiesKHR(gpu(), &efi, &efp);
   26097 
   26098     if (!(efp.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR) ||
   26099         !(efp.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR)) {
   26100         printf("             External fence does not support importing and exporting, skipping test\n");
   26101         return;
   26102     }
   26103 
   26104     VkResult err;
   26105     m_errorMonitor->ExpectSuccess();
   26106 
   26107     // Create a fence to export payload from
   26108     VkFence export_fence;
   26109     {
   26110         VkExportFenceCreateInfoKHR efci = {VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR, nullptr, handle_type};
   26111         VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, &efci, 0};
   26112         err = vkCreateFence(m_device->device(), &fci, nullptr, &export_fence);
   26113         ASSERT_VK_SUCCESS(err);
   26114     }
   26115 
   26116     // Create a fence to import payload into
   26117     VkFence import_fence;
   26118     {
   26119         VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
   26120         err = vkCreateFence(m_device->device(), &fci, nullptr, &import_fence);
   26121         ASSERT_VK_SUCCESS(err);
   26122     }
   26123 
   26124 #ifdef _WIN32
   26125     // Export fence payload to an opaque handle
   26126     HANDLE handle = nullptr;
   26127     {
   26128         VkFenceGetWin32HandleInfoKHR ghi = {VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR, nullptr, export_fence, handle_type};
   26129         auto vkGetFenceWin32HandleKHR =
   26130             (PFN_vkGetFenceWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetFenceWin32HandleKHR");
   26131         err = vkGetFenceWin32HandleKHR(m_device->device(), &ghi, &handle);
   26132         ASSERT_VK_SUCCESS(err);
   26133     }
   26134 
   26135     // Import opaque handle exported above
   26136     {
   26137         VkImportFenceWin32HandleInfoKHR ifi = {
   26138             VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR, nullptr, import_fence, 0, handle_type, handle, nullptr};
   26139         auto vkImportFenceWin32HandleKHR =
   26140             (PFN_vkImportFenceWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportFenceWin32HandleKHR");
   26141         err = vkImportFenceWin32HandleKHR(m_device->device(), &ifi);
   26142         ASSERT_VK_SUCCESS(err);
   26143     }
   26144 #else
   26145     // Export fence payload to an opaque handle
   26146     int fd = 0;
   26147     {
   26148         VkFenceGetFdInfoKHR gfi = {VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR, nullptr, export_fence, handle_type};
   26149         auto vkGetFenceFdKHR = (PFN_vkGetFenceFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetFenceFdKHR");
   26150         err = vkGetFenceFdKHR(m_device->device(), &gfi, &fd);
   26151         ASSERT_VK_SUCCESS(err);
   26152     }
   26153 
   26154     // Import opaque handle exported above
   26155     {
   26156         VkImportFenceFdInfoKHR ifi = {VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR, nullptr, import_fence, 0, handle_type, fd};
   26157         auto vkImportFenceFdKHR = (PFN_vkImportFenceFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportFenceFdKHR");
   26158         err = vkImportFenceFdKHR(m_device->device(), &ifi);
   26159         ASSERT_VK_SUCCESS(err);
   26160     }
   26161 #endif
   26162 
   26163     // Signal the exported fence and wait on the imported fence
   26164     vkQueueSubmit(m_device->m_queue, 0, nullptr, export_fence);
   26165     vkWaitForFences(m_device->device(), 1, &import_fence, VK_TRUE, 1000000000);
   26166     vkResetFences(m_device->device(), 1, &import_fence);
   26167     vkQueueSubmit(m_device->m_queue, 0, nullptr, export_fence);
   26168     vkWaitForFences(m_device->device(), 1, &import_fence, VK_TRUE, 1000000000);
   26169     vkResetFences(m_device->device(), 1, &import_fence);
   26170 
   26171     // Signal the imported fence and wait on the exported fence
   26172     vkQueueSubmit(m_device->m_queue, 0, nullptr, import_fence);
   26173     vkWaitForFences(m_device->device(), 1, &export_fence, VK_TRUE, 1000000000);
   26174     vkResetFences(m_device->device(), 1, &export_fence);
   26175     vkQueueSubmit(m_device->m_queue, 0, nullptr, import_fence);
   26176     vkWaitForFences(m_device->device(), 1, &export_fence, VK_TRUE, 1000000000);
   26177     vkResetFences(m_device->device(), 1, &export_fence);
   26178 
   26179     // Cleanup
   26180     err = vkQueueWaitIdle(m_device->m_queue);
   26181     ASSERT_VK_SUCCESS(err);
   26182     vkDestroyFence(m_device->device(), export_fence, nullptr);
   26183     vkDestroyFence(m_device->device(), import_fence, nullptr);
   26184 
   26185     m_errorMonitor->VerifyNotFound();
   26186 }
   26187 
   26188 extern "C" void *ReleaseNullFence(void *arg) {
   26189     struct thread_data_struct *data = (struct thread_data_struct *)arg;
   26190 
   26191     for (int i = 0; i < 40000; i++) {
   26192         vkDestroyFence(data->device, VK_NULL_HANDLE, NULL);
   26193         if (data->bailout) {
   26194             break;
   26195         }
   26196     }
   26197     return NULL;
   26198 }
   26199 
   26200 TEST_F(VkPositiveLayerTest, ThreadNullFenceCollision) {
   26201     test_platform_thread thread;
   26202 
   26203     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "THREADING ERROR");
   26204 
   26205     ASSERT_NO_FATAL_FAILURE(Init());
   26206 
   26207     struct thread_data_struct data;
   26208     data.device = m_device->device();
   26209     data.bailout = false;
   26210     m_errorMonitor->SetBailout(&data.bailout);
   26211 
   26212     // Call vkDestroyFence of VK_NULL_HANDLE repeatedly using multiple threads.
   26213     // There should be no validation error from collision of that non-object.
   26214     test_platform_thread_create(&thread, ReleaseNullFence, (void *)&data);
   26215     for (int i = 0; i < 40000; i++) {
   26216         vkDestroyFence(m_device->device(), VK_NULL_HANDLE, NULL);
   26217     }
   26218     test_platform_thread_join(thread, NULL);
   26219 
   26220     m_errorMonitor->SetBailout(NULL);
   26221 
   26222     m_errorMonitor->VerifyNotFound();
   26223 }
   26224 
   26225 TEST_F(VkPositiveLayerTest, ClearColorImageWithValidRange) {
   26226     TEST_DESCRIPTION("Record clear color with a valid VkImageSubresourceRange");
   26227 
   26228     ASSERT_NO_FATAL_FAILURE(Init());
   26229     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   26230 
   26231     VkImageObj image(m_device);
   26232     image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
   26233     ASSERT_TRUE(image.create_info().arrayLayers == 1);
   26234     ASSERT_TRUE(image.initialized());
   26235     image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
   26236 
   26237     const VkClearColorValue clear_color = {{0.0f, 0.0f, 0.0f, 1.0f}};
   26238 
   26239     m_commandBuffer->begin();
   26240     const auto cb_handle = m_commandBuffer->handle();
   26241 
   26242     // Try good case
   26243     {
   26244         m_errorMonitor->ExpectSuccess();
   26245         VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
   26246         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
   26247         m_errorMonitor->VerifyNotFound();
   26248     }
   26249 
   26250     // Try good case with VK_REMAINING
   26251     {
   26252         m_errorMonitor->ExpectSuccess();
   26253         VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS};
   26254         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
   26255         m_errorMonitor->VerifyNotFound();
   26256     }
   26257 }
   26258 
   26259 TEST_F(VkPositiveLayerTest, ClearDepthStencilWithValidRange) {
   26260     TEST_DESCRIPTION("Record clear depth with a valid VkImageSubresourceRange");
   26261 
   26262     ASSERT_NO_FATAL_FAILURE(Init());
   26263     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
   26264 
   26265     auto depth_format = FindSupportedDepthStencilFormat(gpu());
   26266     if (!depth_format) {
   26267         printf("             No Depth + Stencil format found. Skipped.\n");
   26268         return;
   26269     }
   26270 
   26271     VkImageObj image(m_device);
   26272     image.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
   26273     ASSERT_TRUE(image.create_info().arrayLayers == 1);
   26274     ASSERT_TRUE(image.initialized());
   26275     const VkImageAspectFlags ds_aspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
   26276     image.SetLayout(ds_aspect, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
   26277 
   26278     const VkClearDepthStencilValue clear_value = {};
   26279 
   26280     m_commandBuffer->begin();
   26281     const auto cb_handle = m_commandBuffer->handle();
   26282 
   26283     // Try good case
   26284     {
   26285         m_errorMonitor->ExpectSuccess();
   26286         VkImageSubresourceRange range = {ds_aspect, 0, 1, 0, 1};
   26287         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
   26288         m_errorMonitor->VerifyNotFound();
   26289     }
   26290 
   26291     // Try good case with VK_REMAINING
   26292     {
   26293         m_errorMonitor->ExpectSuccess();
   26294         VkImageSubresourceRange range = {ds_aspect, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS};
   26295         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
   26296         m_errorMonitor->VerifyNotFound();
   26297     }
   26298 }
   26299 
   26300 TEST_F(VkPositiveLayerTest, CreateGraphicsPipelineWithIgnoredPointers) {
   26301     TEST_DESCRIPTION("Create Graphics Pipeline with pointers that must be ignored by layers");
   26302 
   26303     ASSERT_NO_FATAL_FAILURE(Init());
   26304 
   26305     m_depth_stencil_fmt = FindSupportedDepthStencilFormat(gpu());
   26306     ASSERT_TRUE(m_depth_stencil_fmt != 0);
   26307 
   26308     m_depthStencil->Init(m_device, static_cast<int32_t>(m_width), static_cast<int32_t>(m_height), m_depth_stencil_fmt);
   26309 
   26310     ASSERT_NO_FATAL_FAILURE(InitRenderTarget(m_depthStencil->BindInfo()));
   26311 
   26312     const uint64_t fake_address_64 = 0xCDCDCDCDCDCDCDCD;
   26313     const uint64_t fake_address_32 = 0xCDCDCDCD;
   26314     void *hopefully_undereferencable_pointer =
   26315         sizeof(void *) == 8 ? reinterpret_cast<void *>(fake_address_64) : reinterpret_cast<void *>(fake_address_32);
   26316 
   26317     VkShaderObj vs(m_device, "#version 450\nvoid main(){gl_Position = vec4(0.0, 0.0, 0.0, 1.0);}\n", VK_SHADER_STAGE_VERTEX_BIT,
   26318                    this);
   26319 
   26320     const VkPipelineVertexInputStateCreateInfo pipeline_vertex_input_state_create_info{
   26321         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
   26322         nullptr,  // pNext
   26323         0,        // flags
   26324         0,
   26325         nullptr,  // bindings
   26326         0,
   26327         nullptr  // attributes
   26328     };
   26329 
   26330     const VkPipelineInputAssemblyStateCreateInfo pipeline_input_assembly_state_create_info{
   26331         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
   26332         nullptr,  // pNext
   26333         0,        // flags
   26334         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
   26335         VK_FALSE  // primitive restart
   26336     };
   26337 
   26338     const VkPipelineRasterizationStateCreateInfo pipeline_rasterization_state_create_info_template{
   26339         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
   26340         nullptr,   // pNext
   26341         0,         // flags
   26342         VK_FALSE,  // depthClamp
   26343         VK_FALSE,  // rasterizerDiscardEnable
   26344         VK_POLYGON_MODE_FILL,
   26345         VK_CULL_MODE_NONE,
   26346         VK_FRONT_FACE_COUNTER_CLOCKWISE,
   26347         VK_FALSE,  // depthBias
   26348         0.0f,
   26349         0.0f,
   26350         0.0f,  // depthBias params
   26351         1.0f   // lineWidth
   26352     };
   26353 
   26354     VkPipelineLayout pipeline_layout;
   26355     {
   26356         VkPipelineLayoutCreateInfo pipeline_layout_create_info{
   26357             VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
   26358             nullptr,  // pNext
   26359             0,        // flags
   26360             0,
   26361             nullptr,  // layouts
   26362             0,
   26363             nullptr  // push constants
   26364         };
   26365 
   26366         VkResult err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_create_info, nullptr, &pipeline_layout);
   26367         ASSERT_VK_SUCCESS(err);
   26368     }
   26369 
   26370     // try disabled rasterizer and no tessellation
   26371     {
   26372         m_errorMonitor->ExpectSuccess();
   26373 
   26374         VkPipelineRasterizationStateCreateInfo pipeline_rasterization_state_create_info =
   26375             pipeline_rasterization_state_create_info_template;
   26376         pipeline_rasterization_state_create_info.rasterizerDiscardEnable = VK_TRUE;
   26377 
   26378         VkGraphicsPipelineCreateInfo graphics_pipeline_create_info{
   26379             VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
   26380             nullptr,  // pNext
   26381             0,        // flags
   26382             1,        // stageCount
   26383             &vs.GetStageCreateInfo(),
   26384             &pipeline_vertex_input_state_create_info,
   26385             &pipeline_input_assembly_state_create_info,
   26386             reinterpret_cast<const VkPipelineTessellationStateCreateInfo *>(hopefully_undereferencable_pointer),
   26387             reinterpret_cast<const VkPipelineViewportStateCreateInfo *>(hopefully_undereferencable_pointer),
   26388             &pipeline_rasterization_state_create_info,
   26389             reinterpret_cast<const VkPipelineMultisampleStateCreateInfo *>(hopefully_undereferencable_pointer),
   26390             reinterpret_cast<const VkPipelineDepthStencilStateCreateInfo *>(hopefully_undereferencable_pointer),
   26391             reinterpret_cast<const VkPipelineColorBlendStateCreateInfo *>(hopefully_undereferencable_pointer),
   26392             nullptr,  // dynamic states
   26393             pipeline_layout,
   26394             m_renderPass,
   26395             0,  // subpass
   26396             VK_NULL_HANDLE,
   26397             0};
   26398 
   26399         VkPipeline pipeline;
   26400         vkCreateGraphicsPipelines(m_device->handle(), VK_NULL_HANDLE, 1, &graphics_pipeline_create_info, nullptr, &pipeline);
   26401 
   26402         m_errorMonitor->VerifyNotFound();
   26403 
   26404         vkDestroyPipeline(m_device->handle(), pipeline, nullptr);
   26405     }
   26406 
   26407     const VkPipelineMultisampleStateCreateInfo pipeline_multisample_state_create_info{
   26408         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
   26409         nullptr,  // pNext
   26410         0,        // flags
   26411         VK_SAMPLE_COUNT_1_BIT,
   26412         VK_FALSE,  // sample shading
   26413         0.0f,      // minSampleShading
   26414         nullptr,   // pSampleMask
   26415         VK_FALSE,  // alphaToCoverageEnable
   26416         VK_FALSE   // alphaToOneEnable
   26417     };
   26418 
   26419     // try enabled rasterizer but no subpass attachments
   26420     {
   26421         m_errorMonitor->ExpectSuccess();
   26422 
   26423         VkPipelineRasterizationStateCreateInfo pipeline_rasterization_state_create_info =
   26424             pipeline_rasterization_state_create_info_template;
   26425         pipeline_rasterization_state_create_info.rasterizerDiscardEnable = VK_FALSE;
   26426 
   26427         VkViewport viewport = {0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f};
   26428         VkRect2D scissor = {{0, 0}, {static_cast<uint32_t>(m_width), static_cast<uint32_t>(m_height)}};
   26429 
   26430         const VkPipelineViewportStateCreateInfo pipeline_viewport_state_create_info{
   26431             VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
   26432             nullptr,  // pNext
   26433             0,        // flags
   26434             1,
   26435             &viewport,
   26436             1,
   26437             &scissor};
   26438 
   26439         VkRenderPass render_pass;
   26440         {
   26441             VkSubpassDescription subpass_desc = {};
   26442 
   26443             VkRenderPassCreateInfo render_pass_create_info{
   26444                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
   26445                 nullptr,  // pNext
   26446                 0,        // flags
   26447                 0,
   26448                 nullptr,  // attachments
   26449                 1,
   26450                 &subpass_desc,
   26451                 0,
   26452                 nullptr  // subpass dependencies
   26453             };
   26454 
   26455             VkResult err = vkCreateRenderPass(m_device->handle(), &render_pass_create_info, nullptr, &render_pass);
   26456             ASSERT_VK_SUCCESS(err);
   26457         }
   26458 
   26459         VkGraphicsPipelineCreateInfo graphics_pipeline_create_info{
   26460             VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
   26461             nullptr,  // pNext
   26462             0,        // flags
   26463             1,        // stageCount
   26464             &vs.GetStageCreateInfo(),
   26465             &pipeline_vertex_input_state_create_info,
   26466             &pipeline_input_assembly_state_create_info,
   26467             nullptr,
   26468             &pipeline_viewport_state_create_info,
   26469             &pipeline_rasterization_state_create_info,
   26470             &pipeline_multisample_state_create_info,
   26471             reinterpret_cast<const VkPipelineDepthStencilStateCreateInfo *>(hopefully_undereferencable_pointer),
   26472             reinterpret_cast<const VkPipelineColorBlendStateCreateInfo *>(hopefully_undereferencable_pointer),
   26473             nullptr,  // dynamic states
   26474             pipeline_layout,
   26475             render_pass,
   26476             0,  // subpass
   26477             VK_NULL_HANDLE,
   26478             0};
   26479 
   26480         VkPipeline pipeline;
   26481         vkCreateGraphicsPipelines(m_device->handle(), VK_NULL_HANDLE, 1, &graphics_pipeline_create_info, nullptr, &pipeline);
   26482 
   26483         m_errorMonitor->VerifyNotFound();
   26484 
   26485         vkDestroyPipeline(m_device->handle(), pipeline, nullptr);
   26486         vkDestroyRenderPass(m_device->handle(), render_pass, nullptr);
   26487     }
   26488 
   26489     // try dynamic viewport and scissor
   26490     {
   26491         m_errorMonitor->ExpectSuccess();
   26492 
   26493         VkPipelineRasterizationStateCreateInfo pipeline_rasterization_state_create_info =
   26494             pipeline_rasterization_state_create_info_template;
   26495         pipeline_rasterization_state_create_info.rasterizerDiscardEnable = VK_FALSE;
   26496 
   26497         const VkPipelineViewportStateCreateInfo pipeline_viewport_state_create_info{
   26498             VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
   26499             nullptr,  // pNext
   26500             0,        // flags
   26501             1,
   26502             reinterpret_cast<const VkViewport *>(hopefully_undereferencable_pointer),
   26503             1,
   26504             reinterpret_cast<const VkRect2D *>(hopefully_undereferencable_pointer)};
   26505 
   26506         const VkPipelineDepthStencilStateCreateInfo pipeline_depth_stencil_state_create_info{
   26507             VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
   26508             nullptr,  // pNext
   26509             0,        // flags
   26510         };
   26511 
   26512         const VkPipelineColorBlendAttachmentState pipeline_color_blend_attachment_state = {};
   26513 
   26514         const VkPipelineColorBlendStateCreateInfo pipeline_color_blend_state_create_info{
   26515             VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
   26516             nullptr,  // pNext
   26517             0,        // flags
   26518             VK_FALSE,
   26519             VK_LOGIC_OP_CLEAR,
   26520             1,
   26521             &pipeline_color_blend_attachment_state,
   26522             {0.0f, 0.0f, 0.0f, 0.0f}};
   26523 
   26524         const VkDynamicState dynamic_states[2] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
   26525 
   26526         const VkPipelineDynamicStateCreateInfo pipeline_dynamic_state_create_info{
   26527             VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
   26528             nullptr,  // pNext
   26529             0,        // flags
   26530             2, dynamic_states};
   26531 
   26532         VkGraphicsPipelineCreateInfo graphics_pipeline_create_info{VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
   26533                                                                    nullptr,  // pNext
   26534                                                                    0,        // flags
   26535                                                                    1,        // stageCount
   26536                                                                    &vs.GetStageCreateInfo(),
   26537                                                                    &pipeline_vertex_input_state_create_info,
   26538                                                                    &pipeline_input_assembly_state_create_info,
   26539                                                                    nullptr,
   26540                                                                    &pipeline_viewport_state_create_info,
   26541                                                                    &pipeline_rasterization_state_create_info,
   26542                                                                    &pipeline_multisample_state_create_info,
   26543                                                                    &pipeline_depth_stencil_state_create_info,
   26544                                                                    &pipeline_color_blend_state_create_info,
   26545                                                                    &pipeline_dynamic_state_create_info,  // dynamic states
   26546                                                                    pipeline_layout,
   26547                                                                    m_renderPass,
   26548                                                                    0,  // subpass
   26549                                                                    VK_NULL_HANDLE,
   26550                                                                    0};
   26551 
   26552         VkPipeline pipeline;
   26553         vkCreateGraphicsPipelines(m_device->handle(), VK_NULL_HANDLE, 1, &graphics_pipeline_create_info, nullptr, &pipeline);
   26554 
   26555         m_errorMonitor->VerifyNotFound();
   26556 
   26557         vkDestroyPipeline(m_device->handle(), pipeline, nullptr);
   26558     }
   26559 
   26560     vkDestroyPipelineLayout(m_device->handle(), pipeline_layout, nullptr);
   26561 }
   26562 
   26563 TEST_F(VkPositiveLayerTest, ExternalMemory) {
   26564     TEST_DESCRIPTION("Perform a copy through a pair of buffers linked by external memory");
   26565 
   26566 #ifdef _WIN32
   26567     const auto extension_name = VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME;
   26568     const auto handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
   26569 #else
   26570     const auto extension_name = VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME;
   26571     const auto handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
   26572 #endif
   26573 
   26574     // Check for external memory instance extensions
   26575     if (InstanceExtensionSupported(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME)) {
   26576         m_instance_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME);
   26577         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
   26578     } else {
   26579         printf("             External memory extension not supported, skipping test\n");
   26580         return;
   26581     }
   26582     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   26583 
   26584     // Check for import/export capability
   26585     VkPhysicalDeviceExternalBufferInfoKHR ebi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR, nullptr, 0,
   26586                                                  VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, handle_type};
   26587     VkExternalBufferPropertiesKHR ebp = {VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR, nullptr, {0, 0, 0}};
   26588     auto vkGetPhysicalDeviceExternalBufferPropertiesKHR = (PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR)vkGetInstanceProcAddr(
   26589         instance(), "vkGetPhysicalDeviceExternalBufferPropertiesKHR");
   26590     ASSERT_TRUE(vkGetPhysicalDeviceExternalBufferPropertiesKHR != nullptr);
   26591     vkGetPhysicalDeviceExternalBufferPropertiesKHR(gpu(), &ebi, &ebp);
   26592     if (!(ebp.externalMemoryProperties.compatibleHandleTypes & handle_type) ||
   26593         !(ebp.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR) ||
   26594         !(ebp.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR)) {
   26595         printf("             External buffer does not support importing and exporting, skipping test\n");
   26596         return;
   26597     }
   26598 
   26599     // Check if dedicated allocation is required
   26600     bool dedicated_allocation =
   26601         ebp.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR;
   26602     if (dedicated_allocation) {
   26603         if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME)) {
   26604             m_device_extension_names.push_back(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
   26605             m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
   26606         } else {
   26607             printf("             Dedicated allocation extension not supported, skipping test\n");
   26608             return;
   26609         }
   26610     }
   26611 
   26612     // Check for external memory device extensions
   26613     if (DeviceExtensionSupported(gpu(), nullptr, extension_name)) {
   26614         m_device_extension_names.push_back(extension_name);
   26615         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
   26616     } else {
   26617         printf("             External memory extension not supported, skipping test\n");
   26618         return;
   26619     }
   26620     ASSERT_NO_FATAL_FAILURE(InitState());
   26621 
   26622     m_errorMonitor->ExpectSuccess(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT);
   26623 
   26624     VkMemoryPropertyFlags mem_flags = 0;
   26625     const VkDeviceSize buffer_size = 1024;
   26626 
   26627     // Create export and import buffers
   26628     const VkExternalMemoryBufferCreateInfoKHR external_buffer_info = {VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR,
   26629                                                                       nullptr, handle_type};
   26630     auto buffer_info =
   26631         vk_testing::Buffer::create_info(buffer_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
   26632     buffer_info.pNext = &external_buffer_info;
   26633     vk_testing::Buffer buffer_export;
   26634     buffer_export.init_no_mem(*m_device, buffer_info);
   26635     vk_testing::Buffer buffer_import;
   26636     buffer_import.init_no_mem(*m_device, buffer_info);
   26637 
   26638     // Allocation info
   26639     auto alloc_info = vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, buffer_export.memory_requirements(), mem_flags);
   26640 
   26641     // Add export allocation info to pNext chain
   26642     VkExportMemoryAllocateInfoKHR export_info = {VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR, nullptr, handle_type};
   26643     alloc_info.pNext = &export_info;
   26644 
   26645     // Add dedicated allocation info to pNext chain if required
   26646     VkMemoryDedicatedAllocateInfoKHR dedicated_info = {VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR, nullptr,
   26647                                                        VK_NULL_HANDLE, buffer_export.handle()};
   26648     if (dedicated_allocation) {
   26649         export_info.pNext = &dedicated_info;
   26650     }
   26651 
   26652     // Allocate memory to be exported
   26653     vk_testing::DeviceMemory memory_export;
   26654     memory_export.init(*m_device, alloc_info);
   26655 
   26656     // Bind exported memory
   26657     buffer_export.bind_memory(memory_export, 0);
   26658 
   26659 #ifdef _WIN32
   26660     // Export memory to handle
   26661     auto vkGetMemoryWin32HandleKHR = (PFN_vkGetMemoryWin32HandleKHR)vkGetInstanceProcAddr(instance(), "vkGetMemoryWin32HandleKHR");
   26662     ASSERT_TRUE(vkGetMemoryWin32HandleKHR != nullptr);
   26663     VkMemoryGetWin32HandleInfoKHR mghi = {VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR, nullptr, memory_export.handle(),
   26664                                           handle_type};
   26665     HANDLE handle;
   26666     ASSERT_VK_SUCCESS(vkGetMemoryWin32HandleKHR(m_device->device(), &mghi, &handle));
   26667 
   26668     VkImportMemoryWin32HandleInfoKHR import_info = {VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR, nullptr, handle_type,
   26669                                                     handle};
   26670 #else
   26671     // Export memory to fd
   26672     auto vkGetMemoryFdKHR = (PFN_vkGetMemoryFdKHR)vkGetInstanceProcAddr(instance(), "vkGetMemoryFdKHR");
   26673     ASSERT_TRUE(vkGetMemoryFdKHR != nullptr);
   26674     VkMemoryGetFdInfoKHR mgfi = {VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR, nullptr, memory_export.handle(), handle_type};
   26675     int fd;
   26676     ASSERT_VK_SUCCESS(vkGetMemoryFdKHR(m_device->device(), &mgfi, &fd));
   26677 
   26678     VkImportMemoryFdInfoKHR import_info = {VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, nullptr, handle_type, fd};
   26679 #endif
   26680 
   26681     // Import memory
   26682     alloc_info = vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, buffer_import.memory_requirements(), mem_flags);
   26683     alloc_info.pNext = &import_info;
   26684     vk_testing::DeviceMemory memory_import;
   26685     memory_import.init(*m_device, alloc_info);
   26686 
   26687     // Bind imported memory
   26688     buffer_import.bind_memory(memory_import, 0);
   26689 
   26690     // Create test buffers and fill input buffer
   26691     VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
   26692     vk_testing::Buffer buffer_input;
   26693     buffer_input.init_as_src_and_dst(*m_device, buffer_size, mem_prop);
   26694     auto input_mem = (uint8_t *)buffer_input.memory().map();
   26695     for (uint32_t i = 0; i < buffer_size; i++) {
   26696         input_mem[i] = (i & 0xFF);
   26697     }
   26698     buffer_input.memory().unmap();
   26699     vk_testing::Buffer buffer_output;
   26700     buffer_output.init_as_src_and_dst(*m_device, buffer_size, mem_prop);
   26701 
   26702     // Copy from input buffer to output buffer through the exported/imported memory
   26703     m_commandBuffer->begin();
   26704     VkBufferCopy copy_info = {0, 0, buffer_size};
   26705     vkCmdCopyBuffer(m_commandBuffer->handle(), buffer_input.handle(), buffer_export.handle(), 1, &copy_info);
   26706     // Insert memory barrier to guarantee copy order
   26707     VkMemoryBarrier mem_barrier = {VK_STRUCTURE_TYPE_MEMORY_BARRIER, nullptr, VK_ACCESS_TRANSFER_WRITE_BIT,
   26708                                    VK_ACCESS_TRANSFER_READ_BIT};
   26709     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
   26710                          &mem_barrier, 0, nullptr, 0, nullptr);
   26711     vkCmdCopyBuffer(m_commandBuffer->handle(), buffer_import.handle(), buffer_output.handle(), 1, &copy_info);
   26712     m_commandBuffer->end();
   26713     m_commandBuffer->QueueCommandBuffer();
   26714 
   26715     m_errorMonitor->VerifyNotFound();
   26716 }
   26717 
   26718 TEST_F(VkLayerTest, AMDMixedAttachmentSamplesValidateRenderPass) {
   26719     TEST_DESCRIPTION("Verify error messages for supported and unsupported sample counts in render pass attachments.");
   26720 
   26721     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   26722     if (DeviceExtensionSupported(gpu(), nullptr, VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME)) {
   26723         m_device_extension_names.push_back(VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME);
   26724     } else {
   26725         return;
   26726     }
   26727     ASSERT_NO_FATAL_FAILURE(InitState());
   26728 
   26729     m_errorMonitor->ExpectSuccess();
   26730 
   26731     std::vector<VkAttachmentDescription> attachments;
   26732 
   26733     {
   26734         VkAttachmentDescription att = {};
   26735         att.format = VK_FORMAT_R8G8B8A8_UNORM;
   26736         att.samples = VK_SAMPLE_COUNT_1_BIT;
   26737         att.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
   26738         att.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
   26739         att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
   26740         att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
   26741         att.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   26742         att.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   26743 
   26744         attachments.push_back(att);
   26745 
   26746         att.format = VK_FORMAT_D16_UNORM;
   26747         att.samples = VK_SAMPLE_COUNT_4_BIT;
   26748         att.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
   26749         att.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
   26750         att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
   26751         att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
   26752         att.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   26753         att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
   26754 
   26755         attachments.push_back(att);
   26756     }
   26757 
   26758     VkAttachmentReference color_ref = {};
   26759     color_ref.attachment = 0;
   26760     color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
   26761 
   26762     VkAttachmentReference depth_ref = {};
   26763     depth_ref.attachment = 1;
   26764     depth_ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
   26765 
   26766     VkSubpassDescription subpass = {};
   26767     subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
   26768     subpass.colorAttachmentCount = 1;
   26769     subpass.pColorAttachments = &color_ref;
   26770     subpass.pDepthStencilAttachment = &depth_ref;
   26771 
   26772     VkRenderPassCreateInfo rp_info = {};
   26773     rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
   26774     rp_info.attachmentCount = attachments.size();
   26775     rp_info.pAttachments = attachments.data();
   26776     rp_info.subpassCount = 1;
   26777     rp_info.pSubpasses = &subpass;
   26778 
   26779     vkCreateRenderPass(device(), &rp_info, NULL, &m_renderPass);
   26780     m_errorMonitor->VerifyNotFound();
   26781 
   26782     // Expect an error message for invalid sample counts
   26783 
   26784     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_14000bc4);
   26785 
   26786     attachments[0].samples = VK_SAMPLE_COUNT_4_BIT;
   26787     attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
   26788 
   26789     {
   26790         VkRenderPass render_pass;
   26791         VkResult err = vkCreateRenderPass(device(), &rp_info, NULL, &render_pass);
   26792         m_errorMonitor->VerifyFound();
   26793         ASSERT_NE(err, VK_SUCCESS);
   26794     }
   26795 }
   26796 
   26797 TEST_F(VkLayerTest, AMDMixedAttachmentSamplesValidateGraphicsPipeline) {
   26798     TEST_DESCRIPTION("Verify an error message for an incorrect graphics pipeline rasterization sample count.");
   26799 
   26800     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   26801     if (DeviceExtensionSupported(gpu(), nullptr, VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME)) {
   26802         m_device_extension_names.push_back(VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME);
   26803     } else {
   26804         return;
   26805     }
   26806     ASSERT_NO_FATAL_FAILURE(InitState());
   26807 
   26808     VkRenderpassObj render_pass(m_device);
   26809 
   26810     const VkPipelineLayoutObj pipeline_layout(m_device);
   26811 
   26812     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
   26813     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
   26814 
   26815     // Set a mismatched sample count
   26816 
   26817     VkPipelineMultisampleStateCreateInfo ms_state_ci = {};
   26818     ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
   26819     ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
   26820 
   26821     VkPipelineObj pipe(m_device);
   26822     pipe.AddShader(&vs);
   26823     pipe.AddShader(&fs);
   26824     pipe.AddDefaultColorAttachment();
   26825     pipe.SetMSAA(&ms_state_ci);
   26826 
   26827     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09600bc2);
   26828 
   26829     pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle());
   26830 
   26831     m_errorMonitor->VerifyFound();
   26832 }
   26833 
   26834 TEST_F(VkPositiveLayerTest, ParameterLayerFeatures2Capture) {
   26835     TEST_DESCRIPTION("Ensure parameter_validation_layer correctly captures physical device features");
   26836     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
   26837         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
   26838     } else {
   26839         printf("             Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n");
   26840         return;
   26841     }
   26842 
   26843     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   26844 
   26845     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
   26846         (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
   26847     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
   26848 
   26849     VkResult err;
   26850     m_errorMonitor->ExpectSuccess();
   26851 
   26852     VkPhysicalDeviceFeatures2KHR features2;
   26853     features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
   26854     features2.pNext = nullptr;
   26855 
   26856     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
   26857 
   26858     // We're not creating a valid m_device, but the phy wrapper is useful
   26859     vk_testing::PhysicalDevice physical_device(gpu());
   26860     vk_testing::QueueCreateInfoArray queue_info(physical_device.queue_properties());
   26861     // Only request creation with queuefamilies that have at least one queue
   26862     std::vector<VkDeviceQueueCreateInfo> create_queue_infos;
   26863     auto qci = queue_info.data();
   26864     for (uint32_t i = 0; i < queue_info.size(); ++i) {
   26865         if (qci[i].queueCount) {
   26866             create_queue_infos.push_back(qci[i]);
   26867         }
   26868     }
   26869 
   26870     VkDeviceCreateInfo dev_info = {};
   26871     dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
   26872     dev_info.pNext = &features2;
   26873     dev_info.flags = 0;
   26874     dev_info.queueCreateInfoCount = create_queue_infos.size();
   26875     dev_info.pQueueCreateInfos = create_queue_infos.data();
   26876     dev_info.enabledLayerCount = 0;
   26877     dev_info.ppEnabledLayerNames = nullptr;
   26878     dev_info.enabledExtensionCount = 0;
   26879     dev_info.ppEnabledExtensionNames = nullptr;
   26880     dev_info.pEnabledFeatures = nullptr;
   26881 
   26882     VkDevice device;
   26883     err = vkCreateDevice(gpu(), &dev_info, nullptr, &device);
   26884     ASSERT_VK_SUCCESS(err);
   26885 
   26886     if (features2.features.samplerAnisotropy) {
   26887         // Test that the parameter layer is caching the features correctly using CreateSampler
   26888         VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
   26889         // If the features were not captured correctly, this should cause an error
   26890         sampler_ci.anisotropyEnable = VK_TRUE;
   26891         sampler_ci.maxAnisotropy = physical_device.properties().limits.maxSamplerAnisotropy;
   26892 
   26893         VkSampler sampler = VK_NULL_HANDLE;
   26894         err = vkCreateSampler(device, &sampler_ci, nullptr, &sampler);
   26895         ASSERT_VK_SUCCESS(err);
   26896         vkDestroySampler(device, sampler, nullptr);
   26897     } else {
   26898         printf("             Feature samplerAnisotropy not enabled;  parameter_layer check skipped.\n");
   26899     }
   26900 
   26901     // Verify the core validation layer has captured the physical device features by creating a a query pool.
   26902     if (features2.features.pipelineStatisticsQuery) {
   26903         VkQueryPool query_pool;
   26904         VkQueryPoolCreateInfo qpci{};
   26905         qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
   26906         qpci.queryType = VK_QUERY_TYPE_PIPELINE_STATISTICS;
   26907         qpci.queryCount = 1;
   26908         err = vkCreateQueryPool(device, &qpci, nullptr, &query_pool);
   26909         ASSERT_VK_SUCCESS(err);
   26910 
   26911         vkDestroyQueryPool(device, query_pool, nullptr);
   26912     } else {
   26913         printf("             Feature pipelineStatisticsQuery not enabled;  core_validation_layer check skipped.\n");
   26914     }
   26915 
   26916     vkDestroyDevice(device, nullptr);
   26917 
   26918     m_errorMonitor->VerifyNotFound();
   26919 }
   26920 
   26921 TEST_F(VkPositiveLayerTest, GetMemoryRequirements2) {
   26922     TEST_DESCRIPTION(
   26923         "Get memory requirements with VK_KHR_get_memory_requirements2 instead of core entry points and verify layers do not emit "
   26924         "errors when objects are bound and used");
   26925 
   26926     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   26927 
   26928     // Check for VK_KHR_get_memory_requirementes2 extensions
   26929     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME)) {
   26930         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
   26931     } else {
   26932         printf("             %s not supported, skipping test\n", VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
   26933         return;
   26934     }
   26935 
   26936     ASSERT_NO_FATAL_FAILURE(InitState());
   26937 
   26938     m_errorMonitor->ExpectSuccess(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT);
   26939 
   26940     // Create a test buffer
   26941     vk_testing::Buffer buffer;
   26942     buffer.init_no_mem(*m_device,
   26943                        vk_testing::Buffer::create_info(1024, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT));
   26944 
   26945     // Use extension to get buffer memory reqirements
   26946     auto vkGetBufferMemoryRequirements2KHR = reinterpret_cast<PFN_vkGetBufferMemoryRequirements2KHR>(
   26947         vkGetDeviceProcAddr(m_device->device(), "vkGetBufferMemoryRequirements2KHR"));
   26948     ASSERT_TRUE(vkGetBufferMemoryRequirements2KHR != nullptr);
   26949     VkBufferMemoryRequirementsInfo2KHR buffer_info = {VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR, nullptr,
   26950                                                       buffer.handle()};
   26951     VkMemoryRequirements2KHR buffer_reqs = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR};
   26952     vkGetBufferMemoryRequirements2KHR(m_device->device(), &buffer_info, &buffer_reqs);
   26953 
   26954     // Allocate and bind buffer memory
   26955     vk_testing::DeviceMemory buffer_memory;
   26956     buffer_memory.init(*m_device, vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, buffer_reqs.memoryRequirements, 0));
   26957     vkBindBufferMemory(m_device->device(), buffer.handle(), buffer_memory.handle(), 0);
   26958 
   26959     // Create a test image
   26960     auto image_ci = vk_testing::Image::create_info();
   26961     image_ci.imageType = VK_IMAGE_TYPE_2D;
   26962     image_ci.extent.width = 32;
   26963     image_ci.extent.height = 32;
   26964     image_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
   26965     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
   26966     image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   26967     vk_testing::Image image;
   26968     image.init_no_mem(*m_device, image_ci);
   26969 
   26970     // Use extension to get image memory requirements
   26971     auto vkGetImageMemoryRequirements2KHR = reinterpret_cast<PFN_vkGetImageMemoryRequirements2KHR>(
   26972         vkGetDeviceProcAddr(m_device->device(), "vkGetImageMemoryRequirements2KHR"));
   26973     ASSERT_TRUE(vkGetImageMemoryRequirements2KHR != nullptr);
   26974     VkImageMemoryRequirementsInfo2KHR image_info = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR, nullptr,
   26975                                                     image.handle()};
   26976     VkMemoryRequirements2KHR image_reqs = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR};
   26977     vkGetImageMemoryRequirements2KHR(m_device->device(), &image_info, &image_reqs);
   26978 
   26979     // Allocate and bind image memory
   26980     vk_testing::DeviceMemory image_memory;
   26981     image_memory.init(*m_device, vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, image_reqs.memoryRequirements, 0));
   26982     vkBindImageMemory(m_device->device(), image.handle(), image_memory.handle(), 0);
   26983 
   26984     // Now execute arbitrary commands that use the test buffer and image
   26985     m_commandBuffer->begin();
   26986 
   26987     // Fill buffer with 0
   26988     vkCmdFillBuffer(m_commandBuffer->handle(), buffer.handle(), 0, VK_WHOLE_SIZE, 0);
   26989 
   26990     // Transition and clear image
   26991     const auto subresource_range = image.subresource_range(VK_IMAGE_ASPECT_COLOR_BIT);
   26992     const auto barrier = image.image_memory_barrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
   26993                                                     VK_IMAGE_LAYOUT_GENERAL, subresource_range);
   26994     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
   26995                          nullptr, 0, nullptr, 1, &barrier);
   26996     const VkClearColorValue color = {};
   26997     vkCmdClearColorImage(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, &color, 1, &subresource_range);
   26998 
   26999     // Submit and verify no validation errors
   27000     m_commandBuffer->end();
   27001     m_commandBuffer->QueueCommandBuffer();
   27002     m_errorMonitor->VerifyNotFound();
   27003 }
   27004 
   27005 TEST_F(VkPositiveLayerTest, BindMemory2) {
   27006     TEST_DESCRIPTION(
   27007         "Bind memory with VK_KHR_bind_memory2 instead of core entry points and verify layers do not emit errors when objects are "
   27008         "used");
   27009 
   27010     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
   27011 
   27012     // Check for VK_KHR_get_memory_requirementes2 extensions
   27013     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME)) {
   27014         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
   27015     } else {
   27016         printf("             %s not supported, skipping test\n", VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
   27017         return;
   27018     }
   27019 
   27020     ASSERT_NO_FATAL_FAILURE(InitState());
   27021 
   27022     m_errorMonitor->ExpectSuccess(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT);
   27023 
   27024     // Create a test buffer
   27025     vk_testing::Buffer buffer;
   27026     buffer.init_no_mem(*m_device, vk_testing::Buffer::create_info(1024, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
   27027 
   27028     // Allocate buffer memory
   27029     vk_testing::DeviceMemory buffer_memory;
   27030     buffer_memory.init(*m_device, vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, buffer.memory_requirements(), 0));
   27031 
   27032     // Bind buffer memory with extension
   27033     auto vkBindBufferMemory2KHR =
   27034         reinterpret_cast<PFN_vkBindBufferMemory2KHR>(vkGetDeviceProcAddr(m_device->device(), "vkBindBufferMemory2KHR"));
   27035     ASSERT_TRUE(vkBindBufferMemory2KHR != nullptr);
   27036     VkBindBufferMemoryInfoKHR buffer_bind_info = {VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR, nullptr, buffer.handle(),
   27037                                                   buffer_memory.handle(), 0};
   27038     vkBindBufferMemory2KHR(m_device->device(), 1, &buffer_bind_info);
   27039 
   27040     // Create a test image
   27041     auto image_ci = vk_testing::Image::create_info();
   27042     image_ci.imageType = VK_IMAGE_TYPE_2D;
   27043     image_ci.extent.width = 32;
   27044     image_ci.extent.height = 32;
   27045     image_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
   27046     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
   27047     image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   27048     vk_testing::Image image;
   27049     image.init_no_mem(*m_device, image_ci);
   27050 
   27051     // Allocate image memory
   27052     vk_testing::DeviceMemory image_memory;
   27053     image_memory.init(*m_device, vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, image.memory_requirements(), 0));
   27054 
   27055     // Bind image memory with extension
   27056     auto vkBindImageMemory2KHR =
   27057         reinterpret_cast<PFN_vkBindImageMemory2KHR>(vkGetDeviceProcAddr(m_device->device(), "vkBindImageMemory2KHR"));
   27058     ASSERT_TRUE(vkBindImageMemory2KHR != nullptr);
   27059     VkBindImageMemoryInfoKHR image_bind_info = {VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR, nullptr, image.handle(),
   27060                                                 image_memory.handle(), 0};
   27061     vkBindImageMemory2KHR(m_device->device(), 1, &image_bind_info);
   27062 
   27063     // Now execute arbitrary commands that use the test buffer and image
   27064     m_commandBuffer->begin();
   27065 
   27066     // Fill buffer with 0
   27067     vkCmdFillBuffer(m_commandBuffer->handle(), buffer.handle(), 0, VK_WHOLE_SIZE, 0);
   27068 
   27069     // Transition and clear image
   27070     const auto subresource_range = image.subresource_range(VK_IMAGE_ASPECT_COLOR_BIT);
   27071     const auto barrier = image.image_memory_barrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
   27072                                                     VK_IMAGE_LAYOUT_GENERAL, subresource_range);
   27073     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
   27074                          nullptr, 0, nullptr, 1, &barrier);
   27075     const VkClearColorValue color = {};
   27076     vkCmdClearColorImage(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, &color, 1, &subresource_range);
   27077 
   27078     // Submit and verify no validation errors
   27079     m_commandBuffer->end();
   27080     m_commandBuffer->QueueCommandBuffer();
   27081     m_errorMonitor->VerifyNotFound();
   27082 }
   27083 
   27084 #if defined(ANDROID) && defined(VALIDATION_APK)
   27085 const char *appTag = "VulkanLayerValidationTests";
   27086 static bool initialized = false;
   27087 static bool active = false;
   27088 
   27089 // Convert Intents to argv
   27090 // Ported from Hologram sample, only difference is flexible key
   27091 std::vector<std::string> get_args(android_app &app, const char *intent_extra_data_key) {
   27092     std::vector<std::string> args;
   27093     JavaVM &vm = *app.activity->vm;
   27094     JNIEnv *p_env;
   27095     if (vm.AttachCurrentThread(&p_env, nullptr) != JNI_OK) return args;
   27096 
   27097     JNIEnv &env = *p_env;
   27098     jobject activity = app.activity->clazz;
   27099     jmethodID get_intent_method = env.GetMethodID(env.GetObjectClass(activity), "getIntent", "()Landroid/content/Intent;");
   27100     jobject intent = env.CallObjectMethod(activity, get_intent_method);
   27101     jmethodID get_string_extra_method =
   27102         env.GetMethodID(env.GetObjectClass(intent), "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
   27103     jvalue get_string_extra_args;
   27104     get_string_extra_args.l = env.NewStringUTF(intent_extra_data_key);
   27105     jstring extra_str = static_cast<jstring>(env.CallObjectMethodA(intent, get_string_extra_method, &get_string_extra_args));
   27106 
   27107     std::string args_str;
   27108     if (extra_str) {
   27109         const char *extra_utf = env.GetStringUTFChars(extra_str, nullptr);
   27110         args_str = extra_utf;
   27111         env.ReleaseStringUTFChars(extra_str, extra_utf);
   27112         env.DeleteLocalRef(extra_str);
   27113     }
   27114 
   27115     env.DeleteLocalRef(get_string_extra_args.l);
   27116     env.DeleteLocalRef(intent);
   27117     vm.DetachCurrentThread();
   27118 
   27119     // split args_str
   27120     std::stringstream ss(args_str);
   27121     std::string arg;
   27122     while (std::getline(ss, arg, ' ')) {
   27123         if (!arg.empty()) args.push_back(arg);
   27124     }
   27125 
   27126     return args;
   27127 }
   27128 
   27129 void addFullTestCommentIfPresent(const ::testing::TestInfo &test_info, std::string &error_message) {
   27130     const char *const type_param = test_info.type_param();
   27131     const char *const value_param = test_info.value_param();
   27132 
   27133     if (type_param != NULL || value_param != NULL) {
   27134         error_message.append(", where ");
   27135         if (type_param != NULL) {
   27136             error_message.append("TypeParam = ").append(type_param);
   27137             if (value_param != NULL) error_message.append(" and ");
   27138         }
   27139         if (value_param != NULL) {
   27140             error_message.append("GetParam() = ").append(value_param);
   27141         }
   27142     }
   27143 }
   27144 
   27145 // Inspired by https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md
   27146 class LogcatPrinter : public ::testing::EmptyTestEventListener {
   27147     // Called before a test starts.
   27148     virtual void OnTestStart(const ::testing::TestInfo &test_info) {
   27149         __android_log_print(ANDROID_LOG_INFO, appTag, "[ RUN      ] %s.%s", test_info.test_case_name(), test_info.name());
   27150     }
   27151 
   27152     // Called after a failed assertion or a SUCCEED() invocation.
   27153     virtual void OnTestPartResult(const ::testing::TestPartResult &result) {
   27154         // If the test part succeeded, we don't need to do anything.
   27155         if (result.type() == ::testing::TestPartResult::kSuccess) return;
   27156 
   27157         __android_log_print(ANDROID_LOG_INFO, appTag, "%s in %s:%d %s", result.failed() ? "*** Failure" : "Success",
   27158                             result.file_name(), result.line_number(), result.summary());
   27159     }
   27160 
   27161     // Called after a test ends.
   27162     virtual void OnTestEnd(const ::testing::TestInfo &info) {
   27163         std::string result;
   27164         if (info.result()->Passed()) {
   27165             result.append("[       OK ]");
   27166         } else {
   27167             result.append("[  FAILED  ]");
   27168         }
   27169         result.append(info.test_case_name()).append(".").append(info.name());
   27170         if (info.result()->Failed()) addFullTestCommentIfPresent(info, result);
   27171 
   27172         if (::testing::GTEST_FLAG(print_time)) {
   27173             std::ostringstream os;
   27174             os << info.result()->elapsed_time();
   27175             result.append(" (").append(os.str()).append(" ms)");
   27176         }
   27177 
   27178         __android_log_print(ANDROID_LOG_INFO, appTag, "%s", result.c_str());
   27179     };
   27180 };
   27181 
   27182 static int32_t processInput(struct android_app *app, AInputEvent *event) { return 0; }
   27183 
   27184 static void processCommand(struct android_app *app, int32_t cmd) {
   27185     switch (cmd) {
   27186         case APP_CMD_INIT_WINDOW: {
   27187             if (app->window) {
   27188                 initialized = true;
   27189             }
   27190             break;
   27191         }
   27192         case APP_CMD_GAINED_FOCUS: {
   27193             active = true;
   27194             break;
   27195         }
   27196         case APP_CMD_LOST_FOCUS: {
   27197             active = false;
   27198             break;
   27199         }
   27200     }
   27201 }
   27202 
   27203 void android_main(struct android_app *app) {
   27204     int vulkanSupport = InitVulkan();
   27205     if (vulkanSupport == 0) {
   27206         __android_log_print(ANDROID_LOG_INFO, appTag, "==== FAILED ==== No Vulkan support found");
   27207         return;
   27208     }
   27209 
   27210     app->onAppCmd = processCommand;
   27211     app->onInputEvent = processInput;
   27212 
   27213     while (1) {
   27214         int events;
   27215         struct android_poll_source *source;
   27216         while (ALooper_pollAll(active ? 0 : -1, NULL, &events, (void **)&source) >= 0) {
   27217             if (source) {
   27218                 source->process(app, source);
   27219             }
   27220 
   27221             if (app->destroyRequested != 0) {
   27222                 VkTestFramework::Finish();
   27223                 return;
   27224             }
   27225         }
   27226 
   27227         if (initialized && active) {
   27228             // Use the following key to send arguments to gtest, i.e.
   27229             // --es args "--gtest_filter=-VkLayerTest.foo"
   27230             const char key[] = "args";
   27231             std::vector<std::string> args = get_args(*app, key);
   27232 
   27233             std::string filter = "";
   27234             if (args.size() > 0) {
   27235                 __android_log_print(ANDROID_LOG_INFO, appTag, "Intent args = %s", args[0].c_str());
   27236                 filter += args[0];
   27237             } else {
   27238                 __android_log_print(ANDROID_LOG_INFO, appTag, "No Intent args detected");
   27239             }
   27240 
   27241             int argc = 2;
   27242             char *argv[] = {(char *)"foo", (char *)filter.c_str()};
   27243             __android_log_print(ANDROID_LOG_DEBUG, appTag, "filter = %s", argv[1]);
   27244 
   27245             // Route output to files until we can override the gtest output
   27246             freopen("/sdcard/Android/data/com.example.VulkanLayerValidationTests/files/out.txt", "w", stdout);
   27247             freopen("/sdcard/Android/data/com.example.VulkanLayerValidationTests/files/err.txt", "w", stderr);
   27248 
   27249             ::testing::InitGoogleTest(&argc, argv);
   27250 
   27251             ::testing::TestEventListeners &listeners = ::testing::UnitTest::GetInstance()->listeners();
   27252             listeners.Append(new LogcatPrinter);
   27253 
   27254             VkTestFramework::InitArgs(&argc, argv);
   27255             ::testing::AddGlobalTestEnvironment(new TestEnvironment);
   27256 
   27257             int result = RUN_ALL_TESTS();
   27258 
   27259             if (result != 0) {
   27260                 __android_log_print(ANDROID_LOG_INFO, appTag, "==== Tests FAILED ====");
   27261             } else {
   27262                 __android_log_print(ANDROID_LOG_INFO, appTag, "==== Tests PASSED ====");
   27263             }
   27264 
   27265             VkTestFramework::Finish();
   27266 
   27267             fclose(stdout);
   27268             fclose(stderr);
   27269 
   27270             ANativeActivity_finish(app->activity);
   27271             return;
   27272         }
   27273     }
   27274 }
   27275 #endif
   27276 
   27277 #if defined(_WIN32) && !defined(NDEBUG)
   27278 #include <crtdbg.h>
   27279 #endif
   27280 
   27281 int main(int argc, char **argv) {
   27282     int result;
   27283 
   27284 #ifdef ANDROID
   27285     int vulkanSupport = InitVulkan();
   27286     if (vulkanSupport == 0) return 1;
   27287 #endif
   27288 
   27289 #if defined(_WIN32) && !defined(NDEBUG)
   27290     _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
   27291     _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
   27292 #endif
   27293 
   27294     ::testing::InitGoogleTest(&argc, argv);
   27295     VkTestFramework::InitArgs(&argc, argv);
   27296 
   27297     ::testing::AddGlobalTestEnvironment(new TestEnvironment);
   27298 
   27299     result = RUN_ALL_TESTS();
   27300 
   27301     VkTestFramework::Finish();
   27302     return result;
   27303 }
   27304