• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2015-2019 The Khronos Group Inc.
3  * Copyright (c) 2015-2019 Valve Corporation
4  * Copyright (c) 2015-2019 LunarG, Inc.
5  * Copyright (c) 2015-2019 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@gmail.com>
14  * Author: Chris Forbes <chrisf@ijw.co.nz>
15  * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
16  * Author: Mark Lobodzinski <mark@lunarg.com>
17  * Author: Mike Stroyan <mike@LunarG.com>
18  * Author: Tobin Ehlis <tobine@google.com>
19  * Author: Tony Barbour <tony@LunarG.com>
20  * Author: Cody Northrop <cnorthrop@google.com>
21  * Author: Dave Houlton <daveh@lunarg.com>
22  * Author: Jeremy Kniager <jeremyk@lunarg.com>
23  * Author: Shannon McPherson <shannon@lunarg.com>
24  */
25 
26 #ifdef ANDROID
27 #include "vulkan_wrapper.h"
28 #else
29 #define NOMINMAX
30 #include <vulkan/vulkan.h>
31 #endif
32 
33 #include "layers/vk_device_profile_api_layer.h"
34 
35 #if defined(ANDROID) && defined(VALIDATION_APK)
36 #include <android/log.h>
37 #include <android_native_app_glue.h>
38 #endif
39 
40 #include "icd-spv.h"
41 #include "test_common.h"
42 #include "vk_layer_config.h"
43 #include "vk_format_utils.h"
44 #include "vkrenderframework.h"
45 #include "vk_typemap_helper.h"
46 #include "convert_to_renderpass2.h"
47 
48 #include <algorithm>
49 #include <cmath>
50 #include <functional>
51 #include <limits>
52 #include <memory>
53 #include <unordered_set>
54 
55 //--------------------------------------------------------------------------------------
56 // Mesh and VertexFormat Data
57 //--------------------------------------------------------------------------------------
58 
59 const char *kSkipPrefix = "             TEST SKIPPED:";
60 
61 enum BsoFailSelect {
62     BsoFailNone,
63     BsoFailLineWidth,
64     BsoFailDepthBias,
65     BsoFailViewport,
66     BsoFailScissor,
67     BsoFailBlend,
68     BsoFailDepthBounds,
69     BsoFailStencilReadMask,
70     BsoFailStencilWriteMask,
71     BsoFailStencilReference,
72     BsoFailCmdClearAttachments,
73     BsoFailIndexBuffer,
74     BsoFailIndexBufferBadSize,
75     BsoFailIndexBufferBadOffset,
76     BsoFailIndexBufferBadMapSize,
77     BsoFailIndexBufferBadMapOffset
78 };
79 
80 static const char bindStateVertShaderText[] =
81     "#version 450\n"
82     "vec2 vertices[3];\n"
83     "void main() {\n"
84     "      vertices[0] = vec2(-1.0, -1.0);\n"
85     "      vertices[1] = vec2( 1.0, -1.0);\n"
86     "      vertices[2] = vec2( 0.0,  1.0);\n"
87     "   gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0);\n"
88     "}\n";
89 
90 static const char bindStateFragShaderText[] =
91     "#version 450\n"
92     "\n"
93     "layout(location = 0) out vec4 uFragColor;\n"
94     "void main(){\n"
95     "   uFragColor = vec4(0,1,0,1);\n"
96     "}\n";
97 
98 // Static arrays helper
99 template <class ElementT, size_t array_size>
size(ElementT (&)[array_size])100 size_t size(ElementT (&)[array_size]) {
101     return array_size;
102 }
103 
104 // Format search helper
FindSupportedDepthStencilFormat(VkPhysicalDevice phy)105 VkFormat FindSupportedDepthStencilFormat(VkPhysicalDevice phy) {
106     VkFormat ds_formats[] = {VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT};
107     for (uint32_t i = 0; i < sizeof(ds_formats); i++) {
108         VkFormatProperties format_props;
109         vkGetPhysicalDeviceFormatProperties(phy, ds_formats[i], &format_props);
110 
111         if (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
112             return ds_formats[i];
113         }
114     }
115     return VK_FORMAT_UNDEFINED;
116 }
117 
118 // Returns true if *any* requested features are available.
119 // Assumption is that the framework can successfully create an image as
120 // long as at least one of the feature bits is present (excepting VTX_BUF).
ImageFormatIsSupported(VkPhysicalDevice phy,VkFormat format,VkImageTiling tiling=VK_IMAGE_TILING_OPTIMAL,VkFormatFeatureFlags features=~VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)121 bool ImageFormatIsSupported(VkPhysicalDevice phy, VkFormat format, VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL,
122                             VkFormatFeatureFlags features = ~VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) {
123     VkFormatProperties format_props;
124     vkGetPhysicalDeviceFormatProperties(phy, format, &format_props);
125     VkFormatFeatureFlags phy_features =
126         (VK_IMAGE_TILING_OPTIMAL == tiling ? format_props.optimalTilingFeatures : format_props.linearTilingFeatures);
127     return (0 != (phy_features & features));
128 }
129 
130 // Returns true if format and *all* requested features are available.
ImageFormatAndFeaturesSupported(VkPhysicalDevice phy,VkFormat format,VkImageTiling tiling,VkFormatFeatureFlags features)131 bool ImageFormatAndFeaturesSupported(VkPhysicalDevice phy, VkFormat format, VkImageTiling tiling, VkFormatFeatureFlags features) {
132     VkFormatProperties format_props;
133     vkGetPhysicalDeviceFormatProperties(phy, format, &format_props);
134     VkFormatFeatureFlags phy_features =
135         (VK_IMAGE_TILING_OPTIMAL == tiling ? format_props.optimalTilingFeatures : format_props.linearTilingFeatures);
136     return (features == (phy_features & features));
137 }
138 
139 // Returns true if format and *all* requested features are available.
ImageFormatAndFeaturesSupported(const VkInstance inst,const VkPhysicalDevice phy,const VkImageCreateInfo info,const VkFormatFeatureFlags features)140 bool ImageFormatAndFeaturesSupported(const VkInstance inst, const VkPhysicalDevice phy, const VkImageCreateInfo info,
141                                      const VkFormatFeatureFlags features) {
142     // Verify physical device support of format features
143     if (!ImageFormatAndFeaturesSupported(phy, info.format, info.tiling, features)) {
144         return false;
145     }
146 
147     // Verify that PhysDevImageFormatProp() also claims support for the specific usage
148     VkImageFormatProperties props;
149     VkResult err =
150         vkGetPhysicalDeviceImageFormatProperties(phy, info.format, info.imageType, info.tiling, info.usage, info.flags, &props);
151     if (VK_SUCCESS != err) {
152         return false;
153     }
154 
155 #if 0  // Convinced this chunk doesn't currently add any additional info, but leaving in place because it may be
156        // necessary with future extensions
157 
158     // Verify again using version 2, if supported, which *can* return more property data than the original...
159     // (It's not clear that this is any more definitive than using the original version - but no harm)
160     PFN_vkGetPhysicalDeviceImageFormatProperties2KHR p_GetPDIFP2KHR =
161         (PFN_vkGetPhysicalDeviceImageFormatProperties2KHR)vkGetInstanceProcAddr(inst,
162                                                                                 "vkGetPhysicalDeviceImageFormatProperties2KHR");
163     if (NULL != p_GetPDIFP2KHR) {
164         VkPhysicalDeviceImageFormatInfo2KHR fmt_info{};
165         fmt_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR;
166         fmt_info.pNext = nullptr;
167         fmt_info.format = info.format;
168         fmt_info.type = info.imageType;
169         fmt_info.tiling = info.tiling;
170         fmt_info.usage = info.usage;
171         fmt_info.flags = info.flags;
172 
173         VkImageFormatProperties2KHR fmt_props = {};
174         fmt_props.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR;
175         err = p_GetPDIFP2KHR(phy, &fmt_info, &fmt_props);
176         if (VK_SUCCESS != err) {
177             return false;
178         }
179     }
180 #endif
181 
182     return true;
183 }
184 
185 // Validation report callback prototype
186 static VKAPI_ATTR VkBool32 VKAPI_CALL myDbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject,
187                                                 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg,
188                                                 void *pUserData);
189 
190 // Simple sane SamplerCreateInfo boilerplate
SafeSaneSamplerCreateInfo()191 static VkSamplerCreateInfo SafeSaneSamplerCreateInfo() {
192     VkSamplerCreateInfo sampler_create_info = {};
193     sampler_create_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
194     sampler_create_info.pNext = nullptr;
195     sampler_create_info.magFilter = VK_FILTER_NEAREST;
196     sampler_create_info.minFilter = VK_FILTER_NEAREST;
197     sampler_create_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
198     sampler_create_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
199     sampler_create_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
200     sampler_create_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
201     sampler_create_info.mipLodBias = 0.0;
202     sampler_create_info.anisotropyEnable = VK_FALSE;
203     sampler_create_info.maxAnisotropy = 1.0;
204     sampler_create_info.compareEnable = VK_FALSE;
205     sampler_create_info.compareOp = VK_COMPARE_OP_NEVER;
206     sampler_create_info.minLod = 0.0;
207     sampler_create_info.maxLod = 16.0;
208     sampler_create_info.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
209     sampler_create_info.unnormalizedCoordinates = VK_FALSE;
210 
211     return sampler_create_info;
212 }
213 
214 // Helper for checking createRenderPass2 support and adding related extensions.
CheckCreateRenderPass2Support(VkRenderFramework * renderFramework,std::vector<const char * > & device_extension_names)215 static bool CheckCreateRenderPass2Support(VkRenderFramework *renderFramework, std::vector<const char *> &device_extension_names) {
216     if (renderFramework->DeviceExtensionSupported(renderFramework->gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) {
217         device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME);
218         device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME);
219         device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
220         return true;
221     }
222     return false;
223 }
224 
225 // Dependent "false" type for the static assert, as GCC will evaluate
226 // non-dependent static_asserts even for non-instantiated templates
227 template <typename T>
228 struct AlwaysFalse : std::false_type {};
229 
230 // Helpers to get nearest greater or smaller value (of float) -- useful for testing the boundary cases of Vulkan limits
231 template <typename T>
NearestGreater(const T from)232 T NearestGreater(const T from) {
233     using Lim = std::numeric_limits<T>;
234     const auto positive_direction = Lim::has_infinity ? Lim::infinity() : Lim::max();
235 
236     return std::nextafter(from, positive_direction);
237 }
238 
239 template <typename T>
NearestSmaller(const T from)240 T NearestSmaller(const T from) {
241     using Lim = std::numeric_limits<T>;
242     const auto negative_direction = Lim::has_infinity ? -Lim::infinity() : Lim::lowest();
243 
244     return std::nextafter(from, negative_direction);
245 }
246 
247 // ErrorMonitor Usage:
248 //
249 // Call SetDesiredFailureMsg with a string to be compared against all
250 // encountered log messages, or a validation error enum identifying
251 // desired error message. Passing NULL or VALIDATION_ERROR_MAX_ENUM
252 // will match all log messages. logMsg will return true for skipCall
253 // only if msg is matched or NULL.
254 //
255 // Call VerifyFound to determine if all desired failure messages
256 // were encountered. Call VerifyNotFound to determine if any unexpected
257 // failure was encountered.
258 class ErrorMonitor {
259    public:
ErrorMonitor()260     ErrorMonitor() {
261         test_platform_thread_create_mutex(&mutex_);
262         test_platform_thread_lock_mutex(&mutex_);
263         Reset();
264         test_platform_thread_unlock_mutex(&mutex_);
265     }
266 
~ErrorMonitor()267     ~ErrorMonitor() { test_platform_thread_delete_mutex(&mutex_); }
268 
269     // Set monitor to pristine state
Reset()270     void Reset() {
271         message_flags_ = VK_DEBUG_REPORT_ERROR_BIT_EXT;
272         bailout_ = NULL;
273         message_found_ = VK_FALSE;
274         failure_message_strings_.clear();
275         desired_message_strings_.clear();
276         ignore_message_strings_.clear();
277         other_messages_.clear();
278     }
279 
280     // ErrorMonitor will look for an error message containing the specified string(s)
SetDesiredFailureMsg(const VkFlags msgFlags,const std::string msg)281     void SetDesiredFailureMsg(const VkFlags msgFlags, const std::string msg) { SetDesiredFailureMsg(msgFlags, msg.c_str()); }
SetDesiredFailureMsg(const VkFlags msgFlags,const char * const msgString)282     void SetDesiredFailureMsg(const VkFlags msgFlags, const char *const msgString) {
283         test_platform_thread_lock_mutex(&mutex_);
284         desired_message_strings_.insert(msgString);
285         message_flags_ |= msgFlags;
286         test_platform_thread_unlock_mutex(&mutex_);
287     }
288 
289     // ErrorMonitor will look for an error message containing the specified string(s)
290     template <typename Iter>
SetDesiredFailureMsg(const VkFlags msgFlags,Iter iter,const Iter end)291     void SetDesiredFailureMsg(const VkFlags msgFlags, Iter iter, const Iter end) {
292         for (; iter != end; ++iter) {
293             SetDesiredFailureMsg(msgFlags, *iter);
294         }
295     }
296 
297     // Set an error that the error monitor will ignore. Do not use this function if you are creating a new test.
298     // TODO: This is stopgap to block new unexpected errors from being introduced. The long-term goal is to remove the use of this
299     // function and its definition.
SetUnexpectedError(const char * const msg)300     void SetUnexpectedError(const char *const msg) {
301         test_platform_thread_lock_mutex(&mutex_);
302 
303         ignore_message_strings_.emplace_back(msg);
304 
305         test_platform_thread_unlock_mutex(&mutex_);
306     }
307 
CheckForDesiredMsg(const char * const msgString)308     VkBool32 CheckForDesiredMsg(const char *const msgString) {
309         VkBool32 result = VK_FALSE;
310         test_platform_thread_lock_mutex(&mutex_);
311         if (bailout_ != nullptr) {
312             *bailout_ = true;
313         }
314         string errorString(msgString);
315         bool found_expected = false;
316 
317         if (!IgnoreMessage(errorString)) {
318             for (auto desired_msg_it = desired_message_strings_.begin(); desired_msg_it != desired_message_strings_.end();
319                  ++desired_msg_it) {
320                 if ((*desired_msg_it).length() == 0) {
321                     // An empty desired_msg string "" indicates a positive test - not expecting an error.
322                     // Return true to avoid calling layers/driver with this error.
323                     // And don't erase the "" string, so it remains if another error is found.
324                     result = VK_TRUE;
325                     found_expected = true;
326                     message_found_ = true;
327                     failure_message_strings_.insert(errorString);
328                 } else if (errorString.find(*desired_msg_it) != string::npos) {
329                     found_expected = true;
330                     failure_message_strings_.insert(errorString);
331                     message_found_ = true;
332                     result = VK_TRUE;
333                     // Remove a maximum of one failure message from the set
334                     // Multiset mutation is acceptable because `break` causes flow of control to exit the for loop
335                     desired_message_strings_.erase(desired_msg_it);
336                     break;
337                 }
338             }
339 
340             if (!found_expected) {
341                 printf("Unexpected: %s\n", msgString);
342                 other_messages_.push_back(errorString);
343             }
344         }
345 
346         test_platform_thread_unlock_mutex(&mutex_);
347         return result;
348     }
349 
GetOtherFailureMsgs() const350     vector<string> GetOtherFailureMsgs() const { return other_messages_; }
351 
GetMessageFlags() const352     VkDebugReportFlagsEXT GetMessageFlags() const { return message_flags_; }
353 
AnyDesiredMsgFound() const354     bool AnyDesiredMsgFound() const { return message_found_; }
355 
AllDesiredMsgsFound() const356     bool AllDesiredMsgsFound() const { return desired_message_strings_.empty(); }
357 
SetError(const char * const errorString)358     void SetError(const char *const errorString) {
359         message_found_ = true;
360         failure_message_strings_.insert(errorString);
361     }
362 
SetBailout(bool * bailout)363     void SetBailout(bool *bailout) { bailout_ = bailout; }
364 
DumpFailureMsgs() const365     void DumpFailureMsgs() const {
366         vector<string> otherMsgs = GetOtherFailureMsgs();
367         if (otherMsgs.size()) {
368             cout << "Other error messages logged for this test were:" << endl;
369             for (auto iter = otherMsgs.begin(); iter != otherMsgs.end(); iter++) {
370                 cout << "     " << *iter << endl;
371             }
372         }
373     }
374 
375     // Helpers
376 
377     // ExpectSuccess now takes an optional argument allowing a custom combination of debug flags
ExpectSuccess(VkDebugReportFlagsEXT const message_flag_mask=VK_DEBUG_REPORT_ERROR_BIT_EXT)378     void ExpectSuccess(VkDebugReportFlagsEXT const message_flag_mask = VK_DEBUG_REPORT_ERROR_BIT_EXT) {
379         // Match ANY message matching specified type
380         SetDesiredFailureMsg(message_flag_mask, "");
381         message_flags_ = message_flag_mask;  // override mask handling in SetDesired...
382     }
383 
VerifyFound()384     void VerifyFound() {
385         // Not receiving expected message(s) is a failure. /Before/ throwing, dump any other messages
386         if (!AllDesiredMsgsFound()) {
387             DumpFailureMsgs();
388             for (const auto desired_msg : desired_message_strings_) {
389                 ADD_FAILURE() << "Did not receive expected error '" << desired_msg << "'";
390             }
391         }
392         Reset();
393     }
394 
VerifyNotFound()395     void VerifyNotFound() {
396         // ExpectSuccess() configured us to match anything. Any error is a failure.
397         if (AnyDesiredMsgFound()) {
398             DumpFailureMsgs();
399             for (const auto msg : failure_message_strings_) {
400                 ADD_FAILURE() << "Expected to succeed but got error: " << msg;
401             }
402         }
403         Reset();
404     }
405 
406    private:
407     // TODO: This is stopgap to block new unexpected errors from being introduced. The long-term goal is to remove the use of this
408     // function and its definition.
IgnoreMessage(std::string const & msg) const409     bool IgnoreMessage(std::string const &msg) const {
410         if (ignore_message_strings_.empty()) {
411             return false;
412         }
413 
414         return std::find_if(ignore_message_strings_.begin(), ignore_message_strings_.end(), [&msg](std::string const &str) {
415                    return msg.find(str) != std::string::npos;
416                }) != ignore_message_strings_.end();
417     }
418 
419     VkFlags message_flags_;
420     std::unordered_multiset<std::string> desired_message_strings_;
421     std::unordered_multiset<std::string> failure_message_strings_;
422     std::vector<std::string> ignore_message_strings_;
423     vector<string> other_messages_;
424     test_platform_thread_mutex mutex_;
425     bool *bailout_;
426     bool message_found_;
427 };
428 
myDbgFunc(VkFlags msgFlags,VkDebugReportObjectTypeEXT objType,uint64_t srcObject,size_t location,int32_t msgCode,const char * pLayerPrefix,const char * pMsg,void * pUserData)429 static VKAPI_ATTR VkBool32 VKAPI_CALL myDbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject,
430                                                 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg,
431                                                 void *pUserData) {
432     ErrorMonitor *errMonitor = (ErrorMonitor *)pUserData;
433     if (msgFlags & errMonitor->GetMessageFlags()) {
434         return errMonitor->CheckForDesiredMsg(pMsg);
435     }
436     return VK_FALSE;
437 }
438 
439 class VkLayerTest : public VkRenderFramework {
440    public:
441     void VKTriangleTest(BsoFailSelect failCase);
442     void GenericDrawPreparation(VkCommandBufferObj *commandBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet,
443                                 BsoFailSelect failCase);
444 
Init(VkPhysicalDeviceFeatures * features=nullptr,VkPhysicalDeviceFeatures2 * features2=nullptr,const VkCommandPoolCreateFlags flags=0,void * instance_pnext=nullptr)445     void Init(VkPhysicalDeviceFeatures *features = nullptr, VkPhysicalDeviceFeatures2 *features2 = nullptr,
446               const VkCommandPoolCreateFlags flags = 0, void *instance_pnext = nullptr) {
447         InitFramework(myDbgFunc, m_errorMonitor, instance_pnext);
448         InitState(features, features2, flags);
449     }
450 
451    protected:
452     ErrorMonitor *m_errorMonitor;
453     uint32_t m_instance_api_version = 0;
454     uint32_t m_target_api_version = 0;
455 
456    public:
Monitor()457     ErrorMonitor *Monitor() { return m_errorMonitor; }
CommandBuffer()458     VkCommandBufferObj *CommandBuffer() { return m_commandBuffer; }
459 
460    protected:
461     bool m_enableWSI;
462 
SetUp()463     virtual void SetUp() {
464         m_instance_layer_names.clear();
465         m_instance_extension_names.clear();
466         m_device_extension_names.clear();
467 
468         // Add default instance extensions to the list
469         m_instance_extension_names.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
470 
471         // Use Threading layer first to protect others from
472         // ThreadCommandBufferCollision test
473         m_instance_layer_names.push_back("VK_LAYER_GOOGLE_threading");
474         m_instance_layer_names.push_back("VK_LAYER_LUNARG_parameter_validation");
475         m_instance_layer_names.push_back("VK_LAYER_LUNARG_object_tracker");
476         m_instance_layer_names.push_back("VK_LAYER_LUNARG_core_validation");
477         m_instance_layer_names.push_back("VK_LAYER_GOOGLE_unique_objects");
478         if (VkTestFramework::m_devsim_layer) {
479             if (InstanceLayerSupported("VK_LAYER_LUNARG_device_simulation")) {
480                 m_instance_layer_names.push_back("VK_LAYER_LUNARG_device_simulation");
481             } else {
482                 VkTestFramework::m_devsim_layer = false;
483                 printf("             Did not find VK_LAYER_LUNARG_device_simulation layer so it will not be enabled.\n");
484             }
485         }
486         if (m_enableWSI) {
487             m_instance_extension_names.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
488             m_device_extension_names.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
489 #ifdef NEED_TO_TEST_THIS_ON_PLATFORM
490 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
491             m_instance_extension_names.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
492 #endif  // VK_USE_PLATFORM_ANDROID_KHR
493 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
494             m_instance_extension_names.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
495 #endif  // VK_USE_PLATFORM_WAYLAND_KHR
496 #if defined(VK_USE_PLATFORM_WIN32_KHR)
497             m_instance_extension_names.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
498 #endif  // VK_USE_PLATFORM_WIN32_KHR
499 #endif  // NEED_TO_TEST_THIS_ON_PLATFORM
500 #if defined(VK_USE_PLATFORM_XCB_KHR)
501             m_instance_extension_names.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
502 #elif defined(VK_USE_PLATFORM_XLIB_KHR)
503             m_instance_extension_names.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
504 #endif  // VK_USE_PLATFORM_XLIB_KHR
505         }
506 
507         this->app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
508         this->app_info.pNext = NULL;
509         this->app_info.pApplicationName = "layer_tests";
510         this->app_info.applicationVersion = 1;
511         this->app_info.pEngineName = "unittest";
512         this->app_info.engineVersion = 1;
513         this->app_info.apiVersion = VK_API_VERSION_1_0;
514 
515         m_errorMonitor = new ErrorMonitor;
516 
517         // Find out what version the instance supports and record the default target instance
518         auto enumerateInstanceVersion =
519             (PFN_vkEnumerateInstanceVersion)vkGetInstanceProcAddr(nullptr, "vkEnumerateInstanceVersion");
520         if (enumerateInstanceVersion) {
521             enumerateInstanceVersion(&m_instance_api_version);
522         } else {
523             m_instance_api_version = VK_API_VERSION_1_0;
524         }
525         m_target_api_version = app_info.apiVersion;
526     }
527 
SetTargetApiVersion(uint32_t target_api_version)528     uint32_t SetTargetApiVersion(uint32_t target_api_version) {
529         if (target_api_version == 0) target_api_version = VK_API_VERSION_1_0;
530         if (target_api_version <= m_instance_api_version) {
531             m_target_api_version = target_api_version;
532             app_info.apiVersion = m_target_api_version;
533         }
534         return m_target_api_version;
535     }
DeviceValidationVersion()536     uint32_t DeviceValidationVersion() {
537         // The validation layers, assume the version we are validating to is the apiVersion unless the device apiVersion is lower
538         VkPhysicalDeviceProperties props;
539         GetPhysicalDeviceProperties(&props);
540         return std::min(m_target_api_version, props.apiVersion);
541     }
542 
LoadDeviceProfileLayer(PFN_vkSetPhysicalDeviceFormatPropertiesEXT & fpvkSetPhysicalDeviceFormatPropertiesEXT,PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT & fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)543     bool LoadDeviceProfileLayer(
544         PFN_vkSetPhysicalDeviceFormatPropertiesEXT &fpvkSetPhysicalDeviceFormatPropertiesEXT,
545         PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT &fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT) {
546         // Load required functions
547         fpvkSetPhysicalDeviceFormatPropertiesEXT =
548             (PFN_vkSetPhysicalDeviceFormatPropertiesEXT)vkGetInstanceProcAddr(instance(), "vkSetPhysicalDeviceFormatPropertiesEXT");
549         fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT =
550             (PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT)vkGetInstanceProcAddr(
551                 instance(), "vkGetOriginalPhysicalDeviceFormatPropertiesEXT");
552 
553         if (!(fpvkSetPhysicalDeviceFormatPropertiesEXT) || !(fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) {
554             printf("%s Can't find device_profile_api functions; skipped.\n", kSkipPrefix);
555             return 0;
556         }
557 
558         return 1;
559     }
560 
TearDown()561     virtual void TearDown() {
562         // Clean up resources before we reset
563         ShutdownFramework();
564         delete m_errorMonitor;
565     }
566 
VkLayerTest()567     VkLayerTest() { m_enableWSI = false; }
568 };
569 
VKTriangleTest(BsoFailSelect failCase)570 void VkLayerTest::VKTriangleTest(BsoFailSelect failCase) {
571     ASSERT_TRUE(m_device && m_device->initialized());  // VKTriangleTest assumes Init() has finished
572 
573     ASSERT_NO_FATAL_FAILURE(InitViewport());
574 
575     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
576     VkShaderObj ps(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
577 
578     VkPipelineObj pipelineobj(m_device);
579     pipelineobj.AddDefaultColorAttachment();
580     pipelineobj.AddShader(&vs);
581     pipelineobj.AddShader(&ps);
582 
583     bool failcase_needs_depth = false;  // to mark cases that need depth attachment
584 
585     VkBufferObj index_buffer;
586 
587     switch (failCase) {
588         case BsoFailLineWidth: {
589             pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_LINE_WIDTH);
590             VkPipelineInputAssemblyStateCreateInfo ia_state = {};
591             ia_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
592             ia_state.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
593             pipelineobj.SetInputAssembly(&ia_state);
594             break;
595         }
596         case BsoFailDepthBias: {
597             pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_DEPTH_BIAS);
598             VkPipelineRasterizationStateCreateInfo rs_state = {};
599             rs_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
600             rs_state.depthBiasEnable = VK_TRUE;
601             rs_state.lineWidth = 1.0f;
602             pipelineobj.SetRasterization(&rs_state);
603             break;
604         }
605         case BsoFailViewport: {
606             pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_VIEWPORT);
607             break;
608         }
609         case BsoFailScissor: {
610             pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_SCISSOR);
611             break;
612         }
613         case BsoFailBlend: {
614             pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_BLEND_CONSTANTS);
615             VkPipelineColorBlendAttachmentState att_state = {};
616             att_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
617             att_state.blendEnable = VK_TRUE;
618             pipelineobj.AddColorAttachment(0, att_state);
619             break;
620         }
621         case BsoFailDepthBounds: {
622             failcase_needs_depth = true;
623             pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_DEPTH_BOUNDS);
624             break;
625         }
626         case BsoFailStencilReadMask: {
627             failcase_needs_depth = true;
628             pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK);
629             break;
630         }
631         case BsoFailStencilWriteMask: {
632             failcase_needs_depth = true;
633             pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK);
634             break;
635         }
636         case BsoFailStencilReference: {
637             failcase_needs_depth = true;
638             pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
639             break;
640         }
641 
642         case BsoFailIndexBuffer:
643             break;
644         case BsoFailIndexBufferBadSize:
645         case BsoFailIndexBufferBadOffset:
646         case BsoFailIndexBufferBadMapSize:
647         case BsoFailIndexBufferBadMapOffset: {
648             // Create an index buffer for these tests.
649             // There is no need to populate it because we should bail before trying to draw.
650             uint32_t const indices[] = {0};
651             VkBufferCreateInfo buffer_info = {};
652             buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
653             buffer_info.size = 1024;
654             buffer_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
655             buffer_info.queueFamilyIndexCount = 1;
656             buffer_info.pQueueFamilyIndices = indices;
657             index_buffer.init(*m_device, buffer_info, (VkMemoryPropertyFlags)VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
658         } break;
659         case BsoFailCmdClearAttachments:
660             break;
661         case BsoFailNone:
662             break;
663         default:
664             break;
665     }
666 
667     VkDescriptorSetObj descriptorSet(m_device);
668 
669     VkImageView *depth_attachment = nullptr;
670     if (failcase_needs_depth) {
671         m_depth_stencil_fmt = FindSupportedDepthStencilFormat(gpu());
672         ASSERT_TRUE(m_depth_stencil_fmt != VK_FORMAT_UNDEFINED);
673 
674         m_depthStencil->Init(m_device, static_cast<uint32_t>(m_width), static_cast<uint32_t>(m_height), m_depth_stencil_fmt,
675                              VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
676         depth_attachment = m_depthStencil->BindInfo();
677     }
678 
679     ASSERT_NO_FATAL_FAILURE(InitRenderTarget(1, depth_attachment));
680     m_commandBuffer->begin();
681 
682     GenericDrawPreparation(m_commandBuffer, pipelineobj, descriptorSet, failCase);
683 
684     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
685 
686     // render triangle
687     if (failCase == BsoFailIndexBuffer) {
688         // Use DrawIndexed w/o an index buffer bound
689         m_commandBuffer->DrawIndexed(3, 1, 0, 0, 0);
690     } else if (failCase == BsoFailIndexBufferBadSize) {
691         // Bind the index buffer and draw one too many indices
692         m_commandBuffer->BindIndexBuffer(&index_buffer, 0, VK_INDEX_TYPE_UINT16);
693         m_commandBuffer->DrawIndexed(513, 1, 0, 0, 0);
694     } else if (failCase == BsoFailIndexBufferBadOffset) {
695         // Bind the index buffer and draw one past the end of the buffer using the offset
696         m_commandBuffer->BindIndexBuffer(&index_buffer, 0, VK_INDEX_TYPE_UINT16);
697         m_commandBuffer->DrawIndexed(512, 1, 1, 0, 0);
698     } else if (failCase == BsoFailIndexBufferBadMapSize) {
699         // Bind the index buffer at the middle point and draw one too many indices
700         m_commandBuffer->BindIndexBuffer(&index_buffer, 512, VK_INDEX_TYPE_UINT16);
701         m_commandBuffer->DrawIndexed(257, 1, 0, 0, 0);
702     } else if (failCase == BsoFailIndexBufferBadMapOffset) {
703         // Bind the index buffer at the middle point and draw one past the end of the buffer
704         m_commandBuffer->BindIndexBuffer(&index_buffer, 512, VK_INDEX_TYPE_UINT16);
705         m_commandBuffer->DrawIndexed(256, 1, 1, 0, 0);
706     } else {
707         m_commandBuffer->Draw(3, 1, 0, 0);
708     }
709 
710     if (failCase == BsoFailCmdClearAttachments) {
711         VkClearAttachment color_attachment = {};
712         color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
713         color_attachment.colorAttachment = 2000000000;  // Someone who knew what they were doing would use 0 for the index;
714         VkClearRect clear_rect = {{{0, 0}, {static_cast<uint32_t>(m_width), static_cast<uint32_t>(m_height)}}, 0, 0};
715 
716         vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
717     }
718 
719     // finalize recording of the command buffer
720     m_commandBuffer->EndRenderPass();
721     m_commandBuffer->end();
722     m_commandBuffer->QueueCommandBuffer(true);
723     DestroyRenderTarget();
724 }
725 
GenericDrawPreparation(VkCommandBufferObj * commandBuffer,VkPipelineObj & pipelineobj,VkDescriptorSetObj & descriptorSet,BsoFailSelect failCase)726 void VkLayerTest::GenericDrawPreparation(VkCommandBufferObj *commandBuffer, VkPipelineObj &pipelineobj,
727                                          VkDescriptorSetObj &descriptorSet, BsoFailSelect failCase) {
728     commandBuffer->ClearAllBuffers(m_renderTargets, m_clear_color, m_depthStencil, m_depth_clear_color, m_stencil_clear_color);
729 
730     commandBuffer->PrepareAttachments(m_renderTargets, m_depthStencil);
731     // Make sure depthWriteEnable is set so that Depth fail test will work
732     // correctly
733     // Make sure stencilTestEnable is set so that Stencil fail test will work
734     // correctly
735     VkStencilOpState stencil = {};
736     stencil.failOp = VK_STENCIL_OP_KEEP;
737     stencil.passOp = VK_STENCIL_OP_KEEP;
738     stencil.depthFailOp = VK_STENCIL_OP_KEEP;
739     stencil.compareOp = VK_COMPARE_OP_NEVER;
740 
741     VkPipelineDepthStencilStateCreateInfo ds_ci = {};
742     ds_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
743     ds_ci.pNext = NULL;
744     ds_ci.depthTestEnable = VK_FALSE;
745     ds_ci.depthWriteEnable = VK_TRUE;
746     ds_ci.depthCompareOp = VK_COMPARE_OP_NEVER;
747     ds_ci.depthBoundsTestEnable = VK_FALSE;
748     if (failCase == BsoFailDepthBounds) {
749         ds_ci.depthBoundsTestEnable = VK_TRUE;
750         ds_ci.maxDepthBounds = 0.0f;
751         ds_ci.minDepthBounds = 0.0f;
752     }
753     ds_ci.stencilTestEnable = VK_TRUE;
754     ds_ci.front = stencil;
755     ds_ci.back = stencil;
756 
757     pipelineobj.SetDepthStencil(&ds_ci);
758     pipelineobj.SetViewport(m_viewports);
759     pipelineobj.SetScissor(m_scissors);
760     descriptorSet.CreateVKDescriptorSet(commandBuffer);
761     VkResult err = pipelineobj.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
762     ASSERT_VK_SUCCESS(err);
763     vkCmdBindPipeline(commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineobj.handle());
764     commandBuffer->BindDescriptorSet(descriptorSet);
765 }
766 
767 class VkPositiveLayerTest : public VkLayerTest {
768    public:
769    protected:
770 };
771 
772 class VkWsiEnabledLayerTest : public VkLayerTest {
773    public:
774    protected:
VkWsiEnabledLayerTest()775     VkWsiEnabledLayerTest() { m_enableWSI = true; }
776 };
777 
778 class VkBufferTest {
779    public:
780     enum eTestEnFlags {
781         eDoubleDelete,
782         eInvalidDeviceOffset,
783         eInvalidMemoryOffset,
784         eBindNullBuffer,
785         eBindFakeBuffer,
786         eFreeInvalidHandle,
787         eNone,
788     };
789 
790     enum eTestConditions { eOffsetAlignment = 1 };
791 
GetTestConditionValid(VkDeviceObj * aVulkanDevice,eTestEnFlags aTestFlag,VkBufferUsageFlags aBufferUsage=0)792     static bool GetTestConditionValid(VkDeviceObj *aVulkanDevice, eTestEnFlags aTestFlag, VkBufferUsageFlags aBufferUsage = 0) {
793         if (eInvalidDeviceOffset != aTestFlag && eInvalidMemoryOffset != aTestFlag) {
794             return true;
795         }
796         VkDeviceSize offset_limit = 0;
797         if (eInvalidMemoryOffset == aTestFlag) {
798             VkBuffer vulkanBuffer;
799             VkBufferCreateInfo buffer_create_info = {};
800             buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
801             buffer_create_info.size = 32;
802             buffer_create_info.usage = aBufferUsage;
803 
804             vkCreateBuffer(aVulkanDevice->device(), &buffer_create_info, nullptr, &vulkanBuffer);
805             VkMemoryRequirements memory_reqs = {};
806 
807             vkGetBufferMemoryRequirements(aVulkanDevice->device(), vulkanBuffer, &memory_reqs);
808             vkDestroyBuffer(aVulkanDevice->device(), vulkanBuffer, nullptr);
809             offset_limit = memory_reqs.alignment;
810         } else if ((VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) & aBufferUsage) {
811             offset_limit = aVulkanDevice->props.limits.minTexelBufferOffsetAlignment;
812         } else if (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT & aBufferUsage) {
813             offset_limit = aVulkanDevice->props.limits.minUniformBufferOffsetAlignment;
814         } else if (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT & aBufferUsage) {
815             offset_limit = aVulkanDevice->props.limits.minStorageBufferOffsetAlignment;
816         }
817         return eOffsetAlignment < offset_limit;
818     }
819 
820     // A constructor which performs validation tests within construction.
VkBufferTest(VkDeviceObj * aVulkanDevice,VkBufferUsageFlags aBufferUsage,eTestEnFlags aTestFlag=eNone)821     VkBufferTest(VkDeviceObj *aVulkanDevice, VkBufferUsageFlags aBufferUsage, eTestEnFlags aTestFlag = eNone)
822         : AllocateCurrent(true),
823           BoundCurrent(false),
824           CreateCurrent(false),
825           InvalidDeleteEn(false),
826           VulkanDevice(aVulkanDevice->device()) {
827         if (eBindNullBuffer == aTestFlag || eBindFakeBuffer == aTestFlag) {
828             VkMemoryAllocateInfo memory_allocate_info = {};
829             memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
830             memory_allocate_info.allocationSize = 1;   // fake size -- shouldn't matter for the test
831             memory_allocate_info.memoryTypeIndex = 0;  // fake type -- shouldn't matter for the test
832             vkAllocateMemory(VulkanDevice, &memory_allocate_info, nullptr, &VulkanMemory);
833 
834             VulkanBuffer = (aTestFlag == eBindNullBuffer) ? VK_NULL_HANDLE : (VkBuffer)0xCDCDCDCDCDCDCDCD;
835 
836             vkBindBufferMemory(VulkanDevice, VulkanBuffer, VulkanMemory, 0);
837         } else {
838             VkBufferCreateInfo buffer_create_info = {};
839             buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
840             buffer_create_info.size = 32;
841             buffer_create_info.usage = aBufferUsage;
842 
843             vkCreateBuffer(VulkanDevice, &buffer_create_info, nullptr, &VulkanBuffer);
844 
845             CreateCurrent = true;
846 
847             VkMemoryRequirements memory_requirements;
848             vkGetBufferMemoryRequirements(VulkanDevice, VulkanBuffer, &memory_requirements);
849 
850             VkMemoryAllocateInfo memory_allocate_info = {};
851             memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
852             memory_allocate_info.allocationSize = memory_requirements.size + eOffsetAlignment;
853             bool pass = aVulkanDevice->phy().set_memory_type(memory_requirements.memoryTypeBits, &memory_allocate_info,
854                                                              VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
855             if (!pass) {
856                 CreateCurrent = false;
857                 vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr);
858                 return;
859             }
860 
861             vkAllocateMemory(VulkanDevice, &memory_allocate_info, NULL, &VulkanMemory);
862             // NB: 1 is intentionally an invalid offset value
863             const bool offset_en = eInvalidDeviceOffset == aTestFlag || eInvalidMemoryOffset == aTestFlag;
864             vkBindBufferMemory(VulkanDevice, VulkanBuffer, VulkanMemory, offset_en ? eOffsetAlignment : 0);
865             BoundCurrent = true;
866 
867             InvalidDeleteEn = (eFreeInvalidHandle == aTestFlag);
868         }
869     }
870 
~VkBufferTest()871     ~VkBufferTest() {
872         if (CreateCurrent) {
873             vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr);
874         }
875         if (AllocateCurrent) {
876             if (InvalidDeleteEn) {
877                 union {
878                     VkDeviceMemory device_memory;
879                     unsigned long long index_access;
880                 } bad_index;
881 
882                 bad_index.device_memory = VulkanMemory;
883                 bad_index.index_access++;
884 
885                 vkFreeMemory(VulkanDevice, bad_index.device_memory, nullptr);
886             }
887             vkFreeMemory(VulkanDevice, VulkanMemory, nullptr);
888         }
889     }
890 
GetBufferCurrent()891     bool GetBufferCurrent() { return AllocateCurrent && BoundCurrent && CreateCurrent; }
892 
GetBuffer()893     const VkBuffer &GetBuffer() { return VulkanBuffer; }
894 
TestDoubleDestroy()895     void TestDoubleDestroy() {
896         // Destroy the buffer but leave the flag set, which will cause
897         // the buffer to be destroyed again in the destructor.
898         vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr);
899     }
900 
901    protected:
902     bool AllocateCurrent;
903     bool BoundCurrent;
904     bool CreateCurrent;
905     bool InvalidDeleteEn;
906 
907     VkBuffer VulkanBuffer;
908     VkDevice VulkanDevice;
909     VkDeviceMemory VulkanMemory;
910 };
911 
912 class VkVerticesObj {
913    public:
VkVerticesObj(VkDeviceObj * aVulkanDevice,unsigned aAttributeCount,unsigned aBindingCount,unsigned aByteStride,VkDeviceSize aVertexCount,const float * aVerticies)914     VkVerticesObj(VkDeviceObj *aVulkanDevice, unsigned aAttributeCount, unsigned aBindingCount, unsigned aByteStride,
915                   VkDeviceSize aVertexCount, const float *aVerticies)
916         : BoundCurrent(false),
917           AttributeCount(aAttributeCount),
918           BindingCount(aBindingCount),
919           BindId(BindIdGenerator),
920           PipelineVertexInputStateCreateInfo(),
921           VulkanMemoryBuffer(aVulkanDevice, static_cast<int>(aByteStride * aVertexCount),
922                              reinterpret_cast<const void *>(aVerticies), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) {
923         BindIdGenerator++;  // NB: This can wrap w/misuse
924 
925         VertexInputAttributeDescription = new VkVertexInputAttributeDescription[AttributeCount];
926         VertexInputBindingDescription = new VkVertexInputBindingDescription[BindingCount];
927 
928         PipelineVertexInputStateCreateInfo.pVertexAttributeDescriptions = VertexInputAttributeDescription;
929         PipelineVertexInputStateCreateInfo.vertexAttributeDescriptionCount = AttributeCount;
930         PipelineVertexInputStateCreateInfo.pVertexBindingDescriptions = VertexInputBindingDescription;
931         PipelineVertexInputStateCreateInfo.vertexBindingDescriptionCount = BindingCount;
932         PipelineVertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
933 
934         unsigned i = 0;
935         do {
936             VertexInputAttributeDescription[i].binding = BindId;
937             VertexInputAttributeDescription[i].location = i;
938             VertexInputAttributeDescription[i].format = VK_FORMAT_R32G32B32_SFLOAT;
939             VertexInputAttributeDescription[i].offset = sizeof(float) * aByteStride;
940             i++;
941         } while (AttributeCount < i);
942 
943         i = 0;
944         do {
945             VertexInputBindingDescription[i].binding = BindId;
946             VertexInputBindingDescription[i].stride = aByteStride;
947             VertexInputBindingDescription[i].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
948             i++;
949         } while (BindingCount < i);
950     }
951 
~VkVerticesObj()952     ~VkVerticesObj() {
953         if (VertexInputAttributeDescription) {
954             delete[] VertexInputAttributeDescription;
955         }
956         if (VertexInputBindingDescription) {
957             delete[] VertexInputBindingDescription;
958         }
959     }
960 
AddVertexInputToPipe(VkPipelineObj & aPipelineObj)961     bool AddVertexInputToPipe(VkPipelineObj &aPipelineObj) {
962         aPipelineObj.AddVertexInputAttribs(VertexInputAttributeDescription, AttributeCount);
963         aPipelineObj.AddVertexInputBindings(VertexInputBindingDescription, BindingCount);
964         return true;
965     }
966 
BindVertexBuffers(VkCommandBuffer aCommandBuffer,unsigned aOffsetCount=0,VkDeviceSize * aOffsetList=nullptr)967     void BindVertexBuffers(VkCommandBuffer aCommandBuffer, unsigned aOffsetCount = 0, VkDeviceSize *aOffsetList = nullptr) {
968         VkDeviceSize *offsetList;
969         unsigned offsetCount;
970 
971         if (aOffsetCount) {
972             offsetList = aOffsetList;
973             offsetCount = aOffsetCount;
974         } else {
975             offsetList = new VkDeviceSize[1]();
976             offsetCount = 1;
977         }
978 
979         vkCmdBindVertexBuffers(aCommandBuffer, BindId, offsetCount, &VulkanMemoryBuffer.handle(), offsetList);
980         BoundCurrent = true;
981 
982         if (!aOffsetCount) {
983             delete[] offsetList;
984         }
985     }
986 
987    protected:
988     static uint32_t BindIdGenerator;
989 
990     bool BoundCurrent;
991     unsigned AttributeCount;
992     unsigned BindingCount;
993     uint32_t BindId;
994 
995     VkPipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo;
996     VkVertexInputAttributeDescription *VertexInputAttributeDescription;
997     VkVertexInputBindingDescription *VertexInputBindingDescription;
998     VkConstantBufferObj VulkanMemoryBuffer;
999 };
1000 
1001 uint32_t VkVerticesObj::BindIdGenerator;
1002 
1003 struct OneOffDescriptorSet {
1004     VkDeviceObj *device_;
1005     VkDescriptorPool pool_;
1006     VkDescriptorSetLayoutObj layout_;
1007     VkDescriptorSet set_;
1008     typedef std::vector<VkDescriptorSetLayoutBinding> Bindings;
1009 
OneOffDescriptorSetOneOffDescriptorSet1010     OneOffDescriptorSet(VkDeviceObj *device, const Bindings &bindings)
1011         : device_{device}, pool_{}, layout_(device, bindings), set_{} {
1012         VkResult err;
1013 
1014         std::vector<VkDescriptorPoolSize> sizes;
1015         for (const auto &b : bindings) sizes.push_back({b.descriptorType, std::max(1u, b.descriptorCount)});
1016 
1017         VkDescriptorPoolCreateInfo dspci = {
1018             VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, nullptr, 0, 1, uint32_t(sizes.size()), sizes.data()};
1019         err = vkCreateDescriptorPool(device_->handle(), &dspci, nullptr, &pool_);
1020         if (err != VK_SUCCESS) return;
1021 
1022         VkDescriptorSetAllocateInfo alloc_info = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, nullptr, pool_, 1,
1023                                                   &layout_.handle()};
1024         err = vkAllocateDescriptorSets(device_->handle(), &alloc_info, &set_);
1025     }
1026 
~OneOffDescriptorSetOneOffDescriptorSet1027     ~OneOffDescriptorSet() {
1028         // No need to destroy set-- it's going away with the pool.
1029         vkDestroyDescriptorPool(device_->handle(), pool_, nullptr);
1030     }
1031 
InitializedOneOffDescriptorSet1032     bool Initialized() { return pool_ != VK_NULL_HANDLE && layout_.initialized() && set_ != VK_NULL_HANDLE; }
1033 };
1034 
1035 template <typename T>
IsValidVkStruct(const T & s)1036 bool IsValidVkStruct(const T &s) {
1037     return LvlTypeMap<T>::kSType == s.sType;
1038 }
1039 
1040 // Helper class for tersely creating create pipeline tests
1041 //
1042 // Designed with minimal error checking to ensure easy error state creation
1043 // See OneshotTest for typical usage
1044 struct CreatePipelineHelper {
1045    public:
1046     std::vector<VkDescriptorSetLayoutBinding> dsl_bindings_;
1047     std::unique_ptr<OneOffDescriptorSet> descriptor_set_;
1048     std::vector<VkPipelineShaderStageCreateInfo> shader_stages_;
1049     VkPipelineVertexInputStateCreateInfo vi_ci_ = {};
1050     VkPipelineInputAssemblyStateCreateInfo ia_ci_ = {};
1051     VkPipelineTessellationStateCreateInfo tess_ci_ = {};
1052     VkViewport viewport_ = {};
1053     VkRect2D scissor_ = {};
1054     VkPipelineViewportStateCreateInfo vp_state_ci_ = {};
1055     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci_ = {};
1056     VkPipelineLayoutCreateInfo pipeline_layout_ci_ = {};
1057     VkPipelineLayoutObj pipeline_layout_;
1058     VkPipelineDynamicStateCreateInfo dyn_state_ci_ = {};
1059     VkPipelineRasterizationStateCreateInfo rs_state_ci_ = {};
1060     VkPipelineColorBlendAttachmentState cb_attachments_ = {};
1061     VkPipelineColorBlendStateCreateInfo cb_ci_ = {};
1062     VkGraphicsPipelineCreateInfo gp_ci_ = {};
1063     VkPipelineCacheCreateInfo pc_ci_ = {};
1064     VkPipeline pipeline_ = VK_NULL_HANDLE;
1065     VkPipelineCache pipeline_cache_ = VK_NULL_HANDLE;
1066     std::unique_ptr<VkShaderObj> vs_;
1067     std::unique_ptr<VkShaderObj> fs_;
1068     VkLayerTest &layer_test_;
CreatePipelineHelperCreatePipelineHelper1069     CreatePipelineHelper(VkLayerTest &test) : layer_test_(test) {}
~CreatePipelineHelperCreatePipelineHelper1070     ~CreatePipelineHelper() {
1071         VkDevice device = layer_test_.device();
1072         vkDestroyPipelineCache(device, pipeline_cache_, nullptr);
1073         vkDestroyPipeline(device, pipeline_, nullptr);
1074     }
1075 
InitDescriptorSetInfoCreatePipelineHelper1076     void InitDescriptorSetInfo() { dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}}; }
1077 
InitInputAndVertexInfoCreatePipelineHelper1078     void InitInputAndVertexInfo() {
1079         vi_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
1080 
1081         ia_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
1082         ia_ci_.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
1083     }
1084 
InitMultisampleInfoCreatePipelineHelper1085     void InitMultisampleInfo() {
1086         pipe_ms_state_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
1087         pipe_ms_state_ci_.pNext = nullptr;
1088         pipe_ms_state_ci_.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
1089         pipe_ms_state_ci_.sampleShadingEnable = VK_FALSE;
1090         pipe_ms_state_ci_.minSampleShading = 1.0;
1091         pipe_ms_state_ci_.pSampleMask = NULL;
1092     }
1093 
InitPipelineLayoutInfoCreatePipelineHelper1094     void InitPipelineLayoutInfo() {
1095         pipeline_layout_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
1096         pipeline_layout_ci_.setLayoutCount = 1;     // Not really changeable because InitState() sets exactly one pSetLayout
1097         pipeline_layout_ci_.pSetLayouts = nullptr;  // must bound after it is created
1098     }
1099 
InitViewportInfoCreatePipelineHelper1100     void InitViewportInfo() {
1101         viewport_ = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
1102         scissor_ = {{0, 0}, {64, 64}};
1103 
1104         vp_state_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
1105         vp_state_ci_.pNext = nullptr;
1106         vp_state_ci_.viewportCount = 1;
1107         vp_state_ci_.pViewports = &viewport_;  // ignored if dynamic
1108         vp_state_ci_.scissorCount = 1;
1109         vp_state_ci_.pScissors = &scissor_;  // ignored if dynamic
1110     }
1111 
InitDynamicStateInfoCreatePipelineHelper1112     void InitDynamicStateInfo() {
1113         // Use a "validity" check on the {} initialized structure to detect initialization
1114         // during late bind
1115     }
1116 
InitShaderInfoCreatePipelineHelper1117     void InitShaderInfo() {
1118         vs_.reset(new VkShaderObj(layer_test_.DeviceObj(), bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, &layer_test_));
1119         fs_.reset(new VkShaderObj(layer_test_.DeviceObj(), bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, &layer_test_));
1120         // We shouldn't need a fragment shader but add it to be able to run on more devices
1121         shader_stages_ = {vs_->GetStageCreateInfo(), fs_->GetStageCreateInfo()};
1122     }
1123 
InitRasterizationInfoCreatePipelineHelper1124     void InitRasterizationInfo() {
1125         rs_state_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
1126         rs_state_ci_.pNext = nullptr;
1127         rs_state_ci_.flags = 0;
1128         rs_state_ci_.depthClampEnable = VK_FALSE;
1129         rs_state_ci_.rasterizerDiscardEnable = VK_FALSE;
1130         rs_state_ci_.polygonMode = VK_POLYGON_MODE_FILL;
1131         rs_state_ci_.cullMode = VK_CULL_MODE_BACK_BIT;
1132         rs_state_ci_.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
1133         rs_state_ci_.depthBiasEnable = VK_FALSE;
1134         rs_state_ci_.lineWidth = 1.0F;
1135     }
1136 
InitBlendStateInfoCreatePipelineHelper1137     void InitBlendStateInfo() {
1138         cb_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
1139         cb_ci_.logicOpEnable = VK_FALSE;
1140         cb_ci_.logicOp = VK_LOGIC_OP_COPY;  // ignored if enable is VK_FALSE above
1141         cb_ci_.attachmentCount = layer_test_.RenderPassInfo().subpassCount;
1142         ASSERT_TRUE(IsValidVkStruct(layer_test_.RenderPassInfo()));
1143         cb_ci_.pAttachments = &cb_attachments_;
1144         for (int i = 0; i < 4; i++) {
1145             cb_ci_.blendConstants[0] = 1.0F;
1146         }
1147     }
1148 
InitGraphicsPipelineInfoCreatePipelineHelper1149     void InitGraphicsPipelineInfo() {
1150         // Color-only rendering in a subpass with no depth/stencil attachment
1151         // Active Pipeline Shader Stages
1152         //    Vertex Shader
1153         //    Fragment Shader
1154         // Required: Fixed-Function Pipeline Stages
1155         //    VkPipelineVertexInputStateCreateInfo
1156         //    VkPipelineInputAssemblyStateCreateInfo
1157         //    VkPipelineViewportStateCreateInfo
1158         //    VkPipelineRasterizationStateCreateInfo
1159         //    VkPipelineMultisampleStateCreateInfo
1160         //    VkPipelineColorBlendStateCreateInfo
1161         gp_ci_.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
1162         gp_ci_.pNext = nullptr;
1163         gp_ci_.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
1164         gp_ci_.pVertexInputState = &vi_ci_;
1165         gp_ci_.pInputAssemblyState = &ia_ci_;
1166         gp_ci_.pTessellationState = nullptr;
1167         gp_ci_.pViewportState = &vp_state_ci_;
1168         gp_ci_.pRasterizationState = &rs_state_ci_;
1169         gp_ci_.pMultisampleState = &pipe_ms_state_ci_;
1170         gp_ci_.pDepthStencilState = nullptr;
1171         gp_ci_.pColorBlendState = &cb_ci_;
1172         gp_ci_.pDynamicState = nullptr;
1173         gp_ci_.renderPass = layer_test_.renderPass();
1174     }
1175 
InitPipelineCacheInfoCreatePipelineHelper1176     void InitPipelineCacheInfo() {
1177         pc_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
1178         pc_ci_.pNext = nullptr;
1179         pc_ci_.flags = 0;
1180         pc_ci_.initialDataSize = 0;
1181         pc_ci_.pInitialData = nullptr;
1182     }
1183 
1184     // Not called by default during init_info
InitTesselationStateCreatePipelineHelper1185     void InitTesselationState() {
1186         // TBD -- add shaders and create_info
1187     }
1188 
1189     // TDB -- add control for optional and/or additional initialization
InitInfoCreatePipelineHelper1190     void InitInfo() {
1191         InitDescriptorSetInfo();
1192         InitInputAndVertexInfo();
1193         InitMultisampleInfo();
1194         InitPipelineLayoutInfo();
1195         InitViewportInfo();
1196         InitDynamicStateInfo();
1197         InitShaderInfo();
1198         InitRasterizationInfo();
1199         InitBlendStateInfo();
1200         InitGraphicsPipelineInfo();
1201         InitPipelineCacheInfo();
1202     }
1203 
InitStateCreatePipelineHelper1204     void InitState() {
1205         VkResult err;
1206         descriptor_set_.reset(new OneOffDescriptorSet(layer_test_.DeviceObj(), dsl_bindings_));
1207         ASSERT_TRUE(descriptor_set_->Initialized());
1208 
1209         const std::vector<VkPushConstantRange> push_ranges(
1210             pipeline_layout_ci_.pPushConstantRanges,
1211             pipeline_layout_ci_.pPushConstantRanges + pipeline_layout_ci_.pushConstantRangeCount);
1212         pipeline_layout_ = VkPipelineLayoutObj(layer_test_.DeviceObj(), {&descriptor_set_->layout_}, push_ranges);
1213 
1214         err = vkCreatePipelineCache(layer_test_.device(), &pc_ci_, NULL, &pipeline_cache_);
1215         ASSERT_VK_SUCCESS(err);
1216     }
1217 
LateBindPipelineInfoCreatePipelineHelper1218     void LateBindPipelineInfo() {
1219         // By value or dynamically located items must be late bound
1220         gp_ci_.layout = pipeline_layout_.handle();
1221         gp_ci_.stageCount = shader_stages_.size();
1222         gp_ci_.pStages = shader_stages_.data();
1223         if ((gp_ci_.pTessellationState == nullptr) && IsValidVkStruct(tess_ci_)) {
1224             gp_ci_.pTessellationState = &tess_ci_;
1225         }
1226         if ((gp_ci_.pDynamicState == nullptr) && IsValidVkStruct(dyn_state_ci_)) {
1227             gp_ci_.pDynamicState = &dyn_state_ci_;
1228         }
1229     }
1230 
CreateGraphicsPipelineCreatePipelineHelper1231     VkResult CreateGraphicsPipeline(bool implicit_destroy = true, bool do_late_bind = true) {
1232         VkResult err;
1233         if (do_late_bind) {
1234             LateBindPipelineInfo();
1235         }
1236         if (implicit_destroy && (pipeline_ != VK_NULL_HANDLE)) {
1237             vkDestroyPipeline(layer_test_.device(), pipeline_, nullptr);
1238             pipeline_ = VK_NULL_HANDLE;
1239         }
1240         err = vkCreateGraphicsPipelines(layer_test_.device(), pipeline_cache_, 1, &gp_ci_, NULL, &pipeline_);
1241         return err;
1242     }
1243 
1244     // Helper function to create a simple test case (positive or negative)
1245     //
1246     // info_override can be any callable that takes a CreatePipelineHeper &
1247     // flags, error can be any args accepted by "SetDesiredFailure".
1248     template <typename Test, typename OverrideFunc, typename Error>
OneshotTestCreatePipelineHelper1249     static void OneshotTest(Test &test, OverrideFunc &info_override, const VkFlags flags, const std::vector<Error> &errors,
1250                             bool positive_test = false) {
1251         CreatePipelineHelper helper(test);
1252         helper.InitInfo();
1253         info_override(helper);
1254         helper.InitState();
1255 
1256         for (const auto &error : errors) test.Monitor()->SetDesiredFailureMsg(flags, error);
1257         helper.CreateGraphicsPipeline();
1258 
1259         if (positive_test) {
1260             test.Monitor()->VerifyNotFound();
1261         } else {
1262             test.Monitor()->VerifyFound();
1263         }
1264     }
1265 
1266     template <typename Test, typename OverrideFunc, typename Error>
OneshotTestCreatePipelineHelper1267     static void OneshotTest(Test &test, OverrideFunc &info_override, const VkFlags flags, Error error, bool positive_test = false) {
1268         OneshotTest(test, info_override, flags, std::vector<Error>(1, error), positive_test);
1269     }
1270 };
1271 namespace chain_util {
1272 template <typename T>
Init(const void * pnext_in=nullptr)1273 T Init(const void *pnext_in = nullptr) {
1274     T pnext_obj = {};
1275     pnext_obj.sType = LvlTypeMap<T>::kSType;
1276     pnext_obj.pNext = pnext_in;
1277     return pnext_obj;
1278 }
1279 class ExtensionChain {
1280     const void *head_ = nullptr;
1281     typedef std::function<bool(const char *)> AddIfFunction;
1282     AddIfFunction add_if_;
1283     typedef std::vector<const char *> List;
1284     List *list_;
1285 
1286    public:
1287     template <typename F>
ExtensionChain(F & add_if,List * list)1288     ExtensionChain(F &add_if, List *list) : add_if_(add_if), list_(list) {}
1289     template <typename T>
Add(const char * name,T & obj)1290     void Add(const char *name, T &obj) {
1291         if (add_if_(name)) {
1292             if (list_) {
1293                 list_->push_back(name);
1294             }
1295             obj.pNext = head_;
1296             head_ = &obj;
1297         }
1298     }
Head() const1299     const void *Head() const { return head_; }
1300 };
1301 }  // namespace chain_util
1302 
1303 // PushDescriptorProperties helper
GetPushDescriptorProperties(VkInstance instance,VkPhysicalDevice gpu)1304 VkPhysicalDevicePushDescriptorPropertiesKHR GetPushDescriptorProperties(VkInstance instance, VkPhysicalDevice gpu) {
1305     // Find address of extension call and make the call -- assumes needed extensions are enabled.
1306     PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR =
1307         (PFN_vkGetPhysicalDeviceProperties2KHR)vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2KHR");
1308     assert(vkGetPhysicalDeviceProperties2KHR != nullptr);
1309 
1310     // Get the push descriptor limits
1311     auto push_descriptor_prop = lvl_init_struct<VkPhysicalDevicePushDescriptorPropertiesKHR>();
1312     auto prop2 = lvl_init_struct<VkPhysicalDeviceProperties2KHR>(&push_descriptor_prop);
1313     vkGetPhysicalDeviceProperties2KHR(gpu, &prop2);
1314     return push_descriptor_prop;
1315 }
1316 
1317 // ********************************************************************************************************************
1318 // ********************************************************************************************************************
1319 // ********************************************************************************************************************
1320 // ********************************************************************************************************************
TEST_F(VkLayerTest,RequiredParameter)1321 TEST_F(VkLayerTest, RequiredParameter) {
1322     TEST_DESCRIPTION("Specify VK_NULL_HANDLE, NULL, and 0 for required handle, pointer, array, and array count parameters");
1323 
1324     ASSERT_NO_FATAL_FAILURE(Init());
1325 
1326     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pFeatures specified as NULL");
1327     // Specify NULL for a pointer to a handle
1328     // Expected to trigger an error with
1329     // parameter_validation::validate_required_pointer
1330     vkGetPhysicalDeviceFeatures(gpu(), NULL);
1331     m_errorMonitor->VerifyFound();
1332 
1333     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1334                                          "required parameter pQueueFamilyPropertyCount specified as NULL");
1335     // Specify NULL for pointer to array count
1336     // Expected to trigger an error with parameter_validation::validate_array
1337     vkGetPhysicalDeviceQueueFamilyProperties(gpu(), NULL, NULL);
1338     m_errorMonitor->VerifyFound();
1339 
1340     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-viewportCount-arraylength");
1341     // Specify 0 for a required array count
1342     // Expected to trigger an error with parameter_validation::validate_array
1343     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
1344     m_commandBuffer->SetViewport(0, 0, &viewport);
1345     m_errorMonitor->VerifyFound();
1346 
1347     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCreateImage-pCreateInfo-parameter");
1348     // Specify a null pImageCreateInfo struct pointer
1349     VkImage test_image;
1350     vkCreateImage(device(), NULL, NULL, &test_image);
1351     m_errorMonitor->VerifyFound();
1352 
1353     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-pViewports-parameter");
1354     // Specify NULL for a required array
1355     // Expected to trigger an error with parameter_validation::validate_array
1356     m_commandBuffer->SetViewport(0, 1, NULL);
1357     m_errorMonitor->VerifyFound();
1358 
1359     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter memory specified as VK_NULL_HANDLE");
1360     // Specify VK_NULL_HANDLE for a required handle
1361     // Expected to trigger an error with
1362     // parameter_validation::validate_required_handle
1363     vkUnmapMemory(device(), VK_NULL_HANDLE);
1364     m_errorMonitor->VerifyFound();
1365 
1366     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1367                                          "required parameter pFences[0] specified as VK_NULL_HANDLE");
1368     // Specify VK_NULL_HANDLE for a required handle array entry
1369     // Expected to trigger an error with
1370     // parameter_validation::validate_required_handle_array
1371     VkFence fence = VK_NULL_HANDLE;
1372     vkResetFences(device(), 1, &fence);
1373     m_errorMonitor->VerifyFound();
1374 
1375     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pAllocateInfo specified as NULL");
1376     // Specify NULL for a required struct pointer
1377     // Expected to trigger an error with
1378     // parameter_validation::validate_struct_type
1379     VkDeviceMemory memory = VK_NULL_HANDLE;
1380     vkAllocateMemory(device(), NULL, NULL, &memory);
1381     m_errorMonitor->VerifyFound();
1382 
1383     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "value of faceMask must not be 0");
1384     // Specify 0 for a required VkFlags parameter
1385     // Expected to trigger an error with parameter_validation::validate_flags
1386     m_commandBuffer->SetStencilReference(0, 0);
1387     m_errorMonitor->VerifyFound();
1388 
1389     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "value of pSubmits[0].pWaitDstStageMask[0] must not be 0");
1390     // Specify 0 for a required VkFlags array entry
1391     // Expected to trigger an error with
1392     // parameter_validation::validate_flags_array
1393     VkSemaphore semaphore = VK_NULL_HANDLE;
1394     VkPipelineStageFlags stageFlags = 0;
1395     VkSubmitInfo submitInfo = {};
1396     submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1397     submitInfo.waitSemaphoreCount = 1;
1398     submitInfo.pWaitSemaphores = &semaphore;
1399     submitInfo.pWaitDstStageMask = &stageFlags;
1400     vkQueueSubmit(m_device->m_queue, 1, &submitInfo, VK_NULL_HANDLE);
1401     m_errorMonitor->VerifyFound();
1402 
1403     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubmitInfo-sType-sType");
1404     stageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
1405     // Set a bogus sType and see what happens
1406     submitInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
1407     submitInfo.waitSemaphoreCount = 1;
1408     submitInfo.pWaitSemaphores = &semaphore;
1409     submitInfo.pWaitDstStageMask = &stageFlags;
1410     vkQueueSubmit(m_device->m_queue, 1, &submitInfo, VK_NULL_HANDLE);
1411     m_errorMonitor->VerifyFound();
1412 
1413     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubmitInfo-pWaitSemaphores-parameter");
1414     stageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
1415     submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1416     submitInfo.waitSemaphoreCount = 1;
1417     // Set a null pointer for pWaitSemaphores
1418     submitInfo.pWaitSemaphores = NULL;
1419     submitInfo.pWaitDstStageMask = &stageFlags;
1420     vkQueueSubmit(m_device->m_queue, 1, &submitInfo, VK_NULL_HANDLE);
1421     m_errorMonitor->VerifyFound();
1422 }
1423 
TEST_F(VkLayerTest,PnextOnlyStructValidation)1424 TEST_F(VkLayerTest, PnextOnlyStructValidation) {
1425     TEST_DESCRIPTION("See if checks occur on structs ONLY used in pnext chains.");
1426 
1427     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
1428         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1429     } else {
1430         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
1431                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1432         return;
1433     }
1434     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1435 
1436     std::array<const char *, 2> required_device_extensions = {
1437         {VK_KHR_MAINTENANCE3_EXTENSION_NAME, VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME}};
1438     for (auto device_extension : required_device_extensions) {
1439         if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
1440             m_device_extension_names.push_back(device_extension);
1441         } else {
1442             printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
1443             return;
1444         }
1445     }
1446 
1447     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
1448         (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
1449     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
1450 
1451     // Create a device passing in a bad PdevFeatures2 value
1452     auto indexing_features = lvl_init_struct<VkPhysicalDeviceDescriptorIndexingFeaturesEXT>();
1453     auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&indexing_features);
1454     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
1455     // Set one of the features values to an invalid boolean value
1456     indexing_features.descriptorBindingUniformBufferUpdateAfterBind = 800;
1457 
1458     uint32_t queue_node_count;
1459     vkGetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_node_count, NULL);
1460     VkQueueFamilyProperties *queue_props = new VkQueueFamilyProperties[queue_node_count];
1461     vkGetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_node_count, queue_props);
1462     float priorities[] = {1.0f};
1463     VkDeviceQueueCreateInfo queue_info{};
1464     queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
1465     queue_info.pNext = NULL;
1466     queue_info.flags = 0;
1467     queue_info.queueFamilyIndex = 0;
1468     queue_info.queueCount = 1;
1469     queue_info.pQueuePriorities = &priorities[0];
1470     VkDeviceCreateInfo dev_info = {};
1471     dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
1472     dev_info.pNext = NULL;
1473     dev_info.queueCreateInfoCount = 1;
1474     dev_info.pQueueCreateInfos = &queue_info;
1475     dev_info.enabledLayerCount = 0;
1476     dev_info.ppEnabledLayerNames = NULL;
1477     dev_info.enabledExtensionCount = m_device_extension_names.size();
1478     dev_info.ppEnabledExtensionNames = m_device_extension_names.data();
1479     dev_info.pNext = &features2;
1480     VkDevice dev;
1481     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "is neither VK_TRUE nor VK_FALSE");
1482     m_errorMonitor->SetUnexpectedError("Failed to create");
1483     vkCreateDevice(gpu(), &dev_info, NULL, &dev);
1484     m_errorMonitor->VerifyFound();
1485 }
1486 
TEST_F(VkLayerTest,ReservedParameter)1487 TEST_F(VkLayerTest, ReservedParameter) {
1488     TEST_DESCRIPTION("Specify a non-zero value for a reserved parameter");
1489 
1490     ASSERT_NO_FATAL_FAILURE(Init());
1491 
1492     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " must be 0");
1493     // Specify 0 for a reserved VkFlags parameter
1494     // Expected to trigger an error with
1495     // parameter_validation::validate_reserved_flags
1496     VkEvent event_handle = VK_NULL_HANDLE;
1497     VkEventCreateInfo event_info = {};
1498     event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1499     event_info.flags = 1;
1500     vkCreateEvent(device(), &event_info, NULL, &event_handle);
1501     m_errorMonitor->VerifyFound();
1502 }
1503 
TEST_F(VkLayerTest,DebugMarkerNameTest)1504 TEST_F(VkLayerTest, DebugMarkerNameTest) {
1505     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1506     if (DeviceExtensionSupported(gpu(), "VK_LAYER_LUNARG_core_validation", VK_EXT_DEBUG_MARKER_EXTENSION_NAME)) {
1507         m_device_extension_names.push_back(VK_EXT_DEBUG_MARKER_EXTENSION_NAME);
1508     } else {
1509         printf("%s Debug Marker Extension not supported, skipping test\n", kSkipPrefix);
1510         return;
1511     }
1512     ASSERT_NO_FATAL_FAILURE(InitState());
1513 
1514     PFN_vkDebugMarkerSetObjectNameEXT fpvkDebugMarkerSetObjectNameEXT =
1515         (PFN_vkDebugMarkerSetObjectNameEXT)vkGetInstanceProcAddr(instance(), "vkDebugMarkerSetObjectNameEXT");
1516     if (!(fpvkDebugMarkerSetObjectNameEXT)) {
1517         printf("%s Can't find fpvkDebugMarkerSetObjectNameEXT; skipped.\n", kSkipPrefix);
1518         return;
1519     }
1520 
1521     VkEvent event_handle = VK_NULL_HANDLE;
1522     VkEventCreateInfo event_info = {};
1523     event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1524     vkCreateEvent(device(), &event_info, NULL, &event_handle);
1525     VkDebugMarkerObjectNameInfoEXT name_info = {};
1526     name_info.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT;
1527     name_info.pNext = nullptr;
1528     name_info.object = (uint64_t)event_handle;
1529     name_info.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT;
1530     name_info.pObjectName = "UnimaginablyImprobableString";
1531     fpvkDebugMarkerSetObjectNameEXT(device(), &name_info);
1532 
1533     m_commandBuffer->begin();
1534     vkCmdSetEvent(m_commandBuffer->handle(), event_handle, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
1535     m_commandBuffer->end();
1536     VkSubmitInfo submit_info = {};
1537     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1538     submit_info.commandBufferCount = 1;
1539     submit_info.pCommandBuffers = &m_commandBuffer->handle();
1540     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1541     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "UnimaginablyImprobableString");
1542     vkDestroyEvent(m_device->device(), event_handle, NULL);
1543     m_errorMonitor->VerifyFound();
1544     vkQueueWaitIdle(m_device->m_queue);
1545 
1546     VkBuffer buffer;
1547     VkDeviceMemory memory_1, memory_2;
1548     std::string memory_name = "memory_name";
1549 
1550     VkBufferCreateInfo buffer_create_info = {};
1551     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
1552     buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
1553     buffer_create_info.size = 1;
1554 
1555     vkCreateBuffer(device(), &buffer_create_info, nullptr, &buffer);
1556 
1557     VkMemoryRequirements memRequirements;
1558     vkGetBufferMemoryRequirements(device(), buffer, &memRequirements);
1559 
1560     VkMemoryAllocateInfo memory_allocate_info = {};
1561     memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1562     memory_allocate_info.allocationSize = memRequirements.size;
1563     memory_allocate_info.memoryTypeIndex = 0;
1564 
1565     vkAllocateMemory(device(), &memory_allocate_info, nullptr, &memory_1);
1566     vkAllocateMemory(device(), &memory_allocate_info, nullptr, &memory_2);
1567 
1568     name_info.object = (uint64_t)memory_2;
1569     name_info.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT;
1570     name_info.pObjectName = memory_name.c_str();
1571     fpvkDebugMarkerSetObjectNameEXT(device(), &name_info);
1572 
1573     vkBindBufferMemory(device(), buffer, memory_1, 0);
1574 
1575     // Test core_validation layer
1576     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, memory_name);
1577     vkBindBufferMemory(device(), buffer, memory_2, 0);
1578     m_errorMonitor->VerifyFound();
1579 
1580     vkFreeMemory(device(), memory_1, nullptr);
1581     memory_1 = VK_NULL_HANDLE;
1582     vkFreeMemory(device(), memory_2, nullptr);
1583     memory_2 = VK_NULL_HANDLE;
1584     vkDestroyBuffer(device(), buffer, nullptr);
1585     buffer = VK_NULL_HANDLE;
1586 
1587     VkCommandBuffer commandBuffer;
1588     std::string commandBuffer_name = "command_buffer_name";
1589     VkCommandPool commandpool_1;
1590     VkCommandPool commandpool_2;
1591     VkCommandPoolCreateInfo pool_create_info{};
1592     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
1593     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
1594     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
1595     vkCreateCommandPool(device(), &pool_create_info, nullptr, &commandpool_1);
1596     vkCreateCommandPool(device(), &pool_create_info, nullptr, &commandpool_2);
1597 
1598     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
1599     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
1600     command_buffer_allocate_info.commandPool = commandpool_1;
1601     command_buffer_allocate_info.commandBufferCount = 1;
1602     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
1603     vkAllocateCommandBuffers(device(), &command_buffer_allocate_info, &commandBuffer);
1604 
1605     name_info.object = (uint64_t)commandBuffer;
1606     name_info.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT;
1607     name_info.pObjectName = commandBuffer_name.c_str();
1608     fpvkDebugMarkerSetObjectNameEXT(device(), &name_info);
1609 
1610     VkCommandBufferBeginInfo cb_begin_Info = {};
1611     cb_begin_Info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1612     cb_begin_Info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
1613     vkBeginCommandBuffer(commandBuffer, &cb_begin_Info);
1614 
1615     const VkRect2D scissor = {{-1, 0}, {16, 16}};
1616     const VkRect2D scissors[] = {scissor, scissor};
1617 
1618     // Test parameter_validation layer
1619     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, commandBuffer_name);
1620     vkCmdSetScissor(commandBuffer, 1, 1, scissors);
1621     m_errorMonitor->VerifyFound();
1622 
1623     // Test object_tracker layer
1624     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, commandBuffer_name);
1625     vkFreeCommandBuffers(device(), commandpool_2, 1, &commandBuffer);
1626     m_errorMonitor->VerifyFound();
1627 
1628     vkDestroyCommandPool(device(), commandpool_1, NULL);
1629     vkDestroyCommandPool(device(), commandpool_2, NULL);
1630 }
1631 
TEST_F(VkLayerTest,DebugUtilsNameTest)1632 TEST_F(VkLayerTest, DebugUtilsNameTest) {
1633     // Check for external semaphore instance extensions
1634     if (InstanceExtensionSupported(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) {
1635         m_instance_extension_names.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
1636     } else {
1637         printf("%s Debug Utils Extension not supported, skipping test\n", kSkipPrefix);
1638         return;
1639     }
1640     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1641     ASSERT_NO_FATAL_FAILURE(InitState());
1642 
1643     PFN_vkSetDebugUtilsObjectNameEXT fpvkSetDebugUtilsObjectNameEXT =
1644         (PFN_vkSetDebugUtilsObjectNameEXT)vkGetDeviceProcAddr(m_device->device(), "vkSetDebugUtilsObjectNameEXT");
1645     if (!(fpvkSetDebugUtilsObjectNameEXT)) {
1646         printf("%s Can't find fpvkSetDebugUtilsObjectNameEXT; skipped.\n", kSkipPrefix);
1647         return;
1648     }
1649 
1650     VkEvent event_handle = VK_NULL_HANDLE;
1651     VkEventCreateInfo event_info = {};
1652     event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1653     vkCreateEvent(device(), &event_info, NULL, &event_handle);
1654     VkDebugUtilsObjectNameInfoEXT name_info = {};
1655     name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
1656     name_info.pNext = nullptr;
1657     name_info.objectHandle = (uint64_t)event_handle;
1658     name_info.objectType = VK_OBJECT_TYPE_EVENT;
1659     name_info.pObjectName = "Popbutton_T_Bumfuzzle";
1660     fpvkSetDebugUtilsObjectNameEXT(device(), &name_info);
1661 
1662     m_commandBuffer->begin();
1663     vkCmdSetEvent(m_commandBuffer->handle(), event_handle, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
1664     m_commandBuffer->end();
1665     VkSubmitInfo submit_info = {};
1666     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1667     submit_info.commandBufferCount = 1;
1668     submit_info.pCommandBuffers = &m_commandBuffer->handle();
1669     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1670     // Provoke an error from the core_validation layer
1671     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Popbutton_T_Bumfuzzle");
1672     vkDestroyEvent(m_device->device(), event_handle, NULL);
1673     m_errorMonitor->VerifyFound();
1674     vkQueueWaitIdle(m_device->m_queue);
1675 
1676     // Provoke an error from the object tracker layer
1677     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Popbutton_T_Bumfuzzle");
1678     vkDestroyEvent(m_device->device(), event_handle, NULL);
1679     m_errorMonitor->VerifyFound();
1680 
1681     // Change label for a given object, then provoke an error from core_validation and look for the new name
1682     name_info.pObjectName = "A_Totally_Different_Name";
1683     fpvkSetDebugUtilsObjectNameEXT(device(), &name_info);
1684     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "A_Totally_Different_Name");
1685     vkDestroyEvent(m_device->device(), event_handle, NULL);
1686     m_errorMonitor->VerifyFound();
1687 
1688     vkQueueWaitIdle(m_device->m_queue);
1689 }
1690 
TEST_F(VkLayerTest,InvalidStructSType)1691 TEST_F(VkLayerTest, InvalidStructSType) {
1692     TEST_DESCRIPTION("Specify an invalid VkStructureType for a Vulkan structure's sType field");
1693 
1694     ASSERT_NO_FATAL_FAILURE(Init());
1695 
1696     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pAllocateInfo->sType must be");
1697     // Zero struct memory, effectively setting sType to
1698     // VK_STRUCTURE_TYPE_APPLICATION_INFO
1699     // Expected to trigger an error with
1700     // parameter_validation::validate_struct_type
1701     VkMemoryAllocateInfo alloc_info = {};
1702     VkDeviceMemory memory = VK_NULL_HANDLE;
1703     vkAllocateMemory(device(), &alloc_info, NULL, &memory);
1704     m_errorMonitor->VerifyFound();
1705 
1706     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pSubmits[0].sType must be");
1707     // Zero struct memory, effectively setting sType to
1708     // VK_STRUCTURE_TYPE_APPLICATION_INFO
1709     // Expected to trigger an error with
1710     // parameter_validation::validate_struct_type_array
1711     VkSubmitInfo submit_info = {};
1712     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1713     m_errorMonitor->VerifyFound();
1714 }
1715 
TEST_F(VkLayerTest,InvalidStructPNext)1716 TEST_F(VkLayerTest, InvalidStructPNext) {
1717     TEST_DESCRIPTION("Specify an invalid value for a Vulkan structure's pNext field");
1718 
1719     ASSERT_NO_FATAL_FAILURE(Init());
1720 
1721     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "value of pCreateInfo->pNext must be NULL");
1722     // Set VkMemoryAllocateInfo::pNext to a non-NULL value, when pNext must be NULL.
1723     // Need to pick a function that has no allowed pNext structure types.
1724     // Expected to trigger an error with parameter_validation::validate_struct_pnext
1725     VkEvent event = VK_NULL_HANDLE;
1726     VkEventCreateInfo event_alloc_info = {};
1727     // Zero-initialization will provide the correct sType
1728     VkApplicationInfo app_info = {};
1729     event_alloc_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1730     event_alloc_info.pNext = &app_info;
1731     vkCreateEvent(device(), &event_alloc_info, NULL, &event);
1732     m_errorMonitor->VerifyFound();
1733 
1734     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
1735                                          " chain includes a structure with unexpected VkStructureType ");
1736     // Set VkMemoryAllocateInfo::pNext to a non-NULL value, but use
1737     // a function that has allowed pNext structure types and specify
1738     // a structure type that is not allowed.
1739     // Expected to trigger an error with parameter_validation::validate_struct_pnext
1740     VkDeviceMemory memory = VK_NULL_HANDLE;
1741     VkMemoryAllocateInfo memory_alloc_info = {};
1742     memory_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1743     memory_alloc_info.pNext = &app_info;
1744     vkAllocateMemory(device(), &memory_alloc_info, NULL, &memory);
1745     m_errorMonitor->VerifyFound();
1746 }
1747 
TEST_F(VkLayerTest,UnrecognizedValueOutOfRange)1748 TEST_F(VkLayerTest, UnrecognizedValueOutOfRange) {
1749     ASSERT_NO_FATAL_FAILURE(Init());
1750 
1751     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1752                                          "does not fall within the begin..end range of the core VkFormat enumeration tokens");
1753     // Specify an invalid VkFormat value
1754     // Expected to trigger an error with
1755     // parameter_validation::validate_ranged_enum
1756     VkFormatProperties format_properties;
1757     vkGetPhysicalDeviceFormatProperties(gpu(), static_cast<VkFormat>(8000), &format_properties);
1758     m_errorMonitor->VerifyFound();
1759 }
1760 
TEST_F(VkLayerTest,UnrecognizedValueBadMask)1761 TEST_F(VkLayerTest, UnrecognizedValueBadMask) {
1762     ASSERT_NO_FATAL_FAILURE(Init());
1763 
1764     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "contains flag bits that are not recognized members of");
1765     // Specify an invalid VkFlags bitmask value
1766     // Expected to trigger an error with parameter_validation::validate_flags
1767     VkImageFormatProperties image_format_properties;
1768     vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
1769                                              static_cast<VkImageUsageFlags>(1 << 25), 0, &image_format_properties);
1770     m_errorMonitor->VerifyFound();
1771 }
1772 
TEST_F(VkLayerTest,UnrecognizedValueBadFlag)1773 TEST_F(VkLayerTest, UnrecognizedValueBadFlag) {
1774     ASSERT_NO_FATAL_FAILURE(Init());
1775 
1776     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "contains flag bits that are not recognized members of");
1777     // Specify an invalid VkFlags array entry
1778     // Expected to trigger an error with parameter_validation::validate_flags_array
1779     VkSemaphore semaphore;
1780     VkSemaphoreCreateInfo semaphore_create_info{};
1781     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
1782     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
1783     // `stage_flags` is set to a value which, currently, is not a defined stage flag
1784     // `VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM` works well for this
1785     VkPipelineStageFlags stage_flags = VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM;
1786     // `waitSemaphoreCount` *must* be greater than 0 to perform this check
1787     VkSubmitInfo submit_info = {};
1788     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1789     submit_info.waitSemaphoreCount = 1;
1790     submit_info.pWaitSemaphores = &semaphore;
1791     submit_info.pWaitDstStageMask = &stage_flags;
1792     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1793     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
1794 
1795     m_errorMonitor->VerifyFound();
1796 }
1797 
TEST_F(VkLayerTest,UnrecognizedValueBadBool)1798 TEST_F(VkLayerTest, UnrecognizedValueBadBool) {
1799     // Make sure using VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE doesn't trigger a false positive.
1800     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1801     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME)) {
1802         m_device_extension_names.push_back(VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME);
1803     } else {
1804         printf("%s VK_KHR_sampler_mirror_clamp_to_edge extension not supported, skipping test\n", kSkipPrefix);
1805         return;
1806     }
1807     ASSERT_NO_FATAL_FAILURE(InitState());
1808 
1809     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "is neither VK_TRUE nor VK_FALSE");
1810     // Specify an invalid VkBool32 value, expecting a warning with parameter_validation::validate_bool32
1811     VkSampler sampler = VK_NULL_HANDLE;
1812     VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
1813     sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
1814     sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
1815     sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
1816 
1817     // Not VK_TRUE or VK_FALSE
1818     sampler_info.anisotropyEnable = 3;
1819     vkCreateSampler(m_device->device(), &sampler_info, NULL, &sampler);
1820     m_errorMonitor->VerifyFound();
1821 }
1822 
TEST_F(VkLayerTest,MirrorClampToEdgeNotEnabled)1823 TEST_F(VkLayerTest, MirrorClampToEdgeNotEnabled) {
1824     TEST_DESCRIPTION("Validation should catch using CLAMP_TO_EDGE addressing mode if the extension is not enabled.");
1825 
1826     ASSERT_NO_FATAL_FAILURE(Init());
1827 
1828     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSamplerCreateInfo-addressModeU-01079");
1829     VkSampler sampler = VK_NULL_HANDLE;
1830     VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
1831     // Set the modes to cause the error
1832     sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
1833     sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
1834     sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
1835 
1836     vkCreateSampler(m_device->device(), &sampler_info, NULL, &sampler);
1837     m_errorMonitor->VerifyFound();
1838 }
1839 
TEST_F(VkLayerTest,AnisotropyFeatureDisabled)1840 TEST_F(VkLayerTest, AnisotropyFeatureDisabled) {
1841     TEST_DESCRIPTION("Validation should check anisotropy parameters are correct with samplerAnisotropy disabled.");
1842 
1843     // Determine if required device features are available
1844     VkPhysicalDeviceFeatures device_features = {};
1845     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1846     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
1847     device_features.samplerAnisotropy = VK_FALSE;  // force anisotropy off
1848     ASSERT_NO_FATAL_FAILURE(InitState(&device_features));
1849 
1850     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSamplerCreateInfo-anisotropyEnable-01070");
1851     VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
1852     // With the samplerAnisotropy disable, the sampler must not enable it.
1853     sampler_info.anisotropyEnable = VK_TRUE;
1854     VkSampler sampler = VK_NULL_HANDLE;
1855 
1856     VkResult err;
1857     err = vkCreateSampler(m_device->device(), &sampler_info, NULL, &sampler);
1858     m_errorMonitor->VerifyFound();
1859     if (VK_SUCCESS == err) {
1860         vkDestroySampler(m_device->device(), sampler, NULL);
1861     }
1862     sampler = VK_NULL_HANDLE;
1863 }
1864 
TEST_F(VkLayerTest,AnisotropyFeatureEnabled)1865 TEST_F(VkLayerTest, AnisotropyFeatureEnabled) {
1866     TEST_DESCRIPTION("Validation must check several conditions that apply only when Anisotropy is enabled.");
1867 
1868     // Determine if required device features are available
1869     VkPhysicalDeviceFeatures device_features = {};
1870     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1871     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
1872 
1873     // These tests require that the device support anisotropic filtering
1874     if (VK_TRUE != device_features.samplerAnisotropy) {
1875         printf("%s Test requires unsupported samplerAnisotropy feature. Skipped.\n", kSkipPrefix);
1876         return;
1877     }
1878 
1879     bool cubic_support = false;
1880     if (DeviceExtensionSupported(gpu(), nullptr, "VK_IMG_filter_cubic")) {
1881         m_device_extension_names.push_back("VK_IMG_filter_cubic");
1882         cubic_support = true;
1883     }
1884 
1885     VkSamplerCreateInfo sampler_info_ref = SafeSaneSamplerCreateInfo();
1886     sampler_info_ref.anisotropyEnable = VK_TRUE;
1887     VkSamplerCreateInfo sampler_info = sampler_info_ref;
1888     ASSERT_NO_FATAL_FAILURE(InitState());
1889 
1890     auto do_test = [this](std::string code, const VkSamplerCreateInfo *pCreateInfo) -> void {
1891         VkResult err;
1892         VkSampler sampler = VK_NULL_HANDLE;
1893         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, code);
1894         err = vkCreateSampler(m_device->device(), pCreateInfo, NULL, &sampler);
1895         m_errorMonitor->VerifyFound();
1896         if (VK_SUCCESS == err) {
1897             vkDestroySampler(m_device->device(), sampler, NULL);
1898         }
1899     };
1900 
1901     // maxAnisotropy out-of-bounds low.
1902     sampler_info.maxAnisotropy = NearestSmaller(1.0F);
1903     do_test("VUID-VkSamplerCreateInfo-anisotropyEnable-01071", &sampler_info);
1904     sampler_info.maxAnisotropy = sampler_info_ref.maxAnisotropy;
1905 
1906     // maxAnisotropy out-of-bounds high.
1907     sampler_info.maxAnisotropy = NearestGreater(m_device->phy().properties().limits.maxSamplerAnisotropy);
1908     do_test("VUID-VkSamplerCreateInfo-anisotropyEnable-01071", &sampler_info);
1909     sampler_info.maxAnisotropy = sampler_info_ref.maxAnisotropy;
1910 
1911     // Both anisotropy and unnormalized coords enabled
1912     sampler_info.unnormalizedCoordinates = VK_TRUE;
1913     // If unnormalizedCoordinates is VK_TRUE, minLod and maxLod must be zero
1914     sampler_info.minLod = 0;
1915     sampler_info.maxLod = 0;
1916     do_test("VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01076", &sampler_info);
1917     sampler_info.unnormalizedCoordinates = sampler_info_ref.unnormalizedCoordinates;
1918 
1919     // Both anisotropy and cubic filtering enabled
1920     if (cubic_support) {
1921         sampler_info.minFilter = VK_FILTER_CUBIC_IMG;
1922         do_test("VUID-VkSamplerCreateInfo-magFilter-01081", &sampler_info);
1923         sampler_info.minFilter = sampler_info_ref.minFilter;
1924 
1925         sampler_info.magFilter = VK_FILTER_CUBIC_IMG;
1926         do_test("VUID-VkSamplerCreateInfo-magFilter-01081", &sampler_info);
1927         sampler_info.magFilter = sampler_info_ref.magFilter;
1928     } else {
1929         printf("%s Test requires unsupported extension \"VK_IMG_filter_cubic\". Skipped.\n", kSkipPrefix);
1930     }
1931 }
1932 
TEST_F(VkLayerTest,UnnormalizedCoordinatesEnabled)1933 TEST_F(VkLayerTest, UnnormalizedCoordinatesEnabled) {
1934     TEST_DESCRIPTION("Validate restrictions on sampler parameters when unnormalizedCoordinates is true.");
1935 
1936     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1937     VkSamplerCreateInfo sampler_info_ref = SafeSaneSamplerCreateInfo();
1938     sampler_info_ref.unnormalizedCoordinates = VK_TRUE;
1939     sampler_info_ref.minLod = 0.0f;
1940     sampler_info_ref.maxLod = 0.0f;
1941     VkSamplerCreateInfo sampler_info = sampler_info_ref;
1942     ASSERT_NO_FATAL_FAILURE(InitState());
1943 
1944     auto do_test = [this](std::string code, const VkSamplerCreateInfo *pCreateInfo) -> void {
1945         VkResult err;
1946         VkSampler sampler = VK_NULL_HANDLE;
1947         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, code);
1948         err = vkCreateSampler(m_device->device(), pCreateInfo, NULL, &sampler);
1949         m_errorMonitor->VerifyFound();
1950         if (VK_SUCCESS == err) {
1951             vkDestroySampler(m_device->device(), sampler, NULL);
1952         }
1953     };
1954 
1955     // min and mag filters must be the same
1956     sampler_info.minFilter = VK_FILTER_NEAREST;
1957     sampler_info.magFilter = VK_FILTER_LINEAR;
1958     do_test("VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01072", &sampler_info);
1959     std::swap(sampler_info.minFilter, sampler_info.magFilter);
1960     do_test("VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01072", &sampler_info);
1961     sampler_info = sampler_info_ref;
1962 
1963     // mipmapMode must be NEAREST
1964     sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
1965     do_test("VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01073", &sampler_info);
1966     sampler_info = sampler_info_ref;
1967 
1968     // minlod and maxlod must be zero
1969     sampler_info.maxLod = 3.14159f;
1970     do_test("VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01074", &sampler_info);
1971     sampler_info.minLod = 2.71828f;
1972     do_test("VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01074", &sampler_info);
1973     sampler_info = sampler_info_ref;
1974 
1975     // addressModeU and addressModeV must both be CLAMP_TO_EDGE or CLAMP_TO_BORDER
1976     // checks all 12 invalid combinations out of 16 total combinations
1977     const std::array<VkSamplerAddressMode, 4> kAddressModes = {{
1978         VK_SAMPLER_ADDRESS_MODE_REPEAT,
1979         VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,
1980         VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1981         VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
1982     }};
1983     for (const auto umode : kAddressModes) {
1984         for (const auto vmode : kAddressModes) {
1985             if ((umode != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE && umode != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) ||
1986                 (vmode != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE && vmode != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)) {
1987                 sampler_info.addressModeU = umode;
1988                 sampler_info.addressModeV = vmode;
1989                 do_test("VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01075", &sampler_info);
1990             }
1991         }
1992     }
1993     sampler_info = sampler_info_ref;
1994 
1995     // VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01076 is tested in AnisotropyFeatureEnabled above
1996     // Since it requires checking/enabling the anisotropic filtering feature, it's easier to do it
1997     // with the other anisotropic tests.
1998 
1999     // compareEnable must be VK_FALSE
2000     sampler_info.compareEnable = VK_TRUE;
2001     do_test("VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01077", &sampler_info);
2002     sampler_info = sampler_info_ref;
2003 }
2004 
TEST_F(VkLayerTest,UnrecognizedValueMaxEnum)2005 TEST_F(VkLayerTest, UnrecognizedValueMaxEnum) {
2006     ASSERT_NO_FATAL_FAILURE(Init());
2007 
2008     // Specify MAX_ENUM
2009     VkFormatProperties format_properties;
2010     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "does not fall within the begin..end range");
2011     vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_MAX_ENUM, &format_properties);
2012     m_errorMonitor->VerifyFound();
2013 }
2014 
TEST_F(VkLayerTest,UpdateBufferAlignment)2015 TEST_F(VkLayerTest, UpdateBufferAlignment) {
2016     TEST_DESCRIPTION("Check alignment parameters for vkCmdUpdateBuffer");
2017     uint32_t updateData[] = {1, 2, 3, 4, 5, 6, 7, 8};
2018 
2019     ASSERT_NO_FATAL_FAILURE(Init());
2020 
2021     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
2022     VkBufferObj buffer;
2023     buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs);
2024 
2025     m_commandBuffer->begin();
2026     // Introduce failure by using dstOffset that is not multiple of 4
2027     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4");
2028     m_commandBuffer->UpdateBuffer(buffer.handle(), 1, 4, updateData);
2029     m_errorMonitor->VerifyFound();
2030 
2031     // Introduce failure by using dataSize that is not multiple of 4
2032     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4");
2033     m_commandBuffer->UpdateBuffer(buffer.handle(), 0, 6, updateData);
2034     m_errorMonitor->VerifyFound();
2035 
2036     // Introduce failure by using dataSize that is < 0
2037     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2038                                          "must be greater than zero and less than or equal to 65536");
2039     m_commandBuffer->UpdateBuffer(buffer.handle(), 0, (VkDeviceSize)-44, updateData);
2040     m_errorMonitor->VerifyFound();
2041 
2042     // Introduce failure by using dataSize that is > 65536
2043     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2044                                          "must be greater than zero and less than or equal to 65536");
2045     m_commandBuffer->UpdateBuffer(buffer.handle(), 0, (VkDeviceSize)80000, updateData);
2046     m_errorMonitor->VerifyFound();
2047 
2048     m_commandBuffer->end();
2049 }
2050 
TEST_F(VkLayerTest,FillBufferAlignment)2051 TEST_F(VkLayerTest, FillBufferAlignment) {
2052     TEST_DESCRIPTION("Check alignment parameters for vkCmdFillBuffer");
2053 
2054     ASSERT_NO_FATAL_FAILURE(Init());
2055 
2056     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
2057     VkBufferObj buffer;
2058     buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs);
2059 
2060     m_commandBuffer->begin();
2061 
2062     // Introduce failure by using dstOffset that is not multiple of 4
2063     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4");
2064     m_commandBuffer->FillBuffer(buffer.handle(), 1, 4, 0x11111111);
2065     m_errorMonitor->VerifyFound();
2066 
2067     // Introduce failure by using size that is not multiple of 4
2068     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4");
2069     m_commandBuffer->FillBuffer(buffer.handle(), 0, 6, 0x11111111);
2070     m_errorMonitor->VerifyFound();
2071 
2072     // Introduce failure by using size that is zero
2073     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must be greater than zero");
2074     m_commandBuffer->FillBuffer(buffer.handle(), 0, 0, 0x11111111);
2075     m_errorMonitor->VerifyFound();
2076 
2077     m_commandBuffer->end();
2078 }
2079 
TEST_F(VkLayerTest,PSOPolygonModeInvalid)2080 TEST_F(VkLayerTest, PSOPolygonModeInvalid) {
2081     TEST_DESCRIPTION("Attempt to use a non-solid polygon fill mode in a pipeline when this feature is not enabled.");
2082 
2083     ASSERT_NO_FATAL_FAILURE(Init());
2084     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2085 
2086     std::vector<const char *> device_extension_names;
2087     auto features = m_device->phy().features();
2088     // Artificially disable support for non-solid fill modes
2089     features.fillModeNonSolid = VK_FALSE;
2090     // The sacrificial device object
2091     VkDeviceObj test_device(0, gpu(), device_extension_names, &features);
2092 
2093     VkRenderpassObj render_pass(&test_device);
2094 
2095     const VkPipelineLayoutObj pipeline_layout(&test_device);
2096 
2097     VkPipelineRasterizationStateCreateInfo rs_ci = {};
2098     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
2099     rs_ci.pNext = nullptr;
2100     rs_ci.lineWidth = 1.0f;
2101     rs_ci.rasterizerDiscardEnable = VK_TRUE;
2102 
2103     VkShaderObj vs(&test_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2104     VkShaderObj fs(&test_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2105 
2106     // Set polygonMode to unsupported value POINT, should fail
2107     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2108                                          "polygonMode cannot be VK_POLYGON_MODE_POINT or VK_POLYGON_MODE_LINE");
2109     {
2110         VkPipelineObj pipe(&test_device);
2111         pipe.AddShader(&vs);
2112         pipe.AddShader(&fs);
2113         pipe.AddDefaultColorAttachment();
2114         // Introduce failure by setting unsupported polygon mode
2115         rs_ci.polygonMode = VK_POLYGON_MODE_POINT;
2116         pipe.SetRasterization(&rs_ci);
2117         pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle());
2118     }
2119     m_errorMonitor->VerifyFound();
2120 
2121     // Try again with polygonMode=LINE, should fail
2122     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2123                                          "polygonMode cannot be VK_POLYGON_MODE_POINT or VK_POLYGON_MODE_LINE");
2124     {
2125         VkPipelineObj pipe(&test_device);
2126         pipe.AddShader(&vs);
2127         pipe.AddShader(&fs);
2128         pipe.AddDefaultColorAttachment();
2129         // Introduce failure by setting unsupported polygon mode
2130         rs_ci.polygonMode = VK_POLYGON_MODE_LINE;
2131         pipe.SetRasterization(&rs_ci);
2132         pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle());
2133     }
2134     m_errorMonitor->VerifyFound();
2135 }
2136 
TEST_F(VkLayerTest,SparseBindingImageBufferCreate)2137 TEST_F(VkLayerTest, SparseBindingImageBufferCreate) {
2138     TEST_DESCRIPTION("Create buffer/image with sparse attributes but without the sparse_binding bit set");
2139 
2140     ASSERT_NO_FATAL_FAILURE(Init());
2141 
2142     VkBuffer buffer;
2143     VkBufferCreateInfo buf_info = {};
2144     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
2145     buf_info.pNext = NULL;
2146     buf_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
2147     buf_info.size = 2048;
2148     buf_info.queueFamilyIndexCount = 0;
2149     buf_info.pQueueFamilyIndices = NULL;
2150     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2151 
2152     if (m_device->phy().features().sparseResidencyBuffer) {
2153         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferCreateInfo-flags-00918");
2154 
2155         buf_info.flags = VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT;
2156         vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
2157         m_errorMonitor->VerifyFound();
2158     } else {
2159         printf("%s Test requires unsupported sparseResidencyBuffer feature. Skipped.\n", kSkipPrefix);
2160         return;
2161     }
2162 
2163     if (m_device->phy().features().sparseResidencyAliased) {
2164         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferCreateInfo-flags-00918");
2165 
2166         buf_info.flags = VK_BUFFER_CREATE_SPARSE_ALIASED_BIT;
2167         vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
2168         m_errorMonitor->VerifyFound();
2169     } else {
2170         printf("%s Test requires unsupported sparseResidencyAliased feature. Skipped.\n", kSkipPrefix);
2171         return;
2172     }
2173 
2174     VkImage image;
2175     VkImageCreateInfo image_create_info = {};
2176     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2177     image_create_info.pNext = NULL;
2178     image_create_info.imageType = VK_IMAGE_TYPE_2D;
2179     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
2180     image_create_info.extent.width = 512;
2181     image_create_info.extent.height = 64;
2182     image_create_info.extent.depth = 1;
2183     image_create_info.mipLevels = 1;
2184     image_create_info.arrayLayers = 1;
2185     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
2186     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
2187     image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
2188     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2189     image_create_info.queueFamilyIndexCount = 0;
2190     image_create_info.pQueueFamilyIndices = NULL;
2191     image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2192 
2193     if (m_device->phy().features().sparseResidencyImage2D) {
2194         image_create_info.flags = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT;
2195 
2196         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-flags-00987");
2197         vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2198         m_errorMonitor->VerifyFound();
2199     } else {
2200         printf("%s Test requires unsupported sparseResidencyImage2D feature. Skipped.\n", kSkipPrefix);
2201         return;
2202     }
2203 
2204     if (m_device->phy().features().sparseResidencyAliased) {
2205         image_create_info.flags = VK_IMAGE_CREATE_SPARSE_ALIASED_BIT;
2206 
2207         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-flags-00987");
2208         vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2209         m_errorMonitor->VerifyFound();
2210     } else {
2211         printf("%s Test requires unsupported sparseResidencyAliased feature. Skipped.\n", kSkipPrefix);
2212         return;
2213     }
2214 }
2215 
TEST_F(VkLayerTest,SparseResidencyImageCreateUnsupportedTypes)2216 TEST_F(VkLayerTest, SparseResidencyImageCreateUnsupportedTypes) {
2217     TEST_DESCRIPTION("Create images with sparse residency with unsupported types");
2218 
2219     // Determine which device feature are available
2220     VkPhysicalDeviceFeatures device_features = {};
2221     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
2222     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
2223 
2224     // Mask out device features we don't want and initialize device state
2225     device_features.sparseResidencyImage2D = VK_FALSE;
2226     device_features.sparseResidencyImage3D = VK_FALSE;
2227     ASSERT_NO_FATAL_FAILURE(InitState(&device_features));
2228 
2229     if (!m_device->phy().features().sparseBinding) {
2230         printf("%s Test requires unsupported sparseBinding feature. Skipped.\n", kSkipPrefix);
2231         return;
2232     }
2233 
2234     VkImage image = VK_NULL_HANDLE;
2235     VkResult result = VK_RESULT_MAX_ENUM;
2236     VkImageCreateInfo image_create_info = {};
2237     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2238     image_create_info.pNext = NULL;
2239     image_create_info.imageType = VK_IMAGE_TYPE_1D;
2240     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
2241     image_create_info.extent.width = 512;
2242     image_create_info.extent.height = 1;
2243     image_create_info.extent.depth = 1;
2244     image_create_info.mipLevels = 1;
2245     image_create_info.arrayLayers = 1;
2246     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
2247     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
2248     image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
2249     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2250     image_create_info.queueFamilyIndexCount = 0;
2251     image_create_info.pQueueFamilyIndices = NULL;
2252     image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2253     image_create_info.flags = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_BUFFER_CREATE_SPARSE_BINDING_BIT;
2254 
2255     // 1D image w/ sparse residency is an error
2256     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-imageType-00970");
2257     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2258     m_errorMonitor->VerifyFound();
2259     if (VK_SUCCESS == result) {
2260         vkDestroyImage(m_device->device(), image, NULL);
2261         image = VK_NULL_HANDLE;
2262     }
2263 
2264     // 2D image w/ sparse residency when feature isn't available
2265     image_create_info.imageType = VK_IMAGE_TYPE_2D;
2266     image_create_info.extent.height = 64;
2267     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-imageType-00971");
2268     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2269     m_errorMonitor->VerifyFound();
2270     if (VK_SUCCESS == result) {
2271         vkDestroyImage(m_device->device(), image, NULL);
2272         image = VK_NULL_HANDLE;
2273     }
2274 
2275     // 3D image w/ sparse residency when feature isn't available
2276     image_create_info.imageType = VK_IMAGE_TYPE_3D;
2277     image_create_info.extent.depth = 8;
2278     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-imageType-00972");
2279     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2280     m_errorMonitor->VerifyFound();
2281     if (VK_SUCCESS == result) {
2282         vkDestroyImage(m_device->device(), image, NULL);
2283         image = VK_NULL_HANDLE;
2284     }
2285 }
2286 
TEST_F(VkLayerTest,SparseResidencyImageCreateUnsupportedSamples)2287 TEST_F(VkLayerTest, SparseResidencyImageCreateUnsupportedSamples) {
2288     TEST_DESCRIPTION("Create images with sparse residency with unsupported tiling or sample counts");
2289 
2290     // Determine which device feature are available
2291     VkPhysicalDeviceFeatures device_features = {};
2292     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
2293     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
2294 
2295     // These tests require that the device support sparse residency for 2D images
2296     if (VK_TRUE != device_features.sparseResidencyImage2D) {
2297         printf("%s Test requires unsupported SparseResidencyImage2D feature. Skipped.\n", kSkipPrefix);
2298         return;
2299     }
2300 
2301     // Mask out device features we don't want and initialize device state
2302     device_features.sparseResidency2Samples = VK_FALSE;
2303     device_features.sparseResidency4Samples = VK_FALSE;
2304     device_features.sparseResidency8Samples = VK_FALSE;
2305     device_features.sparseResidency16Samples = VK_FALSE;
2306     ASSERT_NO_FATAL_FAILURE(InitState(&device_features));
2307 
2308     VkImage image = VK_NULL_HANDLE;
2309     VkResult result = VK_RESULT_MAX_ENUM;
2310     VkImageCreateInfo image_create_info = {};
2311     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2312     image_create_info.pNext = NULL;
2313     image_create_info.imageType = VK_IMAGE_TYPE_2D;
2314     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
2315     image_create_info.extent.width = 64;
2316     image_create_info.extent.height = 64;
2317     image_create_info.extent.depth = 1;
2318     image_create_info.mipLevels = 1;
2319     image_create_info.arrayLayers = 1;
2320     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
2321     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
2322     image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
2323     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2324     image_create_info.queueFamilyIndexCount = 0;
2325     image_create_info.pQueueFamilyIndices = NULL;
2326     image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2327     image_create_info.flags = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_BUFFER_CREATE_SPARSE_BINDING_BIT;
2328 
2329     // 2D image w/ sparse residency and linear tiling is an error
2330     m_errorMonitor->SetDesiredFailureMsg(
2331         VK_DEBUG_REPORT_ERROR_BIT_EXT,
2332         "VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT then image tiling of VK_IMAGE_TILING_LINEAR is not supported");
2333     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2334     m_errorMonitor->VerifyFound();
2335     if (VK_SUCCESS == result) {
2336         vkDestroyImage(m_device->device(), image, NULL);
2337         image = VK_NULL_HANDLE;
2338     }
2339     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
2340 
2341     // Multi-sample image w/ sparse residency when feature isn't available (4 flavors)
2342     image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
2343     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-imageType-00973");
2344     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2345     m_errorMonitor->VerifyFound();
2346     if (VK_SUCCESS == result) {
2347         vkDestroyImage(m_device->device(), image, NULL);
2348         image = VK_NULL_HANDLE;
2349     }
2350 
2351     image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
2352     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-imageType-00974");
2353     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2354     m_errorMonitor->VerifyFound();
2355     if (VK_SUCCESS == result) {
2356         vkDestroyImage(m_device->device(), image, NULL);
2357         image = VK_NULL_HANDLE;
2358     }
2359 
2360     image_create_info.samples = VK_SAMPLE_COUNT_8_BIT;
2361     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-imageType-00975");
2362     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2363     m_errorMonitor->VerifyFound();
2364     if (VK_SUCCESS == result) {
2365         vkDestroyImage(m_device->device(), image, NULL);
2366         image = VK_NULL_HANDLE;
2367     }
2368 
2369     image_create_info.samples = VK_SAMPLE_COUNT_16_BIT;
2370     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-imageType-00976");
2371     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2372     m_errorMonitor->VerifyFound();
2373     if (VK_SUCCESS == result) {
2374         vkDestroyImage(m_device->device(), image, NULL);
2375         image = VK_NULL_HANDLE;
2376     }
2377 }
2378 
TEST_F(VkLayerTest,GpuValidationArrayOOB)2379 TEST_F(VkLayerTest, GpuValidationArrayOOB) {
2380     TEST_DESCRIPTION("GPU validation: Verify detection of out-of-bounds descriptor array indexing.");
2381     if (!VkRenderFramework::DeviceCanDraw()) {
2382         printf("%s GPU-Assisted validation test requires a driver that can draw.\n", kSkipPrefix);
2383         return;
2384     }
2385 #if defined(ANDROID)
2386     if (instance() == VK_NULL_HANDLE) {
2387         printf("%s Skipping test on Android temporarily while debugging test execution failure.\n", kSkipPrefix);
2388         return;
2389     }
2390 #endif
2391     VkValidationFeatureEnableEXT enables[] = {VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT};
2392     VkValidationFeaturesEXT features = {};
2393     features.sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT;
2394     features.enabledValidationFeatureCount = 1;
2395     features.pEnabledValidationFeatures = enables;
2396     VkCommandPoolCreateFlags pool_flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
2397     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, pool_flags, &features));
2398     if (m_device->props.apiVersion < VK_API_VERSION_1_1) {
2399         printf("%s GPU-Assisted validation test requires Vulkan 1.1+.\n", kSkipPrefix);
2400         return;
2401     }
2402     ASSERT_NO_FATAL_FAILURE(InitViewport());
2403     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2404 
2405     // Make a uniform buffer to be passed to the shader that contains the invalid array index.
2406     uint32_t qfi = 0;
2407     VkBufferCreateInfo bci = {};
2408     bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
2409     bci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
2410     bci.size = 1024;
2411     bci.queueFamilyIndexCount = 1;
2412     bci.pQueueFamilyIndices = &qfi;
2413     VkBufferObj buffer0;
2414     VkMemoryPropertyFlags mem_props = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
2415     buffer0.init(*m_device, bci, mem_props);
2416     uint32_t *data = (uint32_t *)buffer0.memory().map();
2417     data[0] = 25;
2418     buffer0.memory().unmap();
2419 
2420     // Prepare descriptors
2421     OneOffDescriptorSet ds(m_device, {
2422                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
2423                                          {1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 6, VK_SHADER_STAGE_ALL, nullptr},
2424                                      });
2425 
2426     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
2427     VkTextureObj texture(m_device, nullptr);
2428     VkSamplerObj sampler(m_device);
2429 
2430     VkDescriptorBufferInfo buffer_info[1] = {};
2431     buffer_info[0].buffer = buffer0.handle();
2432     buffer_info[0].offset = 0;
2433     buffer_info[0].range = sizeof(uint32_t);
2434 
2435     VkDescriptorImageInfo image_info[6] = {};
2436     for (int i = 0; i < 6; i++) {
2437         image_info[i] = texture.DescriptorImageInfo();
2438         image_info[i].sampler = sampler.handle();
2439         image_info[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
2440     }
2441 
2442     VkWriteDescriptorSet descriptor_writes[2] = {};
2443     descriptor_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
2444     descriptor_writes[0].dstSet = ds.set_;  // descriptor_set;
2445     descriptor_writes[0].dstBinding = 0;
2446     descriptor_writes[0].descriptorCount = 1;
2447     descriptor_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
2448     descriptor_writes[0].pBufferInfo = buffer_info;
2449     descriptor_writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
2450     descriptor_writes[1].dstSet = ds.set_;  // descriptor_set;
2451     descriptor_writes[1].dstBinding = 1;
2452     descriptor_writes[1].descriptorCount = 6;
2453     descriptor_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
2454     descriptor_writes[1].pImageInfo = image_info;
2455     vkUpdateDescriptorSets(m_device->device(), 2, descriptor_writes, 0, NULL);
2456 
2457     // Shader programs for array OOB test in vertex stage:
2458     // - The vertex shader fetches the invalid index from the uniform buffer and uses it to make an invalid index into another
2459     // array.
2460     char const *vsSource_vert =
2461         "#version 450\n"
2462         "\n"
2463         "layout(std140, set = 0, binding = 0) uniform foo { uint tex_index[1]; } uniform_index_buffer;\n"
2464         "layout(set = 0, binding = 1) uniform sampler2D tex[6];\n"
2465         "vec2 vertices[3];\n"
2466         "void main(){\n"
2467         "      vertices[0] = vec2(-1.0, -1.0);\n"
2468         "      vertices[1] = vec2( 1.0, -1.0);\n"
2469         "      vertices[2] = vec2( 0.0,  1.0);\n"
2470         "   gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0);\n"
2471         "   gl_Position += 1e-30 * texture(tex[uniform_index_buffer.tex_index[0]], vec2(0, 0));\n"
2472         "}\n";
2473     char const *fsSource_vert =
2474         "#version 450\n"
2475         "\n"
2476         "layout(set = 0, binding = 1) uniform sampler2D tex[6];\n"
2477         "layout(location = 0) out vec4 uFragColor;\n"
2478         "void main(){\n"
2479         "   uFragColor = texture(tex[0], vec2(0, 0));\n"
2480         "}\n";
2481 
2482     // Shader programs for array OOB test in fragment stage:
2483     // - The vertex shader fetches the invalid index from the uniform buffer and passes it to the fragment shader.
2484     // - The fragment shader makes the invalid array access.
2485     char const *vsSource_frag =
2486         "#version 450\n"
2487         "\n"
2488         "layout(std140, binding = 0) uniform foo { uint tex_index[1]; } uniform_index_buffer;\n"
2489         "layout(location = 0) out flat uint tex_ind;\n"
2490         "vec2 vertices[3];\n"
2491         "void main(){\n"
2492         "      vertices[0] = vec2(-1.0, -1.0);\n"
2493         "      vertices[1] = vec2( 1.0, -1.0);\n"
2494         "      vertices[2] = vec2( 0.0,  1.0);\n"
2495         "   gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0);\n"
2496         "   tex_ind = uniform_index_buffer.tex_index[0];\n"
2497         "}\n";
2498     char const *fsSource_frag =
2499         "#version 450\n"
2500         "\n"
2501         "layout(set = 0, binding = 1) uniform sampler2D tex[6];\n"
2502         "layout(location = 0) out vec4 uFragColor;\n"
2503         "layout(location = 0) in flat uint tex_ind;\n"
2504         "void main(){\n"
2505         "   uFragColor = texture(tex[tex_ind], vec2(0, 0));\n"
2506         "}\n";
2507 
2508     struct TestCase {
2509         char const *vertex_source;
2510         char const *fragment_source;
2511         bool debug;
2512         char const *expected_error;
2513     };
2514 
2515     std::vector<TestCase> tests;
2516     tests.push_back({vsSource_vert, fsSource_vert, false, "Index of 25 used to index descriptor array of length 6."});
2517     tests.push_back({vsSource_frag, fsSource_frag, false, "Index of 25 used to index descriptor array of length 6."});
2518 #if !defined(ANDROID)
2519     // The Android test framework uses shaderc for online compilations.  Even when configured to compile with debug info,
2520     // shaderc seems to drop the OpLine instructions from the shader binary.  This causes the following two tests to fail
2521     // on Android platforms.  Skip these tests until the shaderc issue is understood/resolved.
2522     tests.push_back({vsSource_vert, fsSource_vert, true,
2523                      "gl_Position += 1e-30 * texture(tex[uniform_index_buffer.tex_index[0]], vec2(0, 0));"});
2524     tests.push_back({vsSource_frag, fsSource_frag, true, "uFragColor = texture(tex[tex_ind], vec2(0, 0));"});
2525 #endif
2526 
2527     VkViewport viewport = m_viewports[0];
2528     VkRect2D scissors = m_scissors[0];
2529 
2530     VkSubmitInfo submit_info = {};
2531     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2532     submit_info.commandBufferCount = 1;
2533     submit_info.pCommandBuffers = &m_commandBuffer->handle();
2534 
2535     for (const auto &iter : tests) {
2536         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.expected_error);
2537         VkShaderObj vs(m_device, iter.vertex_source, VK_SHADER_STAGE_VERTEX_BIT, this, "main", iter.debug);
2538         VkShaderObj fs(m_device, iter.fragment_source, VK_SHADER_STAGE_FRAGMENT_BIT, this, "main", iter.debug);
2539         VkPipelineObj pipe(m_device);
2540         pipe.AddShader(&vs);
2541         pipe.AddShader(&fs);
2542         pipe.AddDefaultColorAttachment();
2543         VkResult err = pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
2544         ASSERT_VK_SUCCESS(err);
2545         m_commandBuffer->begin();
2546         m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2547         vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
2548         vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
2549                                 &ds.set_, 0, nullptr);
2550         vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
2551         vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissors);
2552         vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2553         vkCmdEndRenderPass(m_commandBuffer->handle());
2554         m_commandBuffer->end();
2555         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
2556         vkQueueWaitIdle(m_device->m_queue);
2557         m_errorMonitor->VerifyFound();
2558     }
2559     return;
2560 }
2561 
TEST_F(VkLayerTest,InvalidMemoryAliasing)2562 TEST_F(VkLayerTest, InvalidMemoryAliasing) {
2563     TEST_DESCRIPTION(
2564         "Create a buffer and image, allocate memory, and bind the buffer and image to memory such that they will alias.");
2565     VkResult err;
2566     bool pass;
2567     ASSERT_NO_FATAL_FAILURE(Init());
2568 
2569     VkBuffer buffer, buffer2;
2570     VkImage image;
2571     VkImage image2;
2572     VkDeviceMemory mem;      // buffer will be bound first
2573     VkDeviceMemory mem_img;  // image bound first
2574     VkMemoryRequirements buff_mem_reqs, img_mem_reqs;
2575     VkMemoryRequirements buff_mem_reqs2, img_mem_reqs2;
2576 
2577     VkBufferCreateInfo buf_info = {};
2578     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
2579     buf_info.pNext = NULL;
2580     buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
2581     buf_info.size = 256;
2582     buf_info.queueFamilyIndexCount = 0;
2583     buf_info.pQueueFamilyIndices = NULL;
2584     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2585     buf_info.flags = 0;
2586     err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
2587     ASSERT_VK_SUCCESS(err);
2588 
2589     vkGetBufferMemoryRequirements(m_device->device(), buffer, &buff_mem_reqs);
2590 
2591     VkImageCreateInfo image_create_info = {};
2592     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2593     image_create_info.pNext = NULL;
2594     image_create_info.imageType = VK_IMAGE_TYPE_2D;
2595     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
2596     image_create_info.extent.width = 64;
2597     image_create_info.extent.height = 64;
2598     image_create_info.extent.depth = 1;
2599     image_create_info.mipLevels = 1;
2600     image_create_info.arrayLayers = 1;
2601     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
2602     // Image tiling must be optimal to trigger error when aliasing linear buffer
2603     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
2604     image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
2605     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2606     image_create_info.queueFamilyIndexCount = 0;
2607     image_create_info.pQueueFamilyIndices = NULL;
2608     image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2609     image_create_info.flags = 0;
2610 
2611     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2612     ASSERT_VK_SUCCESS(err);
2613     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image2);
2614     ASSERT_VK_SUCCESS(err);
2615 
2616     vkGetImageMemoryRequirements(m_device->device(), image, &img_mem_reqs);
2617 
2618     VkMemoryAllocateInfo alloc_info = {};
2619     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2620     alloc_info.pNext = NULL;
2621     alloc_info.memoryTypeIndex = 0;
2622     // Ensure memory is big enough for both bindings
2623     alloc_info.allocationSize = buff_mem_reqs.size + img_mem_reqs.size;
2624     pass = m_device->phy().set_memory_type(buff_mem_reqs.memoryTypeBits & img_mem_reqs.memoryTypeBits, &alloc_info,
2625                                            VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
2626     if (!pass) {
2627         printf("%s Failed to set memory type.\n", kSkipPrefix);
2628         vkDestroyBuffer(m_device->device(), buffer, NULL);
2629         vkDestroyImage(m_device->device(), image, NULL);
2630         vkDestroyImage(m_device->device(), image2, NULL);
2631         return;
2632     }
2633     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
2634     ASSERT_VK_SUCCESS(err);
2635     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
2636     ASSERT_VK_SUCCESS(err);
2637 
2638     vkGetImageMemoryRequirements(m_device->device(), image2, &img_mem_reqs2);
2639 
2640     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, " is aliased with linear buffer 0x");
2641     // VALIDATION FAILURE due to image mapping overlapping buffer mapping
2642     err = vkBindImageMemory(m_device->device(), image, mem, 0);
2643     m_errorMonitor->VerifyFound();
2644 
2645     // Now correctly bind image2 to second mem allocation before incorrectly
2646     // aliasing buffer2
2647     err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer2);
2648     ASSERT_VK_SUCCESS(err);
2649     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem_img);
2650     ASSERT_VK_SUCCESS(err);
2651     err = vkBindImageMemory(m_device->device(), image2, mem_img, 0);
2652     ASSERT_VK_SUCCESS(err);
2653     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "is aliased with non-linear image 0x");
2654     vkGetBufferMemoryRequirements(m_device->device(), buffer2, &buff_mem_reqs2);
2655     err = vkBindBufferMemory(m_device->device(), buffer2, mem_img, 0);
2656     m_errorMonitor->VerifyFound();
2657 
2658     vkDestroyBuffer(m_device->device(), buffer, NULL);
2659     vkDestroyBuffer(m_device->device(), buffer2, NULL);
2660     vkDestroyImage(m_device->device(), image, NULL);
2661     vkDestroyImage(m_device->device(), image2, NULL);
2662     vkFreeMemory(m_device->device(), mem, NULL);
2663     vkFreeMemory(m_device->device(), mem_img, NULL);
2664 }
2665 
TEST_F(VkLayerTest,InvalidMemoryMapping)2666 TEST_F(VkLayerTest, InvalidMemoryMapping) {
2667     TEST_DESCRIPTION("Attempt to map memory in a number of incorrect ways");
2668     VkResult err;
2669     bool pass;
2670     ASSERT_NO_FATAL_FAILURE(Init());
2671 
2672     VkBuffer buffer;
2673     VkDeviceMemory mem;
2674     VkMemoryRequirements mem_reqs;
2675 
2676     const VkDeviceSize atom_size = m_device->props.limits.nonCoherentAtomSize;
2677 
2678     VkBufferCreateInfo buf_info = {};
2679     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
2680     buf_info.pNext = NULL;
2681     buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
2682     buf_info.size = 256;
2683     buf_info.queueFamilyIndexCount = 0;
2684     buf_info.pQueueFamilyIndices = NULL;
2685     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2686     buf_info.flags = 0;
2687     err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
2688     ASSERT_VK_SUCCESS(err);
2689 
2690     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
2691     VkMemoryAllocateInfo alloc_info = {};
2692     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2693     alloc_info.pNext = NULL;
2694     alloc_info.memoryTypeIndex = 0;
2695 
2696     // Ensure memory is big enough for both bindings
2697     static const VkDeviceSize allocation_size = 0x10000;
2698     alloc_info.allocationSize = allocation_size;
2699     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
2700     if (!pass) {
2701         printf("%s Failed to set memory type.\n", kSkipPrefix);
2702         vkDestroyBuffer(m_device->device(), buffer, NULL);
2703         return;
2704     }
2705     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
2706     ASSERT_VK_SUCCESS(err);
2707 
2708     uint8_t *pData;
2709     // Attempt to map memory size 0 is invalid
2710     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VkMapMemory: Attempting to map memory range of size zero");
2711     err = vkMapMemory(m_device->device(), mem, 0, 0, 0, (void **)&pData);
2712     m_errorMonitor->VerifyFound();
2713     // Map memory twice
2714     err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData);
2715     ASSERT_VK_SUCCESS(err);
2716     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2717                                          "VkMapMemory: Attempting to map memory on an already-mapped object ");
2718     err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData);
2719     m_errorMonitor->VerifyFound();
2720 
2721     // Unmap the memory to avoid re-map error
2722     vkUnmapMemory(m_device->device(), mem);
2723     // overstep allocation with VK_WHOLE_SIZE
2724     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2725                                          " with size of VK_WHOLE_SIZE oversteps total array size 0x");
2726     err = vkMapMemory(m_device->device(), mem, allocation_size + 1, VK_WHOLE_SIZE, 0, (void **)&pData);
2727     m_errorMonitor->VerifyFound();
2728     // overstep allocation w/o VK_WHOLE_SIZE
2729     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " oversteps total array size 0x");
2730     err = vkMapMemory(m_device->device(), mem, 1, allocation_size, 0, (void **)&pData);
2731     m_errorMonitor->VerifyFound();
2732     // Now error due to unmapping memory that's not mapped
2733     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Unmapping Memory without memory being mapped: ");
2734     vkUnmapMemory(m_device->device(), mem);
2735     m_errorMonitor->VerifyFound();
2736 
2737     // Now map memory and cause errors due to flushing invalid ranges
2738     err = vkMapMemory(m_device->device(), mem, 4 * atom_size, VK_WHOLE_SIZE, 0, (void **)&pData);
2739     ASSERT_VK_SUCCESS(err);
2740     VkMappedMemoryRange mmr = {};
2741     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
2742     mmr.memory = mem;
2743     mmr.offset = atom_size;  // Error b/c offset less than offset of mapped mem
2744     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMappedMemoryRange-size-00685");
2745     vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
2746     m_errorMonitor->VerifyFound();
2747 
2748     // Now flush range that oversteps mapped range
2749     vkUnmapMemory(m_device->device(), mem);
2750     err = vkMapMemory(m_device->device(), mem, 0, 4 * atom_size, 0, (void **)&pData);
2751     ASSERT_VK_SUCCESS(err);
2752     mmr.offset = atom_size;
2753     mmr.size = 4 * atom_size;  // Flushing bounds exceed mapped bounds
2754     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMappedMemoryRange-size-00685");
2755     vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
2756     m_errorMonitor->VerifyFound();
2757 
2758     // Now flush range with VK_WHOLE_SIZE that oversteps offset
2759     vkUnmapMemory(m_device->device(), mem);
2760     err = vkMapMemory(m_device->device(), mem, 2 * atom_size, 4 * atom_size, 0, (void **)&pData);
2761     ASSERT_VK_SUCCESS(err);
2762     mmr.offset = atom_size;
2763     mmr.size = VK_WHOLE_SIZE;
2764     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMappedMemoryRange-size-00686");
2765     vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
2766     m_errorMonitor->VerifyFound();
2767 
2768     // Some platforms have an atomsize of 1 which makes the test meaningless
2769     if (atom_size > 3) {
2770         // Now with an offset NOT a multiple of the device limit
2771         vkUnmapMemory(m_device->device(), mem);
2772         err = vkMapMemory(m_device->device(), mem, 0, 4 * atom_size, 0, (void **)&pData);
2773         ASSERT_VK_SUCCESS(err);
2774         mmr.offset = 3;  // Not a multiple of atom_size
2775         mmr.size = VK_WHOLE_SIZE;
2776         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMappedMemoryRange-offset-00687");
2777         vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
2778         m_errorMonitor->VerifyFound();
2779 
2780         // Now with a size NOT a multiple of the device limit
2781         vkUnmapMemory(m_device->device(), mem);
2782         err = vkMapMemory(m_device->device(), mem, 0, 4 * atom_size, 0, (void **)&pData);
2783         ASSERT_VK_SUCCESS(err);
2784         mmr.offset = atom_size;
2785         mmr.size = 2 * atom_size + 1;  // Not a multiple of atom_size
2786         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMappedMemoryRange-size-01390");
2787         vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
2788         m_errorMonitor->VerifyFound();
2789     }
2790 
2791     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
2792                                            VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
2793     if (!pass) {
2794         printf("%s Failed to set memory type.\n", kSkipPrefix);
2795         vkFreeMemory(m_device->device(), mem, NULL);
2796         vkDestroyBuffer(m_device->device(), buffer, NULL);
2797         return;
2798     }
2799     // TODO : If we can get HOST_VISIBLE w/o HOST_COHERENT we can test cases of
2800     //  kVUID_Core_MemTrack_InvalidMap in validateAndCopyNoncoherentMemoryToDriver()
2801 
2802     vkDestroyBuffer(m_device->device(), buffer, NULL);
2803     vkFreeMemory(m_device->device(), mem, NULL);
2804 }
2805 
TEST_F(VkLayerTest,MapMemWithoutHostVisibleBit)2806 TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit) {
2807     TEST_DESCRIPTION("Allocate memory that is not mappable and then attempt to map it.");
2808     VkResult err;
2809     bool pass;
2810 
2811     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkMapMemory-memory-00682");
2812     ASSERT_NO_FATAL_FAILURE(Init());
2813 
2814     VkMemoryAllocateInfo mem_alloc = {};
2815     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2816     mem_alloc.pNext = NULL;
2817     mem_alloc.allocationSize = 1024;
2818 
2819     pass = m_device->phy().set_memory_type(0xFFFFFFFF, &mem_alloc, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
2820     if (!pass) {  // If we can't find any unmappable memory this test doesn't
2821                   // make sense
2822         printf("%s No unmappable memory types found, skipping test\n", kSkipPrefix);
2823         return;
2824     }
2825 
2826     VkDeviceMemory mem;
2827     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
2828     ASSERT_VK_SUCCESS(err);
2829 
2830     void *mappedAddress = NULL;
2831     err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, &mappedAddress);
2832     m_errorMonitor->VerifyFound();
2833 
2834     vkFreeMemory(m_device->device(), mem, NULL);
2835 }
2836 
TEST_F(VkLayerTest,RebindMemory)2837 TEST_F(VkLayerTest, RebindMemory) {
2838     VkResult err;
2839     bool pass;
2840 
2841     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "which has already been bound to mem object");
2842 
2843     ASSERT_NO_FATAL_FAILURE(Init());
2844 
2845     // Create an image, allocate memory, free it, and then try to bind it
2846     VkImage image;
2847     VkDeviceMemory mem1;
2848     VkDeviceMemory mem2;
2849     VkMemoryRequirements mem_reqs;
2850 
2851     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
2852     const int32_t tex_width = 32;
2853     const int32_t tex_height = 32;
2854 
2855     VkImageCreateInfo image_create_info = {};
2856     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2857     image_create_info.pNext = NULL;
2858     image_create_info.imageType = VK_IMAGE_TYPE_2D;
2859     image_create_info.format = tex_format;
2860     image_create_info.extent.width = tex_width;
2861     image_create_info.extent.height = tex_height;
2862     image_create_info.extent.depth = 1;
2863     image_create_info.mipLevels = 1;
2864     image_create_info.arrayLayers = 1;
2865     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
2866     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
2867     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
2868     image_create_info.flags = 0;
2869 
2870     VkMemoryAllocateInfo mem_alloc = {};
2871     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2872     mem_alloc.pNext = NULL;
2873     mem_alloc.allocationSize = 0;
2874     mem_alloc.memoryTypeIndex = 0;
2875 
2876     // Introduce failure, do NOT set memProps to
2877     // VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
2878     mem_alloc.memoryTypeIndex = 1;
2879     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2880     ASSERT_VK_SUCCESS(err);
2881 
2882     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
2883 
2884     mem_alloc.allocationSize = mem_reqs.size;
2885     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
2886     ASSERT_TRUE(pass);
2887 
2888     // allocate 2 memory objects
2889     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem1);
2890     ASSERT_VK_SUCCESS(err);
2891     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem2);
2892     ASSERT_VK_SUCCESS(err);
2893 
2894     // Bind first memory object to Image object
2895     err = vkBindImageMemory(m_device->device(), image, mem1, 0);
2896     ASSERT_VK_SUCCESS(err);
2897 
2898     // Introduce validation failure, try to bind a different memory object to
2899     // the same image object
2900     err = vkBindImageMemory(m_device->device(), image, mem2, 0);
2901 
2902     m_errorMonitor->VerifyFound();
2903 
2904     vkDestroyImage(m_device->device(), image, NULL);
2905     vkFreeMemory(m_device->device(), mem1, NULL);
2906     vkFreeMemory(m_device->device(), mem2, NULL);
2907 }
2908 
TEST_F(VkLayerTest,QueryMemoryCommitmentWithoutLazyProperty)2909 TEST_F(VkLayerTest, QueryMemoryCommitmentWithoutLazyProperty) {
2910     TEST_DESCRIPTION("Attempt to query memory commitment on memory without lazy allocation");
2911     ASSERT_NO_FATAL_FAILURE(Init());
2912 
2913     auto image_ci = vk_testing::Image::create_info();
2914     image_ci.imageType = VK_IMAGE_TYPE_2D;
2915     image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
2916     image_ci.extent.width = 32;
2917     image_ci.extent.height = 32;
2918     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2919     image_ci.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2920     vk_testing::Image image;
2921     image.init_no_mem(*m_device, image_ci);
2922 
2923     auto mem_reqs = image.memory_requirements();
2924     // memory_type_index is set to 0 here, but is set properly below
2925     auto image_alloc_info = vk_testing::DeviceMemory::alloc_info(mem_reqs.size, 0);
2926 
2927     bool pass;
2928     // the last argument is the "forbid" argument for set_memory_type, disallowing
2929     // that particular memory type rather than requiring it
2930     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &image_alloc_info, 0, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT);
2931     if (!pass) {
2932         printf("%s Failed to set memory type.\n", kSkipPrefix);
2933         return;
2934     }
2935     vk_testing::DeviceMemory mem;
2936     mem.init(*m_device, image_alloc_info);
2937 
2938     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkGetDeviceMemoryCommitment-memory-00690");
2939     VkDeviceSize size;
2940     vkGetDeviceMemoryCommitment(m_device->device(), mem.handle(), &size);
2941     m_errorMonitor->VerifyFound();
2942 }
2943 
TEST_F(VkLayerTest,SubmitSignaledFence)2944 TEST_F(VkLayerTest, SubmitSignaledFence) {
2945     vk_testing::Fence testFence;
2946 
2947     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2948                                          "submitted in SIGNALED state.  Fences must be reset before being submitted");
2949 
2950     VkFenceCreateInfo fenceInfo = {};
2951     fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
2952     fenceInfo.pNext = NULL;
2953     fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
2954 
2955     ASSERT_NO_FATAL_FAILURE(Init());
2956     ASSERT_NO_FATAL_FAILURE(InitViewport());
2957     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2958 
2959     m_commandBuffer->begin();
2960     m_commandBuffer->ClearAllBuffers(m_renderTargets, m_clear_color, nullptr, m_depth_clear_color, m_stencil_clear_color);
2961     m_commandBuffer->end();
2962 
2963     testFence.init(*m_device, fenceInfo);
2964 
2965     VkSubmitInfo submit_info;
2966     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2967     submit_info.pNext = NULL;
2968     submit_info.waitSemaphoreCount = 0;
2969     submit_info.pWaitSemaphores = NULL;
2970     submit_info.pWaitDstStageMask = NULL;
2971     submit_info.commandBufferCount = 1;
2972     submit_info.pCommandBuffers = &m_commandBuffer->handle();
2973     submit_info.signalSemaphoreCount = 0;
2974     submit_info.pSignalSemaphores = NULL;
2975 
2976     vkQueueSubmit(m_device->m_queue, 1, &submit_info, testFence.handle());
2977     vkQueueWaitIdle(m_device->m_queue);
2978 
2979     m_errorMonitor->VerifyFound();
2980 }
2981 
TEST_F(VkLayerTest,InvalidUsageBits)2982 TEST_F(VkLayerTest, InvalidUsageBits) {
2983     TEST_DESCRIPTION(
2984         "Specify wrong usage for image then create conflicting view of image Initialize buffer with wrong usage then perform copy "
2985         "expecting errors from both the image and the buffer (2 calls)");
2986 
2987     ASSERT_NO_FATAL_FAILURE(Init());
2988     auto format = FindSupportedDepthStencilFormat(gpu());
2989     if (!format) {
2990         printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
2991         return;
2992     }
2993 
2994     VkImageObj image(m_device);
2995     // Initialize image with transfer source usage
2996     image.Init(128, 128, 1, format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
2997     ASSERT_TRUE(image.initialized());
2998 
2999     VkImageView dsv;
3000     VkImageViewCreateInfo dsvci = {};
3001     dsvci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
3002     dsvci.image = image.handle();
3003     dsvci.viewType = VK_IMAGE_VIEW_TYPE_2D;
3004     dsvci.format = format;
3005     dsvci.subresourceRange.layerCount = 1;
3006     dsvci.subresourceRange.baseMipLevel = 0;
3007     dsvci.subresourceRange.levelCount = 1;
3008     dsvci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
3009 
3010     // Create a view with depth / stencil aspect for image with different usage
3011     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid usage flag for Image ");
3012     vkCreateImageView(m_device->device(), &dsvci, NULL, &dsv);
3013     m_errorMonitor->VerifyFound();
3014 
3015     // Initialize buffer with TRANSFER_DST usage
3016     VkBufferObj buffer;
3017     VkMemoryPropertyFlags reqs = 0;
3018     buffer.init_as_dst(*m_device, 128 * 128, reqs);
3019     VkBufferImageCopy region = {};
3020     region.bufferRowLength = 128;
3021     region.bufferImageHeight = 128;
3022     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3023     region.imageSubresource.layerCount = 1;
3024     region.imageExtent.height = 16;
3025     region.imageExtent.width = 16;
3026     region.imageExtent.depth = 1;
3027 
3028     // Buffer usage not set to TRANSFER_SRC and image usage not set to TRANSFER_DST
3029     m_commandBuffer->begin();
3030 
3031     // two separate errors from this call:
3032     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyBufferToImage-dstImage-00177");
3033     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyBufferToImage-srcBuffer-00174");
3034 
3035     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
3036                            &region);
3037     m_errorMonitor->VerifyFound();
3038 }
3039 
TEST_F(VkLayerTest,LeakAnObject)3040 TEST_F(VkLayerTest, LeakAnObject) {
3041     VkResult err;
3042 
3043     TEST_DESCRIPTION("Create a fence and destroy its device without first destroying the fence.");
3044 
3045     // Note that we have to create a new device since destroying the
3046     // framework's device causes Teardown() to fail and just calling Teardown
3047     // will destroy the errorMonitor.
3048 
3049     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "has not been destroyed.");
3050 
3051     ASSERT_NO_FATAL_FAILURE(Init());
3052 
3053     vk_testing::QueueCreateInfoArray queue_info(m_device->queue_props);
3054 
3055     // The sacrificial device object
3056     VkDevice testDevice;
3057     VkDeviceCreateInfo device_create_info = {};
3058     auto features = m_device->phy().features();
3059     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
3060     device_create_info.pNext = NULL;
3061     device_create_info.queueCreateInfoCount = queue_info.size();
3062     device_create_info.pQueueCreateInfos = queue_info.data();
3063     device_create_info.enabledLayerCount = 0;
3064     device_create_info.ppEnabledLayerNames = NULL;
3065     device_create_info.pEnabledFeatures = &features;
3066     err = vkCreateDevice(gpu(), &device_create_info, NULL, &testDevice);
3067     ASSERT_VK_SUCCESS(err);
3068 
3069     VkFence fence;
3070     VkFenceCreateInfo fence_create_info = {};
3071     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
3072     fence_create_info.pNext = NULL;
3073     fence_create_info.flags = 0;
3074     err = vkCreateFence(testDevice, &fence_create_info, NULL, &fence);
3075     ASSERT_VK_SUCCESS(err);
3076 
3077     // Induce failure by not calling vkDestroyFence
3078     vkDestroyDevice(testDevice, NULL);
3079     m_errorMonitor->VerifyFound();
3080 }
3081 
TEST_F(VkLayerTest,InvalidCommandPoolConsistency)3082 TEST_F(VkLayerTest, InvalidCommandPoolConsistency) {
3083     TEST_DESCRIPTION("Allocate command buffers from one command pool and attempt to delete them from another.");
3084 
3085     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "FreeCommandBuffers is attempting to free Command Buffer");
3086 
3087     ASSERT_NO_FATAL_FAILURE(Init());
3088     VkCommandPool command_pool_one;
3089     VkCommandPool command_pool_two;
3090 
3091     VkCommandPoolCreateInfo pool_create_info{};
3092     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
3093     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
3094     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
3095 
3096     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_one);
3097 
3098     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_two);
3099 
3100     VkCommandBuffer cb;
3101     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
3102     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
3103     command_buffer_allocate_info.commandPool = command_pool_one;
3104     command_buffer_allocate_info.commandBufferCount = 1;
3105     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
3106     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &cb);
3107 
3108     vkFreeCommandBuffers(m_device->device(), command_pool_two, 1, &cb);
3109 
3110     m_errorMonitor->VerifyFound();
3111 
3112     vkDestroyCommandPool(m_device->device(), command_pool_one, NULL);
3113     vkDestroyCommandPool(m_device->device(), command_pool_two, NULL);
3114 }
3115 
TEST_F(VkLayerTest,InvalidDescriptorPoolConsistency)3116 TEST_F(VkLayerTest, InvalidDescriptorPoolConsistency) {
3117     VkResult err;
3118 
3119     TEST_DESCRIPTION("Allocate descriptor sets from one DS pool and attempt to delete them from another.");
3120 
3121     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "FreeDescriptorSets is attempting to free descriptorSet");
3122 
3123     ASSERT_NO_FATAL_FAILURE(Init());
3124     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3125 
3126     VkDescriptorPoolSize ds_type_count = {};
3127     ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
3128     ds_type_count.descriptorCount = 1;
3129 
3130     VkDescriptorPoolCreateInfo ds_pool_ci = {};
3131     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
3132     ds_pool_ci.pNext = NULL;
3133     ds_pool_ci.flags = 0;
3134     ds_pool_ci.maxSets = 1;
3135     ds_pool_ci.poolSizeCount = 1;
3136     ds_pool_ci.pPoolSizes = &ds_type_count;
3137 
3138     VkDescriptorPool bad_pool;
3139     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &bad_pool);
3140     ASSERT_VK_SUCCESS(err);
3141 
3142     OneOffDescriptorSet ds(m_device, {
3143                                          {0, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
3144                                      });
3145 
3146     err = vkFreeDescriptorSets(m_device->device(), bad_pool, 1, &ds.set_);
3147 
3148     m_errorMonitor->VerifyFound();
3149 
3150     vkDestroyDescriptorPool(m_device->device(), bad_pool, NULL);
3151 }
3152 
TEST_F(VkLayerTest,CreateUnknownObject)3153 TEST_F(VkLayerTest, CreateUnknownObject) {
3154     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkGetImageMemoryRequirements-image-parameter");
3155 
3156     TEST_DESCRIPTION("Pass an invalid image object handle into a Vulkan API call.");
3157 
3158     ASSERT_NO_FATAL_FAILURE(Init());
3159 
3160     // Pass bogus handle into GetImageMemoryRequirements
3161     VkMemoryRequirements mem_reqs;
3162     uint64_t fakeImageHandle = 0xCADECADE;
3163     VkImage fauxImage = reinterpret_cast<VkImage &>(fakeImageHandle);
3164 
3165     vkGetImageMemoryRequirements(m_device->device(), fauxImage, &mem_reqs);
3166 
3167     m_errorMonitor->VerifyFound();
3168 }
3169 
TEST_F(VkLayerTest,UseObjectWithWrongDevice)3170 TEST_F(VkLayerTest, UseObjectWithWrongDevice) {
3171     TEST_DESCRIPTION(
3172         "Try to destroy a render pass object using a device other than the one it was created on. This should generate a distinct "
3173         "error from the invalid handle error.");
3174     // Create first device and renderpass
3175     ASSERT_NO_FATAL_FAILURE(Init());
3176     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3177 
3178     // Create second device
3179     float priorities[] = {1.0f};
3180     VkDeviceQueueCreateInfo queue_info{};
3181     queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
3182     queue_info.pNext = NULL;
3183     queue_info.flags = 0;
3184     queue_info.queueFamilyIndex = 0;
3185     queue_info.queueCount = 1;
3186     queue_info.pQueuePriorities = &priorities[0];
3187 
3188     VkDeviceCreateInfo device_create_info = {};
3189     auto features = m_device->phy().features();
3190     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
3191     device_create_info.pNext = NULL;
3192     device_create_info.queueCreateInfoCount = 1;
3193     device_create_info.pQueueCreateInfos = &queue_info;
3194     device_create_info.enabledLayerCount = 0;
3195     device_create_info.ppEnabledLayerNames = NULL;
3196     device_create_info.pEnabledFeatures = &features;
3197 
3198     VkDevice second_device;
3199     ASSERT_VK_SUCCESS(vkCreateDevice(gpu(), &device_create_info, NULL, &second_device));
3200 
3201     // Try to destroy the renderpass from the first device using the second device
3202     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyRenderPass-renderPass-parent");
3203     vkDestroyRenderPass(second_device, m_renderPass, NULL);
3204     m_errorMonitor->VerifyFound();
3205 
3206     vkDestroyDevice(second_device, NULL);
3207 }
3208 
TEST_F(VkLayerTest,PipelineNotBound)3209 TEST_F(VkLayerTest, PipelineNotBound) {
3210     TEST_DESCRIPTION("Pass in an invalid pipeline object handle into a Vulkan API call.");
3211 
3212     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBindPipeline-pipeline-parameter");
3213 
3214     ASSERT_NO_FATAL_FAILURE(Init());
3215     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3216 
3217     VkPipeline badPipeline = (VkPipeline)((size_t)0xbaadb1be);
3218 
3219     m_commandBuffer->begin();
3220     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
3221 
3222     m_errorMonitor->VerifyFound();
3223 }
3224 
TEST_F(VkLayerTest,BindImageInvalidMemoryType)3225 TEST_F(VkLayerTest, BindImageInvalidMemoryType) {
3226     VkResult err;
3227 
3228     TEST_DESCRIPTION("Test validation check for an invalid memory type index during bind[Buffer|Image]Memory time");
3229 
3230     ASSERT_NO_FATAL_FAILURE(Init());
3231 
3232     // Create an image, allocate memory, set a bad typeIndex and then try to
3233     // bind it
3234     VkImage image;
3235     VkDeviceMemory mem;
3236     VkMemoryRequirements mem_reqs;
3237     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
3238     const int32_t tex_width = 32;
3239     const int32_t tex_height = 32;
3240 
3241     VkImageCreateInfo image_create_info = {};
3242     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3243     image_create_info.pNext = NULL;
3244     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3245     image_create_info.format = tex_format;
3246     image_create_info.extent.width = tex_width;
3247     image_create_info.extent.height = tex_height;
3248     image_create_info.extent.depth = 1;
3249     image_create_info.mipLevels = 1;
3250     image_create_info.arrayLayers = 1;
3251     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3252     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3253     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3254     image_create_info.flags = 0;
3255 
3256     VkMemoryAllocateInfo mem_alloc = {};
3257     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3258     mem_alloc.pNext = NULL;
3259     mem_alloc.allocationSize = 0;
3260     mem_alloc.memoryTypeIndex = 0;
3261 
3262     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
3263     ASSERT_VK_SUCCESS(err);
3264 
3265     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
3266     mem_alloc.allocationSize = mem_reqs.size;
3267 
3268     // Introduce Failure, select invalid TypeIndex
3269     VkPhysicalDeviceMemoryProperties memory_info;
3270 
3271     vkGetPhysicalDeviceMemoryProperties(gpu(), &memory_info);
3272     unsigned int i;
3273     for (i = 0; i < memory_info.memoryTypeCount; i++) {
3274         if ((mem_reqs.memoryTypeBits & (1 << i)) == 0) {
3275             mem_alloc.memoryTypeIndex = i;
3276             break;
3277         }
3278     }
3279     if (i >= memory_info.memoryTypeCount) {
3280         printf("%s No invalid memory type index could be found; skipped.\n", kSkipPrefix);
3281         vkDestroyImage(m_device->device(), image, NULL);
3282         return;
3283     }
3284 
3285     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "for this object type are not compatible with the memory");
3286 
3287     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
3288     ASSERT_VK_SUCCESS(err);
3289 
3290     err = vkBindImageMemory(m_device->device(), image, mem, 0);
3291     (void)err;
3292 
3293     m_errorMonitor->VerifyFound();
3294 
3295     vkDestroyImage(m_device->device(), image, NULL);
3296     vkFreeMemory(m_device->device(), mem, NULL);
3297 }
3298 
TEST_F(VkLayerTest,BindInvalidMemory)3299 TEST_F(VkLayerTest, BindInvalidMemory) {
3300     VkResult err;
3301     bool pass;
3302 
3303     ASSERT_NO_FATAL_FAILURE(Init());
3304 
3305     const VkFormat tex_format = VK_FORMAT_R8G8B8A8_UNORM;
3306     const int32_t tex_width = 256;
3307     const int32_t tex_height = 256;
3308 
3309     VkImageCreateInfo image_create_info = {};
3310     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3311     image_create_info.pNext = NULL;
3312     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3313     image_create_info.format = tex_format;
3314     image_create_info.extent.width = tex_width;
3315     image_create_info.extent.height = tex_height;
3316     image_create_info.extent.depth = 1;
3317     image_create_info.mipLevels = 1;
3318     image_create_info.arrayLayers = 1;
3319     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3320     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3321     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3322     image_create_info.flags = 0;
3323 
3324     VkBufferCreateInfo buffer_create_info = {};
3325     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
3326     buffer_create_info.pNext = NULL;
3327     buffer_create_info.flags = 0;
3328     buffer_create_info.size = 4 * 1024 * 1024;
3329     buffer_create_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
3330     buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
3331 
3332     // Create an image/buffer, allocate memory, free it, and then try to bind it
3333     {
3334         VkImage image = VK_NULL_HANDLE;
3335         VkBuffer buffer = VK_NULL_HANDLE;
3336         err = vkCreateImage(device(), &image_create_info, NULL, &image);
3337         ASSERT_VK_SUCCESS(err);
3338         err = vkCreateBuffer(device(), &buffer_create_info, NULL, &buffer);
3339         ASSERT_VK_SUCCESS(err);
3340         VkMemoryRequirements image_mem_reqs = {}, buffer_mem_reqs = {};
3341         vkGetImageMemoryRequirements(device(), image, &image_mem_reqs);
3342         vkGetBufferMemoryRequirements(device(), buffer, &buffer_mem_reqs);
3343 
3344         VkMemoryAllocateInfo image_mem_alloc = {}, buffer_mem_alloc = {};
3345         image_mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3346         image_mem_alloc.allocationSize = image_mem_reqs.size;
3347         pass = m_device->phy().set_memory_type(image_mem_reqs.memoryTypeBits, &image_mem_alloc, 0);
3348         ASSERT_TRUE(pass);
3349         buffer_mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3350         buffer_mem_alloc.allocationSize = buffer_mem_reqs.size;
3351         pass = m_device->phy().set_memory_type(buffer_mem_reqs.memoryTypeBits, &buffer_mem_alloc, 0);
3352         ASSERT_TRUE(pass);
3353 
3354         VkDeviceMemory image_mem = VK_NULL_HANDLE, buffer_mem = VK_NULL_HANDLE;
3355         err = vkAllocateMemory(device(), &image_mem_alloc, NULL, &image_mem);
3356         ASSERT_VK_SUCCESS(err);
3357         err = vkAllocateMemory(device(), &buffer_mem_alloc, NULL, &buffer_mem);
3358         ASSERT_VK_SUCCESS(err);
3359 
3360         vkFreeMemory(device(), image_mem, NULL);
3361         vkFreeMemory(device(), buffer_mem, NULL);
3362 
3363         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkBindImageMemory-memory-parameter");
3364         err = vkBindImageMemory(device(), image, image_mem, 0);
3365         (void)err;  // This may very well return an error.
3366         m_errorMonitor->VerifyFound();
3367 
3368         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkBindBufferMemory-memory-parameter");
3369         err = vkBindBufferMemory(device(), buffer, buffer_mem, 0);
3370         (void)err;  // This may very well return an error.
3371         m_errorMonitor->VerifyFound();
3372 
3373         vkDestroyImage(m_device->device(), image, NULL);
3374         vkDestroyBuffer(m_device->device(), buffer, NULL);
3375     }
3376 
3377     // Try to bind memory to an object that already has a memory binding
3378     {
3379         VkImage image = VK_NULL_HANDLE;
3380         err = vkCreateImage(device(), &image_create_info, NULL, &image);
3381         ASSERT_VK_SUCCESS(err);
3382         VkBuffer buffer = VK_NULL_HANDLE;
3383         err = vkCreateBuffer(device(), &buffer_create_info, NULL, &buffer);
3384         ASSERT_VK_SUCCESS(err);
3385         VkMemoryRequirements image_mem_reqs = {}, buffer_mem_reqs = {};
3386         vkGetImageMemoryRequirements(device(), image, &image_mem_reqs);
3387         vkGetBufferMemoryRequirements(device(), buffer, &buffer_mem_reqs);
3388         VkMemoryAllocateInfo image_alloc_info = {}, buffer_alloc_info = {};
3389         image_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3390         image_alloc_info.allocationSize = image_mem_reqs.size;
3391         buffer_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3392         buffer_alloc_info.allocationSize = buffer_mem_reqs.size;
3393         pass = m_device->phy().set_memory_type(image_mem_reqs.memoryTypeBits, &image_alloc_info, 0);
3394         ASSERT_TRUE(pass);
3395         pass = m_device->phy().set_memory_type(buffer_mem_reqs.memoryTypeBits, &buffer_alloc_info, 0);
3396         ASSERT_TRUE(pass);
3397         VkDeviceMemory image_mem, buffer_mem;
3398         err = vkAllocateMemory(device(), &image_alloc_info, NULL, &image_mem);
3399         ASSERT_VK_SUCCESS(err);
3400         err = vkAllocateMemory(device(), &buffer_alloc_info, NULL, &buffer_mem);
3401         ASSERT_VK_SUCCESS(err);
3402 
3403         err = vkBindImageMemory(device(), image, image_mem, 0);
3404         ASSERT_VK_SUCCESS(err);
3405         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkBindImageMemory-image-01044");
3406         err = vkBindImageMemory(device(), image, image_mem, 0);
3407         (void)err;  // This may very well return an error.
3408         m_errorMonitor->VerifyFound();
3409 
3410         err = vkBindBufferMemory(device(), buffer, buffer_mem, 0);
3411         ASSERT_VK_SUCCESS(err);
3412         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkBindBufferMemory-buffer-01029");
3413         err = vkBindBufferMemory(device(), buffer, buffer_mem, 0);
3414         (void)err;  // This may very well return an error.
3415         m_errorMonitor->VerifyFound();
3416 
3417         vkFreeMemory(device(), image_mem, NULL);
3418         vkFreeMemory(device(), buffer_mem, NULL);
3419         vkDestroyImage(device(), image, NULL);
3420         vkDestroyBuffer(device(), buffer, NULL);
3421     }
3422 
3423     // Try to bind memory to an object with an invalid memoryOffset
3424     {
3425         VkImage image = VK_NULL_HANDLE;
3426         err = vkCreateImage(device(), &image_create_info, NULL, &image);
3427         ASSERT_VK_SUCCESS(err);
3428         VkBuffer buffer = VK_NULL_HANDLE;
3429         err = vkCreateBuffer(device(), &buffer_create_info, NULL, &buffer);
3430         ASSERT_VK_SUCCESS(err);
3431         VkMemoryRequirements image_mem_reqs = {}, buffer_mem_reqs = {};
3432         vkGetImageMemoryRequirements(device(), image, &image_mem_reqs);
3433         vkGetBufferMemoryRequirements(device(), buffer, &buffer_mem_reqs);
3434         VkMemoryAllocateInfo image_alloc_info = {}, buffer_alloc_info = {};
3435         image_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3436         // Leave some extra space for alignment wiggle room
3437         image_alloc_info.allocationSize = image_mem_reqs.size + image_mem_reqs.alignment;
3438         buffer_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3439         buffer_alloc_info.allocationSize = buffer_mem_reqs.size + buffer_mem_reqs.alignment;
3440         pass = m_device->phy().set_memory_type(image_mem_reqs.memoryTypeBits, &image_alloc_info, 0);
3441         ASSERT_TRUE(pass);
3442         pass = m_device->phy().set_memory_type(buffer_mem_reqs.memoryTypeBits, &buffer_alloc_info, 0);
3443         ASSERT_TRUE(pass);
3444         VkDeviceMemory image_mem, buffer_mem;
3445         err = vkAllocateMemory(device(), &image_alloc_info, NULL, &image_mem);
3446         ASSERT_VK_SUCCESS(err);
3447         err = vkAllocateMemory(device(), &buffer_alloc_info, NULL, &buffer_mem);
3448         ASSERT_VK_SUCCESS(err);
3449 
3450         // Test unaligned memory offset
3451         {
3452             if (image_mem_reqs.alignment > 1) {
3453                 VkDeviceSize image_offset = 1;
3454                 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkBindImageMemory-memoryOffset-01048");
3455                 err = vkBindImageMemory(device(), image, image_mem, image_offset);
3456                 (void)err;  // This may very well return an error.
3457                 m_errorMonitor->VerifyFound();
3458             }
3459 
3460             if (buffer_mem_reqs.alignment > 1) {
3461                 VkDeviceSize buffer_offset = 1;
3462                 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkBindBufferMemory-memoryOffset-01036");
3463                 err = vkBindBufferMemory(device(), buffer, buffer_mem, buffer_offset);
3464                 (void)err;  // This may very well return an error.
3465                 m_errorMonitor->VerifyFound();
3466             }
3467         }
3468 
3469         // Test memory offsets outside the memory allocation
3470         {
3471             VkDeviceSize image_offset =
3472                 (image_alloc_info.allocationSize + image_mem_reqs.alignment) & ~(image_mem_reqs.alignment - 1);
3473             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkBindImageMemory-memoryOffset-01046");
3474             err = vkBindImageMemory(device(), image, image_mem, image_offset);
3475             (void)err;  // This may very well return an error.
3476             m_errorMonitor->VerifyFound();
3477 
3478             VkDeviceSize buffer_offset =
3479                 (buffer_alloc_info.allocationSize + buffer_mem_reqs.alignment) & ~(buffer_mem_reqs.alignment - 1);
3480             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkBindBufferMemory-memoryOffset-01031");
3481             err = vkBindBufferMemory(device(), buffer, buffer_mem, buffer_offset);
3482             (void)err;  // This may very well return an error.
3483             m_errorMonitor->VerifyFound();
3484         }
3485 
3486         // Test memory offsets within the memory allocation, but which leave too little memory for
3487         // the resource.
3488         {
3489             VkDeviceSize image_offset = (image_mem_reqs.size - 1) & ~(image_mem_reqs.alignment - 1);
3490             if ((image_offset > 0) && (image_mem_reqs.size < (image_alloc_info.allocationSize - image_mem_reqs.alignment))) {
3491                 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkBindImageMemory-size-01049");
3492                 err = vkBindImageMemory(device(), image, image_mem, image_offset);
3493                 (void)err;  // This may very well return an error.
3494                 m_errorMonitor->VerifyFound();
3495             }
3496 
3497             VkDeviceSize buffer_offset = (buffer_mem_reqs.size - 1) & ~(buffer_mem_reqs.alignment - 1);
3498             if (buffer_offset > 0) {
3499                 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkBindBufferMemory-size-01037");
3500                 err = vkBindBufferMemory(device(), buffer, buffer_mem, buffer_offset);
3501                 (void)err;  // This may very well return an error.
3502                 m_errorMonitor->VerifyFound();
3503             }
3504         }
3505 
3506         vkFreeMemory(device(), image_mem, NULL);
3507         vkFreeMemory(device(), buffer_mem, NULL);
3508         vkDestroyImage(device(), image, NULL);
3509         vkDestroyBuffer(device(), buffer, NULL);
3510     }
3511 
3512     // Try to bind memory to an object with an invalid memory type
3513     {
3514         VkImage image = VK_NULL_HANDLE;
3515         err = vkCreateImage(device(), &image_create_info, NULL, &image);
3516         ASSERT_VK_SUCCESS(err);
3517         VkBuffer buffer = VK_NULL_HANDLE;
3518         err = vkCreateBuffer(device(), &buffer_create_info, NULL, &buffer);
3519         ASSERT_VK_SUCCESS(err);
3520         VkMemoryRequirements image_mem_reqs = {}, buffer_mem_reqs = {};
3521         vkGetImageMemoryRequirements(device(), image, &image_mem_reqs);
3522         vkGetBufferMemoryRequirements(device(), buffer, &buffer_mem_reqs);
3523         VkMemoryAllocateInfo image_alloc_info = {}, buffer_alloc_info = {};
3524         image_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3525         image_alloc_info.allocationSize = image_mem_reqs.size;
3526         buffer_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3527         buffer_alloc_info.allocationSize = buffer_mem_reqs.size;
3528         // Create a mask of available memory types *not* supported by these resources,
3529         // and try to use one of them.
3530         VkPhysicalDeviceMemoryProperties memory_properties = {};
3531         vkGetPhysicalDeviceMemoryProperties(m_device->phy().handle(), &memory_properties);
3532         VkDeviceMemory image_mem, buffer_mem;
3533 
3534         uint32_t image_unsupported_mem_type_bits = ((1 << memory_properties.memoryTypeCount) - 1) & ~image_mem_reqs.memoryTypeBits;
3535         if (image_unsupported_mem_type_bits != 0) {
3536             pass = m_device->phy().set_memory_type(image_unsupported_mem_type_bits, &image_alloc_info, 0);
3537             ASSERT_TRUE(pass);
3538             err = vkAllocateMemory(device(), &image_alloc_info, NULL, &image_mem);
3539             ASSERT_VK_SUCCESS(err);
3540             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkBindImageMemory-memory-01047");
3541             err = vkBindImageMemory(device(), image, image_mem, 0);
3542             (void)err;  // This may very well return an error.
3543             m_errorMonitor->VerifyFound();
3544             vkFreeMemory(device(), image_mem, NULL);
3545         }
3546 
3547         uint32_t buffer_unsupported_mem_type_bits =
3548             ((1 << memory_properties.memoryTypeCount) - 1) & ~buffer_mem_reqs.memoryTypeBits;
3549         if (buffer_unsupported_mem_type_bits != 0) {
3550             pass = m_device->phy().set_memory_type(buffer_unsupported_mem_type_bits, &buffer_alloc_info, 0);
3551             ASSERT_TRUE(pass);
3552             err = vkAllocateMemory(device(), &buffer_alloc_info, NULL, &buffer_mem);
3553             ASSERT_VK_SUCCESS(err);
3554             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkBindBufferMemory-memory-01035");
3555             err = vkBindBufferMemory(device(), buffer, buffer_mem, 0);
3556             (void)err;  // This may very well return an error.
3557             m_errorMonitor->VerifyFound();
3558             vkFreeMemory(device(), buffer_mem, NULL);
3559         }
3560 
3561         vkDestroyImage(device(), image, NULL);
3562         vkDestroyBuffer(device(), buffer, NULL);
3563     }
3564 
3565     // Try to bind memory to an image created with sparse memory flags
3566     {
3567         VkImageCreateInfo sparse_image_create_info = image_create_info;
3568         sparse_image_create_info.flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
3569         VkImageFormatProperties image_format_properties = {};
3570         err = vkGetPhysicalDeviceImageFormatProperties(m_device->phy().handle(), sparse_image_create_info.format,
3571                                                        sparse_image_create_info.imageType, sparse_image_create_info.tiling,
3572                                                        sparse_image_create_info.usage, sparse_image_create_info.flags,
3573                                                        &image_format_properties);
3574         if (!m_device->phy().features().sparseResidencyImage2D || err == VK_ERROR_FORMAT_NOT_SUPPORTED) {
3575             // most likely means sparse formats aren't supported here; skip this test.
3576         } else {
3577             ASSERT_VK_SUCCESS(err);
3578             if (image_format_properties.maxExtent.width == 0) {
3579                 printf("%s Sparse image format not supported; skipped.\n", kSkipPrefix);
3580                 return;
3581             } else {
3582                 VkImage sparse_image = VK_NULL_HANDLE;
3583                 err = vkCreateImage(m_device->device(), &sparse_image_create_info, NULL, &sparse_image);
3584                 ASSERT_VK_SUCCESS(err);
3585                 VkMemoryRequirements sparse_mem_reqs = {};
3586                 vkGetImageMemoryRequirements(m_device->device(), sparse_image, &sparse_mem_reqs);
3587                 if (sparse_mem_reqs.memoryTypeBits != 0) {
3588                     VkMemoryAllocateInfo sparse_mem_alloc = {};
3589                     sparse_mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3590                     sparse_mem_alloc.pNext = NULL;
3591                     sparse_mem_alloc.allocationSize = sparse_mem_reqs.size;
3592                     sparse_mem_alloc.memoryTypeIndex = 0;
3593                     pass = m_device->phy().set_memory_type(sparse_mem_reqs.memoryTypeBits, &sparse_mem_alloc, 0);
3594                     ASSERT_TRUE(pass);
3595                     VkDeviceMemory sparse_mem = VK_NULL_HANDLE;
3596                     err = vkAllocateMemory(m_device->device(), &sparse_mem_alloc, NULL, &sparse_mem);
3597                     ASSERT_VK_SUCCESS(err);
3598                     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkBindImageMemory-image-01045");
3599                     err = vkBindImageMemory(m_device->device(), sparse_image, sparse_mem, 0);
3600                     // This may very well return an error.
3601                     (void)err;
3602                     m_errorMonitor->VerifyFound();
3603                     vkFreeMemory(m_device->device(), sparse_mem, NULL);
3604                 }
3605                 vkDestroyImage(m_device->device(), sparse_image, NULL);
3606             }
3607         }
3608     }
3609 
3610     // Try to bind memory to a buffer created with sparse memory flags
3611     {
3612         VkBufferCreateInfo sparse_buffer_create_info = buffer_create_info;
3613         sparse_buffer_create_info.flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
3614         if (!m_device->phy().features().sparseResidencyBuffer) {
3615             // most likely means sparse formats aren't supported here; skip this test.
3616         } else {
3617             VkBuffer sparse_buffer = VK_NULL_HANDLE;
3618             err = vkCreateBuffer(m_device->device(), &sparse_buffer_create_info, NULL, &sparse_buffer);
3619             ASSERT_VK_SUCCESS(err);
3620             VkMemoryRequirements sparse_mem_reqs = {};
3621             vkGetBufferMemoryRequirements(m_device->device(), sparse_buffer, &sparse_mem_reqs);
3622             if (sparse_mem_reqs.memoryTypeBits != 0) {
3623                 VkMemoryAllocateInfo sparse_mem_alloc = {};
3624                 sparse_mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3625                 sparse_mem_alloc.pNext = NULL;
3626                 sparse_mem_alloc.allocationSize = sparse_mem_reqs.size;
3627                 sparse_mem_alloc.memoryTypeIndex = 0;
3628                 pass = m_device->phy().set_memory_type(sparse_mem_reqs.memoryTypeBits, &sparse_mem_alloc, 0);
3629                 ASSERT_TRUE(pass);
3630                 VkDeviceMemory sparse_mem = VK_NULL_HANDLE;
3631                 err = vkAllocateMemory(m_device->device(), &sparse_mem_alloc, NULL, &sparse_mem);
3632                 ASSERT_VK_SUCCESS(err);
3633                 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkBindBufferMemory-buffer-01030");
3634                 err = vkBindBufferMemory(m_device->device(), sparse_buffer, sparse_mem, 0);
3635                 // This may very well return an error.
3636                 (void)err;
3637                 m_errorMonitor->VerifyFound();
3638                 vkFreeMemory(m_device->device(), sparse_mem, NULL);
3639             }
3640             vkDestroyBuffer(m_device->device(), sparse_buffer, NULL);
3641         }
3642     }
3643 }
3644 
TEST_F(VkLayerTest,BindMemoryToDestroyedObject)3645 TEST_F(VkLayerTest, BindMemoryToDestroyedObject) {
3646     VkResult err;
3647     bool pass;
3648 
3649     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkBindImageMemory-image-parameter");
3650 
3651     ASSERT_NO_FATAL_FAILURE(Init());
3652 
3653     // Create an image object, allocate memory, destroy the object and then try
3654     // to bind it
3655     VkImage image;
3656     VkDeviceMemory mem;
3657     VkMemoryRequirements mem_reqs;
3658 
3659     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
3660     const int32_t tex_width = 32;
3661     const int32_t tex_height = 32;
3662 
3663     VkImageCreateInfo image_create_info = {};
3664     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3665     image_create_info.pNext = NULL;
3666     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3667     image_create_info.format = tex_format;
3668     image_create_info.extent.width = tex_width;
3669     image_create_info.extent.height = tex_height;
3670     image_create_info.extent.depth = 1;
3671     image_create_info.mipLevels = 1;
3672     image_create_info.arrayLayers = 1;
3673     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3674     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3675     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3676     image_create_info.flags = 0;
3677 
3678     VkMemoryAllocateInfo mem_alloc = {};
3679     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3680     mem_alloc.pNext = NULL;
3681     mem_alloc.allocationSize = 0;
3682     mem_alloc.memoryTypeIndex = 0;
3683 
3684     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
3685     ASSERT_VK_SUCCESS(err);
3686 
3687     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
3688 
3689     mem_alloc.allocationSize = mem_reqs.size;
3690     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
3691     ASSERT_TRUE(pass);
3692 
3693     // Allocate memory
3694     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
3695     ASSERT_VK_SUCCESS(err);
3696 
3697     // Introduce validation failure, destroy Image object before binding
3698     vkDestroyImage(m_device->device(), image, NULL);
3699     ASSERT_VK_SUCCESS(err);
3700 
3701     // Now Try to bind memory to this destroyed object
3702     err = vkBindImageMemory(m_device->device(), image, mem, 0);
3703     // This may very well return an error.
3704     (void)err;
3705 
3706     m_errorMonitor->VerifyFound();
3707 
3708     vkFreeMemory(m_device->device(), mem, NULL);
3709 }
3710 
TEST_F(VkLayerTest,ExceedMemoryAllocationCount)3711 TEST_F(VkLayerTest, ExceedMemoryAllocationCount) {
3712     VkResult err = VK_SUCCESS;
3713     const int max_mems = 32;
3714     VkDeviceMemory mems[max_mems + 1];
3715 
3716     if (!EnableDeviceProfileLayer()) {
3717         printf("%s Failed to enable device profile layer.\n", kSkipPrefix);
3718         return;
3719     }
3720 
3721     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
3722 
3723     PFN_vkSetPhysicalDeviceLimitsEXT fpvkSetPhysicalDeviceLimitsEXT =
3724         (PFN_vkSetPhysicalDeviceLimitsEXT)vkGetInstanceProcAddr(instance(), "vkSetPhysicalDeviceLimitsEXT");
3725     PFN_vkGetOriginalPhysicalDeviceLimitsEXT fpvkGetOriginalPhysicalDeviceLimitsEXT =
3726         (PFN_vkGetOriginalPhysicalDeviceLimitsEXT)vkGetInstanceProcAddr(instance(), "vkGetOriginalPhysicalDeviceLimitsEXT");
3727 
3728     if (!(fpvkSetPhysicalDeviceLimitsEXT) || !(fpvkGetOriginalPhysicalDeviceLimitsEXT)) {
3729         printf("%s Can't find device_profile_api functions; skipped.\n", kSkipPrefix);
3730         return;
3731     }
3732     VkPhysicalDeviceProperties props;
3733     fpvkGetOriginalPhysicalDeviceLimitsEXT(gpu(), &props.limits);
3734     if (props.limits.maxMemoryAllocationCount > max_mems) {
3735         props.limits.maxMemoryAllocationCount = max_mems;
3736         fpvkSetPhysicalDeviceLimitsEXT(gpu(), &props.limits);
3737     }
3738     ASSERT_NO_FATAL_FAILURE(InitState());
3739     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
3740                                          "Number of currently valid memory objects is not less than the maximum allowed");
3741 
3742     VkMemoryAllocateInfo mem_alloc = {};
3743     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3744     mem_alloc.pNext = NULL;
3745     mem_alloc.memoryTypeIndex = 0;
3746     mem_alloc.allocationSize = 4;
3747 
3748     int i;
3749     for (i = 0; i <= max_mems; i++) {
3750         err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mems[i]);
3751         if (err != VK_SUCCESS) {
3752             break;
3753         }
3754     }
3755     m_errorMonitor->VerifyFound();
3756 
3757     for (int j = 0; j < i; j++) {
3758         vkFreeMemory(m_device->device(), mems[j], NULL);
3759     }
3760 }
3761 
TEST_F(VkLayerTest,CreatePipelineBadVertexAttributeFormat)3762 TEST_F(VkLayerTest, CreatePipelineBadVertexAttributeFormat) {
3763     TEST_DESCRIPTION("Test that pipeline validation catches invalid vertex attribute formats");
3764 
3765     ASSERT_NO_FATAL_FAILURE(Init());
3766     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3767 
3768     VkVertexInputBindingDescription input_binding;
3769     memset(&input_binding, 0, sizeof(input_binding));
3770 
3771     VkVertexInputAttributeDescription input_attribs;
3772     memset(&input_attribs, 0, sizeof(input_attribs));
3773 
3774     // Pick a really bad format for this purpose and make sure it should fail
3775     input_attribs.format = VK_FORMAT_BC2_UNORM_BLOCK;
3776     VkFormatProperties format_props = m_device->format_properties(input_attribs.format);
3777     if ((format_props.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) != 0) {
3778         printf("%s Format unsuitable for test; skipped.\n", kSkipPrefix);
3779         return;
3780     }
3781 
3782     input_attribs.location = 0;
3783     char const *vsSource =
3784         "#version 450\n"
3785         "\n"
3786         "void main(){\n"
3787         "   gl_Position = vec4(1);\n"
3788         "}\n";
3789     char const *fsSource =
3790         "#version 450\n"
3791         "\n"
3792         "layout(location=0) out vec4 color;\n"
3793         "void main(){\n"
3794         "   color = vec4(1);\n"
3795         "}\n";
3796 
3797     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkVertexInputAttributeDescription-format-00623");
3798     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
3799     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
3800 
3801     VkPipelineObj pipe(m_device);
3802     pipe.AddDefaultColorAttachment();
3803     pipe.AddShader(&vs);
3804     pipe.AddShader(&fs);
3805 
3806     pipe.AddVertexInputBindings(&input_binding, 1);
3807     pipe.AddVertexInputAttribs(&input_attribs, 1);
3808 
3809     VkDescriptorSetObj descriptorSet(m_device);
3810     descriptorSet.AppendDummy();
3811     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
3812 
3813     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
3814 
3815     m_errorMonitor->VerifyFound();
3816 }
3817 
TEST_F(VkLayerTest,ImageSampleCounts)3818 TEST_F(VkLayerTest, ImageSampleCounts) {
3819     TEST_DESCRIPTION("Use bad sample counts in image transfer calls to trigger validation errors.");
3820     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
3821 
3822     VkMemoryPropertyFlags reqs = 0;
3823     VkImageCreateInfo image_create_info = {};
3824     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3825     image_create_info.pNext = NULL;
3826     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3827     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3828     image_create_info.extent.width = 256;
3829     image_create_info.extent.height = 256;
3830     image_create_info.extent.depth = 1;
3831     image_create_info.mipLevels = 1;
3832     image_create_info.arrayLayers = 1;
3833     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3834     image_create_info.flags = 0;
3835 
3836     VkImageBlit blit_region = {};
3837     blit_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3838     blit_region.srcSubresource.baseArrayLayer = 0;
3839     blit_region.srcSubresource.layerCount = 1;
3840     blit_region.srcSubresource.mipLevel = 0;
3841     blit_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3842     blit_region.dstSubresource.baseArrayLayer = 0;
3843     blit_region.dstSubresource.layerCount = 1;
3844     blit_region.dstSubresource.mipLevel = 0;
3845     blit_region.srcOffsets[0] = {0, 0, 0};
3846     blit_region.srcOffsets[1] = {256, 256, 1};
3847     blit_region.dstOffsets[0] = {0, 0, 0};
3848     blit_region.dstOffsets[1] = {128, 128, 1};
3849 
3850     // Create two images, the source with sampleCount = 4, and attempt to blit
3851     // between them
3852     {
3853         image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
3854         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3855         VkImageObj src_image(m_device);
3856         src_image.init(&image_create_info);
3857         src_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
3858         image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3859         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3860         VkImageObj dst_image(m_device);
3861         dst_image.init(&image_create_info);
3862         dst_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
3863         m_commandBuffer->begin();
3864         // TODO: These 2 VUs are redundant - expect one of them to go away
3865         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImage-00233");
3866         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImage-00228");
3867         vkCmdBlitImage(m_commandBuffer->handle(), src_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_image.handle(),
3868                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit_region, VK_FILTER_NEAREST);
3869         m_errorMonitor->VerifyFound();
3870         m_commandBuffer->end();
3871     }
3872 
3873     // Create two images, the dest with sampleCount = 4, and attempt to blit
3874     // between them
3875     {
3876         image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3877         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3878         VkImageObj src_image(m_device);
3879         src_image.init(&image_create_info);
3880         src_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
3881         image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
3882         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3883         VkImageObj dst_image(m_device);
3884         dst_image.init(&image_create_info);
3885         dst_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
3886         m_commandBuffer->begin();
3887         // TODO: These 2 VUs are redundant - expect one of them to go away
3888         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-dstImage-00234");
3889         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImage-00228");
3890         vkCmdBlitImage(m_commandBuffer->handle(), src_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_image.handle(),
3891                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit_region, VK_FILTER_NEAREST);
3892         m_errorMonitor->VerifyFound();
3893         m_commandBuffer->end();
3894     }
3895 
3896     VkBufferImageCopy copy_region = {};
3897     copy_region.bufferRowLength = 128;
3898     copy_region.bufferImageHeight = 128;
3899     copy_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3900     copy_region.imageSubresource.layerCount = 1;
3901     copy_region.imageExtent.height = 64;
3902     copy_region.imageExtent.width = 64;
3903     copy_region.imageExtent.depth = 1;
3904 
3905     // Create src buffer and dst image with sampleCount = 4 and attempt to copy
3906     // buffer to image
3907     {
3908         VkBufferObj src_buffer;
3909         src_buffer.init_as_src(*m_device, 128 * 128 * 4, reqs);
3910         image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
3911         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3912         VkImageObj dst_image(m_device);
3913         dst_image.init(&image_create_info);
3914         dst_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
3915         m_commandBuffer->begin();
3916         m_errorMonitor->SetDesiredFailureMsg(
3917             VK_DEBUG_REPORT_ERROR_BIT_EXT,
3918             "was created with a sample count of VK_SAMPLE_COUNT_4_BIT but must be VK_SAMPLE_COUNT_1_BIT");
3919         vkCmdCopyBufferToImage(m_commandBuffer->handle(), src_buffer.handle(), dst_image.handle(),
3920                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copy_region);
3921         m_errorMonitor->VerifyFound();
3922         m_commandBuffer->end();
3923     }
3924 
3925     // Create dst buffer and src image with sampleCount = 4 and attempt to copy
3926     // image to buffer
3927     {
3928         VkBufferObj dst_buffer;
3929         dst_buffer.init_as_dst(*m_device, 128 * 128 * 4, reqs);
3930         image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
3931         image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3932         vk_testing::Image src_image;
3933         src_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
3934         m_commandBuffer->begin();
3935         m_errorMonitor->SetDesiredFailureMsg(
3936             VK_DEBUG_REPORT_ERROR_BIT_EXT,
3937             "was created with a sample count of VK_SAMPLE_COUNT_4_BIT but must be VK_SAMPLE_COUNT_1_BIT");
3938         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), src_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3939                                dst_buffer.handle(), 1, &copy_region);
3940         m_errorMonitor->VerifyFound();
3941         m_commandBuffer->end();
3942     }
3943 }
3944 
TEST_F(VkLayerTest,BlitImageFormatTypes)3945 TEST_F(VkLayerTest, BlitImageFormatTypes) {
3946     ASSERT_NO_FATAL_FAILURE(Init());
3947 
3948     VkFormat f_unsigned = VK_FORMAT_R8G8B8A8_UINT;
3949     VkFormat f_signed = VK_FORMAT_R8G8B8A8_SINT;
3950     VkFormat f_float = VK_FORMAT_R32_SFLOAT;
3951     VkFormat f_depth = VK_FORMAT_D32_SFLOAT_S8_UINT;
3952     VkFormat f_depth2 = VK_FORMAT_D32_SFLOAT;
3953 
3954     if (!ImageFormatIsSupported(gpu(), f_unsigned, VK_IMAGE_TILING_OPTIMAL) ||
3955         !ImageFormatIsSupported(gpu(), f_signed, VK_IMAGE_TILING_OPTIMAL) ||
3956         !ImageFormatIsSupported(gpu(), f_float, VK_IMAGE_TILING_OPTIMAL) ||
3957         !ImageFormatIsSupported(gpu(), f_depth, VK_IMAGE_TILING_OPTIMAL) ||
3958         !ImageFormatIsSupported(gpu(), f_depth2, VK_IMAGE_TILING_OPTIMAL)) {
3959         printf("%s Requested formats not supported - BlitImageFormatTypes skipped.\n", kSkipPrefix);
3960         return;
3961     }
3962 
3963     // Note any missing feature bits
3964     bool usrc = !ImageFormatAndFeaturesSupported(gpu(), f_unsigned, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_SRC_BIT);
3965     bool udst = !ImageFormatAndFeaturesSupported(gpu(), f_unsigned, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_DST_BIT);
3966     bool ssrc = !ImageFormatAndFeaturesSupported(gpu(), f_signed, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_SRC_BIT);
3967     bool sdst = !ImageFormatAndFeaturesSupported(gpu(), f_signed, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_DST_BIT);
3968     bool fsrc = !ImageFormatAndFeaturesSupported(gpu(), f_float, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_SRC_BIT);
3969     bool fdst = !ImageFormatAndFeaturesSupported(gpu(), f_float, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_DST_BIT);
3970     bool d1dst = !ImageFormatAndFeaturesSupported(gpu(), f_depth, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_DST_BIT);
3971     bool d2src = !ImageFormatAndFeaturesSupported(gpu(), f_depth2, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_SRC_BIT);
3972 
3973     VkImageObj unsigned_image(m_device);
3974     unsigned_image.Init(64, 64, 1, f_unsigned, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
3975                         VK_IMAGE_TILING_OPTIMAL, 0);
3976     ASSERT_TRUE(unsigned_image.initialized());
3977     unsigned_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
3978 
3979     VkImageObj signed_image(m_device);
3980     signed_image.Init(64, 64, 1, f_signed, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
3981                       VK_IMAGE_TILING_OPTIMAL, 0);
3982     ASSERT_TRUE(signed_image.initialized());
3983     signed_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
3984 
3985     VkImageObj float_image(m_device);
3986     float_image.Init(64, 64, 1, f_float, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL,
3987                      0);
3988     ASSERT_TRUE(float_image.initialized());
3989     float_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
3990 
3991     VkImageObj depth_image(m_device);
3992     depth_image.Init(64, 64, 1, f_depth, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL,
3993                      0);
3994     ASSERT_TRUE(depth_image.initialized());
3995     depth_image.SetLayout(VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_LAYOUT_GENERAL);
3996 
3997     VkImageObj depth_image2(m_device);
3998     depth_image2.Init(64, 64, 1, f_depth2, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
3999                       VK_IMAGE_TILING_OPTIMAL, 0);
4000     ASSERT_TRUE(depth_image2.initialized());
4001     depth_image2.SetLayout(VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_LAYOUT_GENERAL);
4002 
4003     VkImageBlit blitRegion = {};
4004     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4005     blitRegion.srcSubresource.baseArrayLayer = 0;
4006     blitRegion.srcSubresource.layerCount = 1;
4007     blitRegion.srcSubresource.mipLevel = 0;
4008     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4009     blitRegion.dstSubresource.baseArrayLayer = 0;
4010     blitRegion.dstSubresource.layerCount = 1;
4011     blitRegion.dstSubresource.mipLevel = 0;
4012     blitRegion.srcOffsets[0] = {0, 0, 0};
4013     blitRegion.srcOffsets[1] = {64, 64, 1};
4014     blitRegion.dstOffsets[0] = {0, 0, 0};
4015     blitRegion.dstOffsets[1] = {32, 32, 1};
4016 
4017     m_commandBuffer->begin();
4018 
4019     // Unsigned int vs not an int
4020     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImage-00230");
4021     if (usrc) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImage-01999");
4022     if (fdst) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-dstImage-02000");
4023     vkCmdBlitImage(m_commandBuffer->handle(), unsigned_image.image(), unsigned_image.Layout(), float_image.image(),
4024                    float_image.Layout(), 1, &blitRegion, VK_FILTER_NEAREST);
4025     m_errorMonitor->VerifyFound();
4026     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImage-00230");
4027     if (fsrc) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImage-01999");
4028     if (udst) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-dstImage-02000");
4029     vkCmdBlitImage(m_commandBuffer->handle(), float_image.image(), float_image.Layout(), unsigned_image.image(),
4030                    unsigned_image.Layout(), 1, &blitRegion, VK_FILTER_NEAREST);
4031     m_errorMonitor->VerifyFound();
4032 
4033     // Signed int vs not an int,
4034     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImage-00229");
4035     if (ssrc) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImage-01999");
4036     if (fdst) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-dstImage-02000");
4037     vkCmdBlitImage(m_commandBuffer->handle(), signed_image.image(), signed_image.Layout(), float_image.image(),
4038                    float_image.Layout(), 1, &blitRegion, VK_FILTER_NEAREST);
4039     m_errorMonitor->VerifyFound();
4040     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImage-00229");
4041     if (fsrc) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImage-01999");
4042     if (sdst) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-dstImage-02000");
4043     vkCmdBlitImage(m_commandBuffer->handle(), float_image.image(), float_image.Layout(), signed_image.image(),
4044                    signed_image.Layout(), 1, &blitRegion, VK_FILTER_NEAREST);
4045     m_errorMonitor->VerifyFound();
4046 
4047     // Signed vs Unsigned int - generates both VUs
4048     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImage-00229");
4049     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImage-00230");
4050     if (ssrc) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImage-01999");
4051     if (udst) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-dstImage-02000");
4052     vkCmdBlitImage(m_commandBuffer->handle(), signed_image.image(), signed_image.Layout(), unsigned_image.image(),
4053                    unsigned_image.Layout(), 1, &blitRegion, VK_FILTER_NEAREST);
4054     m_errorMonitor->VerifyFound();
4055     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImage-00229");
4056     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImage-00230");
4057     if (usrc) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImage-01999");
4058     if (sdst) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-dstImage-02000");
4059     vkCmdBlitImage(m_commandBuffer->handle(), unsigned_image.image(), unsigned_image.Layout(), signed_image.image(),
4060                    signed_image.Layout(), 1, &blitRegion, VK_FILTER_NEAREST);
4061     m_errorMonitor->VerifyFound();
4062 
4063     // Depth vs any non-identical depth format
4064     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImage-00231");
4065     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
4066     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
4067     if (d2src) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImage-01999");
4068     if (d1dst) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-dstImage-02000");
4069     vkCmdBlitImage(m_commandBuffer->handle(), depth_image2.image(), depth_image2.Layout(), depth_image.image(),
4070                    depth_image.Layout(), 1, &blitRegion, VK_FILTER_NEAREST);
4071     m_errorMonitor->VerifyFound();
4072 
4073     m_commandBuffer->end();
4074 }
4075 
TEST_F(VkLayerTest,BlitImageFilters)4076 TEST_F(VkLayerTest, BlitImageFilters) {
4077     bool cubic_support = false;
4078     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
4079     if (DeviceExtensionSupported(gpu(), nullptr, "VK_IMG_filter_cubic")) {
4080         m_device_extension_names.push_back("VK_IMG_filter_cubic");
4081         cubic_support = true;
4082     }
4083     ASSERT_NO_FATAL_FAILURE(InitState());
4084 
4085     VkFormat fmt = VK_FORMAT_R8_UINT;
4086     if (!ImageFormatIsSupported(gpu(), fmt, VK_IMAGE_TILING_OPTIMAL)) {
4087         printf("%s No R8_UINT format support - BlitImageFilters skipped.\n", kSkipPrefix);
4088         return;
4089     }
4090 
4091     // Create 2D images
4092     VkImageObj src2D(m_device);
4093     VkImageObj dst2D(m_device);
4094     src2D.Init(64, 64, 1, fmt, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
4095     dst2D.Init(64, 64, 1, fmt, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
4096     ASSERT_TRUE(src2D.initialized());
4097     ASSERT_TRUE(dst2D.initialized());
4098     src2D.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
4099     dst2D.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
4100 
4101     // Create 3D image
4102     VkImageCreateInfo ci;
4103     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4104     ci.pNext = NULL;
4105     ci.flags = 0;
4106     ci.imageType = VK_IMAGE_TYPE_3D;
4107     ci.format = fmt;
4108     ci.extent = {64, 64, 4};
4109     ci.mipLevels = 1;
4110     ci.arrayLayers = 1;
4111     ci.samples = VK_SAMPLE_COUNT_1_BIT;
4112     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
4113     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
4114     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
4115     ci.queueFamilyIndexCount = 0;
4116     ci.pQueueFamilyIndices = NULL;
4117     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4118 
4119     VkImageObj src3D(m_device);
4120     src3D.init(&ci);
4121     ASSERT_TRUE(src3D.initialized());
4122 
4123     VkImageBlit blitRegion = {};
4124     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4125     blitRegion.srcSubresource.baseArrayLayer = 0;
4126     blitRegion.srcSubresource.layerCount = 1;
4127     blitRegion.srcSubresource.mipLevel = 0;
4128     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4129     blitRegion.dstSubresource.baseArrayLayer = 0;
4130     blitRegion.dstSubresource.layerCount = 1;
4131     blitRegion.dstSubresource.mipLevel = 0;
4132     blitRegion.srcOffsets[0] = {0, 0, 0};
4133     blitRegion.srcOffsets[1] = {48, 48, 1};
4134     blitRegion.dstOffsets[0] = {0, 0, 0};
4135     blitRegion.dstOffsets[1] = {64, 64, 1};
4136 
4137     m_commandBuffer->begin();
4138 
4139     // UINT format should not support linear filtering, but check to be sure
4140     if (!ImageFormatAndFeaturesSupported(gpu(), fmt, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)) {
4141         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-filter-02001");
4142         vkCmdBlitImage(m_commandBuffer->handle(), src2D.image(), src2D.Layout(), dst2D.image(), dst2D.Layout(), 1, &blitRegion,
4143                        VK_FILTER_LINEAR);
4144         m_errorMonitor->VerifyFound();
4145     }
4146 
4147     if (cubic_support && !ImageFormatAndFeaturesSupported(gpu(), fmt, VK_IMAGE_TILING_OPTIMAL,
4148                                                           VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG)) {
4149         // Invalid filter CUBIC_IMG
4150         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-filter-02002");
4151         vkCmdBlitImage(m_commandBuffer->handle(), src3D.image(), src3D.Layout(), dst2D.image(), dst2D.Layout(), 1, &blitRegion,
4152                        VK_FILTER_CUBIC_IMG);
4153         m_errorMonitor->VerifyFound();
4154 
4155         // Invalid filter CUBIC_IMG + invalid 2D source image
4156         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-filter-02002");
4157         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-filter-00237");
4158         vkCmdBlitImage(m_commandBuffer->handle(), src2D.image(), src2D.Layout(), dst2D.image(), dst2D.Layout(), 1, &blitRegion,
4159                        VK_FILTER_CUBIC_IMG);
4160         m_errorMonitor->VerifyFound();
4161     }
4162 
4163     m_commandBuffer->end();
4164 }
4165 
TEST_F(VkLayerTest,BlitImageLayout)4166 TEST_F(VkLayerTest, BlitImageLayout) {
4167     TEST_DESCRIPTION("Incorrect vkCmdBlitImage layouts");
4168 
4169     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
4170 
4171     VkResult err;
4172     VkFormat fmt = VK_FORMAT_R8G8B8A8_UNORM;
4173 
4174     VkSubmitInfo submit_info = {};
4175     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4176     submit_info.commandBufferCount = 1;
4177     submit_info.pCommandBuffers = &m_commandBuffer->handle();
4178 
4179     // Create images
4180     VkImageObj img_src_transfer(m_device);
4181     VkImageObj img_dst_transfer(m_device);
4182     VkImageObj img_general(m_device);
4183     VkImageObj img_color(m_device);
4184 
4185     img_src_transfer.InitNoLayout(64, 64, 1, fmt, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
4186                                   VK_IMAGE_TILING_OPTIMAL, 0);
4187     img_dst_transfer.InitNoLayout(64, 64, 1, fmt, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
4188                                   VK_IMAGE_TILING_OPTIMAL, 0);
4189     img_general.InitNoLayout(64, 64, 1, fmt, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
4190                              VK_IMAGE_TILING_OPTIMAL, 0);
4191     img_color.InitNoLayout(64, 64, 1, fmt,
4192                            VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
4193                            VK_IMAGE_TILING_OPTIMAL, 0);
4194 
4195     ASSERT_TRUE(img_src_transfer.initialized());
4196     ASSERT_TRUE(img_dst_transfer.initialized());
4197     ASSERT_TRUE(img_general.initialized());
4198     ASSERT_TRUE(img_color.initialized());
4199 
4200     img_src_transfer.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
4201     img_dst_transfer.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4202     img_general.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
4203     img_color.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
4204 
4205     VkImageBlit blit_region = {};
4206     blit_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4207     blit_region.srcSubresource.baseArrayLayer = 0;
4208     blit_region.srcSubresource.layerCount = 1;
4209     blit_region.srcSubresource.mipLevel = 0;
4210     blit_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4211     blit_region.dstSubresource.baseArrayLayer = 0;
4212     blit_region.dstSubresource.layerCount = 1;
4213     blit_region.dstSubresource.mipLevel = 0;
4214     blit_region.srcOffsets[0] = {0, 0, 0};
4215     blit_region.srcOffsets[1] = {48, 48, 1};
4216     blit_region.dstOffsets[0] = {0, 0, 0};
4217     blit_region.dstOffsets[1] = {64, 64, 1};
4218 
4219     m_commandBuffer->begin();
4220 
4221     // Illegal srcImageLayout
4222     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImageLayout-00222");
4223     vkCmdBlitImage(m_commandBuffer->handle(), img_src_transfer.image(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4224                    img_dst_transfer.image(), img_dst_transfer.Layout(), 1, &blit_region, VK_FILTER_LINEAR);
4225     m_errorMonitor->VerifyFound();
4226 
4227     // Illegal destImageLayout
4228     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-dstImageLayout-00227");
4229     vkCmdBlitImage(m_commandBuffer->handle(), img_src_transfer.image(), img_src_transfer.Layout(), img_dst_transfer.image(),
4230                    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, &blit_region, VK_FILTER_LINEAR);
4231 
4232     m_commandBuffer->end();
4233     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
4234     m_errorMonitor->VerifyFound();
4235 
4236     err = vkQueueWaitIdle(m_device->m_queue);
4237     ASSERT_VK_SUCCESS(err);
4238 
4239     m_commandBuffer->reset(0);
4240     m_commandBuffer->begin();
4241 
4242     // Source image in invalid layout at start of the CB
4243     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout");
4244     vkCmdBlitImage(m_commandBuffer->handle(), img_src_transfer.image(), img_src_transfer.Layout(), img_color.image(),
4245                    VK_IMAGE_LAYOUT_GENERAL, 1, &blit_region, VK_FILTER_LINEAR);
4246 
4247     m_commandBuffer->end();
4248     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
4249     m_errorMonitor->VerifyFound();
4250     err = vkQueueWaitIdle(m_device->m_queue);
4251     ASSERT_VK_SUCCESS(err);
4252 
4253     m_commandBuffer->reset(0);
4254     m_commandBuffer->begin();
4255 
4256     // Destination image in invalid layout at start of the CB
4257     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout");
4258     vkCmdBlitImage(m_commandBuffer->handle(), img_color.image(), VK_IMAGE_LAYOUT_GENERAL, img_dst_transfer.image(),
4259                    img_dst_transfer.Layout(), 1, &blit_region, VK_FILTER_LINEAR);
4260 
4261     m_commandBuffer->end();
4262     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
4263     m_errorMonitor->VerifyFound();
4264     err = vkQueueWaitIdle(m_device->m_queue);
4265     ASSERT_VK_SUCCESS(err);
4266 
4267     // Source image in invalid layout in the middle of CB
4268     m_commandBuffer->reset(0);
4269     m_commandBuffer->begin();
4270 
4271     VkImageMemoryBarrier img_barrier = {};
4272     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
4273     img_barrier.pNext = nullptr;
4274     img_barrier.srcAccessMask = 0;
4275     img_barrier.dstAccessMask = 0;
4276     img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
4277     img_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4278     img_barrier.image = img_general.handle();
4279     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
4280     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
4281     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4282     img_barrier.subresourceRange.baseArrayLayer = 0;
4283     img_barrier.subresourceRange.baseMipLevel = 0;
4284     img_barrier.subresourceRange.layerCount = 1;
4285     img_barrier.subresourceRange.levelCount = 1;
4286 
4287     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0,
4288                          nullptr, 0, nullptr, 1, &img_barrier);
4289 
4290     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImageLayout-00221");
4291     vkCmdBlitImage(m_commandBuffer->handle(), img_general.image(), VK_IMAGE_LAYOUT_GENERAL, img_dst_transfer.image(),
4292                    img_dst_transfer.Layout(), 1, &blit_region, VK_FILTER_LINEAR);
4293 
4294     m_commandBuffer->end();
4295     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
4296     m_errorMonitor->VerifyFound();
4297     err = vkQueueWaitIdle(m_device->m_queue);
4298     ASSERT_VK_SUCCESS(err);
4299 
4300     // Destination image in invalid layout in the middle of CB
4301     m_commandBuffer->reset(0);
4302     m_commandBuffer->begin();
4303 
4304     img_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4305     img_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4306     img_barrier.image = img_dst_transfer.handle();
4307 
4308     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0,
4309                          nullptr, 0, nullptr, 1, &img_barrier);
4310 
4311     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-dstImageLayout-00226");
4312     vkCmdBlitImage(m_commandBuffer->handle(), img_src_transfer.image(), img_src_transfer.Layout(), img_dst_transfer.image(),
4313                    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit_region, VK_FILTER_LINEAR);
4314 
4315     m_commandBuffer->end();
4316     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
4317     m_errorMonitor->VerifyFound();
4318     err = vkQueueWaitIdle(m_device->m_queue);
4319     ASSERT_VK_SUCCESS(err);
4320 }
4321 
TEST_F(VkLayerTest,BlitImageOffsets)4322 TEST_F(VkLayerTest, BlitImageOffsets) {
4323     ASSERT_NO_FATAL_FAILURE(Init());
4324 
4325     VkFormat fmt = VK_FORMAT_R8G8B8A8_UNORM;
4326     if (!ImageFormatAndFeaturesSupported(gpu(), fmt, VK_IMAGE_TILING_OPTIMAL,
4327                                          VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT)) {
4328         printf("%s No blit feature bits - BlitImageOffsets skipped.\n", kSkipPrefix);
4329         return;
4330     }
4331 
4332     VkImageCreateInfo ci;
4333     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4334     ci.pNext = NULL;
4335     ci.flags = 0;
4336     ci.imageType = VK_IMAGE_TYPE_1D;
4337     ci.format = fmt;
4338     ci.extent = {64, 1, 1};
4339     ci.mipLevels = 1;
4340     ci.arrayLayers = 1;
4341     ci.samples = VK_SAMPLE_COUNT_1_BIT;
4342     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
4343     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4344     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
4345     ci.queueFamilyIndexCount = 0;
4346     ci.pQueueFamilyIndices = NULL;
4347     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4348 
4349     VkImageObj image_1D(m_device);
4350     image_1D.init(&ci);
4351     ASSERT_TRUE(image_1D.initialized());
4352 
4353     ci.imageType = VK_IMAGE_TYPE_2D;
4354     ci.extent = {64, 64, 1};
4355     VkImageObj image_2D(m_device);
4356     image_2D.init(&ci);
4357     ASSERT_TRUE(image_2D.initialized());
4358 
4359     ci.imageType = VK_IMAGE_TYPE_3D;
4360     ci.extent = {64, 64, 64};
4361     VkImageObj image_3D(m_device);
4362     image_3D.init(&ci);
4363     ASSERT_TRUE(image_3D.initialized());
4364 
4365     VkImageBlit blit_region = {};
4366     blit_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4367     blit_region.srcSubresource.baseArrayLayer = 0;
4368     blit_region.srcSubresource.layerCount = 1;
4369     blit_region.srcSubresource.mipLevel = 0;
4370     blit_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4371     blit_region.dstSubresource.baseArrayLayer = 0;
4372     blit_region.dstSubresource.layerCount = 1;
4373     blit_region.dstSubresource.mipLevel = 0;
4374 
4375     m_commandBuffer->begin();
4376 
4377     // 1D, with src/dest y offsets other than (0,1)
4378     blit_region.srcOffsets[0] = {0, 1, 0};
4379     blit_region.srcOffsets[1] = {30, 1, 1};
4380     blit_region.dstOffsets[0] = {32, 0, 0};
4381     blit_region.dstOffsets[1] = {64, 1, 1};
4382     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageBlit-srcImage-00245");
4383     vkCmdBlitImage(m_commandBuffer->handle(), image_1D.image(), image_1D.Layout(), image_1D.image(), image_1D.Layout(), 1,
4384                    &blit_region, VK_FILTER_NEAREST);
4385     m_errorMonitor->VerifyFound();
4386 
4387     blit_region.srcOffsets[0] = {0, 0, 0};
4388     blit_region.dstOffsets[0] = {32, 1, 0};
4389     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageBlit-dstImage-00250");
4390     vkCmdBlitImage(m_commandBuffer->handle(), image_1D.image(), image_1D.Layout(), image_1D.image(), image_1D.Layout(), 1,
4391                    &blit_region, VK_FILTER_NEAREST);
4392     m_errorMonitor->VerifyFound();
4393 
4394     // 2D, with src/dest z offsets other than (0,1)
4395     blit_region.srcOffsets[0] = {0, 0, 1};
4396     blit_region.srcOffsets[1] = {24, 31, 1};
4397     blit_region.dstOffsets[0] = {32, 32, 0};
4398     blit_region.dstOffsets[1] = {64, 64, 1};
4399     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageBlit-srcImage-00247");
4400     vkCmdBlitImage(m_commandBuffer->handle(), image_2D.image(), image_2D.Layout(), image_2D.image(), image_2D.Layout(), 1,
4401                    &blit_region, VK_FILTER_NEAREST);
4402     m_errorMonitor->VerifyFound();
4403 
4404     blit_region.srcOffsets[0] = {0, 0, 0};
4405     blit_region.dstOffsets[0] = {32, 32, 1};
4406     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageBlit-dstImage-00252");
4407     vkCmdBlitImage(m_commandBuffer->handle(), image_2D.image(), image_2D.Layout(), image_2D.image(), image_2D.Layout(), 1,
4408                    &blit_region, VK_FILTER_NEAREST);
4409     m_errorMonitor->VerifyFound();
4410 
4411     // Source offsets exceeding source image dimensions
4412     blit_region.srcOffsets[0] = {0, 0, 0};
4413     blit_region.srcOffsets[1] = {65, 64, 1};  // src x
4414     blit_region.dstOffsets[0] = {0, 0, 0};
4415     blit_region.dstOffsets[1] = {64, 64, 1};
4416     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageBlit-srcOffset-00243");    // x
4417     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-pRegions-00215");  // src region
4418     vkCmdBlitImage(m_commandBuffer->handle(), image_3D.image(), image_3D.Layout(), image_2D.image(), image_2D.Layout(), 1,
4419                    &blit_region, VK_FILTER_NEAREST);
4420     m_errorMonitor->VerifyFound();
4421 
4422     blit_region.srcOffsets[1] = {64, 65, 1};                                                                    // src y
4423     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageBlit-srcOffset-00244");    // y
4424     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-pRegions-00215");  // src region
4425     vkCmdBlitImage(m_commandBuffer->handle(), image_3D.image(), image_3D.Layout(), image_2D.image(), image_2D.Layout(), 1,
4426                    &blit_region, VK_FILTER_NEAREST);
4427     m_errorMonitor->VerifyFound();
4428 
4429     blit_region.srcOffsets[0] = {0, 0, 65};  // src z
4430     blit_region.srcOffsets[1] = {64, 64, 64};
4431     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageBlit-srcOffset-00246");    // z
4432     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-pRegions-00215");  // src region
4433     vkCmdBlitImage(m_commandBuffer->handle(), image_3D.image(), image_3D.Layout(), image_2D.image(), image_2D.Layout(), 1,
4434                    &blit_region, VK_FILTER_NEAREST);
4435     m_errorMonitor->VerifyFound();
4436 
4437     // Dest offsets exceeding source image dimensions
4438     blit_region.srcOffsets[0] = {0, 0, 0};
4439     blit_region.srcOffsets[1] = {64, 64, 1};
4440     blit_region.dstOffsets[0] = {96, 64, 32};  // dst x
4441     blit_region.dstOffsets[1] = {64, 0, 33};
4442     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageBlit-dstOffset-00248");    // x
4443     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-pRegions-00216");  // dst region
4444     vkCmdBlitImage(m_commandBuffer->handle(), image_2D.image(), image_2D.Layout(), image_3D.image(), image_3D.Layout(), 1,
4445                    &blit_region, VK_FILTER_NEAREST);
4446     m_errorMonitor->VerifyFound();
4447 
4448     blit_region.dstOffsets[0] = {0, 65, 32};                                                                    // dst y
4449     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageBlit-dstOffset-00249");    // y
4450     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-pRegions-00216");  // dst region
4451     vkCmdBlitImage(m_commandBuffer->handle(), image_2D.image(), image_2D.Layout(), image_3D.image(), image_3D.Layout(), 1,
4452                    &blit_region, VK_FILTER_NEAREST);
4453     m_errorMonitor->VerifyFound();
4454 
4455     blit_region.dstOffsets[0] = {0, 64, 65};  // dst z
4456     blit_region.dstOffsets[1] = {64, 0, 64};
4457     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageBlit-dstOffset-00251");    // z
4458     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-pRegions-00216");  // dst region
4459     vkCmdBlitImage(m_commandBuffer->handle(), image_2D.image(), image_2D.Layout(), image_3D.image(), image_3D.Layout(), 1,
4460                    &blit_region, VK_FILTER_NEAREST);
4461     m_errorMonitor->VerifyFound();
4462 
4463     m_commandBuffer->end();
4464 }
4465 
TEST_F(VkLayerTest,MiscBlitImageTests)4466 TEST_F(VkLayerTest, MiscBlitImageTests) {
4467     ASSERT_NO_FATAL_FAILURE(Init());
4468 
4469     VkFormat f_color = VK_FORMAT_R32_SFLOAT;  // Need features ..BLIT_SRC_BIT & ..BLIT_DST_BIT
4470 
4471     if (!ImageFormatAndFeaturesSupported(gpu(), f_color, VK_IMAGE_TILING_OPTIMAL,
4472                                          VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT)) {
4473         printf("%s Requested format features unavailable - MiscBlitImageTests skipped.\n", kSkipPrefix);
4474         return;
4475     }
4476 
4477     VkImageCreateInfo ci;
4478     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4479     ci.pNext = NULL;
4480     ci.flags = 0;
4481     ci.imageType = VK_IMAGE_TYPE_2D;
4482     ci.format = f_color;
4483     ci.extent = {64, 64, 1};
4484     ci.mipLevels = 1;
4485     ci.arrayLayers = 1;
4486     ci.samples = VK_SAMPLE_COUNT_1_BIT;
4487     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
4488     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4489     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
4490     ci.queueFamilyIndexCount = 0;
4491     ci.pQueueFamilyIndices = NULL;
4492     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4493 
4494     // 2D color image
4495     VkImageObj color_img(m_device);
4496     color_img.init(&ci);
4497     ASSERT_TRUE(color_img.initialized());
4498 
4499     // 2D multi-sample image
4500     ci.samples = VK_SAMPLE_COUNT_4_BIT;
4501     VkImageObj ms_img(m_device);
4502     ms_img.init(&ci);
4503     ASSERT_TRUE(ms_img.initialized());
4504 
4505     // 3D color image
4506     ci.samples = VK_SAMPLE_COUNT_1_BIT;
4507     ci.imageType = VK_IMAGE_TYPE_3D;
4508     ci.extent = {64, 64, 8};
4509     VkImageObj color_3D_img(m_device);
4510     color_3D_img.init(&ci);
4511     ASSERT_TRUE(color_3D_img.initialized());
4512 
4513     VkImageBlit blitRegion = {};
4514     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4515     blitRegion.srcSubresource.baseArrayLayer = 0;
4516     blitRegion.srcSubresource.layerCount = 1;
4517     blitRegion.srcSubresource.mipLevel = 0;
4518     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4519     blitRegion.dstSubresource.baseArrayLayer = 0;
4520     blitRegion.dstSubresource.layerCount = 1;
4521     blitRegion.dstSubresource.mipLevel = 0;
4522     blitRegion.srcOffsets[0] = {0, 0, 0};
4523     blitRegion.srcOffsets[1] = {16, 16, 1};
4524     blitRegion.dstOffsets[0] = {32, 32, 0};
4525     blitRegion.dstOffsets[1] = {64, 64, 1};
4526 
4527     m_commandBuffer->begin();
4528 
4529     // Blit with aspectMask errors
4530     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
4531     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
4532     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageBlit-aspectMask-00241");
4533     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageBlit-aspectMask-00242");
4534     vkCmdBlitImage(m_commandBuffer->handle(), color_img.image(), color_img.Layout(), color_img.image(), color_img.Layout(), 1,
4535                    &blitRegion, VK_FILTER_NEAREST);
4536     m_errorMonitor->VerifyFound();
4537 
4538     // Blit with invalid src mip level
4539     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4540     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4541     blitRegion.srcSubresource.mipLevel = ci.mipLevels;
4542     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4543                                          "VUID-vkCmdBlitImage-srcSubresource-01705");  // invalid srcSubresource.mipLevel
4544     // Redundant unavoidable errors
4545     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4546                                          "VUID-VkImageBlit-srcOffset-00243");  // out-of-bounds srcOffset.x
4547     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4548                                          "VUID-VkImageBlit-srcOffset-00244");  // out-of-bounds srcOffset.y
4549     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4550                                          "VUID-VkImageBlit-srcOffset-00246");  // out-of-bounds srcOffset.z
4551     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4552                                          "VUID-vkCmdBlitImage-pRegions-00215");  // region not contained within src image
4553     vkCmdBlitImage(m_commandBuffer->handle(), color_img.image(), color_img.Layout(), color_img.image(), color_img.Layout(), 1,
4554                    &blitRegion, VK_FILTER_NEAREST);
4555     m_errorMonitor->VerifyFound();
4556 
4557     // Blit with invalid dst mip level
4558     blitRegion.srcSubresource.mipLevel = 0;
4559     blitRegion.dstSubresource.mipLevel = ci.mipLevels;
4560     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4561                                          "VUID-vkCmdBlitImage-dstSubresource-01706");  // invalid dstSubresource.mipLevel
4562     // Redundant unavoidable errors
4563     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4564                                          "VUID-VkImageBlit-dstOffset-00248");  // out-of-bounds dstOffset.x
4565     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4566                                          "VUID-VkImageBlit-dstOffset-00249");  // out-of-bounds dstOffset.y
4567     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4568                                          "VUID-VkImageBlit-dstOffset-00251");  // out-of-bounds dstOffset.z
4569     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4570                                          "VUID-vkCmdBlitImage-pRegions-00216");  // region not contained within dst image
4571     vkCmdBlitImage(m_commandBuffer->handle(), color_img.image(), color_img.Layout(), color_img.image(), color_img.Layout(), 1,
4572                    &blitRegion, VK_FILTER_NEAREST);
4573     m_errorMonitor->VerifyFound();
4574 
4575     // Blit with invalid src array layer
4576     blitRegion.dstSubresource.mipLevel = 0;
4577     blitRegion.srcSubresource.baseArrayLayer = ci.arrayLayers;
4578     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4579                                          "VUID-vkCmdBlitImage-srcSubresource-01707");  // invalid srcSubresource layer range
4580     vkCmdBlitImage(m_commandBuffer->handle(), color_img.image(), color_img.Layout(), color_img.image(), color_img.Layout(), 1,
4581                    &blitRegion, VK_FILTER_NEAREST);
4582     m_errorMonitor->VerifyFound();
4583 
4584     // Blit with invalid dst array layer
4585     blitRegion.srcSubresource.baseArrayLayer = 0;
4586     blitRegion.dstSubresource.baseArrayLayer = ci.arrayLayers;
4587     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4588                                          "VUID-vkCmdBlitImage-dstSubresource-01708");  // invalid dstSubresource layer range
4589                                                                                        // Redundant unavoidable errors
4590     vkCmdBlitImage(m_commandBuffer->handle(), color_img.image(), color_img.Layout(), color_img.image(), color_img.Layout(), 1,
4591                    &blitRegion, VK_FILTER_NEAREST);
4592     m_errorMonitor->VerifyFound();
4593 
4594     blitRegion.dstSubresource.baseArrayLayer = 0;
4595 
4596     // Blit multi-sample image
4597     // TODO: redundant VUs, one (1c8) or two (1d2 & 1d4) should be eliminated.
4598     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImage-00228");
4599     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-srcImage-00233");
4600     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-dstImage-00234");
4601     vkCmdBlitImage(m_commandBuffer->handle(), ms_img.image(), ms_img.Layout(), ms_img.image(), ms_img.Layout(), 1, &blitRegion,
4602                    VK_FILTER_NEAREST);
4603     m_errorMonitor->VerifyFound();
4604 
4605     // Blit 3D with baseArrayLayer != 0 or layerCount != 1
4606     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4607     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4608     blitRegion.srcSubresource.baseArrayLayer = 1;
4609     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageBlit-srcImage-00240");
4610     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4611                                          "VUID-vkCmdBlitImage-srcSubresource-01707");  // base+count > total layer count
4612     vkCmdBlitImage(m_commandBuffer->handle(), color_3D_img.image(), color_3D_img.Layout(), color_3D_img.image(),
4613                    color_3D_img.Layout(), 1, &blitRegion, VK_FILTER_NEAREST);
4614     m_errorMonitor->VerifyFound();
4615     blitRegion.srcSubresource.baseArrayLayer = 0;
4616     blitRegion.srcSubresource.layerCount = 0;
4617     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageBlit-srcImage-00240");
4618     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4619                                          "VUID-VkImageSubresourceLayers-layerCount-01700");  // layer count == 0 (src)
4620     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4621                                          "VUID-VkImageBlit-layerCount-00239");  // src/dst layer count mismatch
4622     vkCmdBlitImage(m_commandBuffer->handle(), color_3D_img.image(), color_3D_img.Layout(), color_3D_img.image(),
4623                    color_3D_img.Layout(), 1, &blitRegion, VK_FILTER_NEAREST);
4624     m_errorMonitor->VerifyFound();
4625 
4626     m_commandBuffer->end();
4627 }
4628 
TEST_F(VkLayerTest,BlitToDepthImageTests)4629 TEST_F(VkLayerTest, BlitToDepthImageTests) {
4630     ASSERT_NO_FATAL_FAILURE(Init());
4631 
4632     // Need feature ..BLIT_SRC_BIT but not ..BLIT_DST_BIT
4633     // TODO: provide more choices here; supporting D32_SFLOAT as BLIT_DST isn't unheard of.
4634     VkFormat f_depth = VK_FORMAT_D32_SFLOAT;
4635 
4636     if (!ImageFormatAndFeaturesSupported(gpu(), f_depth, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_SRC_BIT) ||
4637         ImageFormatAndFeaturesSupported(gpu(), f_depth, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_DST_BIT)) {
4638         printf("%s Requested format features unavailable - BlitToDepthImageTests skipped.\n", kSkipPrefix);
4639         return;
4640     }
4641 
4642     VkImageCreateInfo ci;
4643     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4644     ci.pNext = NULL;
4645     ci.flags = 0;
4646     ci.imageType = VK_IMAGE_TYPE_2D;
4647     ci.format = f_depth;
4648     ci.extent = {64, 64, 1};
4649     ci.mipLevels = 1;
4650     ci.arrayLayers = 1;
4651     ci.samples = VK_SAMPLE_COUNT_1_BIT;
4652     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
4653     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4654     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
4655     ci.queueFamilyIndexCount = 0;
4656     ci.pQueueFamilyIndices = NULL;
4657     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4658 
4659     // 2D depth image
4660     VkImageObj depth_img(m_device);
4661     depth_img.init(&ci);
4662     ASSERT_TRUE(depth_img.initialized());
4663 
4664     VkImageBlit blitRegion = {};
4665     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4666     blitRegion.srcSubresource.baseArrayLayer = 0;
4667     blitRegion.srcSubresource.layerCount = 1;
4668     blitRegion.srcSubresource.mipLevel = 0;
4669     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4670     blitRegion.dstSubresource.baseArrayLayer = 0;
4671     blitRegion.dstSubresource.layerCount = 1;
4672     blitRegion.dstSubresource.mipLevel = 0;
4673     blitRegion.srcOffsets[0] = {0, 0, 0};
4674     blitRegion.srcOffsets[1] = {16, 16, 1};
4675     blitRegion.dstOffsets[0] = {32, 32, 0};
4676     blitRegion.dstOffsets[1] = {64, 64, 1};
4677 
4678     m_commandBuffer->begin();
4679 
4680     // Blit depth image - has SRC_BIT but not DST_BIT
4681     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
4682     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
4683     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBlitImage-dstImage-02000");
4684     vkCmdBlitImage(m_commandBuffer->handle(), depth_img.image(), depth_img.Layout(), depth_img.image(), depth_img.Layout(), 1,
4685                    &blitRegion, VK_FILTER_NEAREST);
4686     m_errorMonitor->VerifyFound();
4687 
4688     m_commandBuffer->end();
4689 }
4690 
TEST_F(VkLayerTest,MinImageTransferGranularity)4691 TEST_F(VkLayerTest, MinImageTransferGranularity) {
4692     TEST_DESCRIPTION("Tests for validation of Queue Family property minImageTransferGranularity.");
4693     ASSERT_NO_FATAL_FAILURE(Init());
4694 
4695     auto queue_family_properties = m_device->phy().queue_properties();
4696     auto large_granularity_family =
4697         std::find_if(queue_family_properties.begin(), queue_family_properties.end(), [](VkQueueFamilyProperties family_properties) {
4698             VkExtent3D family_granularity = family_properties.minImageTransferGranularity;
4699             // We need a queue family that supports copy operations and has a large enough minImageTransferGranularity for the tests
4700             // below to make sense.
4701             return (family_properties.queueFlags & VK_QUEUE_TRANSFER_BIT || family_properties.queueFlags & VK_QUEUE_GRAPHICS_BIT ||
4702                     family_properties.queueFlags & VK_QUEUE_COMPUTE_BIT) &&
4703                    family_granularity.depth >= 4 && family_granularity.width >= 4 && family_granularity.height >= 4;
4704         });
4705 
4706     if (large_granularity_family == queue_family_properties.end()) {
4707         printf("%s No queue family has a large enough granularity for this test to be meaningful, skipping test\n", kSkipPrefix);
4708         return;
4709     }
4710     const size_t queue_family_index = std::distance(queue_family_properties.begin(), large_granularity_family);
4711     VkExtent3D granularity = queue_family_properties[queue_family_index].minImageTransferGranularity;
4712     VkCommandPoolObj command_pool(m_device, queue_family_index, 0);
4713 
4714     // Create two images of different types and try to copy between them
4715     VkImage srcImage;
4716     VkImage dstImage;
4717 
4718     VkImageCreateInfo image_create_info = {};
4719     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4720     image_create_info.pNext = NULL;
4721     image_create_info.imageType = VK_IMAGE_TYPE_3D;
4722     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
4723     image_create_info.extent.width = granularity.width * 2;
4724     image_create_info.extent.height = granularity.height * 2;
4725     image_create_info.extent.depth = granularity.depth * 2;
4726     image_create_info.mipLevels = 1;
4727     image_create_info.arrayLayers = 1;
4728     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
4729     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4730     image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
4731     image_create_info.flags = 0;
4732 
4733     VkImageObj src_image_obj(m_device);
4734     src_image_obj.init(&image_create_info);
4735     ASSERT_TRUE(src_image_obj.initialized());
4736     srcImage = src_image_obj.handle();
4737 
4738     image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4739 
4740     VkImageObj dst_image_obj(m_device);
4741     dst_image_obj.init(&image_create_info);
4742     ASSERT_TRUE(dst_image_obj.initialized());
4743     dstImage = dst_image_obj.handle();
4744 
4745     VkCommandBufferObj command_buffer(m_device, &command_pool);
4746     ASSERT_TRUE(command_buffer.initialized());
4747     command_buffer.begin();
4748 
4749     VkImageCopy copyRegion;
4750     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4751     copyRegion.srcSubresource.mipLevel = 0;
4752     copyRegion.srcSubresource.baseArrayLayer = 0;
4753     copyRegion.srcSubresource.layerCount = 1;
4754     copyRegion.srcOffset.x = 0;
4755     copyRegion.srcOffset.y = 0;
4756     copyRegion.srcOffset.z = 0;
4757     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4758     copyRegion.dstSubresource.mipLevel = 0;
4759     copyRegion.dstSubresource.baseArrayLayer = 0;
4760     copyRegion.dstSubresource.layerCount = 1;
4761     copyRegion.dstOffset.x = 0;
4762     copyRegion.dstOffset.y = 0;
4763     copyRegion.dstOffset.z = 0;
4764     copyRegion.extent.width = granularity.width;
4765     copyRegion.extent.height = granularity.height;
4766     copyRegion.extent.depth = granularity.depth;
4767 
4768     // Introduce failure by setting srcOffset to a bad granularity value
4769     copyRegion.srcOffset.y = 3;
4770     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4771                                          "VUID-vkCmdCopyImage-srcOffset-01783");  // srcOffset image transfer granularity
4772     command_buffer.CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
4773     m_errorMonitor->VerifyFound();
4774 
4775     // Introduce failure by setting extent to a granularity value that is bad
4776     // for both the source and destination image.
4777     copyRegion.srcOffset.y = 0;
4778     copyRegion.extent.width = 3;
4779     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4780                                          "VUID-vkCmdCopyImage-srcOffset-01783");  // src extent image transfer granularity
4781     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4782                                          "VUID-vkCmdCopyImage-dstOffset-01784");  // dst extent image transfer granularity
4783     command_buffer.CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
4784     m_errorMonitor->VerifyFound();
4785 
4786     // Now do some buffer/image copies
4787     VkBufferObj buffer;
4788     VkMemoryPropertyFlags reqs = 0;
4789     buffer.init_as_src_and_dst(*m_device, 8 * granularity.height * granularity.width * granularity.depth, reqs);
4790     VkBufferImageCopy region = {};
4791     region.bufferOffset = 0;
4792     region.bufferRowLength = 0;
4793     region.bufferImageHeight = 0;
4794     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4795     region.imageSubresource.layerCount = 1;
4796     region.imageExtent.height = granularity.height;
4797     region.imageExtent.width = granularity.width;
4798     region.imageExtent.depth = granularity.depth;
4799     region.imageOffset.x = 0;
4800     region.imageOffset.y = 0;
4801     region.imageOffset.z = 0;
4802 
4803     // Introduce failure by setting imageExtent to a bad granularity value
4804     region.imageExtent.width = 3;
4805     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4806                                          "VUID-vkCmdCopyImageToBuffer-imageOffset-01794");  // image transfer granularity
4807     vkCmdCopyImageToBuffer(command_buffer.handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer.handle(), 1, &region);
4808     m_errorMonitor->VerifyFound();
4809     region.imageExtent.width = granularity.width;
4810 
4811     // Introduce failure by setting imageOffset to a bad granularity value
4812     region.imageOffset.z = 3;
4813     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4814                                          "VUID-vkCmdCopyBufferToImage-imageOffset-01793");  // image transfer granularity
4815     vkCmdCopyBufferToImage(command_buffer.handle(), buffer.handle(), dstImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
4816     m_errorMonitor->VerifyFound();
4817 
4818     command_buffer.end();
4819 }
4820 
TEST_F(VkLayerTest,MismatchedQueueFamiliesOnSubmit)4821 TEST_F(VkLayerTest, MismatchedQueueFamiliesOnSubmit) {
4822     TEST_DESCRIPTION(
4823         "Submit command buffer created using one queue family and attempt to submit them on a queue created in a different queue "
4824         "family.");
4825 
4826     ASSERT_NO_FATAL_FAILURE(Init());  // assumes it initializes all queue families on vkCreateDevice
4827 
4828     // This test is meaningless unless we have multiple queue families
4829     auto queue_family_properties = m_device->phy().queue_properties();
4830     std::vector<uint32_t> queue_families;
4831     for (uint32_t i = 0; i < queue_family_properties.size(); ++i)
4832         if (queue_family_properties[i].queueCount > 0) queue_families.push_back(i);
4833 
4834     if (queue_families.size() < 2) {
4835         printf("%s Device only has one queue family; skipped.\n", kSkipPrefix);
4836         return;
4837     }
4838 
4839     const uint32_t queue_family = queue_families[0];
4840 
4841     const uint32_t other_queue_family = queue_families[1];
4842     VkQueue other_queue;
4843     vkGetDeviceQueue(m_device->device(), other_queue_family, 0, &other_queue);
4844 
4845     VkCommandPoolObj cmd_pool(m_device, queue_family);
4846     VkCommandBufferObj cmd_buff(m_device, &cmd_pool);
4847 
4848     cmd_buff.begin();
4849     cmd_buff.end();
4850 
4851     // Submit on the wrong queue
4852     VkSubmitInfo submit_info = {};
4853     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4854     submit_info.commandBufferCount = 1;
4855     submit_info.pCommandBuffers = &cmd_buff.handle();
4856 
4857     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkQueueSubmit-pCommandBuffers-00074");
4858     vkQueueSubmit(other_queue, 1, &submit_info, VK_NULL_HANDLE);
4859     m_errorMonitor->VerifyFound();
4860 }
4861 
TEST_F(VkLayerTest,DrawWithPipelineIncompatibleWithSubpass)4862 TEST_F(VkLayerTest, DrawWithPipelineIncompatibleWithSubpass) {
4863     TEST_DESCRIPTION("Use a pipeline for the wrong subpass in a render pass instance");
4864 
4865     ASSERT_NO_FATAL_FAILURE(Init());
4866 
4867     // A renderpass with two subpasses, both writing the same attachment.
4868     VkAttachmentDescription attach[] = {
4869         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4870          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
4871          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4872     };
4873     VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
4874     VkSubpassDescription subpasses[] = {
4875         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr},
4876         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr},
4877     };
4878     VkSubpassDependency dep = {0,
4879                                1,
4880                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4881                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4882                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4883                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4884                                VK_DEPENDENCY_BY_REGION_BIT};
4885     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 2, subpasses, 1, &dep};
4886     VkRenderPass rp;
4887     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4888     ASSERT_VK_SUCCESS(err);
4889 
4890     VkImageObj image(m_device);
4891     image.InitNoLayout(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
4892     VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
4893 
4894     VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &imageView, 32, 32, 1};
4895     VkFramebuffer fb;
4896     err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
4897     ASSERT_VK_SUCCESS(err);
4898 
4899     char const *vsSource =
4900         "#version 450\n"
4901         "void main() { gl_Position = vec4(1); }\n";
4902     char const *fsSource =
4903         "#version 450\n"
4904         "layout(location=0) out vec4 color;\n"
4905         "void main() { color = vec4(1); }\n";
4906 
4907     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
4908     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
4909     VkPipelineObj pipe(m_device);
4910     pipe.AddDefaultColorAttachment();
4911     pipe.AddShader(&vs);
4912     pipe.AddShader(&fs);
4913     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
4914     m_viewports.push_back(viewport);
4915     pipe.SetViewport(m_viewports);
4916     VkRect2D rect = {};
4917     m_scissors.push_back(rect);
4918     pipe.SetScissor(m_scissors);
4919 
4920     const VkPipelineLayoutObj pl(m_device);
4921     pipe.CreateVKPipeline(pl.handle(), rp);
4922 
4923     m_commandBuffer->begin();
4924 
4925     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
4926                                   nullptr,
4927                                   rp,
4928                                   fb,
4929                                   {{
4930                                        0,
4931                                        0,
4932                                    },
4933                                    {32, 32}},
4934                                   0,
4935                                   nullptr};
4936 
4937     // subtest 1: bind in the wrong subpass
4938     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4939     vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
4940     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "built for subpass 0 but used in subpass 1");
4941     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
4942     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
4943     m_errorMonitor->VerifyFound();
4944 
4945     vkCmdEndRenderPass(m_commandBuffer->handle());
4946 
4947     // subtest 2: bind in correct subpass, then transition to next subpass
4948     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
4949     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
4950     vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
4951     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "built for subpass 0 but used in subpass 1");
4952     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
4953     m_errorMonitor->VerifyFound();
4954 
4955     vkCmdEndRenderPass(m_commandBuffer->handle());
4956 
4957     m_commandBuffer->end();
4958 
4959     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
4960     vkDestroyRenderPass(m_device->device(), rp, nullptr);
4961 }
4962 
TEST_F(VkLayerTest,ImageBarrierSubpassConflicts)4963 TEST_F(VkLayerTest, ImageBarrierSubpassConflicts) {
4964     TEST_DESCRIPTION("Add a pipeline barrier within a subpass that has conflicting state");
4965     ASSERT_NO_FATAL_FAILURE(Init());
4966 
4967     // A renderpass with a single subpass that declared a self-dependency
4968     VkAttachmentDescription attach[] = {
4969         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
4970          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
4971          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
4972     };
4973     VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
4974     VkSubpassDescription subpasses[] = {
4975         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr},
4976     };
4977     VkSubpassDependency dep = {0,
4978                                0,
4979                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4980                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4981                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4982                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
4983                                VK_DEPENDENCY_BY_REGION_BIT};
4984     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 1, &dep};
4985     VkRenderPass rp;
4986     VkRenderPass rp_noselfdep;
4987 
4988     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
4989     ASSERT_VK_SUCCESS(err);
4990     rpci.dependencyCount = 0;
4991     rpci.pDependencies = nullptr;
4992     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp_noselfdep);
4993     ASSERT_VK_SUCCESS(err);
4994 
4995     VkImageObj image(m_device);
4996     image.InitNoLayout(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
4997     VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
4998 
4999     VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &imageView, 32, 32, 1};
5000     VkFramebuffer fb;
5001     err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
5002     ASSERT_VK_SUCCESS(err);
5003 
5004     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-pDependencies-02285");
5005     m_commandBuffer->begin();
5006     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
5007                                   nullptr,
5008                                   rp_noselfdep,
5009                                   fb,
5010                                   {{
5011                                        0,
5012                                        0,
5013                                    },
5014                                    {32, 32}},
5015                                   0,
5016                                   nullptr};
5017 
5018     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
5019     VkMemoryBarrier mem_barrier = {};
5020     mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
5021     mem_barrier.pNext = NULL;
5022     mem_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
5023     mem_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
5024     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 1,
5025                          &mem_barrier, 0, nullptr, 0, nullptr);
5026     m_errorMonitor->VerifyFound();
5027     vkCmdEndRenderPass(m_commandBuffer->handle());
5028 
5029     rpbi.renderPass = rp;
5030     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
5031     VkImageMemoryBarrier img_barrier = {};
5032     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
5033     img_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
5034     img_barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
5035     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
5036     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
5037     img_barrier.image = image.handle();
5038     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
5039     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
5040     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
5041     img_barrier.subresourceRange.baseArrayLayer = 0;
5042     img_barrier.subresourceRange.baseMipLevel = 0;
5043     img_barrier.subresourceRange.layerCount = 1;
5044     img_barrier.subresourceRange.levelCount = 1;
5045     // Mis-match src stage mask
5046     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-pDependencies-02285");
5047     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-pDependencies-02285");
5048     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5049                          VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
5050     m_errorMonitor->VerifyFound();
5051     // Now mis-match dst stage mask
5052     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-pDependencies-02285");
5053     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-pDependencies-02285");
5054     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_HOST_BIT,
5055                          VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
5056     m_errorMonitor->VerifyFound();
5057     // Set srcQueueFamilyIndex to something other than IGNORED
5058     img_barrier.srcQueueFamilyIndex = 0;
5059     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-srcQueueFamilyIndex-01182");
5060     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5061                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
5062                          &img_barrier);
5063     m_errorMonitor->VerifyFound();
5064     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
5065     // Mis-match mem barrier src access mask
5066     mem_barrier = {};
5067     mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
5068     mem_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
5069     mem_barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
5070     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-pDependencies-02285");
5071     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-pDependencies-02285");
5072     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5073                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 1, &mem_barrier, 0, nullptr, 0,
5074                          nullptr);
5075     m_errorMonitor->VerifyFound();
5076     // Mis-match mem barrier dst access mask. Also set srcAccessMask to 0 which should not cause an error
5077     mem_barrier.srcAccessMask = 0;
5078     mem_barrier.dstAccessMask = VK_ACCESS_HOST_WRITE_BIT;
5079     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-pDependencies-02285");
5080     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-pDependencies-02285");
5081     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5082                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 1, &mem_barrier, 0, nullptr, 0,
5083                          nullptr);
5084     m_errorMonitor->VerifyFound();
5085     // Mis-match image barrier src access mask
5086     img_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
5087     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-pDependencies-02285");
5088     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-pDependencies-02285");
5089     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5090                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
5091                          &img_barrier);
5092     m_errorMonitor->VerifyFound();
5093     // Mis-match image barrier dst access mask
5094     img_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
5095     img_barrier.dstAccessMask = VK_ACCESS_HOST_WRITE_BIT;
5096     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-pDependencies-02285");
5097     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-pDependencies-02285");
5098     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5099                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
5100                          &img_barrier);
5101     m_errorMonitor->VerifyFound();
5102     // Mis-match dependencyFlags
5103     img_barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
5104     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-pDependencies-02285");
5105     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5106                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0 /* wrong */, 0, nullptr, 0, nullptr, 1, &img_barrier);
5107     m_errorMonitor->VerifyFound();
5108     // Send non-zero bufferMemoryBarrierCount
5109     // Construct a valid BufferMemoryBarrier to avoid any parameter errors
5110     // First we need a valid buffer to reference
5111     VkBufferObj buffer;
5112     VkMemoryPropertyFlags mem_reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
5113     buffer.init_as_src_and_dst(*m_device, 256, mem_reqs);
5114     VkBufferMemoryBarrier bmb = {};
5115     bmb.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
5116     bmb.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
5117     bmb.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
5118     bmb.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
5119     bmb.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
5120     bmb.buffer = buffer.handle();
5121     bmb.offset = 0;
5122     bmb.size = VK_WHOLE_SIZE;
5123     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-bufferMemoryBarrierCount-01178");
5124     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5125                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1, &bmb, 0,
5126                          nullptr);
5127     m_errorMonitor->VerifyFound();
5128     // Add image barrier w/ image handle that's not in framebuffer
5129     VkImageObj lone_image(m_device);
5130     lone_image.InitNoLayout(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
5131     img_barrier.image = lone_image.handle();
5132     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-image-02635");
5133     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5134                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
5135                          &img_barrier);
5136     m_errorMonitor->VerifyFound();
5137     // Have image barrier with mis-matched layouts
5138     img_barrier.image = image.handle();
5139     img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
5140     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-oldLayout-01181");
5141     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5142                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
5143                          &img_barrier);
5144     m_errorMonitor->VerifyFound();
5145 
5146     img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
5147     img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
5148     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-oldLayout-02636");
5149     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5150                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
5151                          &img_barrier);
5152     m_errorMonitor->VerifyFound();
5153     vkCmdEndRenderPass(m_commandBuffer->handle());
5154 
5155     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
5156     vkDestroyRenderPass(m_device->device(), rp, nullptr);
5157     vkDestroyRenderPass(m_device->device(), rp_noselfdep, nullptr);
5158 }
5159 
TEST_F(VkLayerTest,InvalidSecondaryCommandBufferBarrier)5160 TEST_F(VkLayerTest, InvalidSecondaryCommandBufferBarrier) {
5161     TEST_DESCRIPTION("Add an invalid image barrier in a secondary command buffer");
5162     ASSERT_NO_FATAL_FAILURE(Init());
5163 
5164     // A renderpass with a single subpass that declared a self-dependency
5165     VkAttachmentDescription attach[] = {
5166         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
5167          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
5168          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
5169     };
5170     VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
5171     VkSubpassDescription subpasses[] = {
5172         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr},
5173     };
5174     VkSubpassDependency dep = {0,
5175                                0,
5176                                VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5177                                VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5178                                VK_ACCESS_SHADER_WRITE_BIT,
5179                                VK_ACCESS_SHADER_WRITE_BIT,
5180                                VK_DEPENDENCY_BY_REGION_BIT};
5181     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 1, &dep};
5182     VkRenderPass rp;
5183 
5184     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
5185     ASSERT_VK_SUCCESS(err);
5186 
5187     VkImageObj image(m_device);
5188     image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
5189     VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
5190     // Second image that img_barrier will incorrectly use
5191     VkImageObj image2(m_device);
5192     image2.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
5193 
5194     VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &imageView, 32, 32, 1};
5195     VkFramebuffer fb;
5196     err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
5197     ASSERT_VK_SUCCESS(err);
5198 
5199     m_commandBuffer->begin();
5200 
5201     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
5202                                   nullptr,
5203                                   rp,
5204                                   fb,
5205                                   {{
5206                                        0,
5207                                        0,
5208                                    },
5209                                    {32, 32}},
5210                                   0,
5211                                   nullptr};
5212 
5213     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
5214 
5215     VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
5216     VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
5217 
5218     VkCommandBufferInheritanceInfo cbii = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
5219                                            nullptr,
5220                                            rp,
5221                                            0,
5222                                            VK_NULL_HANDLE,  // Set to NULL FB handle intentionally to flesh out any errors
5223                                            VK_FALSE,
5224                                            0,
5225                                            0};
5226     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
5227                                      VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,
5228                                      &cbii};
5229     vkBeginCommandBuffer(secondary.handle(), &cbbi);
5230     VkImageMemoryBarrier img_barrier = {};
5231     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
5232     img_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
5233     img_barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
5234     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
5235     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
5236     img_barrier.image = image2.handle();  // Image mis-matches with FB image
5237     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
5238     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
5239     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
5240     img_barrier.subresourceRange.baseArrayLayer = 0;
5241     img_barrier.subresourceRange.baseMipLevel = 0;
5242     img_barrier.subresourceRange.layerCount = 1;
5243     img_barrier.subresourceRange.levelCount = 1;
5244     vkCmdPipelineBarrier(secondary.handle(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5245                          VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
5246     secondary.end();
5247 
5248     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-image-02635");
5249     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
5250     m_errorMonitor->VerifyFound();
5251 
5252     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
5253     vkDestroyRenderPass(m_device->device(), rp, nullptr);
5254 }
5255 
TEST_F(VkLayerTest,ImageBarrierSubpassConflict)5256 TEST_F(VkLayerTest, ImageBarrierSubpassConflict) {
5257     TEST_DESCRIPTION("Check case where subpass index references different image from image barrier");
5258     ASSERT_NO_FATAL_FAILURE(Init());
5259 
5260     // Create RP/FB combo where subpass has incorrect index attachment, this is 2nd half of "VUID-vkCmdPipelineBarrier-image-02635"
5261     VkAttachmentDescription attach[] = {
5262         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
5263          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
5264          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
5265         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
5266          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
5267          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
5268     };
5269     // ref attachment points to wrong attachment index compared to img_barrier below
5270     VkAttachmentReference ref = {1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
5271     VkSubpassDescription subpasses[] = {
5272         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr},
5273     };
5274     VkSubpassDependency dep = {0,
5275                                0,
5276                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5277                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5278                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5279                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5280                                VK_DEPENDENCY_BY_REGION_BIT};
5281 
5282     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attach, 1, subpasses, 1, &dep};
5283     VkRenderPass rp;
5284 
5285     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
5286     ASSERT_VK_SUCCESS(err);
5287 
5288     VkImageObj image(m_device);
5289     image.InitNoLayout(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
5290     VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
5291     VkImageObj image2(m_device);
5292     image2.InitNoLayout(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
5293     VkImageView imageView2 = image2.targetView(VK_FORMAT_R8G8B8A8_UNORM);
5294     // re-use imageView from start of test
5295     VkImageView iv_array[2] = {imageView, imageView2};
5296 
5297     VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 2, iv_array, 32, 32, 1};
5298     VkFramebuffer fb;
5299     err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
5300     ASSERT_VK_SUCCESS(err);
5301 
5302     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
5303                                   nullptr,
5304                                   rp,
5305                                   fb,
5306                                   {{
5307                                        0,
5308                                        0,
5309                                    },
5310                                    {32, 32}},
5311                                   0,
5312                                   nullptr};
5313 
5314     VkImageMemoryBarrier img_barrier = {};
5315     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
5316     img_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
5317     img_barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
5318     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
5319     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
5320     img_barrier.image = image.handle(); /* barrier references image from attachment index 0 */
5321     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
5322     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
5323     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
5324     img_barrier.subresourceRange.baseArrayLayer = 0;
5325     img_barrier.subresourceRange.baseMipLevel = 0;
5326     img_barrier.subresourceRange.layerCount = 1;
5327     img_barrier.subresourceRange.levelCount = 1;
5328     m_commandBuffer->begin();
5329     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
5330     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-image-02635");
5331     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5332                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
5333                          &img_barrier);
5334     m_errorMonitor->VerifyFound();
5335 
5336     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
5337     vkDestroyRenderPass(m_device->device(), rp, nullptr);
5338 }
5339 
TEST_F(VkLayerTest,TemporaryExternalSemaphore)5340 TEST_F(VkLayerTest, TemporaryExternalSemaphore) {
5341 #ifdef _WIN32
5342     const auto extension_name = VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME;
5343     const auto handle_type = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR;
5344 #else
5345     const auto extension_name = VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME;
5346     const auto handle_type = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
5347 #endif
5348     // Check for external semaphore instance extensions
5349     if (InstanceExtensionSupported(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME)) {
5350         m_instance_extension_names.push_back(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
5351         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5352     } else {
5353         printf("%s External semaphore extension not supported, skipping test\n", kSkipPrefix);
5354         return;
5355     }
5356     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
5357 
5358     // Check for external semaphore device extensions
5359     if (DeviceExtensionSupported(gpu(), nullptr, extension_name)) {
5360         m_device_extension_names.push_back(extension_name);
5361         m_device_extension_names.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
5362     } else {
5363         printf("%s External semaphore extension not supported, skipping test\n", kSkipPrefix);
5364         return;
5365     }
5366     ASSERT_NO_FATAL_FAILURE(InitState());
5367 
5368     // Check for external semaphore import and export capability
5369     VkPhysicalDeviceExternalSemaphoreInfoKHR esi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR, nullptr,
5370                                                     handle_type};
5371     VkExternalSemaphorePropertiesKHR esp = {VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR, nullptr};
5372     auto vkGetPhysicalDeviceExternalSemaphorePropertiesKHR =
5373         (PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)vkGetInstanceProcAddr(
5374             instance(), "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR");
5375     vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(gpu(), &esi, &esp);
5376 
5377     if (!(esp.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR) ||
5378         !(esp.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR)) {
5379         printf("%s External semaphore does not support importing and exporting, skipping test\n", kSkipPrefix);
5380         return;
5381     }
5382 
5383     VkResult err;
5384 
5385     // Create a semaphore to export payload from
5386     VkExportSemaphoreCreateInfoKHR esci = {VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR, nullptr, handle_type};
5387     VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &esci, 0};
5388 
5389     VkSemaphore export_semaphore;
5390     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &export_semaphore);
5391     ASSERT_VK_SUCCESS(err);
5392 
5393     // Create a semaphore to import payload into
5394     sci.pNext = nullptr;
5395     VkSemaphore import_semaphore;
5396     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &import_semaphore);
5397     ASSERT_VK_SUCCESS(err);
5398 
5399 #ifdef _WIN32
5400     // Export semaphore payload to an opaque handle
5401     HANDLE handle = nullptr;
5402     VkSemaphoreGetWin32HandleInfoKHR ghi = {VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR, nullptr, export_semaphore,
5403                                             handle_type};
5404     auto vkGetSemaphoreWin32HandleKHR =
5405         (PFN_vkGetSemaphoreWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetSemaphoreWin32HandleKHR");
5406     err = vkGetSemaphoreWin32HandleKHR(m_device->device(), &ghi, &handle);
5407     ASSERT_VK_SUCCESS(err);
5408 
5409     // Import opaque handle exported above *temporarily*
5410     VkImportSemaphoreWin32HandleInfoKHR ihi = {VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR,
5411                                                nullptr,
5412                                                import_semaphore,
5413                                                VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR,
5414                                                handle_type,
5415                                                handle,
5416                                                nullptr};
5417     auto vkImportSemaphoreWin32HandleKHR =
5418         (PFN_vkImportSemaphoreWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportSemaphoreWin32HandleKHR");
5419     err = vkImportSemaphoreWin32HandleKHR(m_device->device(), &ihi);
5420     ASSERT_VK_SUCCESS(err);
5421 #else
5422     // Export semaphore payload to an opaque handle
5423     int fd = 0;
5424     VkSemaphoreGetFdInfoKHR ghi = {VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR, nullptr, export_semaphore, handle_type};
5425     auto vkGetSemaphoreFdKHR = (PFN_vkGetSemaphoreFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetSemaphoreFdKHR");
5426     err = vkGetSemaphoreFdKHR(m_device->device(), &ghi, &fd);
5427     ASSERT_VK_SUCCESS(err);
5428 
5429     // Import opaque handle exported above *temporarily*
5430     VkImportSemaphoreFdInfoKHR ihi = {VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR, nullptr,     import_semaphore,
5431                                       VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR,          handle_type, fd};
5432     auto vkImportSemaphoreFdKHR = (PFN_vkImportSemaphoreFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportSemaphoreFdKHR");
5433     err = vkImportSemaphoreFdKHR(m_device->device(), &ihi);
5434     ASSERT_VK_SUCCESS(err);
5435 #endif
5436 
5437     // Wait on the imported semaphore twice in vkQueueSubmit, the second wait should be an error
5438     VkPipelineStageFlags flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
5439     VkSubmitInfo si[] = {
5440         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, &flags, 0, nullptr, 1, &export_semaphore},
5441         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &import_semaphore, &flags, 0, nullptr, 0, nullptr},
5442         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, &flags, 0, nullptr, 1, &export_semaphore},
5443         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &import_semaphore, &flags, 0, nullptr, 0, nullptr},
5444     };
5445     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "has no way to be signaled");
5446     vkQueueSubmit(m_device->m_queue, 4, si, VK_NULL_HANDLE);
5447     m_errorMonitor->VerifyFound();
5448 
5449     // Wait on the imported semaphore twice in vkQueueBindSparse, the second wait should be an error
5450     VkBindSparseInfo bi[] = {
5451         {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 1, &export_semaphore},
5452         {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 1, &import_semaphore, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr},
5453         {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 1, &export_semaphore},
5454         {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 1, &import_semaphore, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr},
5455     };
5456     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "has no way to be signaled");
5457     vkQueueBindSparse(m_device->m_queue, 4, bi, VK_NULL_HANDLE);
5458     m_errorMonitor->VerifyFound();
5459 
5460     // Cleanup
5461     err = vkQueueWaitIdle(m_device->m_queue);
5462     ASSERT_VK_SUCCESS(err);
5463     vkDestroySemaphore(m_device->device(), export_semaphore, nullptr);
5464     vkDestroySemaphore(m_device->device(), import_semaphore, nullptr);
5465 }
5466 
TEST_F(VkLayerTest,TemporaryExternalFence)5467 TEST_F(VkLayerTest, TemporaryExternalFence) {
5468 #ifdef _WIN32
5469     const auto extension_name = VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME;
5470     const auto handle_type = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
5471 #else
5472     const auto extension_name = VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME;
5473     const auto handle_type = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
5474 #endif
5475     // Check for external fence instance extensions
5476     if (InstanceExtensionSupported(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME)) {
5477         m_instance_extension_names.push_back(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME);
5478         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5479     } else {
5480         printf("%s External fence extension not supported, skipping test\n", kSkipPrefix);
5481         return;
5482     }
5483     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
5484 
5485     // Check for external fence device extensions
5486     if (DeviceExtensionSupported(gpu(), nullptr, extension_name)) {
5487         m_device_extension_names.push_back(extension_name);
5488         m_device_extension_names.push_back(VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME);
5489     } else {
5490         printf("%s External fence extension not supported, skipping test\n", kSkipPrefix);
5491         return;
5492     }
5493     ASSERT_NO_FATAL_FAILURE(InitState());
5494 
5495     // Check for external fence import and export capability
5496     VkPhysicalDeviceExternalFenceInfoKHR efi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR, nullptr, handle_type};
5497     VkExternalFencePropertiesKHR efp = {VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR, nullptr};
5498     auto vkGetPhysicalDeviceExternalFencePropertiesKHR = (PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR)vkGetInstanceProcAddr(
5499         instance(), "vkGetPhysicalDeviceExternalFencePropertiesKHR");
5500     vkGetPhysicalDeviceExternalFencePropertiesKHR(gpu(), &efi, &efp);
5501 
5502     if (!(efp.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR) ||
5503         !(efp.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR)) {
5504         printf("%s External fence does not support importing and exporting, skipping test\n", kSkipPrefix);
5505         return;
5506     }
5507 
5508     VkResult err;
5509 
5510     // Create a fence to export payload from
5511     VkFence export_fence;
5512     {
5513         VkExportFenceCreateInfoKHR efci = {VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR, nullptr, handle_type};
5514         VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, &efci, 0};
5515         err = vkCreateFence(m_device->device(), &fci, nullptr, &export_fence);
5516         ASSERT_VK_SUCCESS(err);
5517     }
5518 
5519     // Create a fence to import payload into
5520     VkFence import_fence;
5521     {
5522         VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
5523         err = vkCreateFence(m_device->device(), &fci, nullptr, &import_fence);
5524         ASSERT_VK_SUCCESS(err);
5525     }
5526 
5527 #ifdef _WIN32
5528     // Export fence payload to an opaque handle
5529     HANDLE handle = nullptr;
5530     {
5531         VkFenceGetWin32HandleInfoKHR ghi = {VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR, nullptr, export_fence, handle_type};
5532         auto vkGetFenceWin32HandleKHR =
5533             (PFN_vkGetFenceWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetFenceWin32HandleKHR");
5534         err = vkGetFenceWin32HandleKHR(m_device->device(), &ghi, &handle);
5535         ASSERT_VK_SUCCESS(err);
5536     }
5537 
5538     // Import opaque handle exported above
5539     {
5540         VkImportFenceWin32HandleInfoKHR ifi = {VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR,
5541                                                nullptr,
5542                                                import_fence,
5543                                                VK_FENCE_IMPORT_TEMPORARY_BIT_KHR,
5544                                                handle_type,
5545                                                handle,
5546                                                nullptr};
5547         auto vkImportFenceWin32HandleKHR =
5548             (PFN_vkImportFenceWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportFenceWin32HandleKHR");
5549         err = vkImportFenceWin32HandleKHR(m_device->device(), &ifi);
5550         ASSERT_VK_SUCCESS(err);
5551     }
5552 #else
5553     // Export fence payload to an opaque handle
5554     int fd = 0;
5555     {
5556         VkFenceGetFdInfoKHR gfi = {VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR, nullptr, export_fence, handle_type};
5557         auto vkGetFenceFdKHR = (PFN_vkGetFenceFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetFenceFdKHR");
5558         err = vkGetFenceFdKHR(m_device->device(), &gfi, &fd);
5559         ASSERT_VK_SUCCESS(err);
5560     }
5561 
5562     // Import opaque handle exported above
5563     {
5564         VkImportFenceFdInfoKHR ifi = {VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR, nullptr,     import_fence,
5565                                       VK_FENCE_IMPORT_TEMPORARY_BIT_KHR,          handle_type, fd};
5566         auto vkImportFenceFdKHR = (PFN_vkImportFenceFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportFenceFdKHR");
5567         err = vkImportFenceFdKHR(m_device->device(), &ifi);
5568         ASSERT_VK_SUCCESS(err);
5569     }
5570 #endif
5571 
5572     // Undo the temporary import
5573     vkResetFences(m_device->device(), 1, &import_fence);
5574 
5575     // Signal the previously imported fence twice, the second signal should produce a validation error
5576     vkQueueSubmit(m_device->m_queue, 0, nullptr, import_fence);
5577     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is already in use by another submission.");
5578     vkQueueSubmit(m_device->m_queue, 0, nullptr, import_fence);
5579     m_errorMonitor->VerifyFound();
5580 
5581     // Cleanup
5582     err = vkQueueWaitIdle(m_device->m_queue);
5583     ASSERT_VK_SUCCESS(err);
5584     vkDestroyFence(m_device->device(), export_fence, nullptr);
5585     vkDestroyFence(m_device->device(), import_fence, nullptr);
5586 }
5587 
TEST_F(VkPositiveLayerTest,SecondaryCommandBufferBarrier)5588 TEST_F(VkPositiveLayerTest, SecondaryCommandBufferBarrier) {
5589     TEST_DESCRIPTION("Add a pipeline barrier in a secondary command buffer");
5590     ASSERT_NO_FATAL_FAILURE(Init());
5591 
5592     // A renderpass with a single subpass that declared a self-dependency
5593     VkAttachmentDescription attach[] = {
5594         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
5595          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
5596          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
5597     };
5598     VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
5599     VkSubpassDescription subpasses[] = {
5600         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr},
5601     };
5602     VkSubpassDependency dep = {0,
5603                                0,
5604                                VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5605                                VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5606                                VK_ACCESS_SHADER_WRITE_BIT,
5607                                VK_ACCESS_SHADER_WRITE_BIT,
5608                                VK_DEPENDENCY_BY_REGION_BIT};
5609     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 1, &dep};
5610     VkRenderPass rp;
5611 
5612     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
5613     ASSERT_VK_SUCCESS(err);
5614 
5615     VkImageObj image(m_device);
5616     image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
5617     VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
5618 
5619     VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &imageView, 32, 32, 1};
5620     VkFramebuffer fb;
5621     err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
5622     ASSERT_VK_SUCCESS(err);
5623 
5624     m_commandBuffer->begin();
5625 
5626     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
5627                                   nullptr,
5628                                   rp,
5629                                   fb,
5630                                   {{
5631                                        0,
5632                                        0,
5633                                    },
5634                                    {32, 32}},
5635                                   0,
5636                                   nullptr};
5637 
5638     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
5639 
5640     VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
5641     VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
5642 
5643     VkCommandBufferInheritanceInfo cbii = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
5644                                            nullptr,
5645                                            rp,
5646                                            0,
5647                                            VK_NULL_HANDLE,  // Set to NULL FB handle intentionally to flesh out any errors
5648                                            VK_FALSE,
5649                                            0,
5650                                            0};
5651     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
5652                                      VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,
5653                                      &cbii};
5654     vkBeginCommandBuffer(secondary.handle(), &cbbi);
5655     VkMemoryBarrier mem_barrier = {};
5656     mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
5657     mem_barrier.pNext = NULL;
5658     mem_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
5659     mem_barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
5660     vkCmdPipelineBarrier(secondary.handle(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5661                          VK_DEPENDENCY_BY_REGION_BIT, 1, &mem_barrier, 0, nullptr, 0, nullptr);
5662     VkImageMemoryBarrier img_barrier = {};
5663     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
5664     img_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
5665     img_barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
5666     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
5667     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
5668     img_barrier.image = image.handle();
5669     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
5670     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
5671     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
5672     img_barrier.subresourceRange.baseArrayLayer = 0;
5673     img_barrier.subresourceRange.baseMipLevel = 0;
5674     img_barrier.subresourceRange.layerCount = 1;
5675     img_barrier.subresourceRange.levelCount = 1;
5676     vkCmdPipelineBarrier(secondary.handle(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5677                          VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
5678     secondary.end();
5679 
5680     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
5681     vkCmdEndRenderPass(m_commandBuffer->handle());
5682     m_commandBuffer->end();
5683 
5684     VkSubmitInfo submit_info = {};
5685     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5686     submit_info.commandBufferCount = 1;
5687     submit_info.pCommandBuffers = &m_commandBuffer->handle();
5688     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
5689     vkQueueWaitIdle(m_device->m_queue);
5690 
5691     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
5692     vkDestroyRenderPass(m_device->device(), rp, nullptr);
5693 }
5694 
TestRenderPassCreate(ErrorMonitor * error_monitor,const VkDevice device,const VkRenderPassCreateInfo * create_info,bool rp2Supported,const char * rp1_vuid,const char * rp2_vuid)5695 static void TestRenderPassCreate(ErrorMonitor *error_monitor, const VkDevice device, const VkRenderPassCreateInfo *create_info,
5696                                  bool rp2Supported, const char *rp1_vuid, const char *rp2_vuid) {
5697     VkRenderPass render_pass = VK_NULL_HANDLE;
5698     VkResult err;
5699 
5700     if (rp1_vuid) {
5701         error_monitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, rp1_vuid);
5702         err = vkCreateRenderPass(device, create_info, nullptr, &render_pass);
5703         if (err == VK_SUCCESS) vkDestroyRenderPass(device, render_pass, nullptr);
5704         error_monitor->VerifyFound();
5705     }
5706 
5707     if (rp2Supported && rp2_vuid) {
5708         PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR =
5709             (PFN_vkCreateRenderPass2KHR)vkGetDeviceProcAddr(device, "vkCreateRenderPass2KHR");
5710         safe_VkRenderPassCreateInfo2KHR create_info2;
5711         ConvertVkRenderPassCreateInfoToV2KHR(create_info, &create_info2);
5712 
5713         error_monitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, rp2_vuid);
5714         err = vkCreateRenderPass2KHR(device, create_info2.ptr(), nullptr, &render_pass);
5715         if (err == VK_SUCCESS) vkDestroyRenderPass(device, render_pass, nullptr);
5716         error_monitor->VerifyFound();
5717     }
5718 }
5719 
TEST_F(VkLayerTest,RenderPassCreateAttachmentIndexOutOfRange)5720 TEST_F(VkLayerTest, RenderPassCreateAttachmentIndexOutOfRange) {
5721     // Check for VK_KHR_get_physical_device_properties2
5722     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5723         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5724     }
5725 
5726     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
5727     bool rp2Supported = CheckCreateRenderPass2Support(this, m_device_extension_names);
5728     ASSERT_NO_FATAL_FAILURE(InitState());
5729 
5730     // There are no attachments, but refer to attachment 0.
5731     VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
5732     VkSubpassDescription subpasses[] = {
5733         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr},
5734     };
5735 
5736     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, subpasses, 0, nullptr};
5737 
5738     // "... must be less than the total number of attachments ..."
5739     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkRenderPassCreateInfo-attachment-00834",
5740                          "VUID-VkRenderPassCreateInfo2KHR-attachment-03051");
5741 }
5742 
TEST_F(VkLayerTest,RenderPassCreateAttachmentReadOnlyButCleared)5743 TEST_F(VkLayerTest, RenderPassCreateAttachmentReadOnlyButCleared) {
5744     // Check for VK_KHR_get_physical_device_properties2
5745     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5746         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5747     }
5748 
5749     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
5750 
5751     bool rp2Supported = CheckCreateRenderPass2Support(this, m_device_extension_names);
5752     bool maintenance2Supported = rp2Supported;
5753 
5754     // Check for VK_KHR_maintenance2
5755     if (!rp2Supported && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE2_EXTENSION_NAME)) {
5756         m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME);
5757         maintenance2Supported = true;
5758     }
5759 
5760     ASSERT_NO_FATAL_FAILURE(InitState());
5761 
5762     if (m_device->props.apiVersion < VK_API_VERSION_1_1) {
5763         maintenance2Supported = true;
5764     }
5765 
5766     VkAttachmentDescription description = {0,
5767                                            VK_FORMAT_D32_SFLOAT_S8_UINT,
5768                                            VK_SAMPLE_COUNT_1_BIT,
5769                                            VK_ATTACHMENT_LOAD_OP_CLEAR,
5770                                            VK_ATTACHMENT_STORE_OP_DONT_CARE,
5771                                            VK_ATTACHMENT_LOAD_OP_CLEAR,
5772                                            VK_ATTACHMENT_STORE_OP_DONT_CARE,
5773                                            VK_IMAGE_LAYOUT_GENERAL,
5774                                            VK_IMAGE_LAYOUT_GENERAL};
5775 
5776     VkAttachmentReference depth_stencil_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL};
5777 
5778     VkSubpassDescription subpass = {0,      VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &depth_stencil_ref, 0,
5779                                     nullptr};
5780 
5781     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &description, 1, &subpass, 0, nullptr};
5782 
5783     // VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL but depth cleared
5784     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkRenderPassCreateInfo-pAttachments-00836",
5785                          "VUID-VkRenderPassCreateInfo2KHR-pAttachments-02522");
5786 
5787     if (maintenance2Supported) {
5788         // VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL but depth cleared
5789         depth_stencil_ref.layout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
5790 
5791         TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported,
5792                              "VUID-VkRenderPassCreateInfo-pAttachments-01566", nullptr);
5793 
5794         // VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL but depth cleared
5795         depth_stencil_ref.layout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL;
5796 
5797         TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported,
5798                              "VUID-VkRenderPassCreateInfo-pAttachments-01567", nullptr);
5799     }
5800 }
5801 
TEST_F(VkLayerTest,RenderPassCreateAttachmentMismatchingLayoutsColor)5802 TEST_F(VkLayerTest, RenderPassCreateAttachmentMismatchingLayoutsColor) {
5803     TEST_DESCRIPTION("Attachment is used simultaneously as two color attachments with different layouts.");
5804 
5805     // Check for VK_KHR_get_physical_device_properties2
5806     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5807         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5808     }
5809 
5810     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
5811     bool rp2Supported = CheckCreateRenderPass2Support(this, m_device_extension_names);
5812     ASSERT_NO_FATAL_FAILURE(InitState());
5813 
5814     VkAttachmentDescription attach[] = {
5815         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
5816          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
5817          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
5818     };
5819     VkAttachmentReference refs[] = {
5820         {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
5821         {0, VK_IMAGE_LAYOUT_GENERAL},
5822     };
5823     VkSubpassDescription subpasses[] = {
5824         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 2, refs, nullptr, nullptr, 0, nullptr},
5825     };
5826 
5827     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 0, nullptr};
5828 
5829     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported,
5830                          "subpass 0 already uses attachment 0 with a different image layout",
5831                          "subpass 0 already uses attachment 0 with a different image layout");
5832 }
5833 
TEST_F(VkLayerTest,RenderPassCreateAttachmentDescriptionInvalidFinalLayout)5834 TEST_F(VkLayerTest, RenderPassCreateAttachmentDescriptionInvalidFinalLayout) {
5835     TEST_DESCRIPTION("VkAttachmentDescription's finalLayout must not be UNDEFINED or PREINITIALIZED");
5836 
5837     // Check for VK_KHR_get_physical_device_properties2
5838     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5839         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5840     }
5841 
5842     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
5843     bool rp2Supported = CheckCreateRenderPass2Support(this, m_device_extension_names);
5844     ASSERT_NO_FATAL_FAILURE(InitState());
5845 
5846     VkAttachmentDescription attach_desc = {};
5847     attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM;
5848     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
5849     attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
5850     attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
5851     attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
5852     attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
5853     attach_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
5854     attach_desc.finalLayout = VK_IMAGE_LAYOUT_UNDEFINED;
5855     VkAttachmentReference attach_ref = {};
5856     attach_ref.attachment = 0;
5857     attach_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
5858     VkSubpassDescription subpass = {};
5859     subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
5860     subpass.colorAttachmentCount = 1;
5861     subpass.pColorAttachments = &attach_ref;
5862     VkRenderPassCreateInfo rpci = {};
5863     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
5864     rpci.attachmentCount = 1;
5865     rpci.pAttachments = &attach_desc;
5866     rpci.subpassCount = 1;
5867     rpci.pSubpasses = &subpass;
5868 
5869     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkAttachmentDescription-finalLayout-00843",
5870                          "VUID-VkAttachmentDescription2KHR-finalLayout-03061");
5871 
5872     attach_desc.finalLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
5873     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkAttachmentDescription-finalLayout-00843",
5874                          "VUID-VkAttachmentDescription2KHR-finalLayout-03061");
5875 }
5876 
TEST_F(VkLayerTest,RenderPassCreateAttachmentsMisc)5877 TEST_F(VkLayerTest, RenderPassCreateAttachmentsMisc) {
5878     TEST_DESCRIPTION(
5879         "Ensure that CreateRenderPass produces the expected validation errors when a subpass's attachments violate the valid usage "
5880         "conditions.");
5881 
5882     // Check for VK_KHR_get_physical_device_properties2
5883     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5884         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5885     }
5886 
5887     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
5888     bool rp2Supported = CheckCreateRenderPass2Support(this, m_device_extension_names);
5889     ASSERT_NO_FATAL_FAILURE(InitState());
5890 
5891     std::vector<VkAttachmentDescription> attachments = {
5892         // input attachments
5893         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
5894          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
5895         // color attachments
5896         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
5897          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5898          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
5899         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
5900          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5901          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
5902         // depth attachment
5903         {0, VK_FORMAT_D24_UNORM_S8_UINT, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
5904          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5905          VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL},
5906         // resolve attachment
5907         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
5908          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5909          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
5910         // preserve attachments
5911         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
5912          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5913          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
5914     };
5915 
5916     std::vector<VkAttachmentReference> input = {
5917         {0, VK_IMAGE_LAYOUT_GENERAL},
5918     };
5919     std::vector<VkAttachmentReference> color = {
5920         {1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
5921         {2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
5922     };
5923     VkAttachmentReference depth = {3, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
5924     std::vector<VkAttachmentReference> resolve = {
5925         {4, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
5926         {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
5927     };
5928     std::vector<uint32_t> preserve = {5};
5929 
5930     VkSubpassDescription subpass = {0,
5931                                     VK_PIPELINE_BIND_POINT_GRAPHICS,
5932                                     (uint32_t)input.size(),
5933                                     input.data(),
5934                                     (uint32_t)color.size(),
5935                                     color.data(),
5936                                     resolve.data(),
5937                                     &depth,
5938                                     (uint32_t)preserve.size(),
5939                                     preserve.data()};
5940 
5941     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
5942                                    nullptr,
5943                                    0,
5944                                    (uint32_t)attachments.size(),
5945                                    attachments.data(),
5946                                    1,
5947                                    &subpass,
5948                                    0,
5949                                    nullptr};
5950 
5951     // Test too many color attachments
5952     {
5953         std::vector<VkAttachmentReference> too_many_colors(m_device->props.limits.maxColorAttachments + 1, color[0]);
5954         subpass.colorAttachmentCount = (uint32_t)too_many_colors.size();
5955         subpass.pColorAttachments = too_many_colors.data();
5956         subpass.pResolveAttachments = NULL;
5957 
5958         TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported,
5959                              "VUID-VkSubpassDescription-colorAttachmentCount-00845",
5960                              "VUID-VkSubpassDescription2KHR-colorAttachmentCount-03063");
5961 
5962         subpass.colorAttachmentCount = (uint32_t)color.size();
5963         subpass.pColorAttachments = color.data();
5964         subpass.pResolveAttachments = resolve.data();
5965     }
5966 
5967     // Test sample count mismatch between color buffers
5968     attachments[subpass.pColorAttachments[1].attachment].samples = VK_SAMPLE_COUNT_8_BIT;
5969     depth.attachment = VK_ATTACHMENT_UNUSED;  // Avoids triggering 01418
5970 
5971     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported,
5972                          "VUID-VkSubpassDescription-pColorAttachments-01417",
5973                          "VUID-VkSubpassDescription2KHR-pColorAttachments-03069");
5974 
5975     depth.attachment = 3;
5976     attachments[subpass.pColorAttachments[1].attachment].samples = attachments[subpass.pColorAttachments[0].attachment].samples;
5977 
5978     // Test sample count mismatch between color buffers and depth buffer
5979     attachments[subpass.pDepthStencilAttachment->attachment].samples = VK_SAMPLE_COUNT_8_BIT;
5980     subpass.colorAttachmentCount = 1;
5981 
5982     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported,
5983                          "VUID-VkSubpassDescription-pDepthStencilAttachment-01418",
5984                          "VUID-VkSubpassDescription2KHR-pDepthStencilAttachment-03071");
5985 
5986     attachments[subpass.pDepthStencilAttachment->attachment].samples = attachments[subpass.pColorAttachments[0].attachment].samples;
5987     subpass.colorAttachmentCount = (uint32_t)color.size();
5988 
5989     // Test resolve attachment with UNUSED color attachment
5990     color[0].attachment = VK_ATTACHMENT_UNUSED;
5991 
5992     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported,
5993                          "VUID-VkSubpassDescription-pResolveAttachments-00847",
5994                          "VUID-VkSubpassDescription2KHR-pResolveAttachments-03065");
5995 
5996     color[0].attachment = 1;
5997 
5998     // Test resolve from a single-sampled color attachment
5999     attachments[subpass.pColorAttachments[0].attachment].samples = VK_SAMPLE_COUNT_1_BIT;
6000     subpass.colorAttachmentCount = 1;           // avoid mismatch (00337), and avoid double report
6001     subpass.pDepthStencilAttachment = nullptr;  // avoid mismatch (01418)
6002 
6003     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported,
6004                          "VUID-VkSubpassDescription-pResolveAttachments-00848",
6005                          "VUID-VkSubpassDescription2KHR-pResolveAttachments-03066");
6006 
6007     attachments[subpass.pColorAttachments[0].attachment].samples = VK_SAMPLE_COUNT_4_BIT;
6008     subpass.colorAttachmentCount = (uint32_t)color.size();
6009     subpass.pDepthStencilAttachment = &depth;
6010 
6011     // Test resolve to a multi-sampled resolve attachment
6012     attachments[subpass.pResolveAttachments[0].attachment].samples = VK_SAMPLE_COUNT_4_BIT;
6013 
6014     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported,
6015                          "VUID-VkSubpassDescription-pResolveAttachments-00849",
6016                          "VUID-VkSubpassDescription2KHR-pResolveAttachments-03067");
6017 
6018     attachments[subpass.pResolveAttachments[0].attachment].samples = VK_SAMPLE_COUNT_1_BIT;
6019 
6020     // Test with color/resolve format mismatch
6021     attachments[subpass.pColorAttachments[0].attachment].format = VK_FORMAT_R8G8B8A8_SRGB;
6022 
6023     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported,
6024                          "VUID-VkSubpassDescription-pResolveAttachments-00850",
6025                          "VUID-VkSubpassDescription2KHR-pResolveAttachments-03068");
6026 
6027     attachments[subpass.pColorAttachments[0].attachment].format = attachments[subpass.pResolveAttachments[0].attachment].format;
6028 
6029     // Test for UNUSED preserve attachments
6030     preserve[0] = VK_ATTACHMENT_UNUSED;
6031 
6032     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkSubpassDescription-attachment-00853",
6033                          "VUID-VkSubpassDescription2KHR-attachment-03073");
6034 
6035     preserve[0] = 5;
6036     // Test for preserve attachments used elsewhere in the subpass
6037     color[0].attachment = preserve[0];
6038 
6039     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported,
6040                          "VUID-VkSubpassDescription-pPreserveAttachments-00854",
6041                          "VUID-VkSubpassDescription2KHR-pPreserveAttachments-03074");
6042 
6043     color[0].attachment = 1;
6044     input[0].attachment = 0;
6045     input[0].layout = VK_IMAGE_LAYOUT_GENERAL;
6046 
6047     // Test for attachment used first as input with loadOp=CLEAR
6048     {
6049         std::vector<VkSubpassDescription> subpasses = {subpass, subpass, subpass};
6050         subpasses[0].inputAttachmentCount = 0;
6051         subpasses[1].inputAttachmentCount = 0;
6052         attachments[input[0].attachment].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
6053         VkRenderPassCreateInfo rpci_multipass = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
6054                                                  nullptr,
6055                                                  0,
6056                                                  (uint32_t)attachments.size(),
6057                                                  attachments.data(),
6058                                                  (uint32_t)subpasses.size(),
6059                                                  subpasses.data(),
6060                                                  0,
6061                                                  nullptr};
6062 
6063         TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci_multipass, rp2Supported,
6064                              "VUID-VkSubpassDescription-loadOp-00846", "VUID-VkSubpassDescription2KHR-loadOp-03064");
6065 
6066         attachments[input[0].attachment].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
6067     }
6068 }
6069 
TEST_F(VkLayerTest,RenderPassCreateAttachmentReferenceInvalidLayout)6070 TEST_F(VkLayerTest, RenderPassCreateAttachmentReferenceInvalidLayout) {
6071     TEST_DESCRIPTION("Attachment reference uses PREINITIALIZED or UNDEFINED layouts");
6072 
6073     // Check for VK_KHR_get_physical_device_properties2
6074     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6075         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6076     }
6077 
6078     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
6079     bool rp2Supported = CheckCreateRenderPass2Support(this, m_device_extension_names);
6080     ASSERT_NO_FATAL_FAILURE(InitState());
6081 
6082     VkAttachmentDescription attach[] = {
6083         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
6084          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
6085          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
6086     };
6087     VkAttachmentReference refs[] = {
6088         {0, VK_IMAGE_LAYOUT_UNDEFINED},
6089     };
6090     VkSubpassDescription subpasses[] = {
6091         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, refs, nullptr, nullptr, 0, nullptr},
6092     };
6093 
6094     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 0, nullptr};
6095 
6096     // Use UNDEFINED layout
6097     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkAttachmentReference-layout-00857",
6098                          "VUID-VkAttachmentReference2KHR-layout-03077");
6099 
6100     // Use PREINITIALIZED layout
6101     refs[0].layout = VK_IMAGE_LAYOUT_PREINITIALIZED;
6102     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkAttachmentReference-layout-00857",
6103                          "VUID-VkAttachmentReference2KHR-layout-03077");
6104 }
6105 
TEST_F(VkLayerTest,RenderPassCreateOverlappingCorrelationMasks)6106 TEST_F(VkLayerTest, RenderPassCreateOverlappingCorrelationMasks) {
6107     TEST_DESCRIPTION("Create a subpass with overlapping correlation masks");
6108 
6109     // Check for VK_KHR_get_physical_device_properties2
6110     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6111         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6112     }
6113 
6114     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
6115     bool rp2Supported = CheckCreateRenderPass2Support(this, m_device_extension_names);
6116 
6117     if (!rp2Supported) {
6118         if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MULTIVIEW_EXTENSION_NAME)) {
6119             m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME);
6120         } else {
6121             printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_MULTIVIEW_EXTENSION_NAME);
6122             return;
6123         }
6124     }
6125 
6126     ASSERT_NO_FATAL_FAILURE(InitState());
6127 
6128     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr};
6129     uint32_t viewMasks[] = {0x3u};
6130     uint32_t correlationMasks[] = {0x1u, 0x3u};
6131     VkRenderPassMultiviewCreateInfo rpmvci = {
6132         VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO, nullptr, 1, viewMasks, 0, nullptr, 2, correlationMasks};
6133 
6134     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, &rpmvci, 0, 0, nullptr, 1, &subpass, 0, nullptr};
6135 
6136     // Correlation masks must not overlap
6137     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported,
6138                          "VUID-VkRenderPassMultiviewCreateInfo-pCorrelationMasks-00841",
6139                          "VUID-VkRenderPassCreateInfo2KHR-pCorrelatedViewMasks-03056");
6140 
6141     // Check for more specific "don't set any correlation masks when multiview is not enabled"
6142     if (rp2Supported) {
6143         PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR =
6144             (PFN_vkCreateRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCreateRenderPass2KHR");
6145 
6146         viewMasks[0] = 0;
6147         correlationMasks[0] = 0;
6148         correlationMasks[1] = 0;
6149         safe_VkRenderPassCreateInfo2KHR safe_rpci2;
6150         ConvertVkRenderPassCreateInfoToV2KHR(&rpci, &safe_rpci2);
6151 
6152         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkRenderPassCreateInfo2KHR-viewMask-03057");
6153         VkRenderPass rp;
6154         VkResult err = vkCreateRenderPass2KHR(m_device->device(), safe_rpci2.ptr(), nullptr, &rp);
6155         if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr);
6156         m_errorMonitor->VerifyFound();
6157     }
6158 }
6159 
TEST_F(VkLayerTest,RenderPassCreateInvalidViewMasks)6160 TEST_F(VkLayerTest, RenderPassCreateInvalidViewMasks) {
6161     TEST_DESCRIPTION("Create a subpass with the wrong number of view masks, or inconsistent setting of view masks");
6162 
6163     // Check for VK_KHR_get_physical_device_properties2
6164     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6165         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6166     }
6167 
6168     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
6169     bool rp2Supported = CheckCreateRenderPass2Support(this, m_device_extension_names);
6170 
6171     if (!rp2Supported) {
6172         if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MULTIVIEW_EXTENSION_NAME)) {
6173             m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME);
6174         } else {
6175             printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_MULTIVIEW_EXTENSION_NAME);
6176             return;
6177         }
6178     }
6179 
6180     ASSERT_NO_FATAL_FAILURE(InitState());
6181 
6182     VkSubpassDescription subpasses[] = {
6183         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr},
6184         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr},
6185     };
6186     uint32_t viewMasks[] = {0x3u, 0u};
6187     VkRenderPassMultiviewCreateInfo rpmvci = {
6188         VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO, nullptr, 1, viewMasks, 0, nullptr, 0, nullptr};
6189 
6190     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, &rpmvci, 0, 0, nullptr, 2, subpasses, 0, nullptr};
6191 
6192     // Not enough view masks
6193     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkRenderPassCreateInfo-pNext-01928",
6194                          "VUID-VkRenderPassCreateInfo2KHR-viewMask-03058");
6195 }
6196 
TEST_F(VkLayerTest,RenderPassCreateInvalidInputAttachmentReferences)6197 TEST_F(VkLayerTest, RenderPassCreateInvalidInputAttachmentReferences) {
6198     TEST_DESCRIPTION("Create a subpass with the meta data aspect mask set for an input attachment");
6199 
6200     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
6201 
6202     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE2_EXTENSION_NAME)) {
6203         m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME);
6204     } else {
6205         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_MAINTENANCE2_EXTENSION_NAME);
6206         return;
6207     }
6208 
6209     ASSERT_NO_FATAL_FAILURE(InitState());
6210 
6211     VkAttachmentDescription attach = {0,
6212                                       VK_FORMAT_R8G8B8A8_UNORM,
6213                                       VK_SAMPLE_COUNT_1_BIT,
6214                                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6215                                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
6216                                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6217                                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
6218                                       VK_IMAGE_LAYOUT_UNDEFINED,
6219                                       VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
6220     VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
6221 
6222     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &ref, 0, nullptr, nullptr, nullptr, 0, nullptr};
6223     VkInputAttachmentAspectReference iaar = {0, 0, VK_IMAGE_ASPECT_METADATA_BIT};
6224     VkRenderPassInputAttachmentAspectCreateInfo rpiaaci = {VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO,
6225                                                            nullptr, 1, &iaar};
6226 
6227     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, &rpiaaci, 0, 1, &attach, 1, &subpass, 0, nullptr};
6228 
6229     // Invalid meta data aspect
6230     m_errorMonitor->SetDesiredFailureMsg(
6231         VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkRenderPassCreateInfo-pNext-01963");  // Cannot/should not avoid getting this one too
6232     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, false, "VUID-VkInputAttachmentAspectReference-aspectMask-01964",
6233                          nullptr);
6234 
6235     // Aspect not present
6236     iaar.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
6237     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, false, "VUID-VkRenderPassCreateInfo-pNext-01963", nullptr);
6238 
6239     // Invalid subpass index
6240     iaar.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
6241     iaar.subpass = 1;
6242     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, false, "VUID-VkRenderPassCreateInfo-pNext-01926", nullptr);
6243     iaar.subpass = 0;
6244 
6245     // Invalid input attachment index
6246     iaar.inputAttachmentIndex = 1;
6247     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, false, "VUID-VkRenderPassCreateInfo-pNext-01927", nullptr);
6248 }
6249 
TEST_F(VkLayerTest,RenderPassCreateSubpassNonGraphicsPipeline)6250 TEST_F(VkLayerTest, RenderPassCreateSubpassNonGraphicsPipeline) {
6251     TEST_DESCRIPTION("Create a subpass with the compute pipeline bind point");
6252     // Check for VK_KHR_get_physical_device_properties2
6253     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6254         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6255     }
6256 
6257     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
6258     bool rp2Supported = CheckCreateRenderPass2Support(this, m_device_extension_names);
6259     ASSERT_NO_FATAL_FAILURE(InitState());
6260 
6261     VkSubpassDescription subpasses[] = {
6262         {0, VK_PIPELINE_BIND_POINT_COMPUTE, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr},
6263     };
6264 
6265     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, subpasses, 0, nullptr};
6266 
6267     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported,
6268                          "VUID-VkSubpassDescription-pipelineBindPoint-00844",
6269                          "VUID-VkSubpassDescription2KHR-pipelineBindPoint-03062");
6270 }
6271 
TEST_F(VkLayerTest,RenderPassCreateSubpassMissingAttributesBitMultiviewNVX)6272 TEST_F(VkLayerTest, RenderPassCreateSubpassMissingAttributesBitMultiviewNVX) {
6273     TEST_DESCRIPTION("Create a subpass with the VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX flag missing");
6274 
6275     // Check for VK_KHR_get_physical_device_properties2
6276     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6277         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6278     } else {
6279         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_EXTENSION_NAME);
6280         return;
6281     }
6282 
6283     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
6284 
6285     if (DeviceExtensionSupported(gpu(), nullptr, VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_EXTENSION_NAME) &&
6286         DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MULTIVIEW_EXTENSION_NAME)) {
6287         m_device_extension_names.push_back(VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_EXTENSION_NAME);
6288         m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME);
6289     } else {
6290         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_EXTENSION_NAME);
6291         return;
6292     }
6293 
6294     bool rp2Supported = CheckCreateRenderPass2Support(this, m_device_extension_names);
6295     ASSERT_NO_FATAL_FAILURE(InitState());
6296 
6297     VkSubpassDescription subpasses[] = {
6298         {VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr,
6299          nullptr, 0, nullptr},
6300     };
6301 
6302     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, subpasses, 0, nullptr};
6303 
6304     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkSubpassDescription-flags-00856",
6305                          "VUID-VkSubpassDescription2KHR-flags-03076");
6306 }
6307 
TEST_F(VkLayerTest,RenderPassCreate2SubpassInvalidInputAttachmentParameters)6308 TEST_F(VkLayerTest, RenderPassCreate2SubpassInvalidInputAttachmentParameters) {
6309     TEST_DESCRIPTION("Create a subpass with parameters in the input attachment ref which are invalid");
6310 
6311     // Check for VK_KHR_get_physical_device_properties2
6312     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6313         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6314     } else {
6315         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
6316         return;
6317     }
6318 
6319     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
6320 
6321     bool rp2Supported = CheckCreateRenderPass2Support(this, m_device_extension_names);
6322 
6323     if (!rp2Supported) {
6324         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
6325         return;
6326     }
6327 
6328     ASSERT_NO_FATAL_FAILURE(InitState());
6329 
6330     PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR =
6331         rp2Supported ? (PFN_vkCreateRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCreateRenderPass2KHR") : nullptr;
6332 
6333     VkResult err;
6334 
6335     VkAttachmentReference2KHR reference = {VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR, nullptr, VK_ATTACHMENT_UNUSED,
6336                                            VK_IMAGE_LAYOUT_UNDEFINED, 0};
6337     VkSubpassDescription2KHR subpass = {VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR,
6338                                         nullptr,
6339                                         0,
6340                                         VK_PIPELINE_BIND_POINT_GRAPHICS,
6341                                         0,
6342                                         1,
6343                                         &reference,
6344                                         0,
6345                                         nullptr,
6346                                         nullptr,
6347                                         nullptr,
6348                                         0,
6349                                         nullptr};
6350 
6351     VkRenderPassCreateInfo2KHR rpci2 = {
6352         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR, nullptr, 0, 0, nullptr, 1, &subpass, 0, nullptr, 0, nullptr};
6353     VkRenderPass rp;
6354 
6355     // Test for aspect mask of 0
6356     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription2KHR-aspectMask-03176");
6357     err = vkCreateRenderPass2KHR(m_device->device(), &rpci2, nullptr, &rp);
6358     if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr);
6359     m_errorMonitor->VerifyFound();
6360 
6361     // Test for invalid aspect mask bits
6362     reference.aspectMask |= VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM;
6363     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubpassDescription2KHR-aspectMask-03175");
6364     err = vkCreateRenderPass2KHR(m_device->device(), &rpci2, nullptr, &rp);
6365     if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr);
6366     m_errorMonitor->VerifyFound();
6367 }
6368 
TEST_F(VkLayerTest,RenderPassCreateInvalidSubpassDependencies)6369 TEST_F(VkLayerTest, RenderPassCreateInvalidSubpassDependencies) {
6370     // Check for VK_KHR_get_physical_device_properties2
6371     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6372         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6373     }
6374 
6375     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
6376 
6377     bool rp2Supported = CheckCreateRenderPass2Support(this, m_device_extension_names);
6378     bool multiviewSupported = rp2Supported;
6379 
6380     if (!rp2Supported && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MULTIVIEW_EXTENSION_NAME)) {
6381         m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME);
6382         multiviewSupported = true;
6383     }
6384 
6385     // Add a device features struct enabling NO features
6386     VkPhysicalDeviceFeatures features = {0};
6387     ASSERT_NO_FATAL_FAILURE(InitState(&features));
6388 
6389     if (m_device->props.apiVersion >= VK_API_VERSION_1_1) {
6390         multiviewSupported = true;
6391     }
6392 
6393     // Create two dummy subpasses
6394     VkSubpassDescription subpasses[] = {
6395         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr},
6396         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr},
6397     };
6398 
6399     VkSubpassDependency dependency;
6400     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 2, subpasses, 1, &dependency};
6401     //	dependency = { 0, 1, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, 0 };
6402 
6403     // Source subpass is not EXTERNAL, so source stage mask must not include HOST
6404     dependency = {0, 1, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, 0};
6405 
6406     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkSubpassDependency-srcSubpass-00858",
6407                          "VUID-VkSubpassDependency2KHR-srcSubpass-03078");
6408 
6409     // Destination subpass is not EXTERNAL, so destination stage mask must not include HOST
6410     dependency = {0, 1, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, 0};
6411 
6412     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkSubpassDependency-dstSubpass-00859",
6413                          "VUID-VkSubpassDependency2KHR-dstSubpass-03079");
6414 
6415     // Geometry shaders not enabled source
6416     dependency = {0, 1, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, 0};
6417 
6418     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkSubpassDependency-srcStageMask-00860",
6419                          "VUID-VkSubpassDependency2KHR-srcStageMask-03080");
6420 
6421     // Geometry shaders not enabled destination
6422     dependency = {0, 1, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, 0, 0, 0};
6423 
6424     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkSubpassDependency-dstStageMask-00861",
6425                          "VUID-VkSubpassDependency2KHR-dstStageMask-03081");
6426 
6427     // Tessellation not enabled source
6428     dependency = {0, 1, VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, 0};
6429 
6430     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkSubpassDependency-srcStageMask-00862",
6431                          "VUID-VkSubpassDependency2KHR-srcStageMask-03082");
6432 
6433     // Tessellation not enabled destination
6434     dependency = {0, 1, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, 0, 0, 0};
6435 
6436     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkSubpassDependency-dstStageMask-00863",
6437                          "VUID-VkSubpassDependency2KHR-dstStageMask-03083");
6438 
6439     // Potential cyclical dependency
6440     dependency = {1, 0, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, 0};
6441 
6442     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkSubpassDependency-srcSubpass-00864",
6443                          "VUID-VkSubpassDependency2KHR-srcSubpass-03084");
6444 
6445     // EXTERNAL to EXTERNAL dependency
6446     dependency = {
6447         VK_SUBPASS_EXTERNAL, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, 0};
6448 
6449     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkSubpassDependency-srcSubpass-00865",
6450                          "VUID-VkSubpassDependency2KHR-srcSubpass-03085");
6451 
6452     // Source compute stage not part of subpass 0's GRAPHICS pipeline
6453     dependency = {0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, 0};
6454 
6455     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkRenderPassCreateInfo-pDependencies-00837",
6456                          "VUID-VkRenderPassCreateInfo2KHR-pDependencies-03054");
6457 
6458     // Destination compute stage not part of subpass 0's GRAPHICS pipeline
6459     dependency = {VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, 0};
6460 
6461     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkRenderPassCreateInfo-pDependencies-00838",
6462                          "VUID-VkRenderPassCreateInfo2KHR-pDependencies-03055");
6463 
6464     // Non graphics stage in self dependency
6465     dependency = {0, 0, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, 0};
6466 
6467     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkSubpassDependency-srcSubpass-01989",
6468                          "VUID-VkSubpassDependency2KHR-srcSubpass-02244");
6469 
6470     // Logically later source stages in self dependency
6471     dependency = {0, 0, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, 0, 0};
6472 
6473     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkSubpassDependency-srcSubpass-00867",
6474                          "VUID-VkSubpassDependency2KHR-srcSubpass-03087");
6475 
6476     // Source access mask mismatch with source stage mask
6477     dependency = {0, 1, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_ACCESS_UNIFORM_READ_BIT, 0, 0};
6478 
6479     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkSubpassDependency-srcAccessMask-00868",
6480                          "VUID-VkSubpassDependency2KHR-srcAccessMask-03088");
6481 
6482     // Destination access mask mismatch with destination stage mask
6483     dependency = {
6484         0, 1, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 0};
6485 
6486     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkSubpassDependency-dstAccessMask-00869",
6487                          "VUID-VkSubpassDependency2KHR-dstAccessMask-03089");
6488 
6489     if (multiviewSupported) {
6490         // VIEW_LOCAL_BIT but multiview is not enabled
6491         dependency = {0, 1, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
6492                       0, 0, VK_DEPENDENCY_VIEW_LOCAL_BIT};
6493 
6494         TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, nullptr,
6495                              "VUID-VkRenderPassCreateInfo2KHR-viewMask-03059");
6496 
6497         // Enable multiview
6498         uint32_t pViewMasks[2] = {0x3u, 0x3u};
6499         int32_t pViewOffsets[2] = {0, 0};
6500         VkRenderPassMultiviewCreateInfo rpmvci = {
6501             VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO, nullptr, 2, pViewMasks, 0, nullptr, 0, nullptr};
6502         rpci.pNext = &rpmvci;
6503 
6504         // Excessive view offsets
6505         dependency = {0, 1, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
6506                       0, 0, VK_DEPENDENCY_VIEW_LOCAL_BIT};
6507         rpmvci.pViewOffsets = pViewOffsets;
6508         rpmvci.dependencyCount = 2;
6509 
6510         TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, false, "VUID-VkRenderPassCreateInfo-pNext-01929", nullptr);
6511 
6512         rpmvci.dependencyCount = 0;
6513 
6514         // View offset with subpass self dependency
6515         dependency = {0, 0, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
6516                       0, 0, VK_DEPENDENCY_VIEW_LOCAL_BIT};
6517         rpmvci.pViewOffsets = pViewOffsets;
6518         pViewOffsets[0] = 1;
6519         rpmvci.dependencyCount = 1;
6520 
6521         TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, false, "VUID-VkRenderPassCreateInfo-pNext-01930", nullptr);
6522 
6523         rpmvci.dependencyCount = 0;
6524 
6525         // View offset with no view local bit
6526         if (rp2Supported) {
6527             dependency = {0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, 0};
6528             rpmvci.pViewOffsets = pViewOffsets;
6529             pViewOffsets[0] = 1;
6530             rpmvci.dependencyCount = 1;
6531 
6532             safe_VkRenderPassCreateInfo2KHR safe_rpci2;
6533             ConvertVkRenderPassCreateInfoToV2KHR(&rpci, &safe_rpci2);
6534 
6535             TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, nullptr,
6536                                  "VUID-VkSubpassDependency2KHR-dependencyFlags-03092");
6537 
6538             rpmvci.dependencyCount = 0;
6539         }
6540 
6541         // EXTERNAL subpass with VIEW_LOCAL_BIT - source subpass
6542         dependency = {VK_SUBPASS_EXTERNAL,         1, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0,
6543                       VK_DEPENDENCY_VIEW_LOCAL_BIT};
6544 
6545         TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported,
6546                              "VUID-VkSubpassDependency-dependencyFlags-02520",
6547                              "VUID-VkSubpassDependency2KHR-dependencyFlags-03090");
6548 
6549         // EXTERNAL subpass with VIEW_LOCAL_BIT - destination subpass
6550         dependency = {0, VK_SUBPASS_EXTERNAL,         VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0,
6551                       0, VK_DEPENDENCY_VIEW_LOCAL_BIT};
6552 
6553         TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported,
6554                              "VUID-VkSubpassDependency-dependencyFlags-02521",
6555                              "VUID-VkSubpassDependency2KHR-dependencyFlags-03091");
6556 
6557         // Multiple views but no view local bit in self-dependency
6558         dependency = {0, 0, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, 0};
6559 
6560         TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported, "VUID-VkSubpassDependency-srcSubpass-00872",
6561                              "VUID-VkRenderPassCreateInfo2KHR-pDependencies-03060");
6562     }
6563 }
6564 
TEST_F(VkLayerTest,RenderPassCreateInvalidMixedAttachmentSamplesAMD)6565 TEST_F(VkLayerTest, RenderPassCreateInvalidMixedAttachmentSamplesAMD) {
6566     TEST_DESCRIPTION("Verify error messages for supported and unsupported sample counts in render pass attachments.");
6567 
6568     // Check for VK_KHR_get_physical_device_properties2
6569     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6570         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6571     }
6572 
6573     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
6574 
6575     if (DeviceExtensionSupported(gpu(), nullptr, VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME)) {
6576         m_device_extension_names.push_back(VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME);
6577     } else {
6578         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME);
6579         return;
6580     }
6581 
6582     bool rp2Supported = CheckCreateRenderPass2Support(this, m_device_extension_names);
6583 
6584     ASSERT_NO_FATAL_FAILURE(InitState());
6585 
6586     std::vector<VkAttachmentDescription> attachments;
6587 
6588     {
6589         VkAttachmentDescription att = {};
6590         att.format = VK_FORMAT_R8G8B8A8_UNORM;
6591         att.samples = VK_SAMPLE_COUNT_1_BIT;
6592         att.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
6593         att.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
6594         att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
6595         att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
6596         att.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
6597         att.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
6598 
6599         attachments.push_back(att);
6600 
6601         att.format = VK_FORMAT_D16_UNORM;
6602         att.samples = VK_SAMPLE_COUNT_4_BIT;
6603         att.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
6604         att.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
6605         att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
6606         att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
6607         att.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
6608         att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
6609 
6610         attachments.push_back(att);
6611     }
6612 
6613     VkAttachmentReference color_ref = {};
6614     color_ref.attachment = 0;
6615     color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
6616 
6617     VkAttachmentReference depth_ref = {};
6618     depth_ref.attachment = 1;
6619     depth_ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
6620 
6621     VkSubpassDescription subpass = {};
6622     subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
6623     subpass.colorAttachmentCount = 1;
6624     subpass.pColorAttachments = &color_ref;
6625     subpass.pDepthStencilAttachment = &depth_ref;
6626 
6627     VkRenderPassCreateInfo rpci = {};
6628     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
6629     rpci.attachmentCount = attachments.size();
6630     rpci.pAttachments = attachments.data();
6631     rpci.subpassCount = 1;
6632     rpci.pSubpasses = &subpass;
6633 
6634     m_errorMonitor->ExpectSuccess();
6635 
6636     VkRenderPass rp;
6637     VkResult err;
6638 
6639     err = vkCreateRenderPass(device(), &rpci, NULL, &rp);
6640     m_errorMonitor->VerifyNotFound();
6641     if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr);
6642 
6643     // Expect an error message for invalid sample counts
6644     attachments[0].samples = VK_SAMPLE_COUNT_4_BIT;
6645     attachments[1].samples = VK_SAMPLE_COUNT_1_BIT;
6646 
6647     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2Supported,
6648                          "VUID-VkSubpassDescription-pColorAttachments-01506",
6649                          "VUID-VkSubpassDescription2KHR-pColorAttachments-03070");
6650 }
6651 
TestRenderPassBegin(ErrorMonitor * error_monitor,const VkDevice device,const VkCommandBuffer command_buffer,const VkRenderPassBeginInfo * begin_info,bool rp2Supported,const char * rp1_vuid,const char * rp2_vuid)6652 static void TestRenderPassBegin(ErrorMonitor *error_monitor, const VkDevice device, const VkCommandBuffer command_buffer,
6653                                 const VkRenderPassBeginInfo *begin_info, bool rp2Supported, const char *rp1_vuid,
6654                                 const char *rp2_vuid) {
6655     VkCommandBufferBeginInfo cmd_begin_info = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
6656                                                VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, nullptr};
6657 
6658     if (rp1_vuid) {
6659         vkBeginCommandBuffer(command_buffer, &cmd_begin_info);
6660         error_monitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, rp1_vuid);
6661         vkCmdBeginRenderPass(command_buffer, begin_info, VK_SUBPASS_CONTENTS_INLINE);
6662         error_monitor->VerifyFound();
6663         vkResetCommandBuffer(command_buffer, 0);
6664     }
6665     if (rp2Supported && rp2_vuid) {
6666         PFN_vkCmdBeginRenderPass2KHR vkCmdBeginRenderPass2KHR =
6667             (PFN_vkCmdBeginRenderPass2KHR)vkGetDeviceProcAddr(device, "vkCmdBeginRenderPass2KHR");
6668         VkSubpassBeginInfoKHR subpass_begin_info = {VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR, nullptr, VK_SUBPASS_CONTENTS_INLINE};
6669         vkBeginCommandBuffer(command_buffer, &cmd_begin_info);
6670         error_monitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, rp2_vuid);
6671         vkCmdBeginRenderPass2KHR(command_buffer, begin_info, &subpass_begin_info);
6672         error_monitor->VerifyFound();
6673         vkResetCommandBuffer(command_buffer, 0);
6674     }
6675 }
6676 
TEST_F(VkLayerTest,RenderPassBeginInvalidRenderArea)6677 TEST_F(VkLayerTest, RenderPassBeginInvalidRenderArea) {
6678     TEST_DESCRIPTION("Generate INVALID_RENDER_AREA error by beginning renderpass with extent outside of framebuffer");
6679     // Check for VK_KHR_get_physical_device_properties2
6680     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6681         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6682     }
6683 
6684     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
6685     bool rp2Supported = CheckCreateRenderPass2Support(this, m_device_extension_names);
6686     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
6687 
6688     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6689 
6690     // Framebuffer for render target is 256x256, exceed that for INVALID_RENDER_AREA
6691     m_renderPassBeginInfo.renderArea.extent.width = 257;
6692     m_renderPassBeginInfo.renderArea.extent.height = 257;
6693 
6694     TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &m_renderPassBeginInfo, rp2Supported,
6695                         "Cannot execute a render pass with renderArea not within the bound of the framebuffer.",
6696                         "Cannot execute a render pass with renderArea not within the bound of the framebuffer.");
6697 }
6698 
TEST_F(VkLayerTest,RenderPassBeginWithinRenderPass)6699 TEST_F(VkLayerTest, RenderPassBeginWithinRenderPass) {
6700     // Check for VK_KHR_get_physical_device_properties2
6701     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6702         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6703     }
6704 
6705     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
6706     PFN_vkCmdBeginRenderPass2KHR vkCmdBeginRenderPass2KHR = nullptr;
6707     bool rp2Supported = CheckCreateRenderPass2Support(this, m_device_extension_names);
6708     ASSERT_NO_FATAL_FAILURE(InitState());
6709 
6710     if (rp2Supported) {
6711         vkCmdBeginRenderPass2KHR =
6712             (PFN_vkCmdBeginRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdBeginRenderPass2KHR");
6713     }
6714 
6715     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6716 
6717     // Bind a BeginRenderPass within an active RenderPass
6718     m_commandBuffer->begin();
6719     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
6720 
6721     // Just use a dummy Renderpass
6722     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBeginRenderPass-renderpass");
6723     vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
6724 
6725     m_errorMonitor->VerifyFound();
6726 
6727     if (rp2Supported) {
6728         VkSubpassBeginInfoKHR subpassBeginInfo = {VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR, nullptr, VK_SUBPASS_CONTENTS_INLINE};
6729 
6730         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBeginRenderPass2KHR-renderpass");
6731         vkCmdBeginRenderPass2KHR(m_commandBuffer->handle(), &m_renderPassBeginInfo, &subpassBeginInfo);
6732         m_errorMonitor->VerifyFound();
6733     }
6734 }
6735 
TEST_F(VkLayerTest,RenderPassBeginIncompatibleFramebufferRenderPass)6736 TEST_F(VkLayerTest, RenderPassBeginIncompatibleFramebufferRenderPass) {
6737     TEST_DESCRIPTION("Test that renderpass begin is compatible with the framebuffer renderpass ");
6738 
6739     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
6740 
6741     // Create a depth stencil image view
6742     VkImageObj image(m_device);
6743 
6744     image.Init(128, 128, 1, VK_FORMAT_D16_UNORM, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
6745     ASSERT_TRUE(image.initialized());
6746 
6747     VkImageView dsv;
6748     VkImageViewCreateInfo dsvci = {};
6749     dsvci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
6750     dsvci.pNext = nullptr;
6751     dsvci.image = image.handle();
6752     dsvci.viewType = VK_IMAGE_VIEW_TYPE_2D;
6753     dsvci.format = VK_FORMAT_D16_UNORM;
6754     dsvci.subresourceRange.layerCount = 1;
6755     dsvci.subresourceRange.baseMipLevel = 0;
6756     dsvci.subresourceRange.levelCount = 1;
6757     dsvci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
6758     vkCreateImageView(m_device->device(), &dsvci, NULL, &dsv);
6759 
6760     // Create a renderPass with a single attachment that uses loadOp CLEAR
6761     VkAttachmentDescription description = {0,
6762                                            VK_FORMAT_D16_UNORM,
6763                                            VK_SAMPLE_COUNT_1_BIT,
6764                                            VK_ATTACHMENT_LOAD_OP_LOAD,
6765                                            VK_ATTACHMENT_STORE_OP_DONT_CARE,
6766                                            VK_ATTACHMENT_LOAD_OP_CLEAR,
6767                                            VK_ATTACHMENT_STORE_OP_DONT_CARE,
6768                                            VK_IMAGE_LAYOUT_GENERAL,
6769                                            VK_IMAGE_LAYOUT_GENERAL};
6770 
6771     VkAttachmentReference depth_stencil_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
6772 
6773     VkSubpassDescription subpass = {0,      VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &depth_stencil_ref, 0,
6774                                     nullptr};
6775 
6776     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &description, 1, &subpass, 0, nullptr};
6777     VkRenderPass rp1, rp2;
6778 
6779     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp1);
6780     subpass.pDepthStencilAttachment = nullptr;
6781     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp2);
6782 
6783     // Create a framebuffer
6784 
6785     VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp1, 1, &dsv, 128, 128, 1};
6786     VkFramebuffer fb;
6787 
6788     vkCreateFramebuffer(m_device->handle(), &fbci, nullptr, &fb);
6789 
6790     VkRenderPassBeginInfo rp_begin = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp2, fb, {{0, 0}, {128, 128}}, 0, nullptr};
6791 
6792     TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &rp_begin, false,
6793                         "VUID-VkRenderPassBeginInfo-renderPass-00904", nullptr);
6794 
6795     vkDestroyRenderPass(m_device->device(), rp1, nullptr);
6796     vkDestroyRenderPass(m_device->device(), rp2, nullptr);
6797     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
6798     vkDestroyImageView(m_device->device(), dsv, nullptr);
6799 }
6800 
TEST_F(VkLayerTest,RenderPassBeginLayoutsFramebufferImageUsageMismatches)6801 TEST_F(VkLayerTest, RenderPassBeginLayoutsFramebufferImageUsageMismatches) {
6802     TEST_DESCRIPTION(
6803         "Test that renderpass initial/final layouts match up with the usage bits set for each attachment of the framebuffer");
6804 
6805     // Check for VK_KHR_get_physical_device_properties2
6806     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6807         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6808     }
6809 
6810     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
6811     bool rp2Supported = CheckCreateRenderPass2Support(this, m_device_extension_names);
6812     bool maintenance2Supported = rp2Supported;
6813 
6814     // Check for VK_KHR_maintenance2
6815     if (!rp2Supported && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE2_EXTENSION_NAME)) {
6816         m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME);
6817         maintenance2Supported = true;
6818     }
6819 
6820     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
6821 
6822     if (m_device->props.apiVersion >= VK_API_VERSION_1_1) {
6823         maintenance2Supported = true;
6824     }
6825 
6826     // Create an input attachment view
6827     VkImageObj iai(m_device);
6828 
6829     iai.InitNoLayout(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
6830     ASSERT_TRUE(iai.initialized());
6831 
6832     VkImageView iav;
6833     VkImageViewCreateInfo iavci = {};
6834     iavci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
6835     iavci.pNext = nullptr;
6836     iavci.image = iai.handle();
6837     iavci.viewType = VK_IMAGE_VIEW_TYPE_2D;
6838     iavci.format = VK_FORMAT_R8G8B8A8_UNORM;
6839     iavci.subresourceRange.layerCount = 1;
6840     iavci.subresourceRange.baseMipLevel = 0;
6841     iavci.subresourceRange.levelCount = 1;
6842     iavci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
6843     vkCreateImageView(m_device->device(), &iavci, NULL, &iav);
6844 
6845     // Create a color attachment view
6846     VkImageObj cai(m_device);
6847 
6848     cai.InitNoLayout(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
6849     ASSERT_TRUE(cai.initialized());
6850 
6851     VkImageView cav;
6852     VkImageViewCreateInfo cavci = {};
6853     cavci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
6854     cavci.pNext = nullptr;
6855     cavci.image = cai.handle();
6856     cavci.viewType = VK_IMAGE_VIEW_TYPE_2D;
6857     cavci.format = VK_FORMAT_R8G8B8A8_UNORM;
6858     cavci.subresourceRange.layerCount = 1;
6859     cavci.subresourceRange.baseMipLevel = 0;
6860     cavci.subresourceRange.levelCount = 1;
6861     cavci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
6862     vkCreateImageView(m_device->device(), &cavci, NULL, &cav);
6863 
6864     // Create a renderPass with those attachments
6865     VkAttachmentDescription descriptions[] = {
6866         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
6867          VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
6868         {1, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
6869          VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL}};
6870 
6871     VkAttachmentReference input_ref = {0, VK_IMAGE_LAYOUT_GENERAL};
6872     VkAttachmentReference color_ref = {1, VK_IMAGE_LAYOUT_GENERAL};
6873 
6874     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input_ref, 1, &color_ref, nullptr, nullptr, 0, nullptr};
6875 
6876     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descriptions, 1, &subpass, 0, nullptr};
6877 
6878     VkRenderPass rp;
6879 
6880     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
6881 
6882     // Create a framebuffer
6883 
6884     VkImageView views[] = {iav, cav};
6885 
6886     VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 2, views, 128, 128, 1};
6887     VkFramebuffer fb;
6888 
6889     vkCreateFramebuffer(m_device->handle(), &fbci, nullptr, &fb);
6890 
6891     VkRenderPassBeginInfo rp_begin = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {128, 128}}, 0, nullptr};
6892 
6893     VkRenderPass rp_invalid;
6894 
6895     // Initial layout is VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL but attachment doesn't support IMAGE_USAGE_COLOR_ATTACHMENT_BIT
6896     descriptions[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
6897     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_invalid);
6898     rp_begin.renderPass = rp_invalid;
6899     TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &rp_begin, rp2Supported,
6900                         "VUID-vkCmdBeginRenderPass-initialLayout-00895", "VUID-vkCmdBeginRenderPass2KHR-initialLayout-03094");
6901 
6902     vkDestroyRenderPass(m_device->handle(), rp_invalid, nullptr);
6903 
6904     // Initial layout is VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL but attachment doesn't support VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
6905     // / VK_IMAGE_USAGE_SAMPLED_BIT
6906     descriptions[0].initialLayout = VK_IMAGE_LAYOUT_GENERAL;
6907     descriptions[1].initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
6908     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_invalid);
6909     rp_begin.renderPass = rp_invalid;
6910 
6911     TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &rp_begin, rp2Supported,
6912                         "VUID-vkCmdBeginRenderPass-initialLayout-00897", "VUID-vkCmdBeginRenderPass2KHR-initialLayout-03097");
6913 
6914     vkDestroyRenderPass(m_device->handle(), rp_invalid, nullptr);
6915     descriptions[1].initialLayout = VK_IMAGE_LAYOUT_GENERAL;
6916 
6917     // Initial layout is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but attachment doesn't support VK_IMAGE_USAGE_TRANSFER_SRC_BIT
6918     descriptions[0].initialLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6919     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_invalid);
6920     rp_begin.renderPass = rp_invalid;
6921 
6922     TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &rp_begin, rp2Supported,
6923                         "VUID-vkCmdBeginRenderPass-initialLayout-00898", "VUID-vkCmdBeginRenderPass2KHR-initialLayout-03098");
6924 
6925     vkDestroyRenderPass(m_device->handle(), rp_invalid, nullptr);
6926 
6927     // Initial layout is VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL but attachment doesn't support VK_IMAGE_USAGE_TRANSFER_DST_BIT
6928     descriptions[0].initialLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6929     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_invalid);
6930     rp_begin.renderPass = rp_invalid;
6931 
6932     TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &rp_begin, rp2Supported,
6933                         "VUID-vkCmdBeginRenderPass-initialLayout-00899", "VUID-vkCmdBeginRenderPass2KHR-initialLayout-03099");
6934 
6935     vkDestroyRenderPass(m_device->handle(), rp_invalid, nullptr);
6936 
6937     // Initial layout is VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL but attachment doesn't support
6938     // VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
6939     descriptions[0].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
6940     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_invalid);
6941     rp_begin.renderPass = rp_invalid;
6942     const char *initial_layout_vuid_rp1 =
6943         maintenance2Supported ? "VUID-vkCmdBeginRenderPass-initialLayout-01758" : "VUID-vkCmdBeginRenderPass-initialLayout-00896";
6944 
6945     TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &rp_begin, rp2Supported,
6946                         initial_layout_vuid_rp1, "VUID-vkCmdBeginRenderPass2KHR-initialLayout-03096");
6947 
6948     vkDestroyRenderPass(m_device->handle(), rp_invalid, nullptr);
6949 
6950     // Initial layout is VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL but attachment doesn't support
6951     // VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
6952     descriptions[0].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
6953     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_invalid);
6954     rp_begin.renderPass = rp_invalid;
6955 
6956     TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &rp_begin, rp2Supported,
6957                         initial_layout_vuid_rp1, "VUID-vkCmdBeginRenderPass2KHR-initialLayout-03096");
6958 
6959     vkDestroyRenderPass(m_device->handle(), rp_invalid, nullptr);
6960 
6961     if (maintenance2Supported || rp2Supported) {
6962         // Initial layout is VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL but attachment doesn't support
6963         // VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
6964         descriptions[0].initialLayout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
6965         vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_invalid);
6966         rp_begin.renderPass = rp_invalid;
6967 
6968         TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &rp_begin, rp2Supported,
6969                             "VUID-vkCmdBeginRenderPass-initialLayout-01758", "VUID-vkCmdBeginRenderPass2KHR-initialLayout-03096");
6970 
6971         vkDestroyRenderPass(m_device->handle(), rp_invalid, nullptr);
6972 
6973         // Initial layout is VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL but attachment doesn't support
6974         // VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
6975         descriptions[0].initialLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL;
6976         vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_invalid);
6977         rp_begin.renderPass = rp_invalid;
6978 
6979         TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &rp_begin, rp2Supported,
6980                             "VUID-vkCmdBeginRenderPass-initialLayout-01758", "VUID-vkCmdBeginRenderPass2KHR-initialLayout-03096");
6981 
6982         vkDestroyRenderPass(m_device->handle(), rp_invalid, nullptr);
6983     }
6984 
6985     vkDestroyRenderPass(m_device->device(), rp, nullptr);
6986     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
6987     vkDestroyImageView(m_device->device(), iav, nullptr);
6988     vkDestroyImageView(m_device->device(), cav, nullptr);
6989 }
6990 
TEST_F(VkLayerTest,RenderPassBeginClearOpMismatch)6991 TEST_F(VkLayerTest, RenderPassBeginClearOpMismatch) {
6992     TEST_DESCRIPTION(
6993         "Begin a renderPass where clearValueCount is less than the number of renderPass attachments that use "
6994         "loadOp VK_ATTACHMENT_LOAD_OP_CLEAR.");
6995 
6996     // Check for VK_KHR_get_physical_device_properties2
6997     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6998         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6999     }
7000 
7001     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
7002     bool rp2Supported = CheckCreateRenderPass2Support(this, m_device_extension_names);
7003     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
7004 
7005     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7006 
7007     // Create a renderPass with a single attachment that uses loadOp CLEAR
7008     VkAttachmentReference attach = {};
7009     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
7010     VkSubpassDescription subpass = {};
7011     subpass.colorAttachmentCount = 1;
7012     subpass.pColorAttachments = &attach;
7013     VkRenderPassCreateInfo rpci = {};
7014     rpci.subpassCount = 1;
7015     rpci.pSubpasses = &subpass;
7016     rpci.attachmentCount = 1;
7017     VkAttachmentDescription attach_desc = {};
7018     attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
7019     // Set loadOp to CLEAR
7020     attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
7021     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
7022     attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
7023     rpci.pAttachments = &attach_desc;
7024     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
7025     VkRenderPass rp;
7026     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
7027 
7028     VkRenderPassBeginInfo rp_begin = {};
7029     rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
7030     rp_begin.pNext = NULL;
7031     rp_begin.renderPass = renderPass();
7032     rp_begin.framebuffer = framebuffer();
7033     rp_begin.clearValueCount = 0;  // Should be 1
7034 
7035     TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &rp_begin, rp2Supported,
7036                         "VUID-VkRenderPassBeginInfo-clearValueCount-00902", "VUID-VkRenderPassBeginInfo-clearValueCount-00902");
7037 
7038     vkDestroyRenderPass(m_device->device(), rp, NULL);
7039 }
7040 
TEST_F(VkLayerTest,RenderPassBeginSampleLocationsInvalidIndicesEXT)7041 TEST_F(VkLayerTest, RenderPassBeginSampleLocationsInvalidIndicesEXT) {
7042     TEST_DESCRIPTION("Test that attachment indices and subpass indices specifed by sample locations structures are valid");
7043 
7044     // Check for VK_KHR_get_physical_device_properties2
7045     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
7046         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7047     }
7048     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
7049     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME)) {
7050         m_device_extension_names.push_back(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME);
7051     } else {
7052         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME);
7053         return;
7054     }
7055 
7056     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
7057 
7058     // Create a depth stencil image view
7059     VkImageObj image(m_device);
7060 
7061     image.Init(128, 128, 1, VK_FORMAT_D16_UNORM, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
7062     ASSERT_TRUE(image.initialized());
7063 
7064     VkImageView dsv;
7065     VkImageViewCreateInfo dsvci = {};
7066     dsvci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
7067     dsvci.pNext = nullptr;
7068     dsvci.image = image.handle();
7069     dsvci.viewType = VK_IMAGE_VIEW_TYPE_2D;
7070     dsvci.format = VK_FORMAT_D16_UNORM;
7071     dsvci.subresourceRange.layerCount = 1;
7072     dsvci.subresourceRange.baseMipLevel = 0;
7073     dsvci.subresourceRange.levelCount = 1;
7074     dsvci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
7075     vkCreateImageView(m_device->device(), &dsvci, NULL, &dsv);
7076 
7077     // Create a renderPass with a single attachment that uses loadOp CLEAR
7078     VkAttachmentDescription description = {0,
7079                                            VK_FORMAT_D16_UNORM,
7080                                            VK_SAMPLE_COUNT_1_BIT,
7081                                            VK_ATTACHMENT_LOAD_OP_LOAD,
7082                                            VK_ATTACHMENT_STORE_OP_DONT_CARE,
7083                                            VK_ATTACHMENT_LOAD_OP_CLEAR,
7084                                            VK_ATTACHMENT_STORE_OP_DONT_CARE,
7085                                            VK_IMAGE_LAYOUT_GENERAL,
7086                                            VK_IMAGE_LAYOUT_GENERAL};
7087 
7088     VkAttachmentReference depth_stencil_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
7089 
7090     VkSubpassDescription subpass = {0,      VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &depth_stencil_ref, 0,
7091                                     nullptr};
7092 
7093     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &description, 1, &subpass, 0, nullptr};
7094     VkRenderPass rp;
7095 
7096     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
7097 
7098     // Create a framebuffer
7099 
7100     VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &dsv, 128, 128, 1};
7101     VkFramebuffer fb;
7102 
7103     vkCreateFramebuffer(m_device->handle(), &fbci, nullptr, &fb);
7104 
7105     VkSampleLocationEXT sample_location = {0.5, 0.5};
7106 
7107     VkSampleLocationsInfoEXT sample_locations_info = {
7108         VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT, nullptr, VK_SAMPLE_COUNT_1_BIT, {1, 1}, 1, &sample_location};
7109 
7110     VkAttachmentSampleLocationsEXT attachment_sample_locations = {0, sample_locations_info};
7111     VkSubpassSampleLocationsEXT subpass_sample_locations = {0, sample_locations_info};
7112 
7113     VkRenderPassSampleLocationsBeginInfoEXT rp_sl_begin = {VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT,
7114                                                            nullptr,
7115                                                            1,
7116                                                            &attachment_sample_locations,
7117                                                            1,
7118                                                            &subpass_sample_locations};
7119 
7120     VkRenderPassBeginInfo rp_begin = {
7121         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, &rp_sl_begin, rp, fb, {{0, 0}, {128, 128}}, 0, nullptr};
7122 
7123     attachment_sample_locations.attachmentIndex = 1;
7124     TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &rp_begin, false,
7125                         "VUID-VkAttachmentSampleLocationsEXT-attachmentIndex-01531", nullptr);
7126     attachment_sample_locations.attachmentIndex = 0;
7127 
7128     subpass_sample_locations.subpassIndex = 1;
7129     TestRenderPassBegin(m_errorMonitor, m_device->device(), m_commandBuffer->handle(), &rp_begin, false,
7130                         "VUID-VkSubpassSampleLocationsEXT-subpassIndex-01532", nullptr);
7131     subpass_sample_locations.subpassIndex = 0;
7132 
7133     vkDestroyRenderPass(m_device->device(), rp, nullptr);
7134     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
7135     vkDestroyImageView(m_device->device(), dsv, nullptr);
7136 }
7137 
TEST_F(VkLayerTest,RenderPassNextSubpassExcessive)7138 TEST_F(VkLayerTest, RenderPassNextSubpassExcessive) {
7139     TEST_DESCRIPTION("Test that an error is produced when CmdNextSubpass is called too many times in a renderpass instance");
7140 
7141     // Check for VK_KHR_get_physical_device_properties2
7142     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
7143         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7144     }
7145 
7146     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
7147     PFN_vkCmdNextSubpass2KHR vkCmdNextSubpass2KHR = nullptr;
7148     bool rp2Supported = CheckCreateRenderPass2Support(this, m_device_extension_names);
7149     ASSERT_NO_FATAL_FAILURE(InitState());
7150 
7151     if (rp2Supported) {
7152         vkCmdNextSubpass2KHR = (PFN_vkCmdNextSubpass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdNextSubpass2KHR");
7153     }
7154 
7155     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7156 
7157     m_commandBuffer->begin();
7158     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
7159 
7160     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdNextSubpass-None-00909");
7161     vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
7162     m_errorMonitor->VerifyFound();
7163 
7164     if (rp2Supported) {
7165         VkSubpassBeginInfoKHR subpassBeginInfo = {VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR, nullptr, VK_SUBPASS_CONTENTS_INLINE};
7166         VkSubpassEndInfoKHR subpassEndInfo = {VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR, nullptr};
7167 
7168         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdNextSubpass2KHR-None-03102");
7169 
7170         vkCmdNextSubpass2KHR(m_commandBuffer->handle(), &subpassBeginInfo, &subpassEndInfo);
7171         m_errorMonitor->VerifyFound();
7172     }
7173 
7174     m_commandBuffer->EndRenderPass();
7175     m_commandBuffer->end();
7176 }
7177 
TEST_F(VkLayerTest,RenderPassEndBeforeFinalSubpass)7178 TEST_F(VkLayerTest, RenderPassEndBeforeFinalSubpass) {
7179     TEST_DESCRIPTION("Test that an error is produced when CmdEndRenderPass is called before the final subpass has been reached");
7180 
7181     // Check for VK_KHR_get_physical_device_properties2
7182     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
7183         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7184     }
7185 
7186     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
7187     PFN_vkCmdEndRenderPass2KHR vkCmdEndRenderPass2KHR = nullptr;
7188     bool rp2Supported = CheckCreateRenderPass2Support(this, m_device_extension_names);
7189     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
7190 
7191     if (rp2Supported) {
7192         vkCmdEndRenderPass2KHR = (PFN_vkCmdEndRenderPass2KHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdEndRenderPass2KHR");
7193     }
7194 
7195     VkSubpassDescription sd[2] = {{0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr},
7196                                   {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}};
7197 
7198     VkRenderPassCreateInfo rcpi = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 2, sd, 0, nullptr};
7199 
7200     VkRenderPass rp;
7201     VkResult err = vkCreateRenderPass(m_device->device(), &rcpi, nullptr, &rp);
7202     ASSERT_VK_SUCCESS(err);
7203 
7204     VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 16, 16, 1};
7205 
7206     VkFramebuffer fb;
7207     err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
7208     ASSERT_VK_SUCCESS(err);
7209 
7210     m_commandBuffer->begin();
7211 
7212     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {16, 16}}, 0, nullptr};
7213 
7214     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
7215 
7216     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdEndRenderPass-None-00910");
7217     vkCmdEndRenderPass(m_commandBuffer->handle());
7218     m_errorMonitor->VerifyFound();
7219 
7220     if (rp2Supported) {
7221         VkSubpassEndInfoKHR subpassEndInfo = {VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR, nullptr};
7222 
7223         m_commandBuffer->reset();
7224         m_commandBuffer->begin();
7225         vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
7226 
7227         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdEndRenderPass2KHR-None-03103");
7228         vkCmdEndRenderPass2KHR(m_commandBuffer->handle(), &subpassEndInfo);
7229         m_errorMonitor->VerifyFound();
7230     }
7231 
7232     // Clean up.
7233     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
7234     vkDestroyRenderPass(m_device->device(), rp, nullptr);
7235 }
7236 
TEST_F(VkLayerTest,RenderPassDestroyWhileInUse)7237 TEST_F(VkLayerTest, RenderPassDestroyWhileInUse) {
7238     TEST_DESCRIPTION("Delete in-use renderPass.");
7239 
7240     ASSERT_NO_FATAL_FAILURE(Init());
7241     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7242 
7243     // Create simple renderpass
7244     VkAttachmentReference attach = {};
7245     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
7246     VkSubpassDescription subpass = {};
7247     subpass.colorAttachmentCount = 1;
7248     subpass.pColorAttachments = &attach;
7249     VkRenderPassCreateInfo rpci = {};
7250     rpci.subpassCount = 1;
7251     rpci.pSubpasses = &subpass;
7252     rpci.attachmentCount = 1;
7253     VkAttachmentDescription attach_desc = {};
7254     attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
7255     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
7256     attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
7257     rpci.pAttachments = &attach_desc;
7258     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
7259     VkRenderPass rp;
7260     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
7261     ASSERT_VK_SUCCESS(err);
7262 
7263     m_errorMonitor->ExpectSuccess();
7264 
7265     m_commandBuffer->begin();
7266     VkRenderPassBeginInfo rpbi = {};
7267     rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
7268     rpbi.framebuffer = m_framebuffer;
7269     rpbi.renderPass = rp;
7270     m_commandBuffer->BeginRenderPass(rpbi);
7271     m_commandBuffer->EndRenderPass();
7272     m_commandBuffer->end();
7273 
7274     VkSubmitInfo submit_info = {};
7275     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7276     submit_info.commandBufferCount = 1;
7277     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7278     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7279     m_errorMonitor->VerifyNotFound();
7280 
7281     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyRenderPass-renderPass-00873");
7282     vkDestroyRenderPass(m_device->device(), rp, nullptr);
7283     m_errorMonitor->VerifyFound();
7284 
7285     // Wait for queue to complete so we can safely destroy rp
7286     vkQueueWaitIdle(m_device->m_queue);
7287     m_errorMonitor->SetUnexpectedError("If renderPass is not VK_NULL_HANDLE, renderPass must be a valid VkRenderPass handle");
7288     m_errorMonitor->SetUnexpectedError("Was it created? Has it already been destroyed?");
7289     vkDestroyRenderPass(m_device->device(), rp, nullptr);
7290 }
7291 
TEST_F(VkPositiveLayerTest,RenderPassCreateAttachmentUsedTwiceOK)7292 TEST_F(VkPositiveLayerTest, RenderPassCreateAttachmentUsedTwiceOK) {
7293     TEST_DESCRIPTION("Attachment is used simultaneously as color and input, with the same layout. This is OK.");
7294 
7295     ASSERT_NO_FATAL_FAILURE(Init());
7296 
7297     VkAttachmentDescription attach[] = {
7298         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_DONT_CARE,
7299          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
7300     };
7301     VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_GENERAL};
7302     VkSubpassDescription subpasses[] = {
7303         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &ref, 1, &ref, nullptr, nullptr, 0, nullptr},
7304     };
7305 
7306     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 0, nullptr};
7307     VkRenderPass rp;
7308 
7309     m_errorMonitor->ExpectSuccess();
7310     vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
7311     m_errorMonitor->VerifyNotFound();
7312     vkDestroyRenderPass(m_device->device(), rp, nullptr);
7313 }
7314 
TEST_F(VkPositiveLayerTest,RenderPassCreateInitialLayoutUndefined)7315 TEST_F(VkPositiveLayerTest, RenderPassCreateInitialLayoutUndefined) {
7316     TEST_DESCRIPTION(
7317         "Ensure that CmdBeginRenderPass with an attachment's initialLayout of VK_IMAGE_LAYOUT_UNDEFINED works when the command "
7318         "buffer has prior knowledge of that attachment's layout.");
7319 
7320     m_errorMonitor->ExpectSuccess();
7321 
7322     ASSERT_NO_FATAL_FAILURE(Init());
7323 
7324     // A renderpass with one color attachment.
7325     VkAttachmentDescription attachment = {0,
7326                                           VK_FORMAT_R8G8B8A8_UNORM,
7327                                           VK_SAMPLE_COUNT_1_BIT,
7328                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7329                                           VK_ATTACHMENT_STORE_OP_STORE,
7330                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7331                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
7332                                           VK_IMAGE_LAYOUT_UNDEFINED,
7333                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
7334 
7335     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
7336 
7337     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
7338 
7339     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
7340 
7341     VkRenderPass rp;
7342     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
7343     ASSERT_VK_SUCCESS(err);
7344 
7345     // A compatible framebuffer.
7346     VkImageObj image(m_device);
7347     image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
7348     ASSERT_TRUE(image.initialized());
7349 
7350     VkImageViewCreateInfo ivci = {
7351         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
7352         nullptr,
7353         0,
7354         image.handle(),
7355         VK_IMAGE_VIEW_TYPE_2D,
7356         VK_FORMAT_R8G8B8A8_UNORM,
7357         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
7358          VK_COMPONENT_SWIZZLE_IDENTITY},
7359         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
7360     };
7361     VkImageView view;
7362     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
7363     ASSERT_VK_SUCCESS(err);
7364 
7365     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
7366     VkFramebuffer fb;
7367     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
7368     ASSERT_VK_SUCCESS(err);
7369 
7370     // Record a single command buffer which uses this renderpass twice. The
7371     // bug is triggered at the beginning of the second renderpass, when the
7372     // command buffer already has a layout recorded for the attachment.
7373     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
7374     m_commandBuffer->begin();
7375     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
7376     vkCmdEndRenderPass(m_commandBuffer->handle());
7377     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
7378 
7379     m_errorMonitor->VerifyNotFound();
7380 
7381     vkCmdEndRenderPass(m_commandBuffer->handle());
7382     m_commandBuffer->end();
7383 
7384     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
7385     vkDestroyRenderPass(m_device->device(), rp, nullptr);
7386     vkDestroyImageView(m_device->device(), view, nullptr);
7387 }
7388 
TEST_F(VkPositiveLayerTest,RenderPassCreateAttachmentLayoutWithLoadOpThenReadOnly)7389 TEST_F(VkPositiveLayerTest, RenderPassCreateAttachmentLayoutWithLoadOpThenReadOnly) {
7390     TEST_DESCRIPTION(
7391         "Positive test where we create a renderpass with an attachment that uses LOAD_OP_CLEAR, the first subpass has a valid "
7392         "layout, and a second subpass then uses a valid *READ_ONLY* layout.");
7393     m_errorMonitor->ExpectSuccess();
7394     ASSERT_NO_FATAL_FAILURE(Init());
7395     auto depth_format = FindSupportedDepthStencilFormat(gpu());
7396     if (!depth_format) {
7397         printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
7398         return;
7399     }
7400 
7401     VkAttachmentReference attach[2] = {};
7402     attach[0].attachment = 0;
7403     attach[0].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
7404     attach[1].attachment = 0;
7405     attach[1].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
7406     VkSubpassDescription subpasses[2] = {};
7407     // First subpass clears DS attach on load
7408     subpasses[0].pDepthStencilAttachment = &attach[0];
7409     // 2nd subpass reads in DS as input attachment
7410     subpasses[1].inputAttachmentCount = 1;
7411     subpasses[1].pInputAttachments = &attach[1];
7412     VkAttachmentDescription attach_desc = {};
7413     attach_desc.format = depth_format;
7414     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
7415     attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
7416     attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
7417     attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
7418     attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
7419     attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
7420     attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
7421     VkRenderPassCreateInfo rpci = {};
7422     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
7423     rpci.attachmentCount = 1;
7424     rpci.pAttachments = &attach_desc;
7425     rpci.subpassCount = 2;
7426     rpci.pSubpasses = subpasses;
7427 
7428     // Now create RenderPass and verify no errors
7429     VkRenderPass rp;
7430     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
7431     m_errorMonitor->VerifyNotFound();
7432 
7433     vkDestroyRenderPass(m_device->device(), rp, NULL);
7434 }
7435 
TEST_F(VkPositiveLayerTest,RenderPassBeginSubpassZeroTransitionsApplied)7436 TEST_F(VkPositiveLayerTest, RenderPassBeginSubpassZeroTransitionsApplied) {
7437     TEST_DESCRIPTION("Ensure that CmdBeginRenderPass applies the layout transitions for the first subpass");
7438 
7439     m_errorMonitor->ExpectSuccess();
7440 
7441     ASSERT_NO_FATAL_FAILURE(Init());
7442 
7443     // A renderpass with one color attachment.
7444     VkAttachmentDescription attachment = {0,
7445                                           VK_FORMAT_R8G8B8A8_UNORM,
7446                                           VK_SAMPLE_COUNT_1_BIT,
7447                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7448                                           VK_ATTACHMENT_STORE_OP_STORE,
7449                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7450                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
7451                                           VK_IMAGE_LAYOUT_UNDEFINED,
7452                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
7453 
7454     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
7455 
7456     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
7457 
7458     VkSubpassDependency dep = {0,
7459                                0,
7460                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
7461                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
7462                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
7463                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
7464                                VK_DEPENDENCY_BY_REGION_BIT};
7465 
7466     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep};
7467 
7468     VkResult err;
7469     VkRenderPass rp;
7470     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
7471     ASSERT_VK_SUCCESS(err);
7472 
7473     // A compatible framebuffer.
7474     VkImageObj image(m_device);
7475     image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
7476     ASSERT_TRUE(image.initialized());
7477 
7478     VkImageView view = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
7479 
7480     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
7481     VkFramebuffer fb;
7482     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
7483     ASSERT_VK_SUCCESS(err);
7484 
7485     // Record a single command buffer which issues a pipeline barrier w/
7486     // image memory barrier for the attachment. This detects the previously
7487     // missing tracking of the subpass layout by throwing a validation error
7488     // if it doesn't occur.
7489     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
7490     m_commandBuffer->begin();
7491     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
7492 
7493     VkImageMemoryBarrier imb = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
7494                                 nullptr,
7495                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
7496                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
7497                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7498                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
7499                                 VK_QUEUE_FAMILY_IGNORED,
7500                                 VK_QUEUE_FAMILY_IGNORED,
7501                                 image.handle(),
7502                                 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};
7503     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
7504                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
7505                          &imb);
7506 
7507     vkCmdEndRenderPass(m_commandBuffer->handle());
7508     m_errorMonitor->VerifyNotFound();
7509     m_commandBuffer->end();
7510 
7511     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
7512     vkDestroyRenderPass(m_device->device(), rp, nullptr);
7513 }
7514 
TEST_F(VkPositiveLayerTest,RenderPassBeginTransitionsAttachmentUnused)7515 TEST_F(VkPositiveLayerTest, RenderPassBeginTransitionsAttachmentUnused) {
7516     TEST_DESCRIPTION(
7517         "Ensure that layout transitions work correctly without errors, when an attachment reference is VK_ATTACHMENT_UNUSED");
7518 
7519     m_errorMonitor->ExpectSuccess();
7520 
7521     ASSERT_NO_FATAL_FAILURE(Init());
7522 
7523     // A renderpass with no attachments
7524     VkAttachmentReference att_ref = {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
7525 
7526     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
7527 
7528     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, &subpass, 0, nullptr};
7529 
7530     VkRenderPass rp;
7531     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
7532     ASSERT_VK_SUCCESS(err);
7533 
7534     // A compatible framebuffer.
7535     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 32, 32, 1};
7536     VkFramebuffer fb;
7537     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
7538     ASSERT_VK_SUCCESS(err);
7539 
7540     // Record a command buffer which just begins and ends the renderpass. The
7541     // bug manifests in BeginRenderPass.
7542     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
7543     m_commandBuffer->begin();
7544     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
7545     vkCmdEndRenderPass(m_commandBuffer->handle());
7546     m_errorMonitor->VerifyNotFound();
7547     m_commandBuffer->end();
7548 
7549     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
7550     vkDestroyRenderPass(m_device->device(), rp, nullptr);
7551 }
7552 
TEST_F(VkPositiveLayerTest,RenderPassBeginStencilLoadOp)7553 TEST_F(VkPositiveLayerTest, RenderPassBeginStencilLoadOp) {
7554     TEST_DESCRIPTION("Create a stencil-only attachment with a LOAD_OP set to CLEAR. stencil[Load|Store]Op used to be ignored.");
7555     VkResult result = VK_SUCCESS;
7556     ASSERT_NO_FATAL_FAILURE(Init());
7557     auto depth_format = FindSupportedDepthStencilFormat(gpu());
7558     if (!depth_format) {
7559         printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
7560         return;
7561     }
7562     VkImageFormatProperties formatProps;
7563     vkGetPhysicalDeviceImageFormatProperties(gpu(), depth_format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
7564                                              VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
7565                                              &formatProps);
7566     if (formatProps.maxExtent.width < 100 || formatProps.maxExtent.height < 100) {
7567         printf("%s Image format max extent is too small.\n", kSkipPrefix);
7568         return;
7569     }
7570 
7571     VkFormat depth_stencil_fmt = depth_format;
7572     m_depthStencil->Init(m_device, 100, 100, depth_stencil_fmt,
7573                          VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
7574     VkAttachmentDescription att = {};
7575     VkAttachmentReference ref = {};
7576     att.format = depth_stencil_fmt;
7577     att.samples = VK_SAMPLE_COUNT_1_BIT;
7578     att.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
7579     att.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
7580     att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
7581     att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
7582     att.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
7583     att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
7584 
7585     VkClearValue clear;
7586     clear.depthStencil.depth = 1.0;
7587     clear.depthStencil.stencil = 0;
7588     ref.attachment = 0;
7589     ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
7590 
7591     VkSubpassDescription subpass = {};
7592     subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
7593     subpass.flags = 0;
7594     subpass.inputAttachmentCount = 0;
7595     subpass.pInputAttachments = NULL;
7596     subpass.colorAttachmentCount = 0;
7597     subpass.pColorAttachments = NULL;
7598     subpass.pResolveAttachments = NULL;
7599     subpass.pDepthStencilAttachment = &ref;
7600     subpass.preserveAttachmentCount = 0;
7601     subpass.pPreserveAttachments = NULL;
7602 
7603     VkRenderPass rp;
7604     VkRenderPassCreateInfo rp_info = {};
7605     rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
7606     rp_info.attachmentCount = 1;
7607     rp_info.pAttachments = &att;
7608     rp_info.subpassCount = 1;
7609     rp_info.pSubpasses = &subpass;
7610     result = vkCreateRenderPass(device(), &rp_info, NULL, &rp);
7611     ASSERT_VK_SUCCESS(result);
7612 
7613     VkImageView *depthView = m_depthStencil->BindInfo();
7614     VkFramebufferCreateInfo fb_info = {};
7615     fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
7616     fb_info.pNext = NULL;
7617     fb_info.renderPass = rp;
7618     fb_info.attachmentCount = 1;
7619     fb_info.pAttachments = depthView;
7620     fb_info.width = 100;
7621     fb_info.height = 100;
7622     fb_info.layers = 1;
7623     VkFramebuffer fb;
7624     result = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
7625     ASSERT_VK_SUCCESS(result);
7626 
7627     VkRenderPassBeginInfo rpbinfo = {};
7628     rpbinfo.clearValueCount = 1;
7629     rpbinfo.pClearValues = &clear;
7630     rpbinfo.pNext = NULL;
7631     rpbinfo.renderPass = rp;
7632     rpbinfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
7633     rpbinfo.renderArea.extent.width = 100;
7634     rpbinfo.renderArea.extent.height = 100;
7635     rpbinfo.renderArea.offset.x = 0;
7636     rpbinfo.renderArea.offset.y = 0;
7637     rpbinfo.framebuffer = fb;
7638 
7639     VkFenceObj fence;
7640     fence.init(*m_device, VkFenceObj::create_info());
7641     ASSERT_TRUE(fence.initialized());
7642 
7643     m_commandBuffer->begin();
7644     m_commandBuffer->BeginRenderPass(rpbinfo);
7645     m_commandBuffer->EndRenderPass();
7646     m_commandBuffer->end();
7647     m_commandBuffer->QueueCommandBuffer(fence);
7648 
7649     VkImageObj destImage(m_device);
7650     destImage.Init(100, 100, 1, depth_stencil_fmt, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
7651                    VK_IMAGE_TILING_OPTIMAL, 0);
7652     VkImageMemoryBarrier barrier = {};
7653     VkImageSubresourceRange range;
7654     barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
7655     barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
7656     barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
7657     barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
7658     barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7659     barrier.image = m_depthStencil->handle();
7660     range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
7661     range.baseMipLevel = 0;
7662     range.levelCount = 1;
7663     range.baseArrayLayer = 0;
7664     range.layerCount = 1;
7665     barrier.subresourceRange = range;
7666     fence.wait(VK_TRUE, UINT64_MAX);
7667     VkCommandBufferObj cmdbuf(m_device, m_commandPool);
7668     cmdbuf.begin();
7669     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
7670                            &barrier);
7671     barrier.srcAccessMask = 0;
7672     barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
7673     barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7674     barrier.image = destImage.handle();
7675     barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
7676     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
7677                            &barrier);
7678     VkImageCopy cregion;
7679     cregion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
7680     cregion.srcSubresource.mipLevel = 0;
7681     cregion.srcSubresource.baseArrayLayer = 0;
7682     cregion.srcSubresource.layerCount = 1;
7683     cregion.srcOffset.x = 0;
7684     cregion.srcOffset.y = 0;
7685     cregion.srcOffset.z = 0;
7686     cregion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
7687     cregion.dstSubresource.mipLevel = 0;
7688     cregion.dstSubresource.baseArrayLayer = 0;
7689     cregion.dstSubresource.layerCount = 1;
7690     cregion.dstOffset.x = 0;
7691     cregion.dstOffset.y = 0;
7692     cregion.dstOffset.z = 0;
7693     cregion.extent.width = 100;
7694     cregion.extent.height = 100;
7695     cregion.extent.depth = 1;
7696     cmdbuf.CopyImage(m_depthStencil->handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, destImage.handle(),
7697                      VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cregion);
7698     cmdbuf.end();
7699 
7700     VkSubmitInfo submit_info;
7701     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7702     submit_info.pNext = NULL;
7703     submit_info.waitSemaphoreCount = 0;
7704     submit_info.pWaitSemaphores = NULL;
7705     submit_info.pWaitDstStageMask = NULL;
7706     submit_info.commandBufferCount = 1;
7707     submit_info.pCommandBuffers = &cmdbuf.handle();
7708     submit_info.signalSemaphoreCount = 0;
7709     submit_info.pSignalSemaphores = NULL;
7710 
7711     m_errorMonitor->ExpectSuccess();
7712     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7713     m_errorMonitor->VerifyNotFound();
7714 
7715     vkQueueWaitIdle(m_device->m_queue);
7716     vkDestroyRenderPass(m_device->device(), rp, nullptr);
7717     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
7718 }
7719 
TEST_F(VkPositiveLayerTest,RenderPassBeginInlineAndSecondaryCommandBuffers)7720 TEST_F(VkPositiveLayerTest, RenderPassBeginInlineAndSecondaryCommandBuffers) {
7721     m_errorMonitor->ExpectSuccess();
7722 
7723     ASSERT_NO_FATAL_FAILURE(Init());
7724     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7725 
7726     m_commandBuffer->begin();
7727 
7728     vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
7729     vkCmdEndRenderPass(m_commandBuffer->handle());
7730     m_errorMonitor->VerifyNotFound();
7731     vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
7732     m_errorMonitor->VerifyNotFound();
7733     vkCmdEndRenderPass(m_commandBuffer->handle());
7734     m_errorMonitor->VerifyNotFound();
7735 
7736     m_commandBuffer->end();
7737     m_errorMonitor->VerifyNotFound();
7738 }
7739 
TEST_F(VkPositiveLayerTest,RenderPassBeginDepthStencilLayoutTransitionFromUndefined)7740 TEST_F(VkPositiveLayerTest, RenderPassBeginDepthStencilLayoutTransitionFromUndefined) {
7741     TEST_DESCRIPTION(
7742         "Create a render pass with depth-stencil attachment where layout transition from UNDEFINED TO DS_READ_ONLY_OPTIMAL is set "
7743         "by render pass and verify that transition has correctly occurred at queue submit time with no validation errors.");
7744 
7745     ASSERT_NO_FATAL_FAILURE(Init());
7746     auto depth_format = FindSupportedDepthStencilFormat(gpu());
7747     if (!depth_format) {
7748         printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
7749         return;
7750     }
7751     VkImageFormatProperties format_props;
7752     vkGetPhysicalDeviceImageFormatProperties(gpu(), depth_format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
7753                                              VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 0, &format_props);
7754     if (format_props.maxExtent.width < 32 || format_props.maxExtent.height < 32) {
7755         printf("%s Depth extent too small, RenderPassDepthStencilLayoutTransition skipped.\n", kSkipPrefix);
7756         return;
7757     }
7758 
7759     m_errorMonitor->ExpectSuccess();
7760     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7761 
7762     // A renderpass with one depth/stencil attachment.
7763     VkAttachmentDescription attachment = {0,
7764                                           depth_format,
7765                                           VK_SAMPLE_COUNT_1_BIT,
7766                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7767                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
7768                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
7769                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
7770                                           VK_IMAGE_LAYOUT_UNDEFINED,
7771                                           VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
7772 
7773     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
7774 
7775     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &att_ref, 0, nullptr};
7776 
7777     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
7778 
7779     VkRenderPass rp;
7780     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
7781     ASSERT_VK_SUCCESS(err);
7782     // A compatible ds image.
7783     VkImageObj image(m_device);
7784     image.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
7785     ASSERT_TRUE(image.initialized());
7786 
7787     VkImageViewCreateInfo ivci = {
7788         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
7789         nullptr,
7790         0,
7791         image.handle(),
7792         VK_IMAGE_VIEW_TYPE_2D,
7793         depth_format,
7794         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
7795          VK_COMPONENT_SWIZZLE_IDENTITY},
7796         {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 1, 0, 1},
7797     };
7798     VkImageView view;
7799     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
7800     ASSERT_VK_SUCCESS(err);
7801 
7802     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
7803     VkFramebuffer fb;
7804     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
7805     ASSERT_VK_SUCCESS(err);
7806 
7807     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
7808     m_commandBuffer->begin();
7809     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
7810     vkCmdEndRenderPass(m_commandBuffer->handle());
7811     m_commandBuffer->end();
7812     m_commandBuffer->QueueCommandBuffer(false);
7813     m_errorMonitor->VerifyNotFound();
7814 
7815     // Cleanup
7816     vkDestroyImageView(m_device->device(), view, NULL);
7817     vkDestroyRenderPass(m_device->device(), rp, NULL);
7818     vkDestroyFramebuffer(m_device->device(), fb, NULL);
7819 }
7820 
TEST_F(VkLayerTest,DisabledIndependentBlend)7821 TEST_F(VkLayerTest, DisabledIndependentBlend) {
7822     TEST_DESCRIPTION(
7823         "Generate INDEPENDENT_BLEND by disabling independent blend and then specifying different blend states for two "
7824         "attachments");
7825     VkPhysicalDeviceFeatures features = {};
7826     features.independentBlend = VK_FALSE;
7827     ASSERT_NO_FATAL_FAILURE(Init(&features));
7828 
7829     m_errorMonitor->SetDesiredFailureMsg(
7830         VK_DEBUG_REPORT_ERROR_BIT_EXT,
7831         "Invalid Pipeline CreateInfo: If independent blend feature not enabled, all elements of pAttachments must be identical");
7832 
7833     VkDescriptorSetObj descriptorSet(m_device);
7834     descriptorSet.AppendDummy();
7835     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
7836 
7837     VkPipelineObj pipeline(m_device);
7838     // Create a renderPass with two color attachments
7839     VkAttachmentReference attachments[2] = {};
7840     attachments[0].layout = VK_IMAGE_LAYOUT_GENERAL;
7841     attachments[1].attachment = 1;
7842     attachments[1].layout = VK_IMAGE_LAYOUT_GENERAL;
7843 
7844     VkSubpassDescription subpass = {};
7845     subpass.pColorAttachments = attachments;
7846     subpass.colorAttachmentCount = 2;
7847 
7848     VkRenderPassCreateInfo rpci = {};
7849     rpci.subpassCount = 1;
7850     rpci.pSubpasses = &subpass;
7851     rpci.attachmentCount = 2;
7852 
7853     VkAttachmentDescription attach_desc[2] = {};
7854     attach_desc[0].format = VK_FORMAT_B8G8R8A8_UNORM;
7855     attach_desc[0].samples = VK_SAMPLE_COUNT_1_BIT;
7856     attach_desc[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
7857     attach_desc[0].finalLayout = VK_IMAGE_LAYOUT_GENERAL;
7858     attach_desc[1].format = VK_FORMAT_B8G8R8A8_UNORM;
7859     attach_desc[1].samples = VK_SAMPLE_COUNT_1_BIT;
7860     attach_desc[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
7861     attach_desc[1].finalLayout = VK_IMAGE_LAYOUT_GENERAL;
7862 
7863     rpci.pAttachments = attach_desc;
7864     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
7865 
7866     VkRenderPass renderpass;
7867     vkCreateRenderPass(m_device->device(), &rpci, NULL, &renderpass);
7868     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
7869     pipeline.AddShader(&vs);
7870 
7871     VkPipelineColorBlendAttachmentState att_state1 = {}, att_state2 = {};
7872     att_state1.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
7873     att_state1.blendEnable = VK_TRUE;
7874     att_state2.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
7875     att_state2.blendEnable = VK_FALSE;
7876     pipeline.AddColorAttachment(0, att_state1);
7877     pipeline.AddColorAttachment(1, att_state2);
7878     pipeline.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderpass);
7879     m_errorMonitor->VerifyFound();
7880     vkDestroyRenderPass(m_device->device(), renderpass, NULL);
7881 }
7882 
7883 // Is the Pipeline compatible with the expectations of the Renderpass/subpasses?
TEST_F(VkLayerTest,PipelineRenderpassCompatibility)7884 TEST_F(VkLayerTest, PipelineRenderpassCompatibility) {
7885     TEST_DESCRIPTION(
7886         "Create a graphics pipeline that is incompatible with the requirements of its contained Renderpass/subpasses.");
7887     ASSERT_NO_FATAL_FAILURE(Init());
7888 
7889     VkDescriptorSetObj ds_obj(m_device);
7890     ds_obj.AppendDummy();
7891     ds_obj.CreateVKDescriptorSet(m_commandBuffer);
7892 
7893     VkShaderObj vs_obj(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
7894 
7895     VkPipelineColorBlendAttachmentState att_state1 = {};
7896     att_state1.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
7897     att_state1.blendEnable = VK_TRUE;
7898 
7899     VkRenderpassObj rp_obj(m_device);
7900 
7901     {
7902         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
7903                                              "VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00753");
7904         VkPipelineObj pipeline(m_device);
7905         pipeline.AddShader(&vs_obj);
7906         pipeline.AddColorAttachment(0, att_state1);
7907 
7908         VkGraphicsPipelineCreateInfo info = {};
7909         pipeline.InitGraphicsPipelineCreateInfo(&info);
7910         info.pColorBlendState = nullptr;
7911 
7912         pipeline.CreateVKPipeline(ds_obj.GetPipelineLayout(), rp_obj.handle(), &info);
7913         m_errorMonitor->VerifyFound();
7914     }
7915 }
7916 
TEST_F(VkLayerTest,FramebufferCreateErrors)7917 TEST_F(VkLayerTest, FramebufferCreateErrors) {
7918     TEST_DESCRIPTION(
7919         "Hit errors when attempting to create a framebuffer :\n"
7920         " 1. Mismatch between framebuffer & renderPass attachmentCount\n"
7921         " 2. Use a color image as depthStencil attachment\n"
7922         " 3. Mismatch framebuffer & renderPass attachment formats\n"
7923         " 4. Mismatch framebuffer & renderPass attachment #samples\n"
7924         " 5. Framebuffer attachment w/ non-1 mip-levels\n"
7925         " 6. Framebuffer attachment where dimensions don't match\n"
7926         " 7. Framebuffer attachment where dimensions don't match\n"
7927         " 8. Framebuffer attachment w/o identity swizzle\n"
7928         " 9. framebuffer dimensions exceed physical device limits\n");
7929 
7930     ASSERT_NO_FATAL_FAILURE(Init());
7931     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7932 
7933     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkFramebufferCreateInfo-attachmentCount-00876");
7934 
7935     // Create a renderPass with a single color attachment
7936     VkAttachmentReference attach = {};
7937     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
7938     VkSubpassDescription subpass = {};
7939     subpass.pColorAttachments = &attach;
7940     VkRenderPassCreateInfo rpci = {};
7941     rpci.subpassCount = 1;
7942     rpci.pSubpasses = &subpass;
7943     rpci.attachmentCount = 1;
7944     VkAttachmentDescription attach_desc = {};
7945     attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
7946     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
7947     attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
7948     rpci.pAttachments = &attach_desc;
7949     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
7950     VkRenderPass rp;
7951     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
7952     ASSERT_VK_SUCCESS(err);
7953 
7954     VkImageView ivs[2];
7955     ivs[0] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM);
7956     ivs[1] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM);
7957     VkFramebufferCreateInfo fb_info = {};
7958     fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
7959     fb_info.pNext = NULL;
7960     fb_info.renderPass = rp;
7961     // Set mis-matching attachmentCount
7962     fb_info.attachmentCount = 2;
7963     fb_info.pAttachments = ivs;
7964     fb_info.width = 100;
7965     fb_info.height = 100;
7966     fb_info.layers = 1;
7967 
7968     VkFramebuffer fb;
7969     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
7970 
7971     m_errorMonitor->VerifyFound();
7972     if (err == VK_SUCCESS) {
7973         vkDestroyFramebuffer(m_device->device(), fb, NULL);
7974     }
7975     vkDestroyRenderPass(m_device->device(), rp, NULL);
7976 
7977     // Create a renderPass with a depth-stencil attachment created with
7978     // IMAGE_USAGE_COLOR_ATTACHMENT
7979     // Add our color attachment to pDepthStencilAttachment
7980     subpass.pDepthStencilAttachment = &attach;
7981     subpass.pColorAttachments = NULL;
7982     VkRenderPass rp_ds;
7983     err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_ds);
7984     ASSERT_VK_SUCCESS(err);
7985     // Set correct attachment count, but attachment has COLOR usage bit set
7986     fb_info.attachmentCount = 1;
7987     fb_info.renderPass = rp_ds;
7988 
7989     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkFramebufferCreateInfo-pAttachments-02633");
7990     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
7991 
7992     m_errorMonitor->VerifyFound();
7993     if (err == VK_SUCCESS) {
7994         vkDestroyFramebuffer(m_device->device(), fb, NULL);
7995     }
7996     vkDestroyRenderPass(m_device->device(), rp_ds, NULL);
7997 
7998     // Create new renderpass with alternate attachment format from fb
7999     attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM;
8000     subpass.pDepthStencilAttachment = NULL;
8001     subpass.pColorAttachments = &attach;
8002     err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
8003     ASSERT_VK_SUCCESS(err);
8004 
8005     // Cause error due to mis-matched formats between rp & fb
8006     //  rp attachment 0 now has RGBA8 but corresponding fb attach is BGRA8
8007     fb_info.renderPass = rp;
8008     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkFramebufferCreateInfo-pAttachments-00880");
8009     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
8010 
8011     m_errorMonitor->VerifyFound();
8012     if (err == VK_SUCCESS) {
8013         vkDestroyFramebuffer(m_device->device(), fb, NULL);
8014     }
8015     vkDestroyRenderPass(m_device->device(), rp, NULL);
8016 
8017     // Create new renderpass with alternate sample count from fb
8018     attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
8019     attach_desc.samples = VK_SAMPLE_COUNT_4_BIT;
8020     err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
8021     ASSERT_VK_SUCCESS(err);
8022 
8023     // Cause error due to mis-matched sample count between rp & fb
8024     fb_info.renderPass = rp;
8025     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkFramebufferCreateInfo-pAttachments-00881");
8026     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
8027 
8028     m_errorMonitor->VerifyFound();
8029     if (err == VK_SUCCESS) {
8030         vkDestroyFramebuffer(m_device->device(), fb, NULL);
8031     }
8032 
8033     vkDestroyRenderPass(m_device->device(), rp, NULL);
8034 
8035     {
8036         // Create an image with 2 mip levels.
8037         VkImageObj image(m_device);
8038         image.Init(128, 128, 2, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
8039         ASSERT_TRUE(image.initialized());
8040 
8041         // Create a image view with two mip levels.
8042         VkImageView view;
8043         VkImageViewCreateInfo ivci = {};
8044         ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
8045         ivci.image = image.handle();
8046         ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
8047         ivci.format = VK_FORMAT_B8G8R8A8_UNORM;
8048         ivci.subresourceRange.layerCount = 1;
8049         ivci.subresourceRange.baseMipLevel = 0;
8050         // Set level count to 2 (only 1 is allowed for FB attachment)
8051         ivci.subresourceRange.levelCount = 2;
8052         ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
8053         err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
8054         ASSERT_VK_SUCCESS(err);
8055 
8056         // Re-create renderpass to have matching sample count
8057         attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
8058         err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
8059         ASSERT_VK_SUCCESS(err);
8060 
8061         fb_info.renderPass = rp;
8062         fb_info.pAttachments = &view;
8063         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkFramebufferCreateInfo-pAttachments-00883");
8064         err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
8065 
8066         m_errorMonitor->VerifyFound();
8067         if (err == VK_SUCCESS) {
8068             vkDestroyFramebuffer(m_device->device(), fb, NULL);
8069         }
8070         vkDestroyImageView(m_device->device(), view, NULL);
8071     }
8072 
8073     // Update view to original color buffer and grow FB dimensions too big
8074     fb_info.pAttachments = ivs;
8075     fb_info.height = 1024;
8076     fb_info.width = 1024;
8077     fb_info.layers = 2;
8078     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkFramebufferCreateInfo-pAttachments-00882");
8079     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
8080 
8081     m_errorMonitor->VerifyFound();
8082     if (err == VK_SUCCESS) {
8083         vkDestroyFramebuffer(m_device->device(), fb, NULL);
8084     }
8085 
8086     {
8087         // Create an image with one mip level.
8088         VkImageObj image(m_device);
8089         image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
8090         ASSERT_TRUE(image.initialized());
8091 
8092         // Create view attachment with non-identity swizzle
8093         VkImageView view;
8094         VkImageViewCreateInfo ivci = {};
8095         ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
8096         ivci.image = image.handle();
8097         ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
8098         ivci.format = VK_FORMAT_B8G8R8A8_UNORM;
8099         ivci.subresourceRange.layerCount = 1;
8100         ivci.subresourceRange.baseMipLevel = 0;
8101         ivci.subresourceRange.levelCount = 1;
8102         ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
8103         ivci.components.r = VK_COMPONENT_SWIZZLE_G;
8104         ivci.components.g = VK_COMPONENT_SWIZZLE_R;
8105         ivci.components.b = VK_COMPONENT_SWIZZLE_A;
8106         ivci.components.a = VK_COMPONENT_SWIZZLE_B;
8107         err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
8108         ASSERT_VK_SUCCESS(err);
8109 
8110         fb_info.pAttachments = &view;
8111         fb_info.height = 100;
8112         fb_info.width = 100;
8113         fb_info.layers = 1;
8114 
8115         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkFramebufferCreateInfo-pAttachments-00884");
8116         err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
8117 
8118         m_errorMonitor->VerifyFound();
8119         if (err == VK_SUCCESS) {
8120             vkDestroyFramebuffer(m_device->device(), fb, NULL);
8121         }
8122         vkDestroyImageView(m_device->device(), view, NULL);
8123     }
8124 
8125     // reset attachment to color attachment
8126     fb_info.pAttachments = ivs;
8127 
8128     // Request fb that exceeds max width
8129     fb_info.width = m_device->props.limits.maxFramebufferWidth + 1;
8130     fb_info.height = 100;
8131     fb_info.layers = 1;
8132     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkFramebufferCreateInfo-width-00886");
8133     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkFramebufferCreateInfo-pAttachments-00882");
8134     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
8135     m_errorMonitor->VerifyFound();
8136     if (err == VK_SUCCESS) {
8137         vkDestroyFramebuffer(m_device->device(), fb, NULL);
8138     }
8139     // and width=0
8140     fb_info.width = 0;
8141     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkFramebufferCreateInfo-width-00885");
8142     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
8143     m_errorMonitor->VerifyFound();
8144     if (err == VK_SUCCESS) {
8145         vkDestroyFramebuffer(m_device->device(), fb, NULL);
8146     }
8147 
8148     // Request fb that exceeds max height
8149     fb_info.width = 100;
8150     fb_info.height = m_device->props.limits.maxFramebufferHeight + 1;
8151     fb_info.layers = 1;
8152     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkFramebufferCreateInfo-height-00888");
8153     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkFramebufferCreateInfo-pAttachments-00882");
8154     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
8155     m_errorMonitor->VerifyFound();
8156     if (err == VK_SUCCESS) {
8157         vkDestroyFramebuffer(m_device->device(), fb, NULL);
8158     }
8159     // and height=0
8160     fb_info.height = 0;
8161     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkFramebufferCreateInfo-height-00887");
8162     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
8163     m_errorMonitor->VerifyFound();
8164     if (err == VK_SUCCESS) {
8165         vkDestroyFramebuffer(m_device->device(), fb, NULL);
8166     }
8167 
8168     // Request fb that exceeds max layers
8169     fb_info.width = 100;
8170     fb_info.height = 100;
8171     fb_info.layers = m_device->props.limits.maxFramebufferLayers + 1;
8172     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkFramebufferCreateInfo-layers-00890");
8173     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkFramebufferCreateInfo-pAttachments-00882");
8174     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
8175     m_errorMonitor->VerifyFound();
8176     if (err == VK_SUCCESS) {
8177         vkDestroyFramebuffer(m_device->device(), fb, NULL);
8178     }
8179     // and layers=0
8180     fb_info.layers = 0;
8181     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkFramebufferCreateInfo-layers-00889");
8182     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
8183     m_errorMonitor->VerifyFound();
8184     if (err == VK_SUCCESS) {
8185         vkDestroyFramebuffer(m_device->device(), fb, NULL);
8186     }
8187 
8188     vkDestroyRenderPass(m_device->device(), rp, NULL);
8189 }
8190 
TEST_F(VkLayerTest,PointSizeFailure)8191 TEST_F(VkLayerTest, PointSizeFailure) {
8192     TEST_DESCRIPTION("Create a pipeline using TOPOLOGY_POINT_LIST but do not set PointSize in vertex shader.");
8193 
8194     ASSERT_NO_FATAL_FAILURE(Init());
8195     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Pipeline topology is set to POINT_LIST");
8196 
8197     ASSERT_NO_FATAL_FAILURE(InitViewport());
8198 
8199     // Create VS declaring PointSize but not writing to it
8200     static const char NoPointSizeVertShader[] =
8201         "#version 450\n"
8202         "vec2 vertices[3];\n"
8203         "out gl_PerVertex\n"
8204         "{\n"
8205         "    vec4 gl_Position;\n"
8206         "    float gl_PointSize;\n"
8207         "};\n"
8208         "void main() {\n"
8209         "    vertices[0] = vec2(-1.0, -1.0);\n"
8210         "    vertices[1] = vec2( 1.0, -1.0);\n"
8211         "    vertices[2] = vec2( 0.0,  1.0);\n"
8212         "    gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0);\n"
8213         "}\n";
8214 
8215     VkShaderObj vs(m_device, NoPointSizeVertShader, VK_SHADER_STAGE_VERTEX_BIT, this);
8216     VkShaderObj ps(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
8217 
8218     VkPipelineObj pipelineobj(m_device);
8219     pipelineobj.AddDefaultColorAttachment();
8220     pipelineobj.AddShader(&vs);
8221     pipelineobj.AddShader(&ps);
8222 
8223     // Set Input Assembly to TOPOLOGY POINT LIST
8224     VkPipelineInputAssemblyStateCreateInfo ia_state = {};
8225     ia_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
8226     ia_state.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
8227     pipelineobj.SetInputAssembly(&ia_state);
8228 
8229     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8230     m_commandBuffer->begin();
8231     m_commandBuffer->ClearAllBuffers(m_renderTargets, m_clear_color, m_depthStencil, m_depth_clear_color, m_stencil_clear_color);
8232     m_commandBuffer->PrepareAttachments(m_renderTargets, m_depthStencil);
8233     VkDescriptorSetObj descriptorSet(m_device);
8234     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
8235     pipelineobj.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
8236     m_errorMonitor->VerifyFound();
8237 }
8238 
TEST_F(VkLayerTest,PointSizeGeomShaderFailure)8239 TEST_F(VkLayerTest, PointSizeGeomShaderFailure) {
8240     TEST_DESCRIPTION(
8241         "Create a pipeline using TOPOLOGY_POINT_LIST, set PointSize vertex shader, but not in the final geometry stage.");
8242 
8243     ASSERT_NO_FATAL_FAILURE(Init());
8244 
8245     if ((!m_device->phy().features().geometryShader) || (!m_device->phy().features().shaderTessellationAndGeometryPointSize)) {
8246         printf("%s Device does not support the required geometry shader features; skipped.\n", kSkipPrefix);
8247         return;
8248     }
8249 
8250     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Pipeline topology is set to POINT_LIST");
8251 
8252     ASSERT_NO_FATAL_FAILURE(InitViewport());
8253 
8254     // Create VS declaring PointSize and writing to it
8255     static const char PointSizeVertShader[] =
8256         "#version 450\n"
8257         "vec2 vertices[3];\n"
8258         "out gl_PerVertex\n"
8259         "{\n"
8260         "    vec4 gl_Position;\n"
8261         "    float gl_PointSize;\n"
8262         "};\n"
8263         "void main() {\n"
8264         "    vertices[0] = vec2(-1.0, -1.0);\n"
8265         "    vertices[1] = vec2( 1.0, -1.0);\n"
8266         "    vertices[2] = vec2( 0.0,  1.0);\n"
8267         "    gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0);\n"
8268         "    gl_PointSize = 5.0;\n"
8269         "}\n";
8270     static char const *gsSource =
8271         "#version 450\n"
8272         "layout (points) in;\n"
8273         "layout (points) out;\n"
8274         "layout (max_vertices = 1) out;\n"
8275         "void main() {\n"
8276         "   gl_Position = vec4(1.0, 0.5, 0.5, 0.0);\n"
8277         "   EmitVertex();\n"
8278         "}\n";
8279 
8280     VkShaderObj vs(m_device, PointSizeVertShader, VK_SHADER_STAGE_VERTEX_BIT, this);
8281     VkShaderObj gs(m_device, gsSource, VK_SHADER_STAGE_GEOMETRY_BIT, this);
8282     VkShaderObj ps(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
8283 
8284     VkPipelineObj pipelineobj(m_device);
8285     pipelineobj.AddDefaultColorAttachment();
8286     pipelineobj.AddShader(&vs);
8287     pipelineobj.AddShader(&gs);
8288     pipelineobj.AddShader(&ps);
8289 
8290     // Set Input Assembly to TOPOLOGY POINT LIST
8291     VkPipelineInputAssemblyStateCreateInfo ia_state = {};
8292     ia_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
8293     ia_state.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
8294     pipelineobj.SetInputAssembly(&ia_state);
8295 
8296     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8297     m_commandBuffer->begin();
8298     m_commandBuffer->ClearAllBuffers(m_renderTargets, m_clear_color, m_depthStencil, m_depth_clear_color, m_stencil_clear_color);
8299     m_commandBuffer->PrepareAttachments(m_renderTargets, m_depthStencil);
8300     VkDescriptorSetObj descriptorSet(m_device);
8301     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
8302     pipelineobj.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
8303     m_errorMonitor->VerifyFound();
8304 }
8305 
TEST_F(VkLayerTest,DynamicDepthBiasNotBound)8306 TEST_F(VkLayerTest, DynamicDepthBiasNotBound) {
8307     TEST_DESCRIPTION(
8308         "Run a simple draw calls to validate failure when Depth Bias dynamic state is required but not correctly bound.");
8309 
8310     ASSERT_NO_FATAL_FAILURE(Init());
8311     // Dynamic depth bias
8312     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic depth bias state not set for this command buffer");
8313     VKTriangleTest(BsoFailDepthBias);
8314     m_errorMonitor->VerifyFound();
8315 }
8316 
TEST_F(VkLayerTest,DynamicLineWidthNotBound)8317 TEST_F(VkLayerTest, DynamicLineWidthNotBound) {
8318     TEST_DESCRIPTION(
8319         "Run a simple draw calls to validate failure when Line Width dynamic state is required but not correctly bound.");
8320 
8321     ASSERT_NO_FATAL_FAILURE(Init());
8322     // Dynamic line width
8323     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic line width state not set for this command buffer");
8324     VKTriangleTest(BsoFailLineWidth);
8325     m_errorMonitor->VerifyFound();
8326 }
8327 
TEST_F(VkLayerTest,DynamicViewportNotBound)8328 TEST_F(VkLayerTest, DynamicViewportNotBound) {
8329     TEST_DESCRIPTION(
8330         "Run a simple draw calls to validate failure when Viewport dynamic state is required but not correctly bound.");
8331 
8332     ASSERT_NO_FATAL_FAILURE(Init());
8333     // Dynamic viewport state
8334     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8335                                          "Dynamic viewport(s) 0 are used by pipeline state object, but were not provided");
8336     VKTriangleTest(BsoFailViewport);
8337     m_errorMonitor->VerifyFound();
8338 }
8339 
TEST_F(VkLayerTest,DynamicScissorNotBound)8340 TEST_F(VkLayerTest, DynamicScissorNotBound) {
8341     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Scissor dynamic state is required but not correctly bound.");
8342 
8343     ASSERT_NO_FATAL_FAILURE(Init());
8344     // Dynamic scissor state
8345     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8346                                          "Dynamic scissor(s) 0 are used by pipeline state object, but were not provided");
8347     VKTriangleTest(BsoFailScissor);
8348     m_errorMonitor->VerifyFound();
8349 }
8350 
TEST_F(VkLayerTest,DynamicBlendConstantsNotBound)8351 TEST_F(VkLayerTest, DynamicBlendConstantsNotBound) {
8352     TEST_DESCRIPTION(
8353         "Run a simple draw calls to validate failure when Blend Constants dynamic state is required but not correctly bound.");
8354 
8355     ASSERT_NO_FATAL_FAILURE(Init());
8356     // Dynamic blend constant state
8357     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8358                                          "Dynamic blend constants state not set for this command buffer");
8359     VKTriangleTest(BsoFailBlend);
8360     m_errorMonitor->VerifyFound();
8361 }
8362 
TEST_F(VkLayerTest,DynamicDepthBoundsNotBound)8363 TEST_F(VkLayerTest, DynamicDepthBoundsNotBound) {
8364     TEST_DESCRIPTION(
8365         "Run a simple draw calls to validate failure when Depth Bounds dynamic state is required but not correctly bound.");
8366 
8367     ASSERT_NO_FATAL_FAILURE(Init());
8368     if (!m_device->phy().features().depthBounds) {
8369         printf("%s Device does not support depthBounds test; skipped.\n", kSkipPrefix);
8370         return;
8371     }
8372     // Dynamic depth bounds
8373     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8374                                          "Dynamic depth bounds state not set for this command buffer");
8375     VKTriangleTest(BsoFailDepthBounds);
8376     m_errorMonitor->VerifyFound();
8377 }
8378 
TEST_F(VkLayerTest,DynamicStencilReadNotBound)8379 TEST_F(VkLayerTest, DynamicStencilReadNotBound) {
8380     TEST_DESCRIPTION(
8381         "Run a simple draw calls to validate failure when Stencil Read dynamic state is required but not correctly bound.");
8382 
8383     ASSERT_NO_FATAL_FAILURE(Init());
8384     // Dynamic stencil read mask
8385     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8386                                          "Dynamic stencil read mask state not set for this command buffer");
8387     VKTriangleTest(BsoFailStencilReadMask);
8388     m_errorMonitor->VerifyFound();
8389 }
8390 
TEST_F(VkLayerTest,DynamicStencilWriteNotBound)8391 TEST_F(VkLayerTest, DynamicStencilWriteNotBound) {
8392     TEST_DESCRIPTION(
8393         "Run a simple draw calls to validate failure when Stencil Write dynamic state is required but not correctly bound.");
8394 
8395     ASSERT_NO_FATAL_FAILURE(Init());
8396     // Dynamic stencil write mask
8397     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8398                                          "Dynamic stencil write mask state not set for this command buffer");
8399     VKTriangleTest(BsoFailStencilWriteMask);
8400     m_errorMonitor->VerifyFound();
8401 }
8402 
TEST_F(VkLayerTest,DynamicStencilRefNotBound)8403 TEST_F(VkLayerTest, DynamicStencilRefNotBound) {
8404     TEST_DESCRIPTION(
8405         "Run a simple draw calls to validate failure when Stencil Ref dynamic state is required but not correctly bound.");
8406 
8407     ASSERT_NO_FATAL_FAILURE(Init());
8408     // Dynamic stencil reference
8409     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8410                                          "Dynamic stencil reference state not set for this command buffer");
8411     VKTriangleTest(BsoFailStencilReference);
8412     m_errorMonitor->VerifyFound();
8413 }
8414 
TEST_F(VkLayerTest,IndexBufferNotBound)8415 TEST_F(VkLayerTest, IndexBufferNotBound) {
8416     TEST_DESCRIPTION("Run an indexed draw call without an index buffer bound.");
8417 
8418     ASSERT_NO_FATAL_FAILURE(Init());
8419     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8420                                          "Index buffer object not bound to this command buffer when Indexed ");
8421     VKTriangleTest(BsoFailIndexBuffer);
8422     m_errorMonitor->VerifyFound();
8423 }
8424 
TEST_F(VkLayerTest,IndexBufferBadSize)8425 TEST_F(VkLayerTest, IndexBufferBadSize) {
8426     TEST_DESCRIPTION("Run indexed draw call with bad index buffer size.");
8427 
8428     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
8429     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdDrawIndexed() index size ");
8430     VKTriangleTest(BsoFailIndexBufferBadSize);
8431     m_errorMonitor->VerifyFound();
8432 }
8433 
TEST_F(VkLayerTest,IndexBufferBadOffset)8434 TEST_F(VkLayerTest, IndexBufferBadOffset) {
8435     TEST_DESCRIPTION("Run indexed draw call with bad index buffer offset.");
8436 
8437     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
8438     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdDrawIndexed() index size ");
8439     VKTriangleTest(BsoFailIndexBufferBadOffset);
8440     m_errorMonitor->VerifyFound();
8441 }
8442 
TEST_F(VkLayerTest,IndexBufferBadBindSize)8443 TEST_F(VkLayerTest, IndexBufferBadBindSize) {
8444     TEST_DESCRIPTION("Run bind index buffer with a size greater than the index buffer.");
8445 
8446     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
8447     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdDrawIndexed() index size ");
8448     VKTriangleTest(BsoFailIndexBufferBadMapSize);
8449     m_errorMonitor->VerifyFound();
8450 }
8451 
TEST_F(VkLayerTest,IndexBufferBadBindOffset)8452 TEST_F(VkLayerTest, IndexBufferBadBindOffset) {
8453     TEST_DESCRIPTION("Run bind index buffer with an offset greater than the size of the index buffer.");
8454 
8455     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
8456     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdDrawIndexed() index size ");
8457     VKTriangleTest(BsoFailIndexBufferBadMapOffset);
8458     m_errorMonitor->VerifyFound();
8459 }
8460 
TEST_F(VkLayerTest,CommandBufferTwoSubmits)8461 TEST_F(VkLayerTest, CommandBufferTwoSubmits) {
8462     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8463                                          "was begun w/ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has been submitted");
8464 
8465     ASSERT_NO_FATAL_FAILURE(Init());
8466     ASSERT_NO_FATAL_FAILURE(InitViewport());
8467     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8468 
8469     // We luck out b/c by default the framework creates CB w/ the
8470     // VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set
8471     m_commandBuffer->begin();
8472     m_commandBuffer->ClearAllBuffers(m_renderTargets, m_clear_color, nullptr, m_depth_clear_color, m_stencil_clear_color);
8473     m_commandBuffer->end();
8474 
8475     // Bypass framework since it does the waits automatically
8476     VkResult err = VK_SUCCESS;
8477     VkSubmitInfo submit_info;
8478     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
8479     submit_info.pNext = NULL;
8480     submit_info.waitSemaphoreCount = 0;
8481     submit_info.pWaitSemaphores = NULL;
8482     submit_info.pWaitDstStageMask = NULL;
8483     submit_info.commandBufferCount = 1;
8484     submit_info.pCommandBuffers = &m_commandBuffer->handle();
8485     submit_info.signalSemaphoreCount = 0;
8486     submit_info.pSignalSemaphores = NULL;
8487 
8488     err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
8489     ASSERT_VK_SUCCESS(err);
8490     vkQueueWaitIdle(m_device->m_queue);
8491 
8492     // Cause validation error by re-submitting cmd buffer that should only be
8493     // submitted once
8494     err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
8495     vkQueueWaitIdle(m_device->m_queue);
8496 
8497     m_errorMonitor->VerifyFound();
8498 }
8499 
TEST_F(VkLayerTest,AllocDescriptorFromEmptyPool)8500 TEST_F(VkLayerTest, AllocDescriptorFromEmptyPool) {
8501     TEST_DESCRIPTION("Attempt to allocate more sets and descriptors than descriptor pool has available.");
8502     VkResult err;
8503 
8504     ASSERT_NO_FATAL_FAILURE(Init());
8505     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8506 
8507     // This test is valid for Vulkan 1.0 only -- skip if device has an API version greater than 1.0.
8508     if (m_device->props.apiVersion >= VK_API_VERSION_1_1) {
8509         printf("%s Device has apiVersion greater than 1.0 -- skipping Descriptor Set checks.\n", kSkipPrefix);
8510         return;
8511     }
8512 
8513     // Create Pool w/ 1 Sampler descriptor, but try to alloc Uniform Buffer
8514     // descriptor from it
8515     VkDescriptorPoolSize ds_type_count = {};
8516     ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
8517     ds_type_count.descriptorCount = 2;
8518 
8519     VkDescriptorPoolCreateInfo ds_pool_ci = {};
8520     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8521     ds_pool_ci.pNext = NULL;
8522     ds_pool_ci.flags = 0;
8523     ds_pool_ci.maxSets = 1;
8524     ds_pool_ci.poolSizeCount = 1;
8525     ds_pool_ci.pPoolSizes = &ds_type_count;
8526 
8527     VkDescriptorPool ds_pool;
8528     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8529     ASSERT_VK_SUCCESS(err);
8530 
8531     VkDescriptorSetLayoutBinding dsl_binding_samp = {};
8532     dsl_binding_samp.binding = 0;
8533     dsl_binding_samp.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
8534     dsl_binding_samp.descriptorCount = 1;
8535     dsl_binding_samp.stageFlags = VK_SHADER_STAGE_ALL;
8536     dsl_binding_samp.pImmutableSamplers = NULL;
8537 
8538     const VkDescriptorSetLayoutObj ds_layout_samp(m_device, {dsl_binding_samp});
8539 
8540     // Try to allocate 2 sets when pool only has 1 set
8541     VkDescriptorSet descriptor_sets[2];
8542     VkDescriptorSetLayout set_layouts[2] = {ds_layout_samp.handle(), ds_layout_samp.handle()};
8543     VkDescriptorSetAllocateInfo alloc_info = {};
8544     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8545     alloc_info.descriptorSetCount = 2;
8546     alloc_info.descriptorPool = ds_pool;
8547     alloc_info.pSetLayouts = set_layouts;
8548     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8549                                          "VUID-VkDescriptorSetAllocateInfo-descriptorSetCount-00306");
8550     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, descriptor_sets);
8551     m_errorMonitor->VerifyFound();
8552 
8553     alloc_info.descriptorSetCount = 1;
8554     // Create layout w/ descriptor type not available in pool
8555     VkDescriptorSetLayoutBinding dsl_binding = {};
8556     dsl_binding.binding = 0;
8557     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8558     dsl_binding.descriptorCount = 1;
8559     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8560     dsl_binding.pImmutableSamplers = NULL;
8561 
8562     const VkDescriptorSetLayoutObj ds_layout_ub(m_device, {dsl_binding});
8563 
8564     VkDescriptorSet descriptor_set;
8565     alloc_info.descriptorSetCount = 1;
8566     alloc_info.pSetLayouts = &ds_layout_ub.handle();
8567     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkDescriptorSetAllocateInfo-descriptorPool-00307");
8568     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
8569 
8570     m_errorMonitor->VerifyFound();
8571 
8572     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8573 }
8574 
TEST_F(VkLayerTest,FreeDescriptorFromOneShotPool)8575 TEST_F(VkLayerTest, FreeDescriptorFromOneShotPool) {
8576     VkResult err;
8577 
8578     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkFreeDescriptorSets-descriptorPool-00312");
8579 
8580     ASSERT_NO_FATAL_FAILURE(Init());
8581     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8582 
8583     VkDescriptorPoolSize ds_type_count = {};
8584     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8585     ds_type_count.descriptorCount = 1;
8586 
8587     VkDescriptorPoolCreateInfo ds_pool_ci = {};
8588     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
8589     ds_pool_ci.pNext = NULL;
8590     ds_pool_ci.maxSets = 1;
8591     ds_pool_ci.poolSizeCount = 1;
8592     ds_pool_ci.flags = 0;
8593     // Not specifying VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT means
8594     // app can only call vkResetDescriptorPool on this pool.;
8595     ds_pool_ci.pPoolSizes = &ds_type_count;
8596 
8597     VkDescriptorPool ds_pool;
8598     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
8599     ASSERT_VK_SUCCESS(err);
8600 
8601     VkDescriptorSetLayoutBinding dsl_binding = {};
8602     dsl_binding.binding = 0;
8603     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8604     dsl_binding.descriptorCount = 1;
8605     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
8606     dsl_binding.pImmutableSamplers = NULL;
8607 
8608     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
8609 
8610     VkDescriptorSet descriptorSet;
8611     VkDescriptorSetAllocateInfo alloc_info = {};
8612     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
8613     alloc_info.descriptorSetCount = 1;
8614     alloc_info.descriptorPool = ds_pool;
8615     alloc_info.pSetLayouts = &ds_layout.handle();
8616     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
8617     ASSERT_VK_SUCCESS(err);
8618 
8619     err = vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptorSet);
8620     m_errorMonitor->VerifyFound();
8621 
8622     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
8623 }
8624 
TEST_F(VkLayerTest,InvalidDescriptorPool)8625 TEST_F(VkLayerTest, InvalidDescriptorPool) {
8626     // Attempt to clear Descriptor Pool with bad object.
8627     // ObjectTracker should catch this.
8628 
8629     ASSERT_NO_FATAL_FAILURE(Init());
8630     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkResetDescriptorPool-descriptorPool-parameter");
8631     uint64_t fake_pool_handle = 0xbaad6001;
8632     VkDescriptorPool bad_pool = reinterpret_cast<VkDescriptorPool &>(fake_pool_handle);
8633     vkResetDescriptorPool(device(), bad_pool, 0);
8634     m_errorMonitor->VerifyFound();
8635 }
8636 
TEST_F(VkLayerTest,InvalidDescriptorSet)8637 TEST_F(VkLayerTest, InvalidDescriptorSet) {
8638     // Attempt to bind an invalid Descriptor Set to a valid Command Buffer
8639     // ObjectTracker should catch this.
8640     // Create a valid cmd buffer
8641     // call vkCmdBindDescriptorSets w/ false Descriptor Set
8642 
8643     uint64_t fake_set_handle = 0xbaad6001;
8644     VkDescriptorSet bad_set = reinterpret_cast<VkDescriptorSet &>(fake_set_handle);
8645 
8646     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBindDescriptorSets-pDescriptorSets-parameter");
8647 
8648     ASSERT_NO_FATAL_FAILURE(Init());
8649 
8650     VkDescriptorSetLayoutBinding layout_binding = {};
8651     layout_binding.binding = 0;
8652     layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8653     layout_binding.descriptorCount = 1;
8654     layout_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
8655     layout_binding.pImmutableSamplers = NULL;
8656 
8657     const VkDescriptorSetLayoutObj descriptor_set_layout(m_device, {layout_binding});
8658 
8659     const VkPipelineLayoutObj pipeline_layout(DeviceObj(), {&descriptor_set_layout});
8660 
8661     m_commandBuffer->begin();
8662     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &bad_set, 0,
8663                             NULL);
8664     m_errorMonitor->VerifyFound();
8665     m_commandBuffer->end();
8666 }
8667 
TEST_F(VkLayerTest,InvalidDescriptorSetLayout)8668 TEST_F(VkLayerTest, InvalidDescriptorSetLayout) {
8669     // Attempt to create a Pipeline Layout with an invalid Descriptor Set Layout.
8670     // ObjectTracker should catch this.
8671     uint64_t fake_layout_handle = 0xbaad6001;
8672     VkDescriptorSetLayout bad_layout = reinterpret_cast<VkDescriptorSetLayout &>(fake_layout_handle);
8673     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-parameter");
8674     ASSERT_NO_FATAL_FAILURE(Init());
8675     VkPipelineLayout pipeline_layout;
8676     VkPipelineLayoutCreateInfo plci = {};
8677     plci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8678     plci.pNext = NULL;
8679     plci.setLayoutCount = 1;
8680     plci.pSetLayouts = &bad_layout;
8681     vkCreatePipelineLayout(device(), &plci, NULL, &pipeline_layout);
8682 
8683     m_errorMonitor->VerifyFound();
8684 }
8685 
TEST_F(VkLayerTest,WriteDescriptorSetIntegrityCheck)8686 TEST_F(VkLayerTest, WriteDescriptorSetIntegrityCheck) {
8687     TEST_DESCRIPTION(
8688         "This test verifies some requirements of chapter 13.2.3 of the Vulkan Spec "
8689         "1) A uniform buffer update must have a valid buffer index. "
8690         "2) When using an array of descriptors in a single WriteDescriptor, the descriptor types and stageflags "
8691         "must all be the same. "
8692         "3) Immutable Sampler state must match across descriptors. "
8693         "4) That sampled image descriptors have required layouts. ");
8694 
8695     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkWriteDescriptorSet-descriptorType-00324");
8696 
8697     ASSERT_NO_FATAL_FAILURE(Init());
8698 
8699     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
8700     VkSampler sampler;
8701     VkResult err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
8702     ASSERT_VK_SUCCESS(err);
8703 
8704     OneOffDescriptorSet::Bindings bindings = {
8705         {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL},
8706         {1, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, NULL},
8707         {2, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, static_cast<VkSampler *>(&sampler)},
8708         {3, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, NULL}};
8709     OneOffDescriptorSet descriptor_set(m_device, bindings);
8710     ASSERT_TRUE(descriptor_set.Initialized());
8711 
8712     VkWriteDescriptorSet descriptor_write = {};
8713     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8714     descriptor_write.dstSet = descriptor_set.set_;
8715     descriptor_write.dstBinding = 0;
8716     descriptor_write.descriptorCount = 1;
8717     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8718 
8719     // 1) The uniform buffer is intentionally invalid here
8720     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8721     m_errorMonitor->VerifyFound();
8722 
8723     // Create a buffer to update the descriptor with
8724     uint32_t qfi = 0;
8725     VkBufferCreateInfo buffCI = {};
8726     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
8727     buffCI.size = 1024;
8728     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
8729     buffCI.queueFamilyIndexCount = 1;
8730     buffCI.pQueueFamilyIndices = &qfi;
8731 
8732     VkBuffer dyub;
8733     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
8734     ASSERT_VK_SUCCESS(err);
8735 
8736     VkDeviceMemory mem;
8737     VkMemoryRequirements mem_reqs;
8738     vkGetBufferMemoryRequirements(m_device->device(), dyub, &mem_reqs);
8739 
8740     VkMemoryAllocateInfo mem_alloc_info = {};
8741     mem_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
8742     mem_alloc_info.allocationSize = mem_reqs.size;
8743     m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
8744     err = vkAllocateMemory(m_device->device(), &mem_alloc_info, NULL, &mem);
8745     ASSERT_VK_SUCCESS(err);
8746 
8747     err = vkBindBufferMemory(m_device->device(), dyub, mem, 0);
8748     ASSERT_VK_SUCCESS(err);
8749 
8750     VkDescriptorBufferInfo buffInfo[2] = {};
8751     buffInfo[0].buffer = dyub;
8752     buffInfo[0].offset = 0;
8753     buffInfo[0].range = 1024;
8754     buffInfo[1].buffer = dyub;
8755     buffInfo[1].offset = 0;
8756     buffInfo[1].range = 1024;
8757     descriptor_write.pBufferInfo = buffInfo;
8758     descriptor_write.descriptorCount = 2;
8759 
8760     // 2) The stateFlags don't match between the first and second descriptor
8761     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkWriteDescriptorSet-dstArrayElement-00321");
8762     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8763     m_errorMonitor->VerifyFound();
8764 
8765     // 3) The second descriptor has a null_ptr pImmutableSamplers and
8766     // the third descriptor contains an immutable sampler
8767     descriptor_write.dstBinding = 1;
8768     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
8769 
8770     // Make pImageInfo index non-null to avoid complaints of it missing
8771     VkDescriptorImageInfo imageInfo = {};
8772     imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
8773     descriptor_write.pImageInfo = &imageInfo;
8774     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkWriteDescriptorSet-dstArrayElement-00321");
8775     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8776     m_errorMonitor->VerifyFound();
8777 
8778     // 4) That sampled image descriptors have required layouts
8779     // Create images to update the descriptor with
8780     VkImageObj image(m_device);
8781     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
8782     image.Init(32, 32, 1, tex_format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
8783     ASSERT_TRUE(image.initialized());
8784 
8785     // Attmept write with incorrect layout for sampled descriptor
8786     imageInfo.sampler = VK_NULL_HANDLE;
8787     imageInfo.imageView = image.targetView(tex_format);
8788     imageInfo.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
8789 
8790     descriptor_write.dstBinding = 3;
8791     descriptor_write.descriptorCount = 1;
8792     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
8793     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkWriteDescriptorSet-descriptorType-01403");
8794     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8795     m_errorMonitor->VerifyFound();
8796 
8797     vkDestroyBuffer(m_device->device(), dyub, NULL);
8798     vkFreeMemory(m_device->device(), mem, NULL);
8799     vkDestroySampler(m_device->device(), sampler, NULL);
8800 }
8801 
TEST_F(VkLayerTest,WriteDescriptorSetConsecutiveUpdates)8802 TEST_F(VkLayerTest, WriteDescriptorSetConsecutiveUpdates) {
8803     TEST_DESCRIPTION(
8804         "Verifies that updates rolling over to next descriptor work correctly by destroying buffer from consecutive update known "
8805         "to be used in descriptor set and verifying that error is flagged.");
8806 
8807     ASSERT_NO_FATAL_FAILURE(Init());
8808     ASSERT_NO_FATAL_FAILURE(InitViewport());
8809     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8810 
8811     OneOffDescriptorSet ds(m_device, {
8812                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2, VK_SHADER_STAGE_ALL, nullptr},
8813                                          {1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
8814                                      });
8815 
8816     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
8817 
8818     uint32_t qfi = 0;
8819     VkBufferCreateInfo bci = {};
8820     bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
8821     bci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
8822     bci.size = 2048;
8823     bci.queueFamilyIndexCount = 1;
8824     bci.pQueueFamilyIndices = &qfi;
8825     VkBufferObj buffer0;
8826     buffer0.init(*m_device, bci);
8827     VkPipelineObj pipe(m_device);
8828     {  // Scope 2nd buffer to cause early destruction
8829         VkBufferObj buffer1;
8830         bci.size = 1024;
8831         buffer1.init(*m_device, bci);
8832 
8833         VkDescriptorBufferInfo buffer_info[3] = {};
8834         buffer_info[0].buffer = buffer0.handle();
8835         buffer_info[0].offset = 0;
8836         buffer_info[0].range = 1024;
8837         buffer_info[1].buffer = buffer0.handle();
8838         buffer_info[1].offset = 1024;
8839         buffer_info[1].range = 1024;
8840         buffer_info[2].buffer = buffer1.handle();
8841         buffer_info[2].offset = 0;
8842         buffer_info[2].range = 1024;
8843 
8844         VkWriteDescriptorSet descriptor_write = {};
8845         descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
8846         descriptor_write.dstSet = ds.set_;  // descriptor_set;
8847         descriptor_write.dstBinding = 0;
8848         descriptor_write.descriptorCount = 3;
8849         descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8850         descriptor_write.pBufferInfo = buffer_info;
8851 
8852         // Update descriptor
8853         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
8854 
8855         // Create PSO that uses the uniform buffers
8856         char const *vsSource =
8857             "#version 450\n"
8858             "\n"
8859             "void main(){\n"
8860             "   gl_Position = vec4(1);\n"
8861             "}\n";
8862         char const *fsSource =
8863             "#version 450\n"
8864             "\n"
8865             "layout(location=0) out vec4 x;\n"
8866             "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
8867             "layout(set=0) layout(binding=1) uniform blah { int x; } duh;\n"
8868             "void main(){\n"
8869             "   x = vec4(duh.x, bar.y, bar.x, 1);\n"
8870             "}\n";
8871         VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
8872         VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
8873 
8874         pipe.AddShader(&vs);
8875         pipe.AddShader(&fs);
8876         pipe.AddDefaultColorAttachment();
8877 
8878         VkResult err = pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
8879         ASSERT_VK_SUCCESS(err);
8880 
8881         m_commandBuffer->begin();
8882         m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
8883 
8884         vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
8885         vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
8886                                 &ds.set_, 0, nullptr);
8887 
8888         VkViewport viewport = {0, 0, 16, 16, 0, 1};
8889         vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
8890         VkRect2D scissor = {{0, 0}, {16, 16}};
8891         vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
8892         vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
8893         vkCmdEndRenderPass(m_commandBuffer->handle());
8894         m_commandBuffer->end();
8895     }
8896     // buffer2 just went out of scope and was destroyed along with its memory
8897     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Buffer ");
8898     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound DeviceMemory ");
8899     VkSubmitInfo submit_info = {};
8900     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
8901     submit_info.commandBufferCount = 1;
8902     submit_info.pCommandBuffers = &m_commandBuffer->handle();
8903     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
8904     m_errorMonitor->VerifyFound();
8905 }
8906 
TEST_F(VkLayerTest,CreatePipelineLayoutExceedsSetLimit)8907 TEST_F(VkLayerTest, CreatePipelineLayoutExceedsSetLimit) {
8908     TEST_DESCRIPTION("Attempt to create a pipeline layout using more than the physical limit of SetLayouts.");
8909 
8910     ASSERT_NO_FATAL_FAILURE(Init());
8911 
8912     VkDescriptorSetLayoutBinding layout_binding = {};
8913     layout_binding.binding = 0;
8914     layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
8915     layout_binding.descriptorCount = 1;
8916     layout_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
8917     layout_binding.pImmutableSamplers = NULL;
8918 
8919     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8920     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8921     ds_layout_ci.bindingCount = 1;
8922     ds_layout_ci.pBindings = &layout_binding;
8923     VkDescriptorSetLayout ds_layout = {};
8924     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
8925     ASSERT_VK_SUCCESS(err);
8926 
8927     // Create an array of DSLs, one larger than the physical limit
8928     const auto excess_layouts = 1 + m_device->phy().properties().limits.maxBoundDescriptorSets;
8929     std::vector<VkDescriptorSetLayout> dsl_array(excess_layouts, ds_layout);
8930 
8931     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8932     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8933     pipeline_layout_ci.pNext = NULL;
8934     pipeline_layout_ci.setLayoutCount = excess_layouts;
8935     pipeline_layout_ci.pSetLayouts = dsl_array.data();
8936 
8937     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-setLayoutCount-00286");
8938     VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
8939     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
8940     m_errorMonitor->VerifyFound();
8941 
8942     // Clean up
8943     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
8944 }
8945 
TEST_F(VkLayerTest,CreatePipelineLayoutExcessPerStageDescriptors)8946 TEST_F(VkLayerTest, CreatePipelineLayoutExcessPerStageDescriptors) {
8947     TEST_DESCRIPTION("Attempt to create a pipeline layout where total descriptors exceed per-stage limits");
8948 
8949     ASSERT_NO_FATAL_FAILURE(Init());
8950 
8951     uint32_t max_uniform_buffers = m_device->phy().properties().limits.maxPerStageDescriptorUniformBuffers;
8952     uint32_t max_storage_buffers = m_device->phy().properties().limits.maxPerStageDescriptorStorageBuffers;
8953     uint32_t max_sampled_images = m_device->phy().properties().limits.maxPerStageDescriptorSampledImages;
8954     uint32_t max_storage_images = m_device->phy().properties().limits.maxPerStageDescriptorStorageImages;
8955     uint32_t max_samplers = m_device->phy().properties().limits.maxPerStageDescriptorSamplers;
8956     uint32_t max_combined = std::min(max_samplers, max_sampled_images);
8957     uint32_t max_input_attachments = m_device->phy().properties().limits.maxPerStageDescriptorInputAttachments;
8958 
8959     uint32_t sum_dyn_uniform_buffers = m_device->phy().properties().limits.maxDescriptorSetUniformBuffersDynamic;
8960     uint32_t sum_uniform_buffers = m_device->phy().properties().limits.maxDescriptorSetUniformBuffers;
8961     uint32_t sum_dyn_storage_buffers = m_device->phy().properties().limits.maxDescriptorSetStorageBuffersDynamic;
8962     uint32_t sum_storage_buffers = m_device->phy().properties().limits.maxDescriptorSetStorageBuffers;
8963     uint32_t sum_sampled_images = m_device->phy().properties().limits.maxDescriptorSetSampledImages;
8964     uint32_t sum_storage_images = m_device->phy().properties().limits.maxDescriptorSetStorageImages;
8965     uint32_t sum_samplers = m_device->phy().properties().limits.maxDescriptorSetSamplers;
8966     uint32_t sum_input_attachments = m_device->phy().properties().limits.maxDescriptorSetInputAttachments;
8967 
8968     // Devices that report UINT32_MAX for any of these limits can't run this test
8969     if (UINT32_MAX == std::max({max_uniform_buffers, max_storage_buffers, max_sampled_images, max_storage_images, max_samplers})) {
8970         printf("%s Physical device limits report as 2^32-1. Skipping test.\n", kSkipPrefix);
8971         return;
8972     }
8973 
8974     VkDescriptorSetLayoutBinding dslb = {};
8975     std::vector<VkDescriptorSetLayoutBinding> dslb_vec = {};
8976     VkDescriptorSetLayout ds_layout = VK_NULL_HANDLE;
8977     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
8978     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
8979     ds_layout_ci.pNext = NULL;
8980     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
8981     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
8982     pipeline_layout_ci.pNext = NULL;
8983     pipeline_layout_ci.setLayoutCount = 1;
8984     pipeline_layout_ci.pSetLayouts = &ds_layout;
8985     VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
8986 
8987     // VU 0fe0023e - too many sampler type descriptors in fragment stage
8988     dslb_vec.clear();
8989     dslb.binding = 0;
8990     dslb.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
8991     dslb.descriptorCount = max_samplers;
8992     dslb.stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS;
8993     dslb.pImmutableSamplers = NULL;
8994     dslb_vec.push_back(dslb);
8995     dslb.binding = 1;
8996     dslb.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
8997     dslb.descriptorCount = max_combined;
8998     dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
8999     dslb_vec.push_back(dslb);
9000 
9001     ds_layout_ci.bindingCount = dslb_vec.size();
9002     ds_layout_ci.pBindings = dslb_vec.data();
9003     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9004     ASSERT_VK_SUCCESS(err);
9005 
9006     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00287");
9007     if ((max_samplers + max_combined) > sum_samplers) {
9008         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9009                                              "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01677");  // expect all-stages sum too
9010     }
9011     if (max_combined > sum_sampled_images) {
9012         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9013                                              "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01682");  // expect all-stages sum too
9014     }
9015     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9016     m_errorMonitor->VerifyFound();
9017     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
9018     pipeline_layout = VK_NULL_HANDLE;
9019     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9020 
9021     // VU 0fe00240 - too many uniform buffer type descriptors in vertex stage
9022     dslb_vec.clear();
9023     dslb.binding = 0;
9024     dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9025     dslb.descriptorCount = max_uniform_buffers + 1;
9026     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
9027     dslb_vec.push_back(dslb);
9028     dslb.binding = 1;
9029     dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
9030     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
9031     dslb_vec.push_back(dslb);
9032 
9033     ds_layout_ci.bindingCount = dslb_vec.size();
9034     ds_layout_ci.pBindings = dslb_vec.data();
9035     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9036     ASSERT_VK_SUCCESS(err);
9037 
9038     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00288");
9039     if (dslb.descriptorCount > sum_uniform_buffers) {
9040         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9041                                              "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01678");  // expect all-stages sum too
9042     }
9043     if (dslb.descriptorCount > sum_dyn_uniform_buffers) {
9044         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9045                                              "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01679");  // expect all-stages sum too
9046     }
9047     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9048     m_errorMonitor->VerifyFound();
9049     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
9050     pipeline_layout = VK_NULL_HANDLE;
9051     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9052 
9053     // VU 0fe00242 - too many storage buffer type descriptors in compute stage
9054     dslb_vec.clear();
9055     dslb.binding = 0;
9056     dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
9057     dslb.descriptorCount = max_storage_buffers + 1;
9058     dslb.stageFlags = VK_SHADER_STAGE_ALL;
9059     dslb_vec.push_back(dslb);
9060     dslb.binding = 1;
9061     dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
9062     dslb_vec.push_back(dslb);
9063     dslb.binding = 2;
9064     dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
9065     dslb.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
9066     dslb_vec.push_back(dslb);
9067 
9068     ds_layout_ci.bindingCount = dslb_vec.size();
9069     ds_layout_ci.pBindings = dslb_vec.data();
9070     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9071     ASSERT_VK_SUCCESS(err);
9072 
9073     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00289");
9074     if (dslb.descriptorCount > sum_dyn_storage_buffers) {
9075         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9076                                              "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01681");  // expect all-stages sum too
9077     }
9078     if (dslb_vec[0].descriptorCount + dslb_vec[2].descriptorCount > sum_storage_buffers) {
9079         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9080                                              "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01680");  // expect all-stages sum too
9081     }
9082     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9083     m_errorMonitor->VerifyFound();
9084     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
9085     pipeline_layout = VK_NULL_HANDLE;
9086     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9087 
9088     // VU 0fe00244 - too many sampled image type descriptors in multiple stages
9089     dslb_vec.clear();
9090     dslb.binding = 0;
9091     dslb.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
9092     dslb.descriptorCount = max_sampled_images;
9093     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
9094     dslb_vec.push_back(dslb);
9095     dslb.binding = 1;
9096     dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
9097     dslb.stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS;
9098     dslb_vec.push_back(dslb);
9099     dslb.binding = 2;
9100     dslb.descriptorCount = max_combined;
9101     dslb.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
9102     dslb_vec.push_back(dslb);
9103 
9104     ds_layout_ci.bindingCount = dslb_vec.size();
9105     ds_layout_ci.pBindings = dslb_vec.data();
9106     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9107     ASSERT_VK_SUCCESS(err);
9108 
9109     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00290");
9110     if (max_combined + 2 * max_sampled_images > sum_sampled_images) {
9111         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9112                                              "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01682");  // expect all-stages sum too
9113     }
9114     if (max_combined > sum_samplers) {
9115         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9116                                              "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01677");  // expect all-stages sum too
9117     }
9118     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9119     m_errorMonitor->VerifyFound();
9120     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
9121     pipeline_layout = VK_NULL_HANDLE;
9122     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9123 
9124     // VU 0fe00246 - too many storage image type descriptors in fragment stage
9125     dslb_vec.clear();
9126     dslb.binding = 0;
9127     dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
9128     dslb.descriptorCount = 1 + (max_storage_images / 2);
9129     dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
9130     dslb_vec.push_back(dslb);
9131     dslb.binding = 1;
9132     dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
9133     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
9134     dslb_vec.push_back(dslb);
9135 
9136     ds_layout_ci.bindingCount = dslb_vec.size();
9137     ds_layout_ci.pBindings = dslb_vec.data();
9138     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9139     ASSERT_VK_SUCCESS(err);
9140 
9141     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00291");
9142     if (2 * dslb.descriptorCount > sum_storage_images) {
9143         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9144                                              "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01683");  // expect all-stages sum too
9145     }
9146     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9147     m_errorMonitor->VerifyFound();
9148     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
9149     pipeline_layout = VK_NULL_HANDLE;
9150     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9151 
9152     // VU 0fe00d18 - too many input attachments in fragment stage
9153     dslb_vec.clear();
9154     dslb.binding = 0;
9155     dslb.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
9156     dslb.descriptorCount = 1 + max_input_attachments;
9157     dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
9158     dslb_vec.push_back(dslb);
9159 
9160     ds_layout_ci.bindingCount = dslb_vec.size();
9161     ds_layout_ci.pBindings = dslb_vec.data();
9162     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9163     ASSERT_VK_SUCCESS(err);
9164 
9165     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01676");
9166     if (dslb.descriptorCount > sum_input_attachments) {
9167         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9168                                              "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01684");  // expect all-stages sum too
9169     }
9170     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9171     m_errorMonitor->VerifyFound();
9172     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
9173     pipeline_layout = VK_NULL_HANDLE;
9174     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9175 }
9176 
TEST_F(VkLayerTest,CreatePipelineLayoutExcessDescriptorsOverall)9177 TEST_F(VkLayerTest, CreatePipelineLayoutExcessDescriptorsOverall) {
9178     TEST_DESCRIPTION("Attempt to create a pipeline layout where total descriptors exceed limits");
9179 
9180     ASSERT_NO_FATAL_FAILURE(Init());
9181 
9182     uint32_t max_uniform_buffers = m_device->phy().properties().limits.maxPerStageDescriptorUniformBuffers;
9183     uint32_t max_storage_buffers = m_device->phy().properties().limits.maxPerStageDescriptorStorageBuffers;
9184     uint32_t max_sampled_images = m_device->phy().properties().limits.maxPerStageDescriptorSampledImages;
9185     uint32_t max_storage_images = m_device->phy().properties().limits.maxPerStageDescriptorStorageImages;
9186     uint32_t max_samplers = m_device->phy().properties().limits.maxPerStageDescriptorSamplers;
9187     uint32_t max_input_attachments = m_device->phy().properties().limits.maxPerStageDescriptorInputAttachments;
9188 
9189     uint32_t sum_dyn_uniform_buffers = m_device->phy().properties().limits.maxDescriptorSetUniformBuffersDynamic;
9190     uint32_t sum_uniform_buffers = m_device->phy().properties().limits.maxDescriptorSetUniformBuffers;
9191     uint32_t sum_dyn_storage_buffers = m_device->phy().properties().limits.maxDescriptorSetStorageBuffersDynamic;
9192     uint32_t sum_storage_buffers = m_device->phy().properties().limits.maxDescriptorSetStorageBuffers;
9193     uint32_t sum_sampled_images = m_device->phy().properties().limits.maxDescriptorSetSampledImages;
9194     uint32_t sum_storage_images = m_device->phy().properties().limits.maxDescriptorSetStorageImages;
9195     uint32_t sum_samplers = m_device->phy().properties().limits.maxDescriptorSetSamplers;
9196     uint32_t sum_input_attachments = m_device->phy().properties().limits.maxDescriptorSetInputAttachments;
9197 
9198     // Devices that report UINT32_MAX for any of these limits can't run this test
9199     if (UINT32_MAX == std::max({sum_dyn_uniform_buffers, sum_uniform_buffers, sum_dyn_storage_buffers, sum_storage_buffers,
9200                                 sum_sampled_images, sum_storage_images, sum_samplers, sum_input_attachments})) {
9201         printf("%s Physical device limits report as 2^32-1. Skipping test.\n", kSkipPrefix);
9202         return;
9203     }
9204 
9205     VkDescriptorSetLayoutBinding dslb = {};
9206     std::vector<VkDescriptorSetLayoutBinding> dslb_vec = {};
9207     VkDescriptorSetLayout ds_layout = VK_NULL_HANDLE;
9208     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
9209     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
9210     ds_layout_ci.pNext = NULL;
9211     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
9212     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
9213     pipeline_layout_ci.pNext = NULL;
9214     pipeline_layout_ci.setLayoutCount = 1;
9215     pipeline_layout_ci.pSetLayouts = &ds_layout;
9216     VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
9217 
9218     // VU 0fe00d1a - too many sampler type descriptors overall
9219     dslb_vec.clear();
9220     dslb.binding = 0;
9221     dslb.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
9222     dslb.descriptorCount = sum_samplers / 2;
9223     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
9224     dslb.pImmutableSamplers = NULL;
9225     dslb_vec.push_back(dslb);
9226     dslb.binding = 1;
9227     dslb.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
9228     dslb.descriptorCount = sum_samplers - dslb.descriptorCount + 1;
9229     dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
9230     dslb_vec.push_back(dslb);
9231 
9232     ds_layout_ci.bindingCount = dslb_vec.size();
9233     ds_layout_ci.pBindings = dslb_vec.data();
9234     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9235     ASSERT_VK_SUCCESS(err);
9236 
9237     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01677");
9238     if (dslb.descriptorCount > max_samplers) {
9239         m_errorMonitor->SetDesiredFailureMsg(
9240             VK_DEBUG_REPORT_ERROR_BIT_EXT,
9241             "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00287");  // Expect max-per-stage samplers exceeds limits
9242     }
9243     if (dslb.descriptorCount > sum_sampled_images) {
9244         m_errorMonitor->SetDesiredFailureMsg(
9245             VK_DEBUG_REPORT_ERROR_BIT_EXT,
9246             "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01682");  // Expect max overall sampled image count exceeds limits
9247     }
9248     if (dslb.descriptorCount > max_sampled_images) {
9249         m_errorMonitor->SetDesiredFailureMsg(
9250             VK_DEBUG_REPORT_ERROR_BIT_EXT,
9251             "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00290");  // Expect max per-stage sampled image count exceeds limits
9252     }
9253     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9254     m_errorMonitor->VerifyFound();
9255     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
9256     pipeline_layout = VK_NULL_HANDLE;
9257     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9258 
9259     // VU 0fe00d1c - too many uniform buffer type descriptors overall
9260     dslb_vec.clear();
9261     dslb.binding = 0;
9262     dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
9263     dslb.descriptorCount = sum_uniform_buffers + 1;
9264     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
9265     dslb.pImmutableSamplers = NULL;
9266     dslb_vec.push_back(dslb);
9267 
9268     ds_layout_ci.bindingCount = dslb_vec.size();
9269     ds_layout_ci.pBindings = dslb_vec.data();
9270     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9271     ASSERT_VK_SUCCESS(err);
9272 
9273     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01678");
9274     if (dslb.descriptorCount > max_uniform_buffers) {
9275         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9276                                              "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00288");  // expect max-per-stage too
9277     }
9278     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9279     m_errorMonitor->VerifyFound();
9280     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
9281     pipeline_layout = VK_NULL_HANDLE;
9282     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9283 
9284     // VU 0fe00d1e - too many dynamic uniform buffer type descriptors overall
9285     dslb_vec.clear();
9286     dslb.binding = 0;
9287     dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
9288     dslb.descriptorCount = sum_dyn_uniform_buffers + 1;
9289     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
9290     dslb.pImmutableSamplers = NULL;
9291     dslb_vec.push_back(dslb);
9292 
9293     ds_layout_ci.bindingCount = dslb_vec.size();
9294     ds_layout_ci.pBindings = dslb_vec.data();
9295     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9296     ASSERT_VK_SUCCESS(err);
9297 
9298     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01679");
9299     if (dslb.descriptorCount > max_uniform_buffers) {
9300         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9301                                              "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00288");  // expect max-per-stage too
9302     }
9303     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9304     m_errorMonitor->VerifyFound();
9305     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
9306     pipeline_layout = VK_NULL_HANDLE;
9307     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9308 
9309     // VU 0fe00d20 - too many storage buffer type descriptors overall
9310     dslb_vec.clear();
9311     dslb.binding = 0;
9312     dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
9313     dslb.descriptorCount = sum_storage_buffers + 1;
9314     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
9315     dslb.pImmutableSamplers = NULL;
9316     dslb_vec.push_back(dslb);
9317 
9318     ds_layout_ci.bindingCount = dslb_vec.size();
9319     ds_layout_ci.pBindings = dslb_vec.data();
9320     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9321     ASSERT_VK_SUCCESS(err);
9322 
9323     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01680");
9324     if (dslb.descriptorCount > max_storage_buffers) {
9325         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9326                                              "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00289");  // expect max-per-stage too
9327     }
9328     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9329     m_errorMonitor->VerifyFound();
9330     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
9331     pipeline_layout = VK_NULL_HANDLE;
9332     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9333 
9334     // VU 0fe00d22 - too many dynamic storage buffer type descriptors overall
9335     dslb_vec.clear();
9336     dslb.binding = 0;
9337     dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
9338     dslb.descriptorCount = sum_dyn_storage_buffers + 1;
9339     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
9340     dslb.pImmutableSamplers = NULL;
9341     dslb_vec.push_back(dslb);
9342 
9343     ds_layout_ci.bindingCount = dslb_vec.size();
9344     ds_layout_ci.pBindings = dslb_vec.data();
9345     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9346     ASSERT_VK_SUCCESS(err);
9347 
9348     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01681");
9349     if (dslb.descriptorCount > max_storage_buffers) {
9350         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9351                                              "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00289");  // expect max-per-stage too
9352     }
9353     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9354     m_errorMonitor->VerifyFound();
9355     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
9356     pipeline_layout = VK_NULL_HANDLE;
9357     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9358 
9359     // VU 0fe00d24 - too many sampled image type descriptors overall
9360     dslb_vec.clear();
9361     dslb.binding = 0;
9362     dslb.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
9363     dslb.descriptorCount = max_samplers;
9364     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
9365     dslb.pImmutableSamplers = NULL;
9366     dslb_vec.push_back(dslb);
9367     dslb.binding = 1;
9368     dslb.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
9369     // revisit: not robust to odd limits.
9370     uint32_t remaining = (max_samplers > sum_sampled_images ? 0 : (sum_sampled_images - max_samplers) / 2);
9371     dslb.descriptorCount = 1 + remaining;
9372     dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
9373     dslb_vec.push_back(dslb);
9374     dslb.binding = 2;
9375     dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
9376     dslb.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
9377     dslb_vec.push_back(dslb);
9378 
9379     ds_layout_ci.bindingCount = dslb_vec.size();
9380     ds_layout_ci.pBindings = dslb_vec.data();
9381     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9382     ASSERT_VK_SUCCESS(err);
9383 
9384     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01682");
9385     if (std::max(dslb_vec[0].descriptorCount, dslb_vec[1].descriptorCount) > max_sampled_images) {
9386         m_errorMonitor->SetDesiredFailureMsg(
9387             VK_DEBUG_REPORT_ERROR_BIT_EXT,
9388             "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00290");  // Expect max-per-stage sampled images to exceed limits
9389     }
9390     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9391     m_errorMonitor->VerifyFound();
9392     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
9393     pipeline_layout = VK_NULL_HANDLE;
9394     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9395 
9396     // VU 0fe00d26 - too many storage image type descriptors overall
9397     dslb_vec.clear();
9398     dslb.binding = 0;
9399     dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
9400     dslb.descriptorCount = sum_storage_images / 2;
9401     dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
9402     dslb.pImmutableSamplers = NULL;
9403     dslb_vec.push_back(dslb);
9404     dslb.binding = 1;
9405     dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
9406     dslb.descriptorCount = sum_storage_images - dslb.descriptorCount + 1;
9407     dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
9408     dslb_vec.push_back(dslb);
9409 
9410     ds_layout_ci.bindingCount = dslb_vec.size();
9411     ds_layout_ci.pBindings = dslb_vec.data();
9412     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9413     ASSERT_VK_SUCCESS(err);
9414 
9415     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01683");
9416     if (dslb.descriptorCount > max_storage_images) {
9417         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9418                                              "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00291");  // expect max-per-stage too
9419     }
9420     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9421     m_errorMonitor->VerifyFound();
9422     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
9423     pipeline_layout = VK_NULL_HANDLE;
9424     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9425 
9426     // VU 0fe00d28 - too many input attachment type descriptors overall
9427     dslb_vec.clear();
9428     dslb.binding = 0;
9429     dslb.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
9430     dslb.descriptorCount = sum_input_attachments + 1;
9431     dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
9432     dslb.pImmutableSamplers = NULL;
9433     dslb_vec.push_back(dslb);
9434 
9435     ds_layout_ci.bindingCount = dslb_vec.size();
9436     ds_layout_ci.pBindings = dslb_vec.data();
9437     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
9438     ASSERT_VK_SUCCESS(err);
9439 
9440     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01684");
9441     if (dslb.descriptorCount > max_input_attachments) {
9442         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9443                                              "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01676");  // expect max-per-stage too
9444     }
9445     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
9446     m_errorMonitor->VerifyFound();
9447     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);  // Unnecessary but harmless if test passed
9448     pipeline_layout = VK_NULL_HANDLE;
9449     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
9450 }
9451 
TEST_F(VkLayerTest,InvalidCmdBufferBufferDestroyed)9452 TEST_F(VkLayerTest, InvalidCmdBufferBufferDestroyed) {
9453     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid due to a buffer dependency being destroyed.");
9454     ASSERT_NO_FATAL_FAILURE(Init());
9455 
9456     VkBuffer buffer;
9457     VkDeviceMemory mem;
9458     VkMemoryRequirements mem_reqs;
9459 
9460     VkBufferCreateInfo buf_info = {};
9461     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
9462     buf_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
9463     buf_info.size = 256;
9464     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
9465     VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
9466     ASSERT_VK_SUCCESS(err);
9467 
9468     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
9469 
9470     VkMemoryAllocateInfo alloc_info = {};
9471     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
9472     alloc_info.allocationSize = mem_reqs.size;
9473     bool pass = false;
9474     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
9475     if (!pass) {
9476         printf("%s Failed to set memory type.\n", kSkipPrefix);
9477         vkDestroyBuffer(m_device->device(), buffer, NULL);
9478         return;
9479     }
9480     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
9481     ASSERT_VK_SUCCESS(err);
9482 
9483     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
9484     ASSERT_VK_SUCCESS(err);
9485 
9486     m_commandBuffer->begin();
9487     vkCmdFillBuffer(m_commandBuffer->handle(), buffer, 0, VK_WHOLE_SIZE, 0);
9488     m_commandBuffer->end();
9489 
9490     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Buffer ");
9491     // Destroy buffer dependency prior to submit to cause ERROR
9492     vkDestroyBuffer(m_device->device(), buffer, NULL);
9493 
9494     VkSubmitInfo submit_info = {};
9495     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
9496     submit_info.commandBufferCount = 1;
9497     submit_info.pCommandBuffers = &m_commandBuffer->handle();
9498     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
9499 
9500     m_errorMonitor->VerifyFound();
9501     vkQueueWaitIdle(m_device->m_queue);
9502     vkFreeMemory(m_device->handle(), mem, NULL);
9503 }
9504 
TEST_F(VkLayerTest,InvalidCmdBufferBufferViewDestroyed)9505 TEST_F(VkLayerTest, InvalidCmdBufferBufferViewDestroyed) {
9506     TEST_DESCRIPTION("Delete bufferView bound to cmd buffer, then attempt to submit cmd buffer.");
9507 
9508     ASSERT_NO_FATAL_FAILURE(Init());
9509     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9510 
9511     VkDescriptorPoolSize ds_type_count;
9512     ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
9513     ds_type_count.descriptorCount = 1;
9514 
9515     VkDescriptorPoolCreateInfo ds_pool_ci = {};
9516     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
9517     ds_pool_ci.maxSets = 1;
9518     ds_pool_ci.poolSizeCount = 1;
9519     ds_pool_ci.pPoolSizes = &ds_type_count;
9520 
9521     VkDescriptorPool ds_pool;
9522     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
9523     ASSERT_VK_SUCCESS(err);
9524 
9525     VkDescriptorSetLayoutBinding layout_binding;
9526     layout_binding.binding = 0;
9527     layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
9528     layout_binding.descriptorCount = 1;
9529     layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
9530     layout_binding.pImmutableSamplers = NULL;
9531 
9532     const VkDescriptorSetLayoutObj ds_layout(m_device, {layout_binding});
9533 
9534     VkDescriptorSetAllocateInfo alloc_info = {};
9535     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
9536     alloc_info.descriptorSetCount = 1;
9537     alloc_info.descriptorPool = ds_pool;
9538     alloc_info.pSetLayouts = &ds_layout.handle();
9539     VkDescriptorSet descriptor_set;
9540     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
9541     ASSERT_VK_SUCCESS(err);
9542 
9543     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout});
9544 
9545     VkBuffer buffer;
9546     uint32_t queue_family_index = 0;
9547     VkBufferCreateInfo buffer_create_info = {};
9548     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
9549     buffer_create_info.size = 1024;
9550     buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
9551     buffer_create_info.queueFamilyIndexCount = 1;
9552     buffer_create_info.pQueueFamilyIndices = &queue_family_index;
9553 
9554     err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
9555     ASSERT_VK_SUCCESS(err);
9556 
9557     VkMemoryRequirements memory_reqs;
9558     VkDeviceMemory buffer_memory;
9559 
9560     VkMemoryAllocateInfo memory_info = {};
9561     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
9562     memory_info.allocationSize = 0;
9563     memory_info.memoryTypeIndex = 0;
9564 
9565     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
9566     memory_info.allocationSize = memory_reqs.size;
9567     bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
9568     ASSERT_TRUE(pass);
9569 
9570     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
9571     ASSERT_VK_SUCCESS(err);
9572     err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
9573     ASSERT_VK_SUCCESS(err);
9574 
9575     VkBufferView view;
9576     VkBufferViewCreateInfo bvci = {};
9577     bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
9578     bvci.buffer = buffer;
9579     bvci.format = VK_FORMAT_R32_SFLOAT;
9580     bvci.range = VK_WHOLE_SIZE;
9581 
9582     err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view);
9583     ASSERT_VK_SUCCESS(err);
9584 
9585     VkWriteDescriptorSet descriptor_write = {};
9586     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
9587     descriptor_write.dstSet = descriptor_set;
9588     descriptor_write.dstBinding = 0;
9589     descriptor_write.descriptorCount = 1;
9590     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
9591     descriptor_write.pTexelBufferView = &view;
9592 
9593     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
9594 
9595     char const *vsSource =
9596         "#version 450\n"
9597         "\n"
9598         "void main(){\n"
9599         "   gl_Position = vec4(1);\n"
9600         "}\n";
9601     char const *fsSource =
9602         "#version 450\n"
9603         "\n"
9604         "layout(set=0, binding=0, r32f) uniform readonly imageBuffer s;\n"
9605         "layout(location=0) out vec4 x;\n"
9606         "void main(){\n"
9607         "   x = imageLoad(s, 0);\n"
9608         "}\n";
9609     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
9610     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
9611     VkPipelineObj pipe(m_device);
9612     pipe.AddShader(&vs);
9613     pipe.AddShader(&fs);
9614     pipe.AddDefaultColorAttachment();
9615     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
9616 
9617     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound BufferView ");
9618 
9619     m_commandBuffer->begin();
9620     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
9621 
9622     VkViewport viewport = {0, 0, 16, 16, 0, 1};
9623     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
9624     VkRect2D scissor = {{0, 0}, {16, 16}};
9625     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
9626     // Bind pipeline to cmd buffer - This causes crash on Mali
9627     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
9628     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
9629                             &descriptor_set, 0, nullptr);
9630     m_commandBuffer->Draw(1, 0, 0, 0);
9631     m_commandBuffer->EndRenderPass();
9632     m_commandBuffer->end();
9633 
9634     // Delete BufferView in order to invalidate cmd buffer
9635     vkDestroyBufferView(m_device->device(), view, NULL);
9636     // Now attempt submit of cmd buffer
9637     VkSubmitInfo submit_info = {};
9638     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
9639     submit_info.commandBufferCount = 1;
9640     submit_info.pCommandBuffers = &m_commandBuffer->handle();
9641     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
9642     m_errorMonitor->VerifyFound();
9643 
9644     // Clean-up
9645     vkDestroyBuffer(m_device->device(), buffer, NULL);
9646     vkFreeMemory(m_device->device(), buffer_memory, NULL);
9647     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
9648 }
9649 
TEST_F(VkLayerTest,InvalidCmdBufferImageDestroyed)9650 TEST_F(VkLayerTest, InvalidCmdBufferImageDestroyed) {
9651     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid due to an image dependency being destroyed.");
9652     ASSERT_NO_FATAL_FAILURE(Init());
9653 
9654     VkImage image;
9655     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
9656     VkImageCreateInfo image_create_info = {};
9657     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
9658     image_create_info.pNext = NULL;
9659     image_create_info.imageType = VK_IMAGE_TYPE_2D;
9660     image_create_info.format = tex_format;
9661     image_create_info.extent.width = 32;
9662     image_create_info.extent.height = 32;
9663     image_create_info.extent.depth = 1;
9664     image_create_info.mipLevels = 1;
9665     image_create_info.arrayLayers = 1;
9666     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
9667     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
9668     image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
9669     image_create_info.flags = 0;
9670     VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
9671     ASSERT_VK_SUCCESS(err);
9672     // Have to bind memory to image before recording cmd in cmd buffer using it
9673     VkMemoryRequirements mem_reqs;
9674     VkDeviceMemory image_mem;
9675     bool pass;
9676     VkMemoryAllocateInfo mem_alloc = {};
9677     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
9678     mem_alloc.pNext = NULL;
9679     mem_alloc.memoryTypeIndex = 0;
9680     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
9681     mem_alloc.allocationSize = mem_reqs.size;
9682     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
9683     ASSERT_TRUE(pass);
9684     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
9685     ASSERT_VK_SUCCESS(err);
9686     err = vkBindImageMemory(m_device->device(), image, image_mem, 0);
9687     ASSERT_VK_SUCCESS(err);
9688 
9689     m_commandBuffer->begin();
9690     VkClearColorValue ccv;
9691     ccv.float32[0] = 1.0f;
9692     ccv.float32[1] = 1.0f;
9693     ccv.float32[2] = 1.0f;
9694     ccv.float32[3] = 1.0f;
9695     VkImageSubresourceRange isr = {};
9696     isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
9697     isr.baseArrayLayer = 0;
9698     isr.baseMipLevel = 0;
9699     isr.layerCount = 1;
9700     isr.levelCount = 1;
9701     vkCmdClearColorImage(m_commandBuffer->handle(), image, VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &isr);
9702     m_commandBuffer->end();
9703 
9704     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Image ");
9705     // Destroy image dependency prior to submit to cause ERROR
9706     vkDestroyImage(m_device->device(), image, NULL);
9707 
9708     VkSubmitInfo submit_info = {};
9709     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
9710     submit_info.commandBufferCount = 1;
9711     submit_info.pCommandBuffers = &m_commandBuffer->handle();
9712     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
9713 
9714     m_errorMonitor->VerifyFound();
9715     vkFreeMemory(m_device->device(), image_mem, nullptr);
9716 }
9717 
TEST_F(VkLayerTest,InvalidCmdBufferFramebufferImageDestroyed)9718 TEST_F(VkLayerTest, InvalidCmdBufferFramebufferImageDestroyed) {
9719     TEST_DESCRIPTION(
9720         "Attempt to draw with a command buffer that is invalid due to a framebuffer image dependency being destroyed.");
9721     ASSERT_NO_FATAL_FAILURE(Init());
9722     VkFormatProperties format_properties;
9723     VkResult err = VK_SUCCESS;
9724     vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
9725     if (!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
9726         printf("%s Image format doesn't support required features.\n", kSkipPrefix);
9727         return;
9728     }
9729 
9730     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9731 
9732     VkImageCreateInfo image_ci = {};
9733     image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
9734     image_ci.pNext = NULL;
9735     image_ci.imageType = VK_IMAGE_TYPE_2D;
9736     image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
9737     image_ci.extent.width = 32;
9738     image_ci.extent.height = 32;
9739     image_ci.extent.depth = 1;
9740     image_ci.mipLevels = 1;
9741     image_ci.arrayLayers = 1;
9742     image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
9743     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
9744     image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
9745     image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
9746     image_ci.flags = 0;
9747     VkImage image;
9748     ASSERT_VK_SUCCESS(vkCreateImage(m_device->handle(), &image_ci, NULL, &image));
9749 
9750     VkMemoryRequirements memory_reqs;
9751     VkDeviceMemory image_memory;
9752     bool pass;
9753     VkMemoryAllocateInfo memory_info = {};
9754     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
9755     memory_info.pNext = NULL;
9756     memory_info.allocationSize = 0;
9757     memory_info.memoryTypeIndex = 0;
9758     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
9759     memory_info.allocationSize = memory_reqs.size;
9760     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
9761     ASSERT_TRUE(pass);
9762     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
9763     ASSERT_VK_SUCCESS(err);
9764     err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
9765     ASSERT_VK_SUCCESS(err);
9766 
9767     VkImageViewCreateInfo ivci = {
9768         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
9769         nullptr,
9770         0,
9771         image,
9772         VK_IMAGE_VIEW_TYPE_2D,
9773         VK_FORMAT_B8G8R8A8_UNORM,
9774         {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
9775         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
9776     };
9777     VkImageView view;
9778     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
9779     ASSERT_VK_SUCCESS(err);
9780 
9781     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 32, 32, 1};
9782     VkFramebuffer fb;
9783     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
9784     ASSERT_VK_SUCCESS(err);
9785 
9786     // Just use default renderpass with our framebuffer
9787     m_renderPassBeginInfo.framebuffer = fb;
9788     m_renderPassBeginInfo.renderArea.extent.width = 32;
9789     m_renderPassBeginInfo.renderArea.extent.height = 32;
9790     // Create Null cmd buffer for submit
9791     m_commandBuffer->begin();
9792     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
9793     m_commandBuffer->EndRenderPass();
9794     m_commandBuffer->end();
9795     // Destroy image attached to framebuffer to invalidate cmd buffer
9796     vkDestroyImage(m_device->device(), image, NULL);
9797     // Now attempt to submit cmd buffer and verify error
9798     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Image ");
9799     m_commandBuffer->QueueCommandBuffer(false);
9800     m_errorMonitor->VerifyFound();
9801 
9802     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
9803     vkDestroyImageView(m_device->device(), view, nullptr);
9804     vkFreeMemory(m_device->device(), image_memory, nullptr);
9805 }
9806 
TEST_F(VkLayerTest,FramebufferInUseDestroyedSignaled)9807 TEST_F(VkLayerTest, FramebufferInUseDestroyedSignaled) {
9808     TEST_DESCRIPTION("Delete in-use framebuffer.");
9809     ASSERT_NO_FATAL_FAILURE(Init());
9810     VkFormatProperties format_properties;
9811     VkResult err = VK_SUCCESS;
9812     vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
9813 
9814     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9815 
9816     VkImageObj image(m_device);
9817     image.Init(256, 256, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
9818     ASSERT_TRUE(image.initialized());
9819     VkImageView view = image.targetView(VK_FORMAT_B8G8R8A8_UNORM);
9820 
9821     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 256, 256, 1};
9822     VkFramebuffer fb;
9823     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
9824     ASSERT_VK_SUCCESS(err);
9825 
9826     // Just use default renderpass with our framebuffer
9827     m_renderPassBeginInfo.framebuffer = fb;
9828     // Create Null cmd buffer for submit
9829     m_commandBuffer->begin();
9830     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
9831     m_commandBuffer->EndRenderPass();
9832     m_commandBuffer->end();
9833     // Submit cmd buffer to put it in-flight
9834     VkSubmitInfo submit_info = {};
9835     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
9836     submit_info.commandBufferCount = 1;
9837     submit_info.pCommandBuffers = &m_commandBuffer->handle();
9838     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
9839     // Destroy framebuffer while in-flight
9840     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyFramebuffer-framebuffer-00892");
9841     vkDestroyFramebuffer(m_device->device(), fb, NULL);
9842     m_errorMonitor->VerifyFound();
9843     // Wait for queue to complete so we can safely destroy everything
9844     vkQueueWaitIdle(m_device->m_queue);
9845     m_errorMonitor->SetUnexpectedError("If framebuffer is not VK_NULL_HANDLE, framebuffer must be a valid VkFramebuffer handle");
9846     m_errorMonitor->SetUnexpectedError("Unable to remove Framebuffer obj");
9847     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
9848 }
9849 
TEST_F(VkLayerTest,FramebufferImageInUseDestroyedSignaled)9850 TEST_F(VkLayerTest, FramebufferImageInUseDestroyedSignaled) {
9851     TEST_DESCRIPTION("Delete in-use image that's child of framebuffer.");
9852     ASSERT_NO_FATAL_FAILURE(Init());
9853     VkFormatProperties format_properties;
9854     VkResult err = VK_SUCCESS;
9855     vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
9856 
9857     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
9858 
9859     VkImageCreateInfo image_ci = {};
9860     image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
9861     image_ci.pNext = NULL;
9862     image_ci.imageType = VK_IMAGE_TYPE_2D;
9863     image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
9864     image_ci.extent.width = 256;
9865     image_ci.extent.height = 256;
9866     image_ci.extent.depth = 1;
9867     image_ci.mipLevels = 1;
9868     image_ci.arrayLayers = 1;
9869     image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
9870     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
9871     image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
9872     image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
9873     image_ci.flags = 0;
9874     VkImage image;
9875     ASSERT_VK_SUCCESS(vkCreateImage(m_device->handle(), &image_ci, NULL, &image));
9876 
9877     VkMemoryRequirements memory_reqs;
9878     VkDeviceMemory image_memory;
9879     bool pass;
9880     VkMemoryAllocateInfo memory_info = {};
9881     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
9882     memory_info.pNext = NULL;
9883     memory_info.allocationSize = 0;
9884     memory_info.memoryTypeIndex = 0;
9885     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
9886     memory_info.allocationSize = memory_reqs.size;
9887     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
9888     ASSERT_TRUE(pass);
9889     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
9890     ASSERT_VK_SUCCESS(err);
9891     err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
9892     ASSERT_VK_SUCCESS(err);
9893 
9894     VkImageViewCreateInfo ivci = {
9895         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
9896         nullptr,
9897         0,
9898         image,
9899         VK_IMAGE_VIEW_TYPE_2D,
9900         VK_FORMAT_B8G8R8A8_UNORM,
9901         {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
9902         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
9903     };
9904     VkImageView view;
9905     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
9906     ASSERT_VK_SUCCESS(err);
9907 
9908     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 256, 256, 1};
9909     VkFramebuffer fb;
9910     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
9911     ASSERT_VK_SUCCESS(err);
9912 
9913     // Just use default renderpass with our framebuffer
9914     m_renderPassBeginInfo.framebuffer = fb;
9915     // Create Null cmd buffer for submit
9916     m_commandBuffer->begin();
9917     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
9918     m_commandBuffer->EndRenderPass();
9919     m_commandBuffer->end();
9920     // Submit cmd buffer to put it (and attached imageView) in-flight
9921     VkSubmitInfo submit_info = {};
9922     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
9923     submit_info.commandBufferCount = 1;
9924     submit_info.pCommandBuffers = &m_commandBuffer->handle();
9925     // Submit cmd buffer to put framebuffer and children in-flight
9926     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
9927     // Destroy image attached to framebuffer while in-flight
9928     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyImage-image-01000");
9929     vkDestroyImage(m_device->device(), image, NULL);
9930     m_errorMonitor->VerifyFound();
9931     // Wait for queue to complete so we can safely destroy image and other objects
9932     vkQueueWaitIdle(m_device->m_queue);
9933     m_errorMonitor->SetUnexpectedError("If image is not VK_NULL_HANDLE, image must be a valid VkImage handle");
9934     m_errorMonitor->SetUnexpectedError("Unable to remove Image obj");
9935     vkDestroyImage(m_device->device(), image, NULL);
9936     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
9937     vkDestroyImageView(m_device->device(), view, nullptr);
9938     vkFreeMemory(m_device->device(), image_memory, nullptr);
9939 }
9940 
TEST_F(VkLayerTest,ImageMemoryNotBound)9941 TEST_F(VkLayerTest, ImageMemoryNotBound) {
9942     TEST_DESCRIPTION("Attempt to draw with an image which has not had memory bound to it.");
9943     ASSERT_NO_FATAL_FAILURE(Init());
9944 
9945     VkImage image;
9946     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
9947     VkImageCreateInfo image_create_info = {};
9948     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
9949     image_create_info.pNext = NULL;
9950     image_create_info.imageType = VK_IMAGE_TYPE_2D;
9951     image_create_info.format = tex_format;
9952     image_create_info.extent.width = 32;
9953     image_create_info.extent.height = 32;
9954     image_create_info.extent.depth = 1;
9955     image_create_info.mipLevels = 1;
9956     image_create_info.arrayLayers = 1;
9957     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
9958     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
9959     image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
9960     image_create_info.flags = 0;
9961     VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
9962     ASSERT_VK_SUCCESS(err);
9963     // Have to bind memory to image before recording cmd in cmd buffer using it
9964     VkMemoryRequirements mem_reqs;
9965     VkDeviceMemory image_mem;
9966     bool pass;
9967     VkMemoryAllocateInfo mem_alloc = {};
9968     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
9969     mem_alloc.pNext = NULL;
9970     mem_alloc.memoryTypeIndex = 0;
9971     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
9972     mem_alloc.allocationSize = mem_reqs.size;
9973     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
9974     ASSERT_TRUE(pass);
9975     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
9976     ASSERT_VK_SUCCESS(err);
9977 
9978     // Introduce error, do not call vkBindImageMemory(m_device->device(), image, image_mem, 0);
9979     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
9980                                          " used with no memory bound. Memory should be bound by calling vkBindImageMemory().");
9981 
9982     m_commandBuffer->begin();
9983     VkClearColorValue ccv;
9984     ccv.float32[0] = 1.0f;
9985     ccv.float32[1] = 1.0f;
9986     ccv.float32[2] = 1.0f;
9987     ccv.float32[3] = 1.0f;
9988     VkImageSubresourceRange isr = {};
9989     isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
9990     isr.baseArrayLayer = 0;
9991     isr.baseMipLevel = 0;
9992     isr.layerCount = 1;
9993     isr.levelCount = 1;
9994     vkCmdClearColorImage(m_commandBuffer->handle(), image, VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &isr);
9995     m_commandBuffer->end();
9996 
9997     m_errorMonitor->VerifyFound();
9998     vkDestroyImage(m_device->device(), image, NULL);
9999     vkFreeMemory(m_device->device(), image_mem, nullptr);
10000 }
10001 
TEST_F(VkLayerTest,BufferMemoryNotBound)10002 TEST_F(VkLayerTest, BufferMemoryNotBound) {
10003     TEST_DESCRIPTION("Attempt to copy from a buffer which has not had memory bound to it.");
10004     ASSERT_NO_FATAL_FAILURE(Init());
10005 
10006     VkImageObj image(m_device);
10007     image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
10008                VK_IMAGE_TILING_OPTIMAL, 0);
10009     ASSERT_TRUE(image.initialized());
10010 
10011     VkBuffer buffer;
10012     VkDeviceMemory mem;
10013     VkMemoryRequirements mem_reqs;
10014 
10015     VkBufferCreateInfo buf_info = {};
10016     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
10017     buf_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
10018     buf_info.size = 1024;
10019     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
10020     VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
10021     ASSERT_VK_SUCCESS(err);
10022 
10023     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
10024 
10025     VkMemoryAllocateInfo alloc_info = {};
10026     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
10027     alloc_info.allocationSize = 1024;
10028     bool pass = false;
10029     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
10030     if (!pass) {
10031         printf("%s Failed to set memory type.\n", kSkipPrefix);
10032         vkDestroyBuffer(m_device->device(), buffer, NULL);
10033         return;
10034     }
10035     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
10036     ASSERT_VK_SUCCESS(err);
10037 
10038     // Introduce failure by not calling vkBindBufferMemory(m_device->device(), buffer, mem, 0);
10039     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10040                                          " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
10041     VkBufferImageCopy region = {};
10042     region.bufferRowLength = 16;
10043     region.bufferImageHeight = 16;
10044     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10045 
10046     region.imageSubresource.layerCount = 1;
10047     region.imageExtent.height = 4;
10048     region.imageExtent.width = 4;
10049     region.imageExtent.depth = 1;
10050     m_commandBuffer->begin();
10051     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer, image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
10052     m_commandBuffer->end();
10053 
10054     m_errorMonitor->VerifyFound();
10055 
10056     vkDestroyBuffer(m_device->device(), buffer, NULL);
10057     vkFreeMemory(m_device->handle(), mem, NULL);
10058 }
10059 
TEST_F(VkLayerTest,InvalidCmdBufferEventDestroyed)10060 TEST_F(VkLayerTest, InvalidCmdBufferEventDestroyed) {
10061     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid due to an event dependency being destroyed.");
10062     ASSERT_NO_FATAL_FAILURE(Init());
10063 
10064     VkEvent event;
10065     VkEventCreateInfo evci = {};
10066     evci.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
10067     VkResult result = vkCreateEvent(m_device->device(), &evci, NULL, &event);
10068     ASSERT_VK_SUCCESS(result);
10069 
10070     m_commandBuffer->begin();
10071     vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
10072     m_commandBuffer->end();
10073 
10074     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Event ");
10075     // Destroy event dependency prior to submit to cause ERROR
10076     vkDestroyEvent(m_device->device(), event, NULL);
10077 
10078     VkSubmitInfo submit_info = {};
10079     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
10080     submit_info.commandBufferCount = 1;
10081     submit_info.pCommandBuffers = &m_commandBuffer->handle();
10082     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
10083 
10084     m_errorMonitor->VerifyFound();
10085 }
10086 
TEST_F(VkLayerTest,InvalidCmdBufferQueryPoolDestroyed)10087 TEST_F(VkLayerTest, InvalidCmdBufferQueryPoolDestroyed) {
10088     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid due to a query pool dependency being destroyed.");
10089     ASSERT_NO_FATAL_FAILURE(Init());
10090 
10091     VkQueryPool query_pool;
10092     VkQueryPoolCreateInfo qpci{};
10093     qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
10094     qpci.queryType = VK_QUERY_TYPE_TIMESTAMP;
10095     qpci.queryCount = 1;
10096     VkResult result = vkCreateQueryPool(m_device->device(), &qpci, nullptr, &query_pool);
10097     ASSERT_VK_SUCCESS(result);
10098 
10099     m_commandBuffer->begin();
10100     vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
10101     m_commandBuffer->end();
10102 
10103     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound QueryPool ");
10104     // Destroy query pool dependency prior to submit to cause ERROR
10105     vkDestroyQueryPool(m_device->device(), query_pool, NULL);
10106 
10107     VkSubmitInfo submit_info = {};
10108     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
10109     submit_info.commandBufferCount = 1;
10110     submit_info.pCommandBuffers = &m_commandBuffer->handle();
10111     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
10112 
10113     m_errorMonitor->VerifyFound();
10114 }
10115 
TEST_F(VkLayerTest,InvalidCmdBufferPipelineDestroyed)10116 TEST_F(VkLayerTest, InvalidCmdBufferPipelineDestroyed) {
10117     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid due to a pipeline dependency being destroyed.");
10118     ASSERT_NO_FATAL_FAILURE(Init());
10119     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10120 
10121     {
10122         // Use helper to create graphics pipeline
10123         CreatePipelineHelper helper(*this);
10124         helper.InitInfo();
10125         helper.InitState();
10126         helper.CreateGraphicsPipeline();
10127 
10128         // Bind helper pipeline to command buffer
10129         m_commandBuffer->begin();
10130         vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, helper.pipeline_);
10131         m_commandBuffer->end();
10132 
10133         // pipeline will be destroyed when helper goes out of scope
10134     }
10135 
10136     // Cause error by submitting command buffer that references destroyed pipeline
10137     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Pipeline ");
10138     m_commandBuffer->QueueCommandBuffer(false);
10139     m_errorMonitor->VerifyFound();
10140 }
10141 
TEST_F(VkPositiveLayerTest,DestroyPipelineRenderPass)10142 TEST_F(VkPositiveLayerTest, DestroyPipelineRenderPass) {
10143     TEST_DESCRIPTION("Draw using a pipeline whose create renderPass has been destroyed.");
10144     m_errorMonitor->ExpectSuccess();
10145     ASSERT_NO_FATAL_FAILURE(Init());
10146     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10147 
10148     VkResult err;
10149 
10150     // Create a renderPass that's compatible with Draw-time renderPass
10151     VkAttachmentDescription att = {};
10152     att.format = m_render_target_fmt;
10153     att.samples = VK_SAMPLE_COUNT_1_BIT;
10154     att.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
10155     att.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
10156     att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
10157     att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
10158     att.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
10159     att.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10160 
10161     VkAttachmentReference ref = {};
10162     ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
10163     ref.attachment = 0;
10164 
10165     m_renderPassClearValues.clear();
10166     VkClearValue clear = {};
10167     clear.color = m_clear_color;
10168 
10169     VkSubpassDescription subpass = {};
10170     subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
10171     subpass.flags = 0;
10172     subpass.inputAttachmentCount = 0;
10173     subpass.pInputAttachments = NULL;
10174     subpass.colorAttachmentCount = 1;
10175     subpass.pColorAttachments = &ref;
10176     subpass.pResolveAttachments = NULL;
10177 
10178     subpass.pDepthStencilAttachment = NULL;
10179     subpass.preserveAttachmentCount = 0;
10180     subpass.pPreserveAttachments = NULL;
10181 
10182     VkRenderPassCreateInfo rp_info = {};
10183     rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
10184     rp_info.attachmentCount = 1;
10185     rp_info.pAttachments = &att;
10186     rp_info.subpassCount = 1;
10187     rp_info.pSubpasses = &subpass;
10188 
10189     VkRenderPass rp;
10190     err = vkCreateRenderPass(device(), &rp_info, NULL, &rp);
10191     ASSERT_VK_SUCCESS(err);
10192 
10193     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
10194     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
10195 
10196     VkPipelineObj pipe(m_device);
10197     pipe.AddDefaultColorAttachment();
10198     pipe.AddShader(&vs);
10199     pipe.AddShader(&fs);
10200     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
10201     m_viewports.push_back(viewport);
10202     pipe.SetViewport(m_viewports);
10203     VkRect2D rect = {{0, 0}, {64, 64}};
10204     m_scissors.push_back(rect);
10205     pipe.SetScissor(m_scissors);
10206 
10207     const VkPipelineLayoutObj pl(m_device);
10208     pipe.CreateVKPipeline(pl.handle(), rp);
10209 
10210     m_commandBuffer->begin();
10211     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
10212     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
10213     // Destroy renderPass before pipeline is used in Draw
10214     //  We delay until after CmdBindPipeline to verify that invalid binding isn't
10215     //  created between CB & renderPass, which we used to do.
10216     vkDestroyRenderPass(m_device->device(), rp, nullptr);
10217     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
10218     vkCmdEndRenderPass(m_commandBuffer->handle());
10219     m_commandBuffer->end();
10220 
10221     VkSubmitInfo submit_info = {};
10222     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
10223     submit_info.commandBufferCount = 1;
10224     submit_info.pCommandBuffers = &m_commandBuffer->handle();
10225     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
10226     m_errorMonitor->VerifyNotFound();
10227     vkQueueWaitIdle(m_device->m_queue);
10228 }
10229 
TEST_F(VkLayerTest,InvalidCmdBufferDescriptorSetBufferDestroyed)10230 TEST_F(VkLayerTest, InvalidCmdBufferDescriptorSetBufferDestroyed) {
10231     TEST_DESCRIPTION(
10232         "Attempt to draw with a command buffer that is invalid due to a bound descriptor set with a buffer dependency being "
10233         "destroyed.");
10234     ASSERT_NO_FATAL_FAILURE(Init());
10235     ASSERT_NO_FATAL_FAILURE(InitViewport());
10236     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10237 
10238     VkDescriptorPoolSize ds_type_count = {};
10239     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
10240     ds_type_count.descriptorCount = 1;
10241 
10242     VkDescriptorPoolCreateInfo ds_pool_ci = {};
10243     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
10244     ds_pool_ci.pNext = NULL;
10245     ds_pool_ci.maxSets = 1;
10246     ds_pool_ci.poolSizeCount = 1;
10247     ds_pool_ci.pPoolSizes = &ds_type_count;
10248 
10249     VkDescriptorPool ds_pool;
10250     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
10251     ASSERT_VK_SUCCESS(err);
10252 
10253     VkDescriptorSetLayoutBinding dsl_binding = {};
10254     dsl_binding.binding = 0;
10255     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
10256     dsl_binding.descriptorCount = 1;
10257     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
10258     dsl_binding.pImmutableSamplers = NULL;
10259 
10260     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
10261 
10262     VkDescriptorSet descriptorSet;
10263     VkDescriptorSetAllocateInfo alloc_info = {};
10264     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
10265     alloc_info.descriptorSetCount = 1;
10266     alloc_info.descriptorPool = ds_pool;
10267     alloc_info.pSetLayouts = &ds_layout.handle();
10268     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
10269     ASSERT_VK_SUCCESS(err);
10270 
10271     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout});
10272 
10273     // Create a buffer to update the descriptor with
10274     uint32_t qfi = 0;
10275     VkBufferCreateInfo buffCI = {};
10276     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
10277     buffCI.size = 1024;
10278     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
10279     buffCI.queueFamilyIndexCount = 1;
10280     buffCI.pQueueFamilyIndices = &qfi;
10281 
10282     VkBuffer buffer;
10283     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &buffer);
10284     ASSERT_VK_SUCCESS(err);
10285     // Allocate memory and bind to buffer so we can make it to the appropriate
10286     // error
10287     VkMemoryRequirements memReqs;
10288     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
10289     VkMemoryAllocateInfo mem_alloc = {};
10290     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
10291     mem_alloc.pNext = NULL;
10292     mem_alloc.allocationSize = memReqs.size;
10293     mem_alloc.memoryTypeIndex = 0;
10294     bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
10295     if (!pass) {
10296         printf("%s Failed to set memory type.\n", kSkipPrefix);
10297         vkDestroyBuffer(m_device->device(), buffer, NULL);
10298         return;
10299     }
10300 
10301     VkDeviceMemory mem;
10302     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
10303     ASSERT_VK_SUCCESS(err);
10304     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
10305     ASSERT_VK_SUCCESS(err);
10306     // Correctly update descriptor to avoid "NOT_UPDATED" error
10307     VkDescriptorBufferInfo buffInfo = {};
10308     buffInfo.buffer = buffer;
10309     buffInfo.offset = 0;
10310     buffInfo.range = 1024;
10311 
10312     VkWriteDescriptorSet descriptor_write;
10313     memset(&descriptor_write, 0, sizeof(descriptor_write));
10314     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
10315     descriptor_write.dstSet = descriptorSet;
10316     descriptor_write.dstBinding = 0;
10317     descriptor_write.descriptorCount = 1;
10318     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
10319     descriptor_write.pBufferInfo = &buffInfo;
10320 
10321     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
10322 
10323     // Create PSO to be used for draw-time errors below
10324     char const *vsSource =
10325         "#version 450\n"
10326         "\n"
10327         "void main(){\n"
10328         "   gl_Position = vec4(1);\n"
10329         "}\n";
10330     char const *fsSource =
10331         "#version 450\n"
10332         "\n"
10333         "layout(location=0) out vec4 x;\n"
10334         "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
10335         "void main(){\n"
10336         "   x = vec4(bar.y);\n"
10337         "}\n";
10338     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
10339     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
10340     VkPipelineObj pipe(m_device);
10341     pipe.AddShader(&vs);
10342     pipe.AddShader(&fs);
10343     pipe.AddDefaultColorAttachment();
10344     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
10345 
10346     m_commandBuffer->begin();
10347     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
10348     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
10349     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
10350                             &descriptorSet, 0, NULL);
10351 
10352     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &m_viewports[0]);
10353     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &m_scissors[0]);
10354 
10355     m_commandBuffer->Draw(1, 0, 0, 0);
10356     m_commandBuffer->EndRenderPass();
10357     m_commandBuffer->end();
10358     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Buffer ");
10359     // Destroy buffer should invalidate the cmd buffer, causing error on submit
10360     vkDestroyBuffer(m_device->device(), buffer, NULL);
10361     // Attempt to submit cmd buffer
10362     VkSubmitInfo submit_info = {};
10363     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
10364     submit_info.commandBufferCount = 1;
10365     submit_info.pCommandBuffers = &m_commandBuffer->handle();
10366     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
10367     m_errorMonitor->VerifyFound();
10368     // Cleanup
10369     vkFreeMemory(m_device->device(), mem, NULL);
10370 
10371     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
10372 }
10373 
TEST_F(VkLayerTest,InvalidCmdBufferDescriptorSetImageSamplerDestroyed)10374 TEST_F(VkLayerTest, InvalidCmdBufferDescriptorSetImageSamplerDestroyed) {
10375     TEST_DESCRIPTION(
10376         "Attempt to draw with a command buffer that is invalid due to a bound descriptor sets with a combined image sampler having "
10377         "their image, sampler, and descriptor set each respectively destroyed and then attempting to submit associated cmd "
10378         "buffers. Attempt to destroy a DescriptorSet that is in use.");
10379     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
10380     ASSERT_NO_FATAL_FAILURE(InitViewport());
10381     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10382 
10383     VkDescriptorPoolSize ds_type_count = {};
10384     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
10385     ds_type_count.descriptorCount = 1;
10386 
10387     VkDescriptorPoolCreateInfo ds_pool_ci = {};
10388     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
10389     ds_pool_ci.pNext = NULL;
10390     ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
10391     ds_pool_ci.maxSets = 1;
10392     ds_pool_ci.poolSizeCount = 1;
10393     ds_pool_ci.pPoolSizes = &ds_type_count;
10394 
10395     VkDescriptorPool ds_pool;
10396     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
10397     ASSERT_VK_SUCCESS(err);
10398 
10399     VkDescriptorSetLayoutBinding dsl_binding = {};
10400     dsl_binding.binding = 0;
10401     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
10402     dsl_binding.descriptorCount = 1;
10403     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
10404     dsl_binding.pImmutableSamplers = NULL;
10405 
10406     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
10407 
10408     VkDescriptorSet descriptorSet;
10409     VkDescriptorSetAllocateInfo alloc_info = {};
10410     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
10411     alloc_info.descriptorSetCount = 1;
10412     alloc_info.descriptorPool = ds_pool;
10413     alloc_info.pSetLayouts = &ds_layout.handle();
10414     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
10415     ASSERT_VK_SUCCESS(err);
10416 
10417     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout});
10418 
10419     // Create images to update the descriptor with
10420     VkImage image;
10421     VkImage image2;
10422     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
10423     const int32_t tex_width = 32;
10424     const int32_t tex_height = 32;
10425     VkImageCreateInfo image_create_info = {};
10426     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
10427     image_create_info.pNext = NULL;
10428     image_create_info.imageType = VK_IMAGE_TYPE_2D;
10429     image_create_info.format = tex_format;
10430     image_create_info.extent.width = tex_width;
10431     image_create_info.extent.height = tex_height;
10432     image_create_info.extent.depth = 1;
10433     image_create_info.mipLevels = 1;
10434     image_create_info.arrayLayers = 1;
10435     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
10436     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
10437     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
10438     image_create_info.flags = 0;
10439     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
10440     ASSERT_VK_SUCCESS(err);
10441     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image2);
10442     ASSERT_VK_SUCCESS(err);
10443 
10444     VkMemoryRequirements memory_reqs;
10445     VkDeviceMemory image_memory;
10446     bool pass;
10447     VkMemoryAllocateInfo memory_info = {};
10448     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
10449     memory_info.pNext = NULL;
10450     memory_info.allocationSize = 0;
10451     memory_info.memoryTypeIndex = 0;
10452     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
10453     // Allocate enough memory for both images
10454     VkDeviceSize align_mod = memory_reqs.size % memory_reqs.alignment;
10455     VkDeviceSize aligned_size = ((align_mod == 0) ? memory_reqs.size : (memory_reqs.size + memory_reqs.alignment - align_mod));
10456     memory_info.allocationSize = aligned_size * 2;
10457     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
10458     ASSERT_TRUE(pass);
10459     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
10460     ASSERT_VK_SUCCESS(err);
10461     err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
10462     ASSERT_VK_SUCCESS(err);
10463     // Bind second image to memory right after first image
10464     err = vkBindImageMemory(m_device->device(), image2, image_memory, aligned_size);
10465     ASSERT_VK_SUCCESS(err);
10466 
10467     VkImageViewCreateInfo image_view_create_info = {};
10468     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
10469     image_view_create_info.image = image;
10470     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
10471     image_view_create_info.format = tex_format;
10472     image_view_create_info.subresourceRange.layerCount = 1;
10473     image_view_create_info.subresourceRange.baseMipLevel = 0;
10474     image_view_create_info.subresourceRange.levelCount = 1;
10475     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10476 
10477     VkImageView tmp_view;  // First test deletes this view
10478     VkImageView view;
10479     VkImageView view2;
10480     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &tmp_view);
10481     ASSERT_VK_SUCCESS(err);
10482     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
10483     ASSERT_VK_SUCCESS(err);
10484     image_view_create_info.image = image2;
10485     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view2);
10486     ASSERT_VK_SUCCESS(err);
10487     // Create Samplers
10488     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
10489     VkSampler sampler;
10490     VkSampler sampler2;
10491     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
10492     ASSERT_VK_SUCCESS(err);
10493     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler2);
10494     ASSERT_VK_SUCCESS(err);
10495     // Update descriptor with image and sampler
10496     VkDescriptorImageInfo img_info = {};
10497     img_info.sampler = sampler;
10498     img_info.imageView = tmp_view;
10499     img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
10500 
10501     VkWriteDescriptorSet descriptor_write;
10502     memset(&descriptor_write, 0, sizeof(descriptor_write));
10503     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
10504     descriptor_write.dstSet = descriptorSet;
10505     descriptor_write.dstBinding = 0;
10506     descriptor_write.descriptorCount = 1;
10507     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
10508     descriptor_write.pImageInfo = &img_info;
10509 
10510     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
10511 
10512     // Create PSO to be used for draw-time errors below
10513     char const *vsSource =
10514         "#version 450\n"
10515         "\n"
10516         "void main(){\n"
10517         "   gl_Position = vec4(1);\n"
10518         "}\n";
10519     char const *fsSource =
10520         "#version 450\n"
10521         "\n"
10522         "layout(set=0, binding=0) uniform sampler2D s;\n"
10523         "layout(location=0) out vec4 x;\n"
10524         "void main(){\n"
10525         "   x = texture(s, vec2(1));\n"
10526         "}\n";
10527     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
10528     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
10529     VkPipelineObj pipe(m_device);
10530     pipe.AddShader(&vs);
10531     pipe.AddShader(&fs);
10532     pipe.AddDefaultColorAttachment();
10533     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
10534 
10535     // First error case is destroying sampler prior to cmd buffer submission
10536     m_commandBuffer->begin();
10537 
10538     // Transit image layout from VK_IMAGE_LAYOUT_UNDEFINED into VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
10539     VkImageMemoryBarrier barrier = {};
10540     barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
10541     barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
10542     barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
10543     barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10544     barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
10545     barrier.image = image;
10546     barrier.srcAccessMask = 0;
10547     barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
10548     barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10549     barrier.subresourceRange.baseMipLevel = 0;
10550     barrier.subresourceRange.levelCount = 1;
10551     barrier.subresourceRange.baseArrayLayer = 0;
10552     barrier.subresourceRange.layerCount = 1;
10553     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
10554                          nullptr, 0, nullptr, 1, &barrier);
10555 
10556     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
10557     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
10558     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
10559                             &descriptorSet, 0, NULL);
10560     VkViewport viewport = {0, 0, 16, 16, 0, 1};
10561     VkRect2D scissor = {{0, 0}, {16, 16}};
10562     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
10563     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
10564     m_commandBuffer->Draw(1, 0, 0, 0);
10565     m_commandBuffer->EndRenderPass();
10566     m_commandBuffer->end();
10567     VkSubmitInfo submit_info = {};
10568     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
10569     submit_info.commandBufferCount = 1;
10570     submit_info.pCommandBuffers = &m_commandBuffer->handle();
10571     // This first submit should be successful
10572     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
10573     vkQueueWaitIdle(m_device->m_queue);
10574 
10575     // Now destroy imageview and reset cmdBuffer
10576     vkDestroyImageView(m_device->device(), tmp_view, NULL);
10577     m_commandBuffer->reset(0);
10578     m_commandBuffer->begin();
10579     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
10580     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
10581     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
10582                             &descriptorSet, 0, NULL);
10583     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
10584     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
10585     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that has been destroyed.");
10586     m_commandBuffer->Draw(1, 0, 0, 0);
10587     m_errorMonitor->VerifyFound();
10588     m_commandBuffer->EndRenderPass();
10589     m_commandBuffer->end();
10590 
10591     // Re-update descriptor with new view
10592     img_info.imageView = view;
10593     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
10594     // Now test destroying sampler prior to cmd buffer submission
10595     m_commandBuffer->begin();
10596     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
10597     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
10598     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
10599                             &descriptorSet, 0, NULL);
10600     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
10601     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
10602     m_commandBuffer->Draw(1, 0, 0, 0);
10603     m_commandBuffer->EndRenderPass();
10604     m_commandBuffer->end();
10605     // Destroy sampler invalidates the cmd buffer, causing error on submit
10606     vkDestroySampler(m_device->device(), sampler, NULL);
10607     // Attempt to submit cmd buffer
10608     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is invalid because bound Sampler");
10609     submit_info = {};
10610     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
10611     submit_info.commandBufferCount = 1;
10612     submit_info.pCommandBuffers = &m_commandBuffer->handle();
10613     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
10614     m_errorMonitor->VerifyFound();
10615 
10616     // Now re-update descriptor with valid sampler and delete image
10617     img_info.sampler = sampler2;
10618     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
10619 
10620     VkCommandBufferBeginInfo info = {};
10621     info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
10622     info.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
10623 
10624     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Image ");
10625     m_commandBuffer->begin(&info);
10626     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
10627     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
10628     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
10629                             &descriptorSet, 0, NULL);
10630     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
10631     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
10632     m_commandBuffer->Draw(1, 0, 0, 0);
10633     m_commandBuffer->EndRenderPass();
10634     m_commandBuffer->end();
10635     // Destroy image invalidates the cmd buffer, causing error on submit
10636     vkDestroyImage(m_device->device(), image, NULL);
10637     // Attempt to submit cmd buffer
10638     submit_info = {};
10639     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
10640     submit_info.commandBufferCount = 1;
10641     submit_info.pCommandBuffers = &m_commandBuffer->handle();
10642     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
10643     m_errorMonitor->VerifyFound();
10644     // Now update descriptor to be valid, but then free descriptor
10645     img_info.imageView = view2;
10646     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
10647     m_commandBuffer->begin(&info);
10648 
10649     // Transit image2 layout from VK_IMAGE_LAYOUT_UNDEFINED into VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
10650     barrier.image = image2;
10651     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
10652                          nullptr, 0, nullptr, 1, &barrier);
10653 
10654     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
10655     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
10656     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
10657                             &descriptorSet, 0, NULL);
10658     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
10659     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
10660     m_commandBuffer->Draw(1, 0, 0, 0);
10661     m_commandBuffer->EndRenderPass();
10662     m_commandBuffer->end();
10663     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
10664 
10665     // Immediately try to destroy the descriptor set in the active command buffer - failure expected
10666     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot call vkFreeDescriptorSets() on descriptor set 0x");
10667     vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptorSet);
10668     m_errorMonitor->VerifyFound();
10669 
10670     // Try again once the queue is idle - should succeed w/o error
10671     // TODO - though the particular error above doesn't re-occur, there are other 'unexpecteds' still to clean up
10672     vkQueueWaitIdle(m_device->m_queue);
10673     m_errorMonitor->SetUnexpectedError(
10674         "pDescriptorSets must be a valid pointer to an array of descriptorSetCount VkDescriptorSet handles, each element of which "
10675         "must either be a valid handle or VK_NULL_HANDLE");
10676     m_errorMonitor->SetUnexpectedError("Unable to remove DescriptorSet obj");
10677     vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptorSet);
10678 
10679     // Attempt to submit cmd buffer containing the freed descriptor set
10680     submit_info = {};
10681     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
10682     submit_info.commandBufferCount = 1;
10683     submit_info.pCommandBuffers = &m_commandBuffer->handle();
10684     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound DescriptorSet ");
10685     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
10686     m_errorMonitor->VerifyFound();
10687 
10688     // Cleanup
10689     vkFreeMemory(m_device->device(), image_memory, NULL);
10690     vkDestroySampler(m_device->device(), sampler2, NULL);
10691     vkDestroyImage(m_device->device(), image2, NULL);
10692     vkDestroyImageView(m_device->device(), view, NULL);
10693     vkDestroyImageView(m_device->device(), view2, NULL);
10694     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
10695 }
10696 
TEST_F(VkLayerTest,InvalidDescriptorSetSamplerDestroyed)10697 TEST_F(VkLayerTest, InvalidDescriptorSetSamplerDestroyed) {
10698     TEST_DESCRIPTION("Attempt to draw with a bound descriptor sets with a combined image sampler where sampler has been deleted.");
10699     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
10700     ASSERT_NO_FATAL_FAILURE(InitViewport());
10701     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10702 
10703     OneOffDescriptorSet ds(m_device, {
10704                                          {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
10705                                      });
10706 
10707     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
10708     // Create images to update the descriptor with
10709     VkImageObj image(m_device);
10710     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
10711     image.Init(32, 32, 1, tex_format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
10712     ASSERT_TRUE(image.initialized());
10713 
10714     VkImageViewCreateInfo image_view_create_info = {};
10715     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
10716     image_view_create_info.image = image.handle();
10717     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
10718     image_view_create_info.format = tex_format;
10719     image_view_create_info.subresourceRange.layerCount = 1;
10720     image_view_create_info.subresourceRange.baseMipLevel = 0;
10721     image_view_create_info.subresourceRange.levelCount = 1;
10722     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10723 
10724     VkImageView view;
10725     VkResult err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
10726     ASSERT_VK_SUCCESS(err);
10727     // Create Samplers
10728     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
10729     VkSampler sampler;
10730     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
10731     ASSERT_VK_SUCCESS(err);
10732     // Update descriptor with image and sampler
10733     VkDescriptorImageInfo img_info = {};
10734     img_info.sampler = sampler;
10735     img_info.imageView = view;
10736     img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
10737 
10738     VkWriteDescriptorSet descriptor_write;
10739     memset(&descriptor_write, 0, sizeof(descriptor_write));
10740     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
10741     descriptor_write.dstSet = ds.set_;
10742     descriptor_write.dstBinding = 0;
10743     descriptor_write.descriptorCount = 1;
10744     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
10745     descriptor_write.pImageInfo = &img_info;
10746 
10747     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
10748     // Destroy the sampler before it's bound to the cmd buffer
10749     vkDestroySampler(m_device->device(), sampler, NULL);
10750 
10751     // Create PSO to be used for draw-time errors below
10752     char const *vsSource =
10753         "#version 450\n"
10754         "\n"
10755         "void main(){\n"
10756         "   gl_Position = vec4(1);\n"
10757         "}\n";
10758     char const *fsSource =
10759         "#version 450\n"
10760         "\n"
10761         "layout(set=0, binding=0) uniform sampler2D s;\n"
10762         "layout(location=0) out vec4 x;\n"
10763         "void main(){\n"
10764         "   x = texture(s, vec2(1));\n"
10765         "}\n";
10766     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
10767     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
10768     VkPipelineObj pipe(m_device);
10769     pipe.AddShader(&vs);
10770     pipe.AddShader(&fs);
10771     pipe.AddDefaultColorAttachment();
10772     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
10773 
10774     // First error case is destroying sampler prior to cmd buffer submission
10775     m_commandBuffer->begin();
10776     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
10777     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
10778     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &ds.set_, 0,
10779                             NULL);
10780     VkViewport viewport = {0, 0, 16, 16, 0, 1};
10781     VkRect2D scissor = {{0, 0}, {16, 16}};
10782     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
10783     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
10784     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10785                                          " Descriptor in binding #0 at global descriptor index 0 is using sampler ");
10786     m_commandBuffer->Draw(1, 0, 0, 0);
10787     m_errorMonitor->VerifyFound();
10788 
10789     m_commandBuffer->EndRenderPass();
10790     m_commandBuffer->end();
10791 
10792     vkDestroyImageView(m_device->device(), view, NULL);
10793 }
10794 
TEST_F(VkLayerTest,ImageDescriptorLayoutMismatchInternal)10795 TEST_F(VkLayerTest, ImageDescriptorLayoutMismatchInternal) {
10796     TEST_DESCRIPTION("Create an image sampler layout->image layout mismatch within a command buffer");
10797     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
10798     ASSERT_NO_FATAL_FAILURE(InitViewport());
10799     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10800 
10801     VkDescriptorPoolSize ds_type_count = {};
10802     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
10803     ds_type_count.descriptorCount = 1;
10804 
10805     VkDescriptorPoolCreateInfo ds_pool_ci = {};
10806     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
10807     ds_pool_ci.pNext = NULL;
10808     ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
10809     ds_pool_ci.maxSets = 1;
10810     ds_pool_ci.poolSizeCount = 1;
10811     ds_pool_ci.pPoolSizes = &ds_type_count;
10812 
10813     VkDescriptorPool ds_pool;
10814     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
10815     ASSERT_VK_SUCCESS(err);
10816 
10817     VkDescriptorSetLayoutBinding dsl_binding = {};
10818     dsl_binding.binding = 0;
10819     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
10820     dsl_binding.descriptorCount = 1;
10821     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
10822     dsl_binding.pImmutableSamplers = NULL;
10823 
10824     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
10825 
10826     VkDescriptorSet descriptorSet;
10827     VkDescriptorSetAllocateInfo alloc_info = {};
10828     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
10829     alloc_info.descriptorSetCount = 1;
10830     alloc_info.descriptorPool = ds_pool;
10831     alloc_info.pSetLayouts = &ds_layout.handle();
10832     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
10833     ASSERT_VK_SUCCESS(err);
10834 
10835     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout});
10836 
10837     // Create images to update the descriptor with
10838     const VkFormat format = VK_FORMAT_B8G8R8A8_UNORM;
10839     VkImageObj image(m_device);
10840     image.Init(32, 32, 1, format, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_TILING_OPTIMAL,
10841                0);
10842     ASSERT_TRUE(image.initialized());
10843 
10844     VkImageViewCreateInfo image_view_create_info = {};
10845     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
10846     image_view_create_info.image = image.handle();
10847     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
10848     image_view_create_info.format = format;
10849     image_view_create_info.subresourceRange.layerCount = 1;
10850     image_view_create_info.subresourceRange.baseMipLevel = 0;
10851     image_view_create_info.subresourceRange.levelCount = 1;
10852     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10853 
10854     VkImageView view;
10855     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
10856     ASSERT_VK_SUCCESS(err);
10857     // Create Sampler
10858     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
10859     VkSampler sampler;
10860     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
10861     ASSERT_VK_SUCCESS(err);
10862     // Update descriptor with image and sampler
10863     VkDescriptorImageInfo img_info = {};
10864     img_info.sampler = sampler;
10865     img_info.imageView = view;
10866     // This should cause a mis-match. Actual layout at use time is SHADER_RO
10867     img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
10868 
10869     VkWriteDescriptorSet descriptor_write;
10870     memset(&descriptor_write, 0, sizeof(descriptor_write));
10871     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
10872     descriptor_write.dstSet = descriptorSet;
10873     descriptor_write.dstBinding = 0;
10874     descriptor_write.descriptorCount = 1;
10875     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
10876     descriptor_write.pImageInfo = &img_info;
10877 
10878     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
10879 
10880     // Create PSO to be used for draw-time errors below
10881     char const *vsSource =
10882         "#version 450\n"
10883         "\n"
10884         "void main(){\n"
10885         "   gl_Position = vec4(1);\n"
10886         "}\n";
10887     char const *fsSource =
10888         "#version 450\n"
10889         "\n"
10890         "layout(set=0, binding=0) uniform sampler2D s;\n"
10891         "layout(location=0) out vec4 x;\n"
10892         "void main(){\n"
10893         "   x = texture(s, vec2(1));\n"
10894         "}\n";
10895     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
10896     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
10897     VkPipelineObj pipe(m_device);
10898     pipe.AddShader(&vs);
10899     pipe.AddShader(&fs);
10900     pipe.AddDefaultColorAttachment();
10901     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
10902 
10903     VkCommandBufferObj cmd_buf(m_device, m_commandPool);
10904     cmd_buf.begin();
10905     // record layout different than actual descriptor layout of SHADER_RO
10906     image.SetLayout(&cmd_buf, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
10907     cmd_buf.BeginRenderPass(m_renderPassBeginInfo);
10908     vkCmdBindPipeline(cmd_buf.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
10909     vkCmdBindDescriptorSets(cmd_buf.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &descriptorSet, 0,
10910                             NULL);
10911     VkViewport viewport = {0, 0, 16, 16, 0, 1};
10912     VkRect2D scissor = {{0, 0}, {16, 16}};
10913     vkCmdSetViewport(cmd_buf.handle(), 0, 1, &viewport);
10914     vkCmdSetScissor(cmd_buf.handle(), 0, 1, &scissor);
10915     // At draw time the update layout will mis-match the actual layout
10916     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkDescriptorImageInfo-imageLayout-00344");
10917     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
10918                                          "UNASSIGNED-CoreValidation-DrawState-DescriptorSetNotUpdated");
10919     cmd_buf.Draw(1, 0, 0, 0);
10920     m_errorMonitor->VerifyFound();
10921     cmd_buf.EndRenderPass();
10922     cmd_buf.end();
10923     // Submit cmd buffer
10924     VkSubmitInfo submit_info = {};
10925     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
10926     submit_info.commandBufferCount = 1;
10927     submit_info.pCommandBuffers = &cmd_buf.handle();
10928     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
10929     vkQueueWaitIdle(m_device->m_queue);
10930     // Cleanup
10931     vkDestroySampler(m_device->device(), sampler, NULL);
10932     vkDestroyImageView(m_device->device(), view, NULL);
10933     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
10934 }
10935 
TEST_F(VkLayerTest,ImageDescriptorLayoutMismatchExternal)10936 TEST_F(VkLayerTest, ImageDescriptorLayoutMismatchExternal) {
10937     TEST_DESCRIPTION("Create an image sampler layout->image layout mismatch external to a command buffer");
10938 
10939     ASSERT_NO_FATAL_FAILURE(Init());
10940     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10941 
10942     OneOffDescriptorSet ds(m_device, {
10943                                          {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
10944                                      });
10945 
10946     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
10947     VkSampler sampler;
10948 
10949     VkResult err;
10950     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
10951     ASSERT_VK_SUCCESS(err);
10952 
10953     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
10954 
10955     VkImageObj image(m_device);
10956     // Transition image to be used in shader to SHADER_READ_ONLY_OPTIMAL
10957     image.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
10958                VK_IMAGE_TILING_OPTIMAL, 0);
10959 
10960     ASSERT_TRUE(image.initialized());
10961 
10962     VkImageView view;
10963     VkImageViewCreateInfo ivci = {};
10964     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
10965     ivci.image = image.handle();
10966     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
10967     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
10968     ivci.subresourceRange.layerCount = 1;
10969     ivci.subresourceRange.baseMipLevel = 0;
10970     ivci.subresourceRange.levelCount = 1;
10971     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
10972 
10973     err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
10974     ASSERT_VK_SUCCESS(err);
10975 
10976     VkDescriptorImageInfo image_info{};
10977     // Set error condition -- anything but Shader_Read_Only_Optimal which is the current image layout
10978     image_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
10979     image_info.imageView = view;
10980     image_info.sampler = sampler;
10981 
10982     VkWriteDescriptorSet descriptor_write = {};
10983     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
10984     descriptor_write.dstSet = ds.set_;
10985     descriptor_write.dstBinding = 0;
10986     descriptor_write.descriptorCount = 1;
10987     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
10988     descriptor_write.pImageInfo = &image_info;
10989 
10990     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
10991 
10992     char const *vsSource =
10993         "#version 450\n"
10994         "\n"
10995         "void main(){\n"
10996         "   gl_Position = vec4(1);\n"
10997         "}\n";
10998     char const *fsSource =
10999         "#version 450\n"
11000         "\n"
11001         "layout(set=0, binding=0) uniform sampler2D s;\n"
11002         "layout(location=0) out vec4 x;\n"
11003         "void main(){\n"
11004         "   x = texture(s, vec2(1));\n"
11005         "}\n";
11006 
11007     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
11008     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
11009     VkPipelineObj pipe(m_device);
11010     pipe.AddShader(&vs);
11011     pipe.AddShader(&fs);
11012     pipe.AddDefaultColorAttachment();
11013     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
11014 
11015     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout");
11016 
11017     m_commandBuffer->begin();
11018     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
11019     // Bind pipeline to cmd buffer
11020     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
11021     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &ds.set_, 0,
11022                             nullptr);
11023 
11024     VkViewport viewport = {0, 0, 16, 16, 0, 1};
11025     VkRect2D scissor = {{0, 0}, {16, 16}};
11026     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
11027     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
11028 
11029     m_commandBuffer->Draw(1, 0, 0, 0);
11030     m_commandBuffer->EndRenderPass();
11031     m_commandBuffer->end();
11032     VkSubmitInfo submit_info = {};
11033     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
11034     submit_info.commandBufferCount = 1;
11035     submit_info.pCommandBuffers = &m_commandBuffer->handle();
11036     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
11037 
11038     m_errorMonitor->VerifyFound();
11039     vkQueueWaitIdle(m_device->m_queue);
11040     vkDestroyImageView(m_device->device(), view, NULL);
11041     vkDestroySampler(m_device->device(), sampler, nullptr);
11042 }
11043 
TEST_F(VkLayerTest,DescriptorPoolInUseDestroyedSignaled)11044 TEST_F(VkLayerTest, DescriptorPoolInUseDestroyedSignaled) {
11045     TEST_DESCRIPTION("Delete a DescriptorPool with a DescriptorSet that is in use.");
11046     ASSERT_NO_FATAL_FAILURE(Init());
11047     ASSERT_NO_FATAL_FAILURE(InitViewport());
11048     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
11049 
11050     VkDescriptorPoolSize ds_type_count = {};
11051     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11052     ds_type_count.descriptorCount = 1;
11053 
11054     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11055     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11056     ds_pool_ci.pNext = NULL;
11057     ds_pool_ci.maxSets = 1;
11058     ds_pool_ci.poolSizeCount = 1;
11059     ds_pool_ci.pPoolSizes = &ds_type_count;
11060 
11061     VkDescriptorPool ds_pool;
11062     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11063     ASSERT_VK_SUCCESS(err);
11064 
11065     VkDescriptorSetLayoutBinding dsl_binding = {};
11066     dsl_binding.binding = 0;
11067     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11068     dsl_binding.descriptorCount = 1;
11069     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11070     dsl_binding.pImmutableSamplers = NULL;
11071 
11072     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
11073 
11074     VkDescriptorSet descriptor_set;
11075     VkDescriptorSetAllocateInfo alloc_info = {};
11076     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11077     alloc_info.descriptorSetCount = 1;
11078     alloc_info.descriptorPool = ds_pool;
11079     alloc_info.pSetLayouts = &ds_layout.handle();
11080     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
11081     ASSERT_VK_SUCCESS(err);
11082 
11083     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout});
11084 
11085     // Create image to update the descriptor with
11086     VkImageObj image(m_device);
11087     image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
11088     ASSERT_TRUE(image.initialized());
11089 
11090     VkImageView view = image.targetView(VK_FORMAT_B8G8R8A8_UNORM);
11091     // Create Sampler
11092     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
11093     VkSampler sampler;
11094     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11095     ASSERT_VK_SUCCESS(err);
11096     // Update descriptor with image and sampler
11097     VkDescriptorImageInfo img_info = {};
11098     img_info.sampler = sampler;
11099     img_info.imageView = view;
11100     img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
11101 
11102     VkWriteDescriptorSet descriptor_write;
11103     memset(&descriptor_write, 0, sizeof(descriptor_write));
11104     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11105     descriptor_write.dstSet = descriptor_set;
11106     descriptor_write.dstBinding = 0;
11107     descriptor_write.descriptorCount = 1;
11108     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11109     descriptor_write.pImageInfo = &img_info;
11110 
11111     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11112 
11113     // Create PSO to be used for draw-time errors below
11114     char const *vsSource =
11115         "#version 450\n"
11116         "\n"
11117         "void main(){\n"
11118         "   gl_Position = vec4(1);\n"
11119         "}\n";
11120     char const *fsSource =
11121         "#version 450\n"
11122         "\n"
11123         "layout(set=0, binding=0) uniform sampler2D s;\n"
11124         "layout(location=0) out vec4 x;\n"
11125         "void main(){\n"
11126         "   x = texture(s, vec2(1));\n"
11127         "}\n";
11128     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
11129     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
11130     VkPipelineObj pipe(m_device);
11131     pipe.AddShader(&vs);
11132     pipe.AddShader(&fs);
11133     pipe.AddDefaultColorAttachment();
11134     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
11135 
11136     m_commandBuffer->begin();
11137     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
11138     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
11139     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
11140                             &descriptor_set, 0, NULL);
11141 
11142     VkViewport viewport = {0, 0, 16, 16, 0, 1};
11143     VkRect2D scissor = {{0, 0}, {16, 16}};
11144     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
11145     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
11146 
11147     m_commandBuffer->Draw(1, 0, 0, 0);
11148     m_commandBuffer->EndRenderPass();
11149     m_commandBuffer->end();
11150     // Submit cmd buffer to put pool in-flight
11151     VkSubmitInfo submit_info = {};
11152     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
11153     submit_info.commandBufferCount = 1;
11154     submit_info.pCommandBuffers = &m_commandBuffer->handle();
11155     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
11156     // Destroy pool while in-flight, causing error
11157     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyDescriptorPool-descriptorPool-00303");
11158     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11159     m_errorMonitor->VerifyFound();
11160     vkQueueWaitIdle(m_device->m_queue);
11161     // Cleanup
11162     vkDestroySampler(m_device->device(), sampler, NULL);
11163     m_errorMonitor->SetUnexpectedError(
11164         "If descriptorPool is not VK_NULL_HANDLE, descriptorPool must be a valid VkDescriptorPool handle");
11165     m_errorMonitor->SetUnexpectedError("Unable to remove DescriptorPool obj");
11166     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11167     // TODO : It seems Validation layers think ds_pool was already destroyed, even though it wasn't?
11168 }
11169 
TEST_F(VkLayerTest,DescriptorPoolInUseResetSignaled)11170 TEST_F(VkLayerTest, DescriptorPoolInUseResetSignaled) {
11171     TEST_DESCRIPTION("Reset a DescriptorPool with a DescriptorSet that is in use.");
11172     ASSERT_NO_FATAL_FAILURE(Init());
11173     ASSERT_NO_FATAL_FAILURE(InitViewport());
11174     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
11175 
11176     VkDescriptorPoolSize ds_type_count = {};
11177     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11178     ds_type_count.descriptorCount = 1;
11179 
11180     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11181     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11182     ds_pool_ci.pNext = nullptr;
11183     ds_pool_ci.maxSets = 1;
11184     ds_pool_ci.poolSizeCount = 1;
11185     ds_pool_ci.pPoolSizes = &ds_type_count;
11186 
11187     VkDescriptorPool ds_pool;
11188     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, nullptr, &ds_pool);
11189     ASSERT_VK_SUCCESS(err);
11190 
11191     VkDescriptorSetLayoutBinding dsl_binding = {};
11192     dsl_binding.binding = 0;
11193     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11194     dsl_binding.descriptorCount = 1;
11195     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11196     dsl_binding.pImmutableSamplers = nullptr;
11197 
11198     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
11199 
11200     VkDescriptorSet descriptor_set;
11201     VkDescriptorSetAllocateInfo alloc_info = {};
11202     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11203     alloc_info.descriptorSetCount = 1;
11204     alloc_info.descriptorPool = ds_pool;
11205     alloc_info.pSetLayouts = &ds_layout.handle();
11206     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
11207     ASSERT_VK_SUCCESS(err);
11208 
11209     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout});
11210 
11211     // Create image to update the descriptor with
11212     VkImageObj image(m_device);
11213     image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
11214     ASSERT_TRUE(image.initialized());
11215 
11216     VkImageView view = image.targetView(VK_FORMAT_B8G8R8A8_UNORM);
11217     // Create Sampler
11218     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
11219     VkSampler sampler;
11220     err = vkCreateSampler(m_device->device(), &sampler_ci, nullptr, &sampler);
11221     ASSERT_VK_SUCCESS(err);
11222     // Update descriptor with image and sampler
11223     VkDescriptorImageInfo img_info = {};
11224     img_info.sampler = sampler;
11225     img_info.imageView = view;
11226     img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
11227 
11228     VkWriteDescriptorSet descriptor_write;
11229     memset(&descriptor_write, 0, sizeof(descriptor_write));
11230     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11231     descriptor_write.dstSet = descriptor_set;
11232     descriptor_write.dstBinding = 0;
11233     descriptor_write.descriptorCount = 1;
11234     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11235     descriptor_write.pImageInfo = &img_info;
11236 
11237     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, nullptr);
11238 
11239     // Create PSO to be used for draw-time errors below
11240     char const *vsSource =
11241         "#version 450\n"
11242         "\n"
11243         "void main(){\n"
11244         "   gl_Position = vec4(1);\n"
11245         "}\n";
11246     char const *fsSource =
11247         "#version 450\n"
11248         "\n"
11249         "layout(set=0, binding=0) uniform sampler2D s;\n"
11250         "layout(location=0) out vec4 x;\n"
11251         "void main(){\n"
11252         "   x = texture(s, vec2(1));\n"
11253         "}\n";
11254     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
11255     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
11256     VkPipelineObj pipe(m_device);
11257     pipe.AddShader(&vs);
11258     pipe.AddShader(&fs);
11259     pipe.AddDefaultColorAttachment();
11260     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
11261 
11262     m_commandBuffer->begin();
11263     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
11264     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
11265     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
11266                             &descriptor_set, 0, nullptr);
11267 
11268     VkViewport viewport = {0, 0, 16, 16, 0, 1};
11269     VkRect2D scissor = {{0, 0}, {16, 16}};
11270     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
11271     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
11272 
11273     m_commandBuffer->Draw(1, 0, 0, 0);
11274     m_commandBuffer->EndRenderPass();
11275     m_commandBuffer->end();
11276     // Submit cmd buffer to put pool in-flight
11277     VkSubmitInfo submit_info = {};
11278     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
11279     submit_info.commandBufferCount = 1;
11280     submit_info.pCommandBuffers = &m_commandBuffer->handle();
11281     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
11282     // Reset pool while in-flight, causing error
11283     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkResetDescriptorPool-descriptorPool-00313");
11284     vkResetDescriptorPool(m_device->device(), ds_pool, 0);
11285     m_errorMonitor->VerifyFound();
11286     vkQueueWaitIdle(m_device->m_queue);
11287     // Cleanup
11288     vkDestroySampler(m_device->device(), sampler, nullptr);
11289     m_errorMonitor->SetUnexpectedError(
11290         "If descriptorPool is not VK_NULL_HANDLE, descriptorPool must be a valid VkDescriptorPool handle");
11291     m_errorMonitor->SetUnexpectedError("Unable to remove DescriptorPool obj");
11292     vkDestroyDescriptorPool(m_device->device(), ds_pool, nullptr);
11293 }
11294 
TEST_F(VkLayerTest,DescriptorImageUpdateNoMemoryBound)11295 TEST_F(VkLayerTest, DescriptorImageUpdateNoMemoryBound) {
11296     TEST_DESCRIPTION("Attempt an image descriptor set update where image's bound memory has been freed.");
11297     ASSERT_NO_FATAL_FAILURE(Init());
11298     ASSERT_NO_FATAL_FAILURE(InitViewport());
11299     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
11300 
11301     VkDescriptorPoolSize ds_type_count = {};
11302     ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11303     ds_type_count.descriptorCount = 1;
11304 
11305     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11306     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11307     ds_pool_ci.pNext = NULL;
11308     ds_pool_ci.maxSets = 1;
11309     ds_pool_ci.poolSizeCount = 1;
11310     ds_pool_ci.pPoolSizes = &ds_type_count;
11311 
11312     VkDescriptorPool ds_pool;
11313     VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11314     ASSERT_VK_SUCCESS(err);
11315 
11316     VkDescriptorSetLayoutBinding dsl_binding = {};
11317     dsl_binding.binding = 0;
11318     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11319     dsl_binding.descriptorCount = 1;
11320     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11321     dsl_binding.pImmutableSamplers = NULL;
11322 
11323     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
11324 
11325     VkDescriptorSet descriptorSet;
11326     VkDescriptorSetAllocateInfo alloc_info = {};
11327     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11328     alloc_info.descriptorSetCount = 1;
11329     alloc_info.descriptorPool = ds_pool;
11330     alloc_info.pSetLayouts = &ds_layout.handle();
11331     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11332     ASSERT_VK_SUCCESS(err);
11333 
11334     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout});
11335 
11336     // Create images to update the descriptor with
11337     VkImage image;
11338     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
11339     const int32_t tex_width = 32;
11340     const int32_t tex_height = 32;
11341     VkImageCreateInfo image_create_info = {};
11342     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
11343     image_create_info.pNext = NULL;
11344     image_create_info.imageType = VK_IMAGE_TYPE_2D;
11345     image_create_info.format = tex_format;
11346     image_create_info.extent.width = tex_width;
11347     image_create_info.extent.height = tex_height;
11348     image_create_info.extent.depth = 1;
11349     image_create_info.mipLevels = 1;
11350     image_create_info.arrayLayers = 1;
11351     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
11352     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
11353     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
11354     image_create_info.flags = 0;
11355     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
11356     ASSERT_VK_SUCCESS(err);
11357     // Initially bind memory to avoid error at bind view time. We'll break binding before update.
11358     VkMemoryRequirements memory_reqs;
11359     VkDeviceMemory image_memory;
11360     bool pass;
11361     VkMemoryAllocateInfo memory_info = {};
11362     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
11363     memory_info.pNext = NULL;
11364     memory_info.allocationSize = 0;
11365     memory_info.memoryTypeIndex = 0;
11366     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
11367     // Allocate enough memory for image
11368     memory_info.allocationSize = memory_reqs.size;
11369     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
11370     ASSERT_TRUE(pass);
11371     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
11372     ASSERT_VK_SUCCESS(err);
11373     err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
11374     ASSERT_VK_SUCCESS(err);
11375 
11376     VkImageViewCreateInfo image_view_create_info = {};
11377     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
11378     image_view_create_info.image = image;
11379     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
11380     image_view_create_info.format = tex_format;
11381     image_view_create_info.subresourceRange.layerCount = 1;
11382     image_view_create_info.subresourceRange.baseMipLevel = 0;
11383     image_view_create_info.subresourceRange.levelCount = 1;
11384     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
11385 
11386     VkImageView view;
11387     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
11388     ASSERT_VK_SUCCESS(err);
11389     // Create Samplers
11390     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
11391     VkSampler sampler;
11392     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
11393     ASSERT_VK_SUCCESS(err);
11394     // Update descriptor with image and sampler
11395     VkDescriptorImageInfo img_info = {};
11396     img_info.sampler = sampler;
11397     img_info.imageView = view;
11398     img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
11399 
11400     VkWriteDescriptorSet descriptor_write;
11401     memset(&descriptor_write, 0, sizeof(descriptor_write));
11402     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11403     descriptor_write.dstSet = descriptorSet;
11404     descriptor_write.dstBinding = 0;
11405     descriptor_write.descriptorCount = 1;
11406     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
11407     descriptor_write.pImageInfo = &img_info;
11408     // Break memory binding and attempt update
11409     vkFreeMemory(m_device->device(), image_memory, nullptr);
11410     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11411                                          " previously bound memory was freed. Memory must not be freed prior to this operation.");
11412     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11413                                          "vkUpdateDescriptorSets() failed write update validation for Descriptor Set 0x");
11414     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11415     m_errorMonitor->VerifyFound();
11416     // Cleanup
11417     vkDestroyImage(m_device->device(), image, NULL);
11418     vkDestroySampler(m_device->device(), sampler, NULL);
11419     vkDestroyImageView(m_device->device(), view, NULL);
11420     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11421 }
11422 
TEST_F(VkLayerTest,InvalidPipeline)11423 TEST_F(VkLayerTest, InvalidPipeline) {
11424     uint64_t fake_pipeline_handle = 0xbaad6001;
11425     VkPipeline bad_pipeline = reinterpret_cast<VkPipeline &>(fake_pipeline_handle);
11426 
11427     // Enable VK_KHR_draw_indirect_count for KHR variants
11428     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
11429     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME)) {
11430         m_device_extension_names.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
11431     }
11432     ASSERT_NO_FATAL_FAILURE(InitState());
11433     bool has_khr_indirect = DeviceExtensionEnabled(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
11434     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
11435 
11436     // Attempt to bind an invalid Pipeline to a valid Command Buffer
11437     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBindPipeline-pipeline-parameter");
11438     m_commandBuffer->begin();
11439     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, bad_pipeline);
11440     m_errorMonitor->VerifyFound();
11441 
11442     // Try each of the 6 flavors of Draw()
11443     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);  // Draw*() calls must be submitted within a renderpass
11444 
11445     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDraw-None-00442");
11446     m_commandBuffer->Draw(1, 0, 0, 0);
11447     m_errorMonitor->VerifyFound();
11448 
11449     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndexed-None-00461");
11450     m_commandBuffer->DrawIndexed(1, 1, 0, 0, 0);
11451     m_errorMonitor->VerifyFound();
11452 
11453     VkBufferObj buffer;
11454     VkBufferCreateInfo ci = {};
11455     ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
11456     ci.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
11457     ci.size = 1024;
11458     buffer.init(*m_device, ci);
11459     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndirect-None-00485");
11460     vkCmdDrawIndirect(m_commandBuffer->handle(), buffer.handle(), 0, 1, 0);
11461     m_errorMonitor->VerifyFound();
11462 
11463     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndexedIndirect-None-00537");
11464     vkCmdDrawIndexedIndirect(m_commandBuffer->handle(), buffer.handle(), 0, 1, 0);
11465     m_errorMonitor->VerifyFound();
11466 
11467     if (has_khr_indirect) {
11468         auto fpCmdDrawIndirectCountKHR =
11469             (PFN_vkCmdDrawIndirectCountKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdDrawIndirectCountKHR");
11470         ASSERT_NE(fpCmdDrawIndirectCountKHR, nullptr);
11471 
11472         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndirectCountKHR-None-03119");
11473         // stride must be a multiple of 4 and must be greater than or equal to sizeof(VkDrawIndirectCommand)
11474         fpCmdDrawIndirectCountKHR(m_commandBuffer->handle(), buffer.handle(), 0, buffer.handle(), 512, 1, 512);
11475         m_errorMonitor->VerifyFound();
11476 
11477         auto fpCmdDrawIndexedIndirectCountKHR =
11478             (PFN_vkCmdDrawIndexedIndirectCountKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdDrawIndexedIndirectCountKHR");
11479         ASSERT_NE(fpCmdDrawIndexedIndirectCountKHR, nullptr);
11480         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndexedIndirectCountKHR-None-03151");
11481         // stride must be a multiple of 4 and must be greater than or equal to sizeof(VkDrawIndexedIndirectCommand)
11482         fpCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), buffer.handle(), 0, buffer.handle(), 512, 1, 512);
11483         m_errorMonitor->VerifyFound();
11484     }
11485 
11486     // Also try the Dispatch variants
11487     vkCmdEndRenderPass(m_commandBuffer->handle());  // Compute submissions must be outside a renderpass
11488 
11489     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatch-None-00391");
11490     vkCmdDispatch(m_commandBuffer->handle(), 0, 0, 0);
11491     m_errorMonitor->VerifyFound();
11492 
11493     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatchIndirect-None-00404");
11494     vkCmdDispatchIndirect(m_commandBuffer->handle(), buffer.handle(), 0);
11495     m_errorMonitor->VerifyFound();
11496 }
11497 
TEST_F(VkLayerTest,CmdDispatchExceedLimits)11498 TEST_F(VkLayerTest, CmdDispatchExceedLimits) {
11499     TEST_DESCRIPTION("Compute dispatch with dimensions that exceed device limits");
11500 
11501     // Enable KHX device group extensions, if available
11502     if (InstanceExtensionSupported(VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME)) {
11503         m_instance_extension_names.push_back(VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME);
11504     }
11505     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
11506     bool khx_dg_ext_available = false;
11507     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DEVICE_GROUP_EXTENSION_NAME)) {
11508         m_device_extension_names.push_back(VK_KHR_DEVICE_GROUP_EXTENSION_NAME);
11509         khx_dg_ext_available = true;
11510     }
11511     ASSERT_NO_FATAL_FAILURE(InitState());
11512 
11513     uint32_t x_limit = m_device->props.limits.maxComputeWorkGroupCount[0];
11514     uint32_t y_limit = m_device->props.limits.maxComputeWorkGroupCount[1];
11515     uint32_t z_limit = m_device->props.limits.maxComputeWorkGroupCount[2];
11516     if (std::max({x_limit, y_limit, z_limit}) == UINT32_MAX) {
11517         printf("%s device maxComputeWorkGroupCount limit reports UINT32_MAX, test not possible, skipping.\n", kSkipPrefix);
11518         return;
11519     }
11520 
11521     // Create a minimal compute pipeline
11522     std::string cs_text = "#version 450\nvoid main() {}\n";  // minimal no-op shader
11523     VkShaderObj cs_obj(m_device, cs_text.c_str(), VK_SHADER_STAGE_COMPUTE_BIT, this);
11524 
11525     VkPipelineLayoutCreateInfo info = {};
11526     info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
11527     info.pNext = nullptr;
11528     VkPipelineLayout pipe_layout;
11529     vkCreatePipelineLayout(device(), &info, nullptr, &pipe_layout);
11530 
11531     VkComputePipelineCreateInfo pipeline_info = {};
11532     pipeline_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
11533     pipeline_info.pNext = nullptr;
11534     pipeline_info.flags = khx_dg_ext_available ? VK_PIPELINE_CREATE_DISPATCH_BASE_KHR : 0;
11535     pipeline_info.layout = pipe_layout;
11536     pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
11537     pipeline_info.basePipelineIndex = -1;
11538     pipeline_info.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
11539     pipeline_info.stage.pNext = nullptr;
11540     pipeline_info.stage.flags = 0;
11541     pipeline_info.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
11542     pipeline_info.stage.module = cs_obj.handle();
11543     pipeline_info.stage.pName = "main";
11544     pipeline_info.stage.pSpecializationInfo = nullptr;
11545     VkPipeline cs_pipeline;
11546     vkCreateComputePipelines(device(), VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &cs_pipeline);
11547 
11548     // Bind pipeline to command buffer
11549     m_commandBuffer->begin();
11550     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, cs_pipeline);
11551 
11552     // Dispatch counts that exceed device limits
11553     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatch-groupCountX-00386");
11554     vkCmdDispatch(m_commandBuffer->handle(), x_limit + 1, y_limit, z_limit);
11555     m_errorMonitor->VerifyFound();
11556 
11557     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatch-groupCountY-00387");
11558     vkCmdDispatch(m_commandBuffer->handle(), x_limit, y_limit + 1, z_limit);
11559     m_errorMonitor->VerifyFound();
11560 
11561     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatch-groupCountZ-00388");
11562     vkCmdDispatch(m_commandBuffer->handle(), x_limit, y_limit, z_limit + 1);
11563     m_errorMonitor->VerifyFound();
11564 
11565     if (khx_dg_ext_available) {
11566         PFN_vkCmdDispatchBaseKHR fp_vkCmdDispatchBaseKHR =
11567             (PFN_vkCmdDispatchBaseKHR)vkGetInstanceProcAddr(instance(), "vkCmdDispatchBaseKHR");
11568 
11569         // Base equals or exceeds limit
11570         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatchBase-baseGroupX-00421");
11571         fp_vkCmdDispatchBaseKHR(m_commandBuffer->handle(), x_limit, y_limit - 1, z_limit - 1, 0, 0, 0);
11572         m_errorMonitor->VerifyFound();
11573 
11574         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatchBase-baseGroupX-00422");
11575         fp_vkCmdDispatchBaseKHR(m_commandBuffer->handle(), x_limit - 1, y_limit, z_limit - 1, 0, 0, 0);
11576         m_errorMonitor->VerifyFound();
11577 
11578         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatchBase-baseGroupZ-00423");
11579         fp_vkCmdDispatchBaseKHR(m_commandBuffer->handle(), x_limit - 1, y_limit - 1, z_limit, 0, 0, 0);
11580         m_errorMonitor->VerifyFound();
11581 
11582         // (Base + count) exceeds limit
11583         uint32_t x_base = x_limit / 2;
11584         uint32_t y_base = y_limit / 2;
11585         uint32_t z_base = z_limit / 2;
11586         x_limit -= x_base;
11587         y_limit -= y_base;
11588         z_limit -= z_base;
11589 
11590         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatchBase-groupCountX-00424");
11591         fp_vkCmdDispatchBaseKHR(m_commandBuffer->handle(), x_base, y_base, z_base, x_limit + 1, y_limit, z_limit);
11592         m_errorMonitor->VerifyFound();
11593 
11594         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatchBase-groupCountY-00425");
11595         fp_vkCmdDispatchBaseKHR(m_commandBuffer->handle(), x_base, y_base, z_base, x_limit, y_limit + 1, z_limit);
11596         m_errorMonitor->VerifyFound();
11597 
11598         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDispatchBase-groupCountZ-00426");
11599         fp_vkCmdDispatchBaseKHR(m_commandBuffer->handle(), x_base, y_base, z_base, x_limit, y_limit, z_limit + 1);
11600         m_errorMonitor->VerifyFound();
11601     } else {
11602         printf("%s KHX_DEVICE_GROUP_* extensions not supported, skipping CmdDispatchBaseKHR() tests.\n", kSkipPrefix);
11603     }
11604 
11605     // Clean up
11606     vkDestroyPipeline(device(), cs_pipeline, nullptr);
11607     vkDestroyPipelineLayout(device(), pipe_layout, nullptr);
11608 }
11609 
TEST_F(VkLayerTest,MultiplaneImageLayoutBadAspectFlags)11610 TEST_F(VkLayerTest, MultiplaneImageLayoutBadAspectFlags) {
11611     TEST_DESCRIPTION("Query layout of a multiplane image using illegal aspect flag masks");
11612 
11613     // Enable KHR multiplane req'd extensions
11614     bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
11615                                                     VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
11616     if (mp_extensions) {
11617         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
11618     }
11619     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
11620     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
11621     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
11622     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
11623     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
11624     if (mp_extensions) {
11625         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
11626         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
11627         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
11628         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
11629     } else {
11630         printf("%s test requires KHR multiplane extensions, not available.  Skipping.\n", kSkipPrefix);
11631         return;
11632     }
11633     ASSERT_NO_FATAL_FAILURE(InitState());
11634 
11635     VkImageCreateInfo ci = {};
11636     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
11637     ci.pNext = NULL;
11638     ci.flags = 0;
11639     ci.imageType = VK_IMAGE_TYPE_2D;
11640     ci.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR;
11641     ci.extent = {128, 128, 1};
11642     ci.mipLevels = 1;
11643     ci.arrayLayers = 1;
11644     ci.samples = VK_SAMPLE_COUNT_1_BIT;
11645     ci.tiling = VK_IMAGE_TILING_LINEAR;
11646     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
11647     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11648     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
11649 
11650     // Verify formats
11651     bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, VK_FORMAT_FEATURE_TRANSFER_SRC_BIT);
11652     ci.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR;
11653     supported = supported && ImageFormatAndFeaturesSupported(instance(), gpu(), ci, VK_FORMAT_FEATURE_TRANSFER_SRC_BIT);
11654     if (!supported) {
11655         printf("%s Multiplane image format not supported.  Skipping test.\n", kSkipPrefix);
11656         return;  // Assume there's low ROI on searching for different mp formats
11657     }
11658 
11659     VkImage image_2plane, image_3plane;
11660     ci.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR;
11661     VkResult err = vkCreateImage(device(), &ci, NULL, &image_2plane);
11662     ASSERT_VK_SUCCESS(err);
11663 
11664     ci.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR;
11665     err = vkCreateImage(device(), &ci, NULL, &image_3plane);
11666     ASSERT_VK_SUCCESS(err);
11667 
11668     // Query layout of 3rd plane, for a 2-plane image
11669     VkImageSubresource subres = {};
11670     subres.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
11671     subres.mipLevel = 0;
11672     subres.arrayLayer = 0;
11673     VkSubresourceLayout layout = {};
11674 
11675     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkGetImageSubresourceLayout-format-01581");
11676     vkGetImageSubresourceLayout(device(), image_2plane, &subres, &layout);
11677     m_errorMonitor->VerifyFound();
11678 
11679     // Query layout using color aspect, for a 3-plane image
11680     subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
11681     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkGetImageSubresourceLayout-format-01582");
11682     vkGetImageSubresourceLayout(device(), image_3plane, &subres, &layout);
11683     m_errorMonitor->VerifyFound();
11684 
11685     // Clean up
11686     vkDestroyImage(device(), image_2plane, NULL);
11687     vkDestroyImage(device(), image_3plane, NULL);
11688 }
11689 
TEST_F(VkPositiveLayerTest,MultiplaneGetImageSubresourceLayout)11690 TEST_F(VkPositiveLayerTest, MultiplaneGetImageSubresourceLayout) {
11691     TEST_DESCRIPTION("Positive test, query layout of a single plane of a multiplane image. (repro Github #2530)");
11692 
11693     // Enable KHR multiplane req'd extensions
11694     bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
11695                                                     VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
11696     if (mp_extensions) {
11697         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
11698     }
11699     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
11700     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
11701     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
11702     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
11703     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
11704     if (mp_extensions) {
11705         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
11706         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
11707         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
11708         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
11709     } else {
11710         printf("%s test requires KHR multiplane extensions, not available.  Skipping.\n", kSkipPrefix);
11711         return;
11712     }
11713     ASSERT_NO_FATAL_FAILURE(InitState());
11714 
11715     VkImageCreateInfo ci = {};
11716     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
11717     ci.pNext = NULL;
11718     ci.flags = 0;
11719     ci.imageType = VK_IMAGE_TYPE_2D;
11720     ci.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR;
11721     ci.extent = {128, 128, 1};
11722     ci.mipLevels = 1;
11723     ci.arrayLayers = 1;
11724     ci.samples = VK_SAMPLE_COUNT_1_BIT;
11725     ci.tiling = VK_IMAGE_TILING_LINEAR;
11726     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
11727     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11728     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
11729 
11730     // Verify format
11731     bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, VK_FORMAT_FEATURE_TRANSFER_SRC_BIT);
11732     if (!supported) {
11733         printf("%s Multiplane image format not supported.  Skipping test.\n", kSkipPrefix);
11734         return;  // Assume there's low ROI on searching for different mp formats
11735     }
11736 
11737     VkImage image;
11738     VkResult err = vkCreateImage(device(), &ci, NULL, &image);
11739     ASSERT_VK_SUCCESS(err);
11740 
11741     // Query layout of 3rd plane
11742     VkImageSubresource subres = {};
11743     subres.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
11744     subres.mipLevel = 0;
11745     subres.arrayLayer = 0;
11746     VkSubresourceLayout layout = {};
11747 
11748     m_errorMonitor->ExpectSuccess();
11749     vkGetImageSubresourceLayout(device(), image, &subres, &layout);
11750     m_errorMonitor->VerifyNotFound();
11751 
11752     vkDestroyImage(device(), image, NULL);
11753 }
11754 
TEST_F(VkLayerTest,InvalidBufferViewObject)11755 TEST_F(VkLayerTest, InvalidBufferViewObject) {
11756     // Create a single TEXEL_BUFFER descriptor and send it an invalid bufferView
11757     // First, cause the bufferView to be invalid due to underlying buffer being destroyed
11758     // Then destroy view itself and verify that same error is hit
11759     VkResult err;
11760 
11761     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkWriteDescriptorSet-descriptorType-00323");
11762 
11763     ASSERT_NO_FATAL_FAILURE(Init());
11764     VkDescriptorPoolSize ds_type_count = {};
11765     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
11766     ds_type_count.descriptorCount = 1;
11767 
11768     VkDescriptorPoolCreateInfo ds_pool_ci = {};
11769     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
11770     ds_pool_ci.pNext = NULL;
11771     ds_pool_ci.maxSets = 1;
11772     ds_pool_ci.poolSizeCount = 1;
11773     ds_pool_ci.pPoolSizes = &ds_type_count;
11774 
11775     VkDescriptorPool ds_pool;
11776     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
11777     ASSERT_VK_SUCCESS(err);
11778 
11779     VkDescriptorSetLayoutBinding dsl_binding = {};
11780     dsl_binding.binding = 0;
11781     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
11782     dsl_binding.descriptorCount = 1;
11783     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
11784     dsl_binding.pImmutableSamplers = NULL;
11785 
11786     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
11787 
11788     VkDescriptorSet descriptorSet;
11789     VkDescriptorSetAllocateInfo alloc_info = {};
11790     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11791     alloc_info.descriptorSetCount = 1;
11792     alloc_info.descriptorPool = ds_pool;
11793     alloc_info.pSetLayouts = &ds_layout.handle();
11794     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
11795     ASSERT_VK_SUCCESS(err);
11796 
11797     // Create a valid bufferView to start with
11798     VkBuffer buffer;
11799     uint32_t queue_family_index = 0;
11800     VkBufferCreateInfo buffer_create_info = {};
11801     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
11802     buffer_create_info.size = 1024;
11803     buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
11804     buffer_create_info.queueFamilyIndexCount = 1;
11805     buffer_create_info.pQueueFamilyIndices = &queue_family_index;
11806 
11807     err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
11808     ASSERT_VK_SUCCESS(err);
11809 
11810     VkMemoryRequirements memory_reqs;
11811     VkDeviceMemory buffer_memory;
11812 
11813     VkMemoryAllocateInfo memory_info = {};
11814     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
11815     memory_info.allocationSize = 0;
11816     memory_info.memoryTypeIndex = 0;
11817 
11818     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
11819     memory_info.allocationSize = memory_reqs.size;
11820     bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
11821     ASSERT_TRUE(pass);
11822 
11823     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
11824     ASSERT_VK_SUCCESS(err);
11825     err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
11826     ASSERT_VK_SUCCESS(err);
11827 
11828     VkBufferView view;
11829     VkBufferViewCreateInfo bvci = {};
11830     bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
11831     bvci.buffer = buffer;
11832     bvci.format = VK_FORMAT_R32_SFLOAT;
11833     bvci.range = VK_WHOLE_SIZE;
11834 
11835     err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view);
11836     ASSERT_VK_SUCCESS(err);
11837 
11838     // First Destroy buffer underlying view which should hit error in CV
11839     vkDestroyBuffer(m_device->device(), buffer, NULL);
11840 
11841     VkWriteDescriptorSet descriptor_write;
11842     memset(&descriptor_write, 0, sizeof(descriptor_write));
11843     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
11844     descriptor_write.dstSet = descriptorSet;
11845     descriptor_write.dstBinding = 0;
11846     descriptor_write.descriptorCount = 1;
11847     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
11848     descriptor_write.pTexelBufferView = &view;
11849 
11850     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11851     m_errorMonitor->VerifyFound();
11852 
11853     // Now destroy view itself and verify same error, which is hit in PV this time
11854     vkDestroyBufferView(m_device->device(), view, NULL);
11855     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkWriteDescriptorSet-descriptorType-00323");
11856     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
11857     m_errorMonitor->VerifyFound();
11858 
11859     vkFreeMemory(m_device->device(), buffer_memory, NULL);
11860     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
11861 }
11862 
TEST_F(VkLayerTest,CreateBufferViewNoMemoryBoundToBuffer)11863 TEST_F(VkLayerTest, CreateBufferViewNoMemoryBoundToBuffer) {
11864     TEST_DESCRIPTION("Attempt to create a buffer view with a buffer that has no memory bound to it.");
11865 
11866     VkResult err;
11867     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
11868                                          " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
11869 
11870     ASSERT_NO_FATAL_FAILURE(Init());
11871 
11872     // Create a buffer with no bound memory and then attempt to create
11873     // a buffer view.
11874     VkBufferCreateInfo buff_ci = {};
11875     buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
11876     buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
11877     buff_ci.size = 256;
11878     buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11879     VkBuffer buffer;
11880     err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
11881     ASSERT_VK_SUCCESS(err);
11882 
11883     VkBufferViewCreateInfo buff_view_ci = {};
11884     buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
11885     buff_view_ci.buffer = buffer;
11886     buff_view_ci.format = VK_FORMAT_R8_UNORM;
11887     buff_view_ci.range = VK_WHOLE_SIZE;
11888     VkBufferView buff_view;
11889     err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buff_view);
11890 
11891     m_errorMonitor->VerifyFound();
11892     vkDestroyBuffer(m_device->device(), buffer, NULL);
11893     // If last error is success, it still created the view, so delete it.
11894     if (err == VK_SUCCESS) {
11895         vkDestroyBufferView(m_device->device(), buff_view, NULL);
11896     }
11897 }
11898 
TEST_F(VkLayerTest,InvalidBufferViewCreateInfoEntries)11899 TEST_F(VkLayerTest, InvalidBufferViewCreateInfoEntries) {
11900     TEST_DESCRIPTION("Attempt to create a buffer view with invalid create info.");
11901 
11902     ASSERT_NO_FATAL_FAILURE(Init());
11903 
11904     const VkPhysicalDeviceLimits &dev_limits = m_device->props.limits;
11905     const VkDeviceSize minTexelBufferOffsetAlignment = dev_limits.minTexelBufferOffsetAlignment;
11906     if (minTexelBufferOffsetAlignment == 1) {
11907         printf("%s Test requires minTexelOffsetAlignment to not be equal to 1. \n", kSkipPrefix);
11908         return;
11909     }
11910 
11911     const VkFormat format_with_uniform_texel_support = VK_FORMAT_R8G8B8A8_UNORM;
11912     const char *format_with_uniform_texel_support_string = "VK_FORMAT_R8G8B8A8_UNORM";
11913     const VkFormat format_without_texel_support = VK_FORMAT_R8G8B8_UNORM;
11914     const char *format_without_texel_support_string = "VK_FORMAT_R8G8B8_UNORM";
11915     VkFormatProperties format_properties;
11916     vkGetPhysicalDeviceFormatProperties(gpu(), format_with_uniform_texel_support, &format_properties);
11917     if (!(format_properties.bufferFeatures & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT)) {
11918         printf("%s Test requires %s to support VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT\n", kSkipPrefix,
11919                format_with_uniform_texel_support_string);
11920         return;
11921     }
11922     vkGetPhysicalDeviceFormatProperties(gpu(), format_without_texel_support, &format_properties);
11923     if ((format_properties.bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT) ||
11924         (format_properties.bufferFeatures & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT)) {
11925         printf(
11926             "%s Test requires %s to not support VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT nor "
11927             "VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT\n",
11928             kSkipPrefix, format_without_texel_support_string);
11929         return;
11930     }
11931 
11932     // Create a test buffer--buffer must have been created using VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT or
11933     // VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, so use a different usage value instead to cause an error
11934     const VkDeviceSize resource_size = 1024;
11935     const VkBufferCreateInfo bad_buffer_info = VkBufferObj::create_info(resource_size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
11936     VkBufferObj bad_buffer;
11937     bad_buffer.init(*m_device, bad_buffer_info, (VkMemoryPropertyFlags)VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
11938 
11939     // Create a test buffer view
11940     VkBufferViewCreateInfo buff_view_ci = {};
11941     buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
11942     buff_view_ci.buffer = bad_buffer.handle();
11943     buff_view_ci.format = format_with_uniform_texel_support;
11944     buff_view_ci.range = VK_WHOLE_SIZE;
11945 
11946     auto CatchError = [this, &buff_view_ci](const string &desired_error_string) {
11947         VkBufferView buff_view;
11948         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, desired_error_string);
11949         VkResult err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buff_view);
11950         m_errorMonitor->VerifyFound();
11951         // If previous error is success, it still created the view, so delete it
11952         if (err == VK_SUCCESS) {
11953             vkDestroyBufferView(m_device->device(), buff_view, NULL);
11954         }
11955     };
11956 
11957     CatchError("VUID-VkBufferViewCreateInfo-buffer-00932");
11958 
11959     // Create a better test buffer
11960     const VkBufferCreateInfo buffer_info = VkBufferObj::create_info(resource_size, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT);
11961     VkBufferObj buffer;
11962     buffer.init(*m_device, buffer_info, (VkMemoryPropertyFlags)VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
11963 
11964     // Offset must be less than the size of the buffer, so set it equal to the buffer size to cause an error
11965     buff_view_ci.buffer = buffer.handle();
11966     buff_view_ci.offset = buffer.create_info().size;
11967     CatchError("VUID-VkBufferViewCreateInfo-offset-00925");
11968 
11969     // Offset must be a multiple of VkPhysicalDeviceLimits::minTexelBufferOffsetAlignment so add 1 to ensure it is not
11970     buff_view_ci.offset = minTexelBufferOffsetAlignment + 1;
11971     CatchError("VUID-VkBufferViewCreateInfo-offset-00926");
11972 
11973     // Set offset to acceptable value for range tests
11974     buff_view_ci.offset = minTexelBufferOffsetAlignment;
11975     // Setting range equal to 0 will cause an error to occur
11976     buff_view_ci.range = 0;
11977     CatchError("VUID-VkBufferViewCreateInfo-range-00928");
11978 
11979     uint32_t format_size = FormatElementSize(buff_view_ci.format);
11980     // Range must be a multiple of the element size of format, so add one to ensure it is not
11981     buff_view_ci.range = format_size + 1;
11982     CatchError("VUID-VkBufferViewCreateInfo-range-00929");
11983 
11984     // Twice the element size of format multiplied by VkPhysicalDeviceLimits::maxTexelBufferElements guarantees range divided by the
11985     // element size is greater than maxTexelBufferElements, causing failure
11986     buff_view_ci.range = 2 * format_size * dev_limits.maxTexelBufferElements;
11987     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferViewCreateInfo-range-00930");
11988     CatchError("VUID-VkBufferViewCreateInfo-offset-00931");
11989 
11990     // Set rage to acceptable value for buffer tests
11991     buff_view_ci.format = format_without_texel_support;
11992     buff_view_ci.range = VK_WHOLE_SIZE;
11993 
11994     // `buffer` was created using VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT so we can use that for the first buffer test
11995     CatchError("VUID-VkBufferViewCreateInfo-buffer-00933");
11996 
11997     // Create a new buffer using VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT
11998     const VkBufferCreateInfo storage_buffer_info =
11999         VkBufferObj::create_info(resource_size, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
12000     VkBufferObj storage_buffer;
12001     storage_buffer.init(*m_device, storage_buffer_info, (VkMemoryPropertyFlags)VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
12002 
12003     buff_view_ci.buffer = storage_buffer.handle();
12004     CatchError("VUID-VkBufferViewCreateInfo-buffer-00934");
12005 }
12006 
TEST_F(VkLayerTest,InvalidDynamicOffsetCases)12007 TEST_F(VkLayerTest, InvalidDynamicOffsetCases) {
12008     // Create a descriptorSet w/ dynamic descriptor and then hit 3 offset error
12009     // cases:
12010     // 1. No dynamicOffset supplied
12011     // 2. Too many dynamicOffsets supplied
12012     // 3. Dynamic offset oversteps buffer being updated
12013     VkResult err;
12014     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12015                                          " requires 1 dynamicOffsets, but only 0 dynamicOffsets are left in pDynamicOffsets ");
12016 
12017     ASSERT_NO_FATAL_FAILURE(Init());
12018     ASSERT_NO_FATAL_FAILURE(InitViewport());
12019     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12020 
12021     VkDescriptorPoolSize ds_type_count = {};
12022     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
12023     ds_type_count.descriptorCount = 1;
12024 
12025     VkDescriptorPoolCreateInfo ds_pool_ci = {};
12026     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12027     ds_pool_ci.pNext = NULL;
12028     ds_pool_ci.maxSets = 1;
12029     ds_pool_ci.poolSizeCount = 1;
12030     ds_pool_ci.pPoolSizes = &ds_type_count;
12031 
12032     VkDescriptorPool ds_pool;
12033     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12034     ASSERT_VK_SUCCESS(err);
12035 
12036     VkDescriptorSetLayoutBinding dsl_binding = {};
12037     dsl_binding.binding = 0;
12038     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
12039     dsl_binding.descriptorCount = 1;
12040     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12041     dsl_binding.pImmutableSamplers = NULL;
12042 
12043     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
12044 
12045     VkDescriptorSet descriptorSet;
12046     VkDescriptorSetAllocateInfo alloc_info = {};
12047     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12048     alloc_info.descriptorSetCount = 1;
12049     alloc_info.descriptorPool = ds_pool;
12050     alloc_info.pSetLayouts = &ds_layout.handle();
12051     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12052     ASSERT_VK_SUCCESS(err);
12053 
12054     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout});
12055 
12056     // Create a buffer to update the descriptor with
12057     uint32_t qfi = 0;
12058     VkBufferCreateInfo buffCI = {};
12059     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
12060     buffCI.size = 1024;
12061     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
12062     buffCI.queueFamilyIndexCount = 1;
12063     buffCI.pQueueFamilyIndices = &qfi;
12064 
12065     VkBuffer dyub;
12066     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
12067     ASSERT_VK_SUCCESS(err);
12068     // Allocate memory and bind to buffer so we can make it to the appropriate error
12069     VkMemoryRequirements memReqs;
12070     vkGetBufferMemoryRequirements(m_device->device(), dyub, &memReqs);
12071     VkMemoryAllocateInfo mem_alloc = {};
12072     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
12073     mem_alloc.pNext = NULL;
12074     mem_alloc.allocationSize = memReqs.size;
12075     mem_alloc.memoryTypeIndex = 0;
12076     bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
12077     if (!pass) {
12078         printf("%s Failed to allocate memory.\n", kSkipPrefix);
12079         vkDestroyBuffer(m_device->device(), dyub, NULL);
12080         return;
12081     }
12082 
12083     VkDeviceMemory mem;
12084     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
12085     ASSERT_VK_SUCCESS(err);
12086     err = vkBindBufferMemory(m_device->device(), dyub, mem, 0);
12087     ASSERT_VK_SUCCESS(err);
12088     // Correctly update descriptor to avoid "NOT_UPDATED" error
12089     VkDescriptorBufferInfo buffInfo = {};
12090     buffInfo.buffer = dyub;
12091     buffInfo.offset = 0;
12092     buffInfo.range = 1024;
12093 
12094     VkWriteDescriptorSet descriptor_write;
12095     memset(&descriptor_write, 0, sizeof(descriptor_write));
12096     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
12097     descriptor_write.dstSet = descriptorSet;
12098     descriptor_write.dstBinding = 0;
12099     descriptor_write.descriptorCount = 1;
12100     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
12101     descriptor_write.pBufferInfo = &buffInfo;
12102 
12103     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
12104 
12105     m_commandBuffer->begin();
12106     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
12107     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
12108                             &descriptorSet, 0, NULL);
12109     m_errorMonitor->VerifyFound();
12110     uint32_t pDynOff[2] = {512, 756};
12111     // Now cause error b/c too many dynOffsets in array for # of dyn descriptors
12112     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12113                                          "Attempting to bind 1 descriptorSets with 1 dynamic descriptors, but ");
12114     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
12115                             &descriptorSet, 2, pDynOff);
12116     m_errorMonitor->VerifyFound();
12117     // Finally cause error due to dynamicOffset being too big
12118     m_errorMonitor->SetDesiredFailureMsg(
12119         VK_DEBUG_REPORT_ERROR_BIT_EXT,
12120         " dynamic offset 512 combined with offset 0 and range 1024 that oversteps the buffer size of 1024");
12121     // Create PSO to be used for draw-time errors below
12122     char const *vsSource =
12123         "#version 450\n"
12124         "\n"
12125         "void main(){\n"
12126         "   gl_Position = vec4(1);\n"
12127         "}\n";
12128     char const *fsSource =
12129         "#version 450\n"
12130         "\n"
12131         "layout(location=0) out vec4 x;\n"
12132         "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
12133         "void main(){\n"
12134         "   x = vec4(bar.y);\n"
12135         "}\n";
12136     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
12137     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
12138     VkPipelineObj pipe(m_device);
12139     pipe.AddShader(&vs);
12140     pipe.AddShader(&fs);
12141     pipe.AddDefaultColorAttachment();
12142     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
12143 
12144     VkViewport viewport = {0, 0, 16, 16, 0, 1};
12145     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
12146     VkRect2D scissor = {{0, 0}, {16, 16}};
12147     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
12148 
12149     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12150     // This update should succeed, but offset size of 512 will overstep buffer
12151     // /w range 1024 & size 1024
12152     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
12153                             &descriptorSet, 1, pDynOff);
12154     m_commandBuffer->Draw(1, 0, 0, 0);
12155     m_errorMonitor->VerifyFound();
12156 
12157     m_commandBuffer->EndRenderPass();
12158     m_commandBuffer->end();
12159 
12160     vkDestroyBuffer(m_device->device(), dyub, NULL);
12161     vkFreeMemory(m_device->device(), mem, NULL);
12162 
12163     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12164 }
12165 
TEST_F(VkLayerTest,DescriptorBufferUpdateNoMemoryBound)12166 TEST_F(VkLayerTest, DescriptorBufferUpdateNoMemoryBound) {
12167     TEST_DESCRIPTION("Attempt to update a descriptor with a non-sparse buffer that doesn't have memory bound");
12168     VkResult err;
12169     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12170                                          " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
12171     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12172                                          "vkUpdateDescriptorSets() failed write update validation for Descriptor Set 0x");
12173 
12174     ASSERT_NO_FATAL_FAILURE(Init());
12175     ASSERT_NO_FATAL_FAILURE(InitViewport());
12176     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12177 
12178     VkDescriptorPoolSize ds_type_count = {};
12179     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
12180     ds_type_count.descriptorCount = 1;
12181 
12182     VkDescriptorPoolCreateInfo ds_pool_ci = {};
12183     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12184     ds_pool_ci.pNext = NULL;
12185     ds_pool_ci.maxSets = 1;
12186     ds_pool_ci.poolSizeCount = 1;
12187     ds_pool_ci.pPoolSizes = &ds_type_count;
12188 
12189     VkDescriptorPool ds_pool;
12190     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12191     ASSERT_VK_SUCCESS(err);
12192 
12193     VkDescriptorSetLayoutBinding dsl_binding = {};
12194     dsl_binding.binding = 0;
12195     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
12196     dsl_binding.descriptorCount = 1;
12197     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12198     dsl_binding.pImmutableSamplers = NULL;
12199 
12200     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
12201 
12202     VkDescriptorSet descriptorSet;
12203     VkDescriptorSetAllocateInfo alloc_info = {};
12204     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12205     alloc_info.descriptorSetCount = 1;
12206     alloc_info.descriptorPool = ds_pool;
12207     alloc_info.pSetLayouts = &ds_layout.handle();
12208     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12209     ASSERT_VK_SUCCESS(err);
12210 
12211     // Create a buffer to update the descriptor with
12212     uint32_t qfi = 0;
12213     VkBufferCreateInfo buffCI = {};
12214     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
12215     buffCI.size = 1024;
12216     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
12217     buffCI.queueFamilyIndexCount = 1;
12218     buffCI.pQueueFamilyIndices = &qfi;
12219 
12220     VkBuffer dyub;
12221     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
12222     ASSERT_VK_SUCCESS(err);
12223 
12224     // Attempt to update descriptor without binding memory to it
12225     VkDescriptorBufferInfo buffInfo = {};
12226     buffInfo.buffer = dyub;
12227     buffInfo.offset = 0;
12228     buffInfo.range = 1024;
12229 
12230     VkWriteDescriptorSet descriptor_write;
12231     memset(&descriptor_write, 0, sizeof(descriptor_write));
12232     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
12233     descriptor_write.dstSet = descriptorSet;
12234     descriptor_write.dstBinding = 0;
12235     descriptor_write.descriptorCount = 1;
12236     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
12237     descriptor_write.pBufferInfo = &buffInfo;
12238 
12239     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
12240     m_errorMonitor->VerifyFound();
12241 
12242     vkDestroyBuffer(m_device->device(), dyub, NULL);
12243     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12244 }
12245 
TEST_F(VkLayerTest,InvalidPushConstants)12246 TEST_F(VkLayerTest, InvalidPushConstants) {
12247     ASSERT_NO_FATAL_FAILURE(Init());
12248     ASSERT_NO_FATAL_FAILURE(InitViewport());
12249     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12250 
12251     VkPipelineLayout pipeline_layout;
12252     VkPushConstantRange pc_range = {};
12253     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
12254     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
12255     pipeline_layout_ci.pushConstantRangeCount = 1;
12256     pipeline_layout_ci.pPushConstantRanges = &pc_range;
12257 
12258     //
12259     // Check for invalid push constant ranges in pipeline layouts.
12260     //
12261     struct PipelineLayoutTestCase {
12262         VkPushConstantRange const range;
12263         char const *msg;
12264     };
12265 
12266     const uint32_t too_big = m_device->props.limits.maxPushConstantsSize + 0x4;
12267     const std::array<PipelineLayoutTestCase, 10> range_tests = {{
12268         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 0}, "vkCreatePipelineLayout() call has push constants index 0 with size 0."},
12269         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 1}, "vkCreatePipelineLayout() call has push constants index 0 with size 1."},
12270         {{VK_SHADER_STAGE_VERTEX_BIT, 4, 1}, "vkCreatePipelineLayout() call has push constants index 0 with size 1."},
12271         {{VK_SHADER_STAGE_VERTEX_BIT, 4, 0}, "vkCreatePipelineLayout() call has push constants index 0 with size 0."},
12272         {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4}, "vkCreatePipelineLayout() call has push constants index 0 with offset 1. Offset must"},
12273         {{VK_SHADER_STAGE_VERTEX_BIT, 0, too_big}, "vkCreatePipelineLayout() call has push constants index 0 with offset "},
12274         {{VK_SHADER_STAGE_VERTEX_BIT, too_big, too_big}, "vkCreatePipelineLayout() call has push constants index 0 with offset "},
12275         {{VK_SHADER_STAGE_VERTEX_BIT, too_big, 4}, "vkCreatePipelineLayout() call has push constants index 0 with offset "},
12276         {{VK_SHADER_STAGE_VERTEX_BIT, 0xFFFFFFF0, 0x00000020},
12277          "vkCreatePipelineLayout() call has push constants index 0 with offset "},
12278         {{VK_SHADER_STAGE_VERTEX_BIT, 0x00000020, 0xFFFFFFF0},
12279          "vkCreatePipelineLayout() call has push constants index 0 with offset "},
12280     }};
12281 
12282     // Check for invalid offset and size
12283     for (const auto &iter : range_tests) {
12284         pc_range = iter.range;
12285         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg);
12286         vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12287         m_errorMonitor->VerifyFound();
12288     }
12289 
12290     // Check for invalid stage flag
12291     pc_range.offset = 0;
12292     pc_range.size = 16;
12293     pc_range.stageFlags = 0;
12294     m_errorMonitor->SetDesiredFailureMsg(
12295         VK_DEBUG_REPORT_ERROR_BIT_EXT,
12296         "vkCreatePipelineLayout: value of pCreateInfo->pPushConstantRanges[0].stageFlags must not be 0");
12297     vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12298     m_errorMonitor->VerifyFound();
12299 
12300     // Check for duplicate stage flags in a list of push constant ranges.
12301     // A shader can only have one push constant block and that block is mapped
12302     // to the push constant range that has that shader's stage flag set.
12303     // The shader's stage flag can only appear once in all the ranges, so the
12304     // implementation can find the one and only range to map it to.
12305     const uint32_t ranges_per_test = 5;
12306     struct DuplicateStageFlagsTestCase {
12307         VkPushConstantRange const ranges[ranges_per_test];
12308         std::vector<char const *> const msg;
12309     };
12310     // Overlapping ranges are OK, but a stage flag can appear only once.
12311     const std::array<DuplicateStageFlagsTestCase, 3> duplicate_stageFlags_tests = {
12312         {
12313             {{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
12314               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
12315               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
12316               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
12317               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
12318              {
12319                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 1.",
12320                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 2.",
12321                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 3.",
12322                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 4.",
12323                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 2.",
12324                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 3.",
12325                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 4.",
12326                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 2 and 3.",
12327                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 2 and 4.",
12328                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 3 and 4.",
12329              }},
12330             {{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
12331               {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 4},
12332               {VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4},
12333               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
12334               {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 4}},
12335              {
12336                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 3.",
12337                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 4.",
12338              }},
12339             {{{VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4},
12340               {VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0, 4},
12341               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
12342               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
12343               {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 4}},
12344              {
12345                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 2 and 3.",
12346              }},
12347         },
12348     };
12349 
12350     for (const auto &iter : duplicate_stageFlags_tests) {
12351         pipeline_layout_ci.pPushConstantRanges = iter.ranges;
12352         pipeline_layout_ci.pushConstantRangeCount = ranges_per_test;
12353         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg.begin(), iter.msg.end());
12354         vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
12355         m_errorMonitor->VerifyFound();
12356     }
12357 
12358     //
12359     // CmdPushConstants tests
12360     //
12361 
12362     // Setup a pipeline layout with ranges: [0,32) [16,80)
12363     const std::vector<VkPushConstantRange> pc_range2 = {{VK_SHADER_STAGE_VERTEX_BIT, 16, 64},
12364                                                         {VK_SHADER_STAGE_FRAGMENT_BIT, 0, 32}};
12365     const VkPipelineLayoutObj pipeline_layout_obj(m_device, {}, pc_range2);
12366 
12367     const uint8_t dummy_values[100] = {};
12368 
12369     m_commandBuffer->begin();
12370     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
12371 
12372     // Check for invalid stage flag
12373     // Note that VU 00996 isn't reached due to parameter validation
12374     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdPushConstants: value of stageFlags must not be 0");
12375     vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), 0, 0, 16, dummy_values);
12376     m_errorMonitor->VerifyFound();
12377 
12378     // Positive tests for the overlapping ranges
12379     m_errorMonitor->ExpectSuccess();
12380     vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16, dummy_values);
12381     m_errorMonitor->VerifyNotFound();
12382     m_errorMonitor->ExpectSuccess();
12383     vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_VERTEX_BIT, 32, 48, dummy_values);
12384     m_errorMonitor->VerifyNotFound();
12385     m_errorMonitor->ExpectSuccess();
12386     vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(),
12387                        VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 16, 16, dummy_values);
12388     m_errorMonitor->VerifyNotFound();
12389 
12390     // Wrong cmd stages for extant range
12391     // No range for all cmd stages -- "VUID-vkCmdPushConstants-offset-01795" VUID-vkCmdPushConstants-offset-01795
12392     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPushConstants-offset-01795");
12393     // Missing cmd stages for found overlapping range -- "VUID-vkCmdPushConstants-offset-01796" VUID-vkCmdPushConstants-offset-01796
12394     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPushConstants-offset-01796");
12395     vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_GEOMETRY_BIT, 0, 16, dummy_values);
12396     m_errorMonitor->VerifyFound();
12397 
12398     // Wrong no extant range
12399     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPushConstants-offset-01795");
12400     vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_FRAGMENT_BIT, 80, 4, dummy_values);
12401     m_errorMonitor->VerifyFound();
12402 
12403     // Wrong overlapping extent
12404     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPushConstants-offset-01795");
12405     vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(),
12406                        VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 20, dummy_values);
12407     m_errorMonitor->VerifyFound();
12408 
12409     // Wrong stage flags for valid overlapping range
12410     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPushConstants-offset-01796");
12411     vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_VERTEX_BIT, 16, 16, dummy_values);
12412     m_errorMonitor->VerifyFound();
12413 
12414     m_commandBuffer->EndRenderPass();
12415     m_commandBuffer->end();
12416 }
12417 
TEST_F(VkLayerTest,DescriptorSetCompatibility)12418 TEST_F(VkLayerTest, DescriptorSetCompatibility) {
12419     // Test various desriptorSet errors with bad binding combinations
12420     using std::vector;
12421     VkResult err;
12422 
12423     ASSERT_NO_FATAL_FAILURE(Init());
12424     ASSERT_NO_FATAL_FAILURE(InitViewport());
12425     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12426 
12427     static const uint32_t NUM_DESCRIPTOR_TYPES = 5;
12428     VkDescriptorPoolSize ds_type_count[NUM_DESCRIPTOR_TYPES] = {};
12429     ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12430     ds_type_count[0].descriptorCount = 10;
12431     ds_type_count[1].type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
12432     ds_type_count[1].descriptorCount = 2;
12433     ds_type_count[2].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
12434     ds_type_count[2].descriptorCount = 2;
12435     ds_type_count[3].type = VK_DESCRIPTOR_TYPE_SAMPLER;
12436     ds_type_count[3].descriptorCount = 5;
12437     // TODO : LunarG ILO driver currently asserts in desc.c w/ INPUT_ATTACHMENT
12438     // type
12439     // ds_type_count[4].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
12440     ds_type_count[4].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
12441     ds_type_count[4].descriptorCount = 2;
12442 
12443     VkDescriptorPoolCreateInfo ds_pool_ci = {};
12444     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12445     ds_pool_ci.pNext = NULL;
12446     ds_pool_ci.maxSets = 5;
12447     ds_pool_ci.poolSizeCount = NUM_DESCRIPTOR_TYPES;
12448     ds_pool_ci.pPoolSizes = ds_type_count;
12449 
12450     VkDescriptorPool ds_pool;
12451     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12452     ASSERT_VK_SUCCESS(err);
12453 
12454     static const uint32_t MAX_DS_TYPES_IN_LAYOUT = 2;
12455     VkDescriptorSetLayoutBinding dsl_binding[MAX_DS_TYPES_IN_LAYOUT] = {};
12456     dsl_binding[0].binding = 0;
12457     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12458     dsl_binding[0].descriptorCount = 5;
12459     dsl_binding[0].stageFlags = VK_SHADER_STAGE_ALL;
12460     dsl_binding[0].pImmutableSamplers = NULL;
12461 
12462     // Create layout identical to set0 layout but w/ different stageFlags
12463     VkDescriptorSetLayoutBinding dsl_fs_stage_only = {};
12464     dsl_fs_stage_only.binding = 0;
12465     dsl_fs_stage_only.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12466     dsl_fs_stage_only.descriptorCount = 5;
12467     dsl_fs_stage_only.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;  // Different stageFlags to cause error at
12468                                                                   // bind time
12469     dsl_fs_stage_only.pImmutableSamplers = NULL;
12470 
12471     vector<VkDescriptorSetLayoutObj> ds_layouts;
12472     // Create 4 unique layouts for full pipelineLayout, and 1 special fs-only
12473     // layout for error case
12474     ds_layouts.emplace_back(m_device, std::vector<VkDescriptorSetLayoutBinding>(1, dsl_binding[0]));
12475 
12476     const VkDescriptorSetLayoutObj ds_layout_fs_only(m_device, {dsl_fs_stage_only});
12477 
12478     dsl_binding[0].binding = 0;
12479     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
12480     dsl_binding[0].descriptorCount = 2;
12481     dsl_binding[1].binding = 1;
12482     dsl_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
12483     dsl_binding[1].descriptorCount = 2;
12484     dsl_binding[1].stageFlags = VK_SHADER_STAGE_ALL;
12485     dsl_binding[1].pImmutableSamplers = NULL;
12486     ds_layouts.emplace_back(m_device, std::vector<VkDescriptorSetLayoutBinding>({dsl_binding[0], dsl_binding[1]}));
12487 
12488     dsl_binding[0].binding = 0;
12489     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
12490     dsl_binding[0].descriptorCount = 5;
12491     ds_layouts.emplace_back(m_device, std::vector<VkDescriptorSetLayoutBinding>(1, dsl_binding[0]));
12492 
12493     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
12494     dsl_binding[0].descriptorCount = 2;
12495     ds_layouts.emplace_back(m_device, std::vector<VkDescriptorSetLayoutBinding>(1, dsl_binding[0]));
12496 
12497     const auto &ds_vk_layouts = MakeVkHandles<VkDescriptorSetLayout>(ds_layouts);
12498 
12499     static const uint32_t NUM_SETS = 4;
12500     VkDescriptorSet descriptorSet[NUM_SETS] = {};
12501     VkDescriptorSetAllocateInfo alloc_info = {};
12502     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12503     alloc_info.descriptorPool = ds_pool;
12504     alloc_info.descriptorSetCount = ds_vk_layouts.size();
12505     alloc_info.pSetLayouts = ds_vk_layouts.data();
12506     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, descriptorSet);
12507     ASSERT_VK_SUCCESS(err);
12508     VkDescriptorSet ds0_fs_only = {};
12509     alloc_info.descriptorSetCount = 1;
12510     alloc_info.pSetLayouts = &ds_layout_fs_only.handle();
12511     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &ds0_fs_only);
12512     ASSERT_VK_SUCCESS(err);
12513 
12514     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layouts[0], &ds_layouts[1]});
12515     // Create pipelineLayout with only one setLayout
12516     const VkPipelineLayoutObj single_pipe_layout(m_device, {&ds_layouts[0]});
12517     // Create pipelineLayout with 2 descriptor setLayout at index 0
12518     const VkPipelineLayoutObj pipe_layout_one_desc(m_device, {&ds_layouts[3]});
12519     // Create pipelineLayout with 5 SAMPLER descriptor setLayout at index 0
12520     const VkPipelineLayoutObj pipe_layout_five_samp(m_device, {&ds_layouts[2]});
12521     // Create pipelineLayout with UB type, but stageFlags for FS only
12522     VkPipelineLayoutObj pipe_layout_fs_only(m_device, {&ds_layout_fs_only});
12523     // Create pipelineLayout w/ incompatible set0 layout, but set1 is fine
12524     const VkPipelineLayoutObj pipe_layout_bad_set0(m_device, {&ds_layout_fs_only, &ds_layouts[1]});
12525 
12526     // Create PSO to be used for draw-time errors below
12527     char const *vsSource =
12528         "#version 450\n"
12529         "\n"
12530         "void main(){\n"
12531         "   gl_Position = vec4(1);\n"
12532         "}\n";
12533     char const *fsSource =
12534         "#version 450\n"
12535         "\n"
12536         "layout(location=0) out vec4 x;\n"
12537         "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
12538         "void main(){\n"
12539         "   x = vec4(bar.y);\n"
12540         "}\n";
12541     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
12542     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
12543     VkPipelineObj pipe(m_device);
12544     pipe.AddShader(&vs);
12545     pipe.AddShader(&fs);
12546     pipe.AddDefaultColorAttachment();
12547     pipe.CreateVKPipeline(pipe_layout_fs_only.handle(), renderPass());
12548 
12549     m_commandBuffer->begin();
12550     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
12551 
12552     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
12553     // TODO : Want to cause various binding incompatibility issues here to test
12554     // DrawState
12555     //  First cause various verify_layout_compatibility() fails
12556     //  Second disturb early and late sets and verify INFO msgs
12557     // VerifySetLayoutCompatibility fail cases:
12558     // 1. invalid VkPipelineLayout (layout) passed into vkCmdBindDescriptorSets
12559     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBindDescriptorSets-layout-parameter");
12560     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, (VkPipelineLayout)((size_t)0xbaadb1be), 0,
12561                             1, &descriptorSet[0], 0, NULL);
12562     m_errorMonitor->VerifyFound();
12563 
12564     // 2. layoutIndex exceeds # of layouts in layout
12565     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " attempting to bind set to index 1");
12566     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, single_pipe_layout.handle(), 0, 2,
12567                             &descriptorSet[0], 0, NULL);
12568     m_errorMonitor->VerifyFound();
12569 
12570     // 3. Pipeline setLayout[0] has 2 descriptors, but set being bound has 5
12571     // descriptors
12572     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has 2 descriptors, but DescriptorSetLayout ");
12573     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_one_desc.handle(), 0, 1,
12574                             &descriptorSet[0], 0, NULL);
12575     m_errorMonitor->VerifyFound();
12576 
12577     // 4. same # of descriptors but mismatch in type
12578     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is type 'VK_DESCRIPTOR_TYPE_SAMPLER' but binding ");
12579     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_five_samp.handle(), 0, 1,
12580                             &descriptorSet[0], 0, NULL);
12581     m_errorMonitor->VerifyFound();
12582 
12583     // 5. same # of descriptors but mismatch in stageFlags
12584     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12585                                          " has stageFlags 16 but binding 0 for DescriptorSetLayout ");
12586     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_fs_only.handle(), 0, 1,
12587                             &descriptorSet[0], 0, NULL);
12588     m_errorMonitor->VerifyFound();
12589 
12590     // Now that we're done actively using the pipelineLayout that gfx pipeline
12591     //  was created with, we should be able to delete it. Do that now to verify
12592     //  that validation obeys pipelineLayout lifetime
12593     pipe_layout_fs_only.Reset();
12594 
12595     // Cause draw-time errors due to PSO incompatibilities
12596     // 1. Error due to not binding required set (we actually use same code as
12597     // above to disturb set0)
12598     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 2,
12599                             &descriptorSet[0], 0, NULL);
12600     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_bad_set0.handle(), 1, 1,
12601                             &descriptorSet[1], 0, NULL);
12602     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " uses set #0 but that set is not bound.");
12603 
12604     VkViewport viewport = {0, 0, 16, 16, 0, 1};
12605     VkRect2D scissor = {{0, 0}, {16, 16}};
12606     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
12607     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
12608 
12609     m_commandBuffer->Draw(1, 0, 0, 0);
12610     m_errorMonitor->VerifyFound();
12611 
12612     // 2. Error due to bound set not being compatible with PSO's
12613     // VkPipelineLayout (diff stageFlags in this case)
12614     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 2,
12615                             &descriptorSet[0], 0, NULL);
12616     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " bound as set #0 is not compatible with ");
12617     m_commandBuffer->Draw(1, 0, 0, 0);
12618     m_errorMonitor->VerifyFound();
12619 
12620     // Remaining clean-up
12621     m_commandBuffer->EndRenderPass();
12622     m_commandBuffer->end();
12623 
12624     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12625 }
12626 
TEST_F(VkLayerTest,NoBeginCommandBuffer)12627 TEST_F(VkLayerTest, NoBeginCommandBuffer) {
12628     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12629                                          "You must call vkBeginCommandBuffer() before this call to ");
12630 
12631     ASSERT_NO_FATAL_FAILURE(Init());
12632     VkCommandBufferObj commandBuffer(m_device, m_commandPool);
12633     // Call EndCommandBuffer() w/o calling BeginCommandBuffer()
12634     vkEndCommandBuffer(commandBuffer.handle());
12635 
12636     m_errorMonitor->VerifyFound();
12637 }
12638 
TEST_F(VkLayerTest,SecondaryCommandBufferNullRenderpass)12639 TEST_F(VkLayerTest, SecondaryCommandBufferNullRenderpass) {
12640     ASSERT_NO_FATAL_FAILURE(Init());
12641 
12642     VkCommandBufferObj cb(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
12643 
12644     // Force the failure by not setting the Renderpass and Framebuffer fields
12645     VkCommandBufferInheritanceInfo cmd_buf_hinfo = {};
12646     cmd_buf_hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
12647 
12648     VkCommandBufferBeginInfo cmd_buf_info = {};
12649     cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
12650     cmd_buf_info.pNext = NULL;
12651     cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
12652     cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
12653 
12654     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkCommandBufferBeginInfo-flags-00053");
12655     vkBeginCommandBuffer(cb.handle(), &cmd_buf_info);
12656     m_errorMonitor->VerifyFound();
12657 }
12658 
TEST_F(VkLayerTest,SecondaryCommandBufferRerecordedExplicitReset)12659 TEST_F(VkLayerTest, SecondaryCommandBufferRerecordedExplicitReset) {
12660     ASSERT_NO_FATAL_FAILURE(Init());
12661 
12662     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was destroyed or rerecorded");
12663 
12664     // A pool we can reset in.
12665     VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
12666     VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
12667 
12668     secondary.begin();
12669     secondary.end();
12670 
12671     m_commandBuffer->begin();
12672     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
12673 
12674     // rerecording of secondary
12675     secondary.reset();  // explicit reset here.
12676     secondary.begin();
12677     secondary.end();
12678 
12679     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
12680     m_errorMonitor->VerifyFound();
12681 }
12682 
TEST_F(VkLayerTest,SecondaryCommandBufferRerecordedNoReset)12683 TEST_F(VkLayerTest, SecondaryCommandBufferRerecordedNoReset) {
12684     ASSERT_NO_FATAL_FAILURE(Init());
12685 
12686     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was destroyed or rerecorded");
12687 
12688     // A pool we can reset in.
12689     VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
12690     VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
12691 
12692     secondary.begin();
12693     secondary.end();
12694 
12695     m_commandBuffer->begin();
12696     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
12697 
12698     // rerecording of secondary
12699     secondary.begin();  // implicit reset in begin
12700     secondary.end();
12701 
12702     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
12703     m_errorMonitor->VerifyFound();
12704 }
12705 
TEST_F(VkLayerTest,CascadedInvalidation)12706 TEST_F(VkLayerTest, CascadedInvalidation) {
12707     ASSERT_NO_FATAL_FAILURE(Init());
12708 
12709     VkEventCreateInfo eci = {VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, nullptr, 0};
12710     VkEvent event;
12711     vkCreateEvent(m_device->device(), &eci, nullptr, &event);
12712 
12713     VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
12714     secondary.begin();
12715     vkCmdSetEvent(secondary.handle(), event, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
12716     secondary.end();
12717 
12718     m_commandBuffer->begin();
12719     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
12720     m_commandBuffer->end();
12721 
12722     // destroying the event should invalidate both primary and secondary CB
12723     vkDestroyEvent(m_device->device(), event, nullptr);
12724 
12725     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "invalid because bound Event");
12726     m_commandBuffer->QueueCommandBuffer(false);
12727     m_errorMonitor->VerifyFound();
12728 }
12729 
TEST_F(VkLayerTest,CommandBufferResetErrors)12730 TEST_F(VkLayerTest, CommandBufferResetErrors) {
12731     // Cause error due to Begin while recording CB
12732     // Then cause 2 errors for attempting to reset CB w/o having
12733     // VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT set for the pool from
12734     // which CBs were allocated. Note that this bit is off by default.
12735     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot call Begin on command buffer");
12736 
12737     ASSERT_NO_FATAL_FAILURE(Init());
12738 
12739     // Calls AllocateCommandBuffers
12740     VkCommandBufferObj commandBuffer(m_device, m_commandPool);
12741 
12742     // Force the failure by setting the Renderpass and Framebuffer fields with (fake) data
12743     VkCommandBufferInheritanceInfo cmd_buf_hinfo = {};
12744     cmd_buf_hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
12745     VkCommandBufferBeginInfo cmd_buf_info = {};
12746     cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
12747     cmd_buf_info.pNext = NULL;
12748     cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
12749     cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
12750 
12751     // Begin CB to transition to recording state
12752     vkBeginCommandBuffer(commandBuffer.handle(), &cmd_buf_info);
12753     // Can't re-begin. This should trigger error
12754     vkBeginCommandBuffer(commandBuffer.handle(), &cmd_buf_info);
12755     m_errorMonitor->VerifyFound();
12756 
12757     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkResetCommandBuffer-commandBuffer-00046");
12758     VkCommandBufferResetFlags flags = 0;  // Don't care about flags for this test
12759     // Reset attempt will trigger error due to incorrect CommandPool state
12760     vkResetCommandBuffer(commandBuffer.handle(), flags);
12761     m_errorMonitor->VerifyFound();
12762 
12763     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkBeginCommandBuffer-commandBuffer-00050");
12764     // Transition CB to RECORDED state
12765     vkEndCommandBuffer(commandBuffer.handle());
12766     // Now attempting to Begin will implicitly reset, which triggers error
12767     vkBeginCommandBuffer(commandBuffer.handle(), &cmd_buf_info);
12768     m_errorMonitor->VerifyFound();
12769 }
12770 
TEST_F(VkLayerTest,InvalidPipelineCreateState)12771 TEST_F(VkLayerTest, InvalidPipelineCreateState) {
12772     // Attempt to Create Gfx Pipeline w/o a VS
12773     VkResult err;
12774 
12775     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
12776                                          "Invalid Pipeline CreateInfo State: Vertex Shader required");
12777 
12778     ASSERT_NO_FATAL_FAILURE(Init());
12779     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12780 
12781     VkDescriptorPoolSize ds_type_count = {};
12782     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12783     ds_type_count.descriptorCount = 1;
12784 
12785     VkDescriptorPoolCreateInfo ds_pool_ci = {};
12786     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
12787     ds_pool_ci.pNext = NULL;
12788     ds_pool_ci.maxSets = 1;
12789     ds_pool_ci.poolSizeCount = 1;
12790     ds_pool_ci.pPoolSizes = &ds_type_count;
12791 
12792     VkDescriptorPool ds_pool;
12793     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
12794     ASSERT_VK_SUCCESS(err);
12795 
12796     VkDescriptorSetLayoutBinding dsl_binding = {};
12797     dsl_binding.binding = 0;
12798     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
12799     dsl_binding.descriptorCount = 1;
12800     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
12801     dsl_binding.pImmutableSamplers = NULL;
12802 
12803     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
12804 
12805     VkDescriptorSet descriptorSet;
12806     VkDescriptorSetAllocateInfo alloc_info = {};
12807     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
12808     alloc_info.descriptorSetCount = 1;
12809     alloc_info.descriptorPool = ds_pool;
12810     alloc_info.pSetLayouts = &ds_layout.handle();
12811     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
12812     ASSERT_VK_SUCCESS(err);
12813 
12814     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout});
12815 
12816     VkPipelineRasterizationStateCreateInfo rs_state_ci = {};
12817     rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
12818     rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL;
12819     rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT;
12820     rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
12821     rs_state_ci.depthClampEnable = VK_FALSE;
12822     rs_state_ci.rasterizerDiscardEnable = VK_TRUE;
12823     rs_state_ci.depthBiasEnable = VK_FALSE;
12824     rs_state_ci.lineWidth = 1.0f;
12825 
12826     VkPipelineVertexInputStateCreateInfo vi_ci = {};
12827     vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
12828     vi_ci.pNext = nullptr;
12829     vi_ci.vertexBindingDescriptionCount = 0;
12830     vi_ci.pVertexBindingDescriptions = nullptr;
12831     vi_ci.vertexAttributeDescriptionCount = 0;
12832     vi_ci.pVertexAttributeDescriptions = nullptr;
12833 
12834     VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
12835     ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
12836     ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
12837 
12838     VkPipelineShaderStageCreateInfo shaderStages[2];
12839     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
12840 
12841     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
12842     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
12843     shaderStages[0] = fs.GetStageCreateInfo();  // should be: vs.GetStageCreateInfo();
12844     shaderStages[1] = fs.GetStageCreateInfo();
12845 
12846     VkGraphicsPipelineCreateInfo gp_ci = {};
12847     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
12848     gp_ci.pViewportState = nullptr;  // no viewport b/c rasterizer is disabled
12849     gp_ci.pRasterizationState = &rs_state_ci;
12850     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
12851     gp_ci.layout = pipeline_layout.handle();
12852     gp_ci.renderPass = renderPass();
12853     gp_ci.pVertexInputState = &vi_ci;
12854     gp_ci.pInputAssemblyState = &ia_ci;
12855 
12856     gp_ci.stageCount = 1;
12857     gp_ci.pStages = shaderStages;
12858 
12859     VkPipelineCacheCreateInfo pc_ci = {};
12860     pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
12861     pc_ci.initialDataSize = 0;
12862     pc_ci.pInitialData = 0;
12863 
12864     VkPipeline pipeline;
12865     VkPipelineCache pipelineCache;
12866 
12867     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
12868     ASSERT_VK_SUCCESS(err);
12869     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
12870     m_errorMonitor->VerifyFound();
12871 
12872     // Finally, check the string validation for the shader stage pName variable.  Correct the shader stage data, and bork the
12873     // string before calling again
12874     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "contains invalid characters or is badly formed");
12875     shaderStages[0] = vs.GetStageCreateInfo();
12876     const uint8_t cont_char = 0xf8;
12877     char bad_string[] = {static_cast<char>(cont_char), static_cast<char>(cont_char), static_cast<char>(cont_char),
12878                          static_cast<char>(cont_char)};
12879     shaderStages[0].pName = bad_string;
12880     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline);
12881     m_errorMonitor->VerifyFound();
12882 
12883     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
12884     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
12885 }
12886 
TEST_F(VkLayerTest,InvalidPipelineSampleRateFeatureDisable)12887 TEST_F(VkLayerTest, InvalidPipelineSampleRateFeatureDisable) {
12888     // Enable sample shading in pipeline when the feature is disabled.
12889     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
12890 
12891     // Disable sampleRateShading here
12892     VkPhysicalDeviceFeatures device_features = {};
12893     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
12894     device_features.sampleRateShading = VK_FALSE;
12895 
12896     ASSERT_NO_FATAL_FAILURE(InitState(&device_features));
12897     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12898 
12899     // Cause the error by enabling sample shading...
12900     auto set_shading_enable = [](CreatePipelineHelper &helper) { helper.pipe_ms_state_ci_.sampleShadingEnable = VK_TRUE; };
12901     CreatePipelineHelper::OneshotTest(*this, set_shading_enable, VK_DEBUG_REPORT_ERROR_BIT_EXT,
12902                                       "VUID-VkPipelineMultisampleStateCreateInfo-sampleShadingEnable-00784");
12903 }
12904 
TEST_F(VkLayerTest,InvalidPipelineSampleRateFeatureEnable)12905 TEST_F(VkLayerTest, InvalidPipelineSampleRateFeatureEnable) {
12906     // Enable sample shading in pipeline when the feature is disabled.
12907     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
12908 
12909     // Require sampleRateShading here
12910     VkPhysicalDeviceFeatures device_features = {};
12911     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
12912     if (device_features.sampleRateShading == VK_FALSE) {
12913         printf("%s SampleRateShading feature is disabled -- skipping related checks.\n", kSkipPrefix);
12914         return;
12915     }
12916 
12917     ASSERT_NO_FATAL_FAILURE(InitState(&device_features));
12918     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12919 
12920     auto range_test = [this](float value, bool positive_test) {
12921         auto info_override = [value](CreatePipelineHelper &helper) {
12922             helper.pipe_ms_state_ci_.sampleShadingEnable = VK_TRUE;
12923             helper.pipe_ms_state_ci_.minSampleShading = value;
12924         };
12925         CreatePipelineHelper::OneshotTest(*this, info_override, VK_DEBUG_REPORT_ERROR_BIT_EXT,
12926                                           "VUID-VkPipelineMultisampleStateCreateInfo-minSampleShading-00786", positive_test);
12927     };
12928 
12929     range_test(NearestSmaller(0.0F), false);
12930     range_test(NearestGreater(1.0F), false);
12931     range_test(0.0F, /* positive_test= */ true);
12932     range_test(1.0F, /* positive_test= */ true);
12933 }
12934 
TEST_F(VkLayerTest,InvalidPipelineSamplePNext)12935 TEST_F(VkLayerTest, InvalidPipelineSamplePNext) {
12936     // Enable sample shading in pipeline when the feature is disabled.
12937     // Check for VK_KHR_get_physical_device_properties2
12938     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
12939         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12940     }
12941     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
12942 
12943     // Set up the extension structs
12944     auto sampleLocations = chain_util::Init<VkPipelineSampleLocationsStateCreateInfoEXT>();
12945     sampleLocations.sampleLocationsInfo.sType = VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT;
12946     auto coverageToColor = chain_util::Init<VkPipelineCoverageToColorStateCreateInfoNV>();
12947     auto coverageModulation = chain_util::Init<VkPipelineCoverageModulationStateCreateInfoNV>();
12948     auto discriminatrix = [this](const char *name) { return DeviceExtensionSupported(gpu(), nullptr, name); };
12949     chain_util::ExtensionChain chain(discriminatrix, &m_device_extension_names);
12950     chain.Add(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME, sampleLocations);
12951     chain.Add(VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME, coverageToColor);
12952     chain.Add(VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME, coverageModulation);
12953     const void *extension_head = chain.Head();
12954 
12955     ASSERT_NO_FATAL_FAILURE(InitState());
12956     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12957 
12958     if (extension_head) {
12959         auto good_chain = [extension_head](CreatePipelineHelper &helper) { helper.pipe_ms_state_ci_.pNext = extension_head; };
12960         CreatePipelineHelper::OneshotTest(*this, good_chain, (VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT),
12961                                           "No error", true);
12962     } else {
12963         printf("%s Required extension not present -- skipping positive checks.\n", kSkipPrefix);
12964     }
12965 
12966     auto instance_ci = chain_util::Init<VkInstanceCreateInfo>();
12967     auto bad_chain = [&instance_ci](CreatePipelineHelper &helper) { helper.pipe_ms_state_ci_.pNext = &instance_ci; };
12968     CreatePipelineHelper::OneshotTest(*this, bad_chain, VK_DEBUG_REPORT_WARNING_BIT_EXT,
12969                                       "VUID-VkPipelineMultisampleStateCreateInfo-pNext-pNext");
12970 }
12971 
TEST_F(VkLayerTest,VertexAttributeDivisorExtension)12972 TEST_F(VkLayerTest, VertexAttributeDivisorExtension) {
12973     TEST_DESCRIPTION("Test VUIDs added with VK_EXT_vertex_attribute_divisor extension.");
12974 
12975     bool inst_ext = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12976     if (inst_ext) {
12977         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12978         ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
12979     }
12980     if (inst_ext && DeviceExtensionSupported(gpu(), nullptr, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME)) {
12981         m_device_extension_names.push_back(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME);
12982     } else {
12983         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME);
12984         return;
12985     }
12986 
12987     VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vadf = {};
12988     vadf.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
12989     vadf.vertexAttributeInstanceRateDivisor = VK_TRUE;
12990     vadf.vertexAttributeInstanceRateZeroDivisor = VK_TRUE;
12991 
12992     VkPhysicalDeviceFeatures2 pd_features2 = {};
12993     pd_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
12994     pd_features2.pNext = &vadf;
12995 
12996     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features2));
12997     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12998 
12999     const VkPhysicalDeviceLimits &dev_limits = m_device->props.limits;
13000     VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT pdvad_props = {};
13001     pdvad_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT;
13002     VkPhysicalDeviceProperties2 pd_props2 = {};
13003     pd_props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
13004     pd_props2.pNext = &pdvad_props;
13005     vkGetPhysicalDeviceProperties2(gpu(), &pd_props2);
13006 
13007     VkVertexInputBindingDivisorDescriptionEXT vibdd = {};
13008     VkPipelineVertexInputDivisorStateCreateInfoEXT pvids_ci = {};
13009     pvids_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
13010     pvids_ci.vertexBindingDivisorCount = 1;
13011     pvids_ci.pVertexBindingDivisors = &vibdd;
13012     VkVertexInputBindingDescription vibd = {};
13013     vibd.stride = 12;
13014     vibd.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
13015 
13016     using std::vector;
13017     struct TestCase {
13018         uint32_t div_binding;
13019         uint32_t div_divisor;
13020         uint32_t desc_binding;
13021         VkVertexInputRate desc_rate;
13022         vector<std::string> vuids;
13023     };
13024 
13025     // clang-format off
13026     vector<TestCase> test_cases = {
13027         {   0,
13028             1,
13029             0,
13030             VK_VERTEX_INPUT_RATE_VERTEX,
13031             {"VUID-VkVertexInputBindingDivisorDescriptionEXT-inputRate-01871"}
13032         },
13033         {   dev_limits.maxVertexInputBindings + 1,
13034             1,
13035             0,
13036             VK_VERTEX_INPUT_RATE_INSTANCE,
13037             {"VUID-VkVertexInputBindingDivisorDescriptionEXT-binding-01869",
13038              "VUID-VkVertexInputBindingDivisorDescriptionEXT-inputRate-01871"}
13039         }
13040     };
13041 
13042     if (UINT32_MAX != pdvad_props.maxVertexAttribDivisor) {  // Can't test overflow if maxVAD is UINT32_MAX
13043         test_cases.push_back(
13044             {   0,
13045                 pdvad_props.maxVertexAttribDivisor + 1,
13046                 0,
13047                 VK_VERTEX_INPUT_RATE_INSTANCE,
13048                 {"VUID-VkVertexInputBindingDivisorDescriptionEXT-divisor-01870"}
13049             } );
13050     }
13051     // clang-format on
13052 
13053     for (const auto &test_case : test_cases) {
13054         const auto bad_divisor_state = [&test_case, &vibdd, &pvids_ci, &vibd](CreatePipelineHelper &helper) {
13055             vibdd.binding = test_case.div_binding;
13056             vibdd.divisor = test_case.div_divisor;
13057             vibd.binding = test_case.desc_binding;
13058             vibd.inputRate = test_case.desc_rate;
13059             helper.vi_ci_.pNext = &pvids_ci;
13060             helper.vi_ci_.vertexBindingDescriptionCount = 1;
13061             helper.vi_ci_.pVertexBindingDescriptions = &vibd;
13062         };
13063         CreatePipelineHelper::OneshotTest(*this, bad_divisor_state, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids);
13064     }
13065 }
13066 
TEST_F(VkLayerTest,VertexAttributeDivisorDisabled)13067 TEST_F(VkLayerTest, VertexAttributeDivisorDisabled) {
13068     TEST_DESCRIPTION("Test instance divisor feature disabled for VK_EXT_vertex_attribute_divisor extension.");
13069 
13070     bool inst_ext = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
13071     if (inst_ext) {
13072         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
13073         ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
13074     }
13075     if (inst_ext && DeviceExtensionSupported(gpu(), nullptr, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME)) {
13076         m_device_extension_names.push_back(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME);
13077     } else {
13078         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME);
13079         return;
13080     }
13081 
13082     VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vadf = {};
13083     vadf.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
13084     vadf.vertexAttributeInstanceRateDivisor = VK_FALSE;
13085     vadf.vertexAttributeInstanceRateZeroDivisor = VK_FALSE;
13086     VkPhysicalDeviceFeatures2 pd_features2 = {};
13087     pd_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
13088     pd_features2.pNext = &vadf;
13089 
13090     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features2));
13091     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13092 
13093     VkVertexInputBindingDivisorDescriptionEXT vibdd = {};
13094     vibdd.binding = 0;
13095     vibdd.divisor = 2;
13096     VkPipelineVertexInputDivisorStateCreateInfoEXT pvids_ci = {};
13097     pvids_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
13098     pvids_ci.vertexBindingDivisorCount = 1;
13099     pvids_ci.pVertexBindingDivisors = &vibdd;
13100     VkVertexInputBindingDescription vibd = {};
13101     vibd.binding = vibdd.binding;
13102     vibd.stride = 12;
13103     vibd.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;
13104 
13105     const auto instance_rate = [&pvids_ci, &vibd](CreatePipelineHelper &helper) {
13106         helper.vi_ci_.pNext = &pvids_ci;
13107         helper.vi_ci_.vertexBindingDescriptionCount = 1;
13108         helper.vi_ci_.pVertexBindingDescriptions = &vibd;
13109     };
13110     CreatePipelineHelper::OneshotTest(*this, instance_rate, VK_DEBUG_REPORT_ERROR_BIT_EXT,
13111                                       "VUID-VkVertexInputBindingDivisorDescriptionEXT-vertexAttributeInstanceRateDivisor-02229");
13112 }
13113 
TEST_F(VkLayerTest,VertexAttributeDivisorInstanceRateZero)13114 TEST_F(VkLayerTest, VertexAttributeDivisorInstanceRateZero) {
13115     TEST_DESCRIPTION("Test instanceRateZero feature of VK_EXT_vertex_attribute_divisor extension.");
13116 
13117     bool inst_ext = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
13118     if (inst_ext) {
13119         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
13120         ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
13121     }
13122     if (inst_ext && DeviceExtensionSupported(gpu(), nullptr, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME)) {
13123         m_device_extension_names.push_back(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME);
13124     } else {
13125         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME);
13126         return;
13127     }
13128 
13129     VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vadf = {};
13130     vadf.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
13131     vadf.vertexAttributeInstanceRateDivisor = VK_TRUE;
13132     vadf.vertexAttributeInstanceRateZeroDivisor = VK_FALSE;
13133     VkPhysicalDeviceFeatures2 pd_features2 = {};
13134     pd_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
13135     pd_features2.pNext = &vadf;
13136 
13137     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features2));
13138     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13139 
13140     VkVertexInputBindingDivisorDescriptionEXT vibdd = {};
13141     vibdd.binding = 0;
13142     vibdd.divisor = 0;
13143     VkPipelineVertexInputDivisorStateCreateInfoEXT pvids_ci = {};
13144     pvids_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
13145     pvids_ci.vertexBindingDivisorCount = 1;
13146     pvids_ci.pVertexBindingDivisors = &vibdd;
13147     VkVertexInputBindingDescription vibd = {};
13148     vibd.binding = vibdd.binding;
13149     vibd.stride = 12;
13150     vibd.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;
13151 
13152     const auto instance_rate = [&pvids_ci, &vibd](CreatePipelineHelper &helper) {
13153         helper.vi_ci_.pNext = &pvids_ci;
13154         helper.vi_ci_.vertexBindingDescriptionCount = 1;
13155         helper.vi_ci_.pVertexBindingDescriptions = &vibd;
13156     };
13157     CreatePipelineHelper::OneshotTest(
13158         *this, instance_rate, VK_DEBUG_REPORT_ERROR_BIT_EXT,
13159         "VUID-VkVertexInputBindingDivisorDescriptionEXT-vertexAttributeInstanceRateZeroDivisor-02228");
13160 }
13161 
13162 /*// TODO : This test should be good, but needs Tess support in compiler to run
13163 TEST_F(VkLayerTest, InvalidPatchControlPoints)
13164 {
13165     // Attempt to Create Gfx Pipeline w/o a VS
13166     VkResult        err;
13167 
13168     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
13169         "Invalid Pipeline CreateInfo State: VK_PRIMITIVE_TOPOLOGY_PATCH
13170 primitive ");
13171 
13172     ASSERT_NO_FATAL_FAILURE(Init());
13173     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13174 
13175     VkDescriptorPoolSize ds_type_count = {};
13176         ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
13177         ds_type_count.descriptorCount = 1;
13178 
13179     VkDescriptorPoolCreateInfo ds_pool_ci = {};
13180         ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
13181         ds_pool_ci.pNext = NULL;
13182         ds_pool_ci.poolSizeCount = 1;
13183         ds_pool_ci.pPoolSizes = &ds_type_count;
13184 
13185     VkDescriptorPool ds_pool;
13186     err = vkCreateDescriptorPool(m_device->device(),
13187 VK_DESCRIPTOR_POOL_USAGE_NON_FREE, 1, &ds_pool_ci, NULL, &ds_pool);
13188     ASSERT_VK_SUCCESS(err);
13189 
13190     VkDescriptorSetLayoutBinding dsl_binding = {};
13191         dsl_binding.binding = 0;
13192         dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
13193         dsl_binding.descriptorCount = 1;
13194         dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
13195         dsl_binding.pImmutableSamplers = NULL;
13196 
13197     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
13198         ds_layout_ci.sType =
13199 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
13200         ds_layout_ci.pNext = NULL;
13201         ds_layout_ci.bindingCount = 1;
13202         ds_layout_ci.pBindings = &dsl_binding;
13203 
13204     VkDescriptorSetLayout ds_layout;
13205     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL,
13206 &ds_layout);
13207     ASSERT_VK_SUCCESS(err);
13208 
13209     VkDescriptorSet descriptorSet;
13210     err = vkAllocateDescriptorSets(m_device->device(), ds_pool,
13211 VK_DESCRIPTOR_SET_USAGE_NON_FREE, 1, &ds_layout, &descriptorSet);
13212     ASSERT_VK_SUCCESS(err);
13213 
13214     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
13215         pipeline_layout_ci.sType =
13216 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
13217         pipeline_layout_ci.pNext = NULL;
13218         pipeline_layout_ci.setLayoutCount = 1;
13219         pipeline_layout_ci.pSetLayouts = &ds_layout;
13220 
13221     VkPipelineLayout pipeline_layout;
13222     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL,
13223 &pipeline_layout);
13224     ASSERT_VK_SUCCESS(err);
13225 
13226     VkPipelineShaderStageCreateInfo shaderStages[3];
13227     memset(&shaderStages, 0, 3 * sizeof(VkPipelineShaderStageCreateInfo));
13228 
13229     VkShaderObj vs(m_device,bindStateVertShaderText,VK_SHADER_STAGE_VERTEX_BIT,
13230 this);
13231     // Just using VS txt for Tess shaders as we don't care about functionality
13232     VkShaderObj
13233 tc(m_device,bindStateVertShaderText,VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
13234 this);
13235     VkShaderObj
13236 te(m_device,bindStateVertShaderText,VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
13237 this);
13238 
13239     shaderStages[0].sType  =
13240 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
13241     shaderStages[0].stage  = VK_SHADER_STAGE_VERTEX_BIT;
13242     shaderStages[0].shader = vs.handle();
13243     shaderStages[1].sType  =
13244 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
13245     shaderStages[1].stage  = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
13246     shaderStages[1].shader = tc.handle();
13247     shaderStages[2].sType  =
13248 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
13249     shaderStages[2].stage  = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
13250     shaderStages[2].shader = te.handle();
13251 
13252     VkPipelineInputAssemblyStateCreateInfo iaCI = {};
13253         iaCI.sType =
13254 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
13255         iaCI.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
13256 
13257     VkPipelineTessellationStateCreateInfo tsCI = {};
13258         tsCI.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
13259         tsCI.patchControlPoints = 0; // This will cause an error
13260 
13261     VkGraphicsPipelineCreateInfo gp_ci = {};
13262         gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
13263         gp_ci.pNext = NULL;
13264         gp_ci.stageCount = 3;
13265         gp_ci.pStages = shaderStages;
13266         gp_ci.pVertexInputState = NULL;
13267         gp_ci.pInputAssemblyState = &iaCI;
13268         gp_ci.pTessellationState = &tsCI;
13269         gp_ci.pViewportState = NULL;
13270         gp_ci.pRasterizationState = NULL;
13271         gp_ci.pMultisampleState = NULL;
13272         gp_ci.pDepthStencilState = NULL;
13273         gp_ci.pColorBlendState = NULL;
13274         gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
13275         gp_ci.layout = pipeline_layout;
13276         gp_ci.renderPass = renderPass();
13277 
13278     VkPipelineCacheCreateInfo pc_ci = {};
13279         pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
13280         pc_ci.pNext = NULL;
13281         pc_ci.initialSize = 0;
13282         pc_ci.initialData = 0;
13283         pc_ci.maxSize = 0;
13284 
13285     VkPipeline pipeline;
13286     VkPipelineCache pipelineCache;
13287 
13288     err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL,
13289 &pipelineCache);
13290     ASSERT_VK_SUCCESS(err);
13291     err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1,
13292 &gp_ci, NULL, &pipeline);
13293 
13294     m_errorMonitor->VerifyFound();
13295 
13296     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
13297     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
13298     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
13299     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
13300 }
13301 */
13302 
TEST_F(VkLayerTest,PSOViewportStateTests)13303 TEST_F(VkLayerTest, PSOViewportStateTests) {
13304     TEST_DESCRIPTION("Test VkPipelineViewportStateCreateInfo viewport and scissor count validation for non-multiViewport");
13305 
13306     VkPhysicalDeviceFeatures features{};
13307     ASSERT_NO_FATAL_FAILURE(Init(&features));
13308     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13309 
13310     const auto break_vp_state = [](CreatePipelineHelper &helper) {
13311         helper.rs_state_ci_.rasterizerDiscardEnable = VK_FALSE;
13312         helper.gp_ci_.pViewportState = nullptr;
13313     };
13314     CreatePipelineHelper::OneshotTest(*this, break_vp_state, VK_DEBUG_REPORT_ERROR_BIT_EXT,
13315                                       "VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00750");
13316 
13317     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
13318     VkViewport viewports[] = {viewport, viewport};
13319     VkRect2D scissor = {{0, 0}, {64, 64}};
13320     VkRect2D scissors[] = {scissor, scissor};
13321 
13322     // test viewport and scissor arrays
13323     using std::vector;
13324     struct TestCase {
13325         uint32_t viewport_count;
13326         VkViewport *viewports;
13327         uint32_t scissor_count;
13328         VkRect2D *scissors;
13329 
13330         vector<std::string> vuids;
13331     };
13332 
13333     vector<TestCase> test_cases = {
13334         {0,
13335          viewports,
13336          1,
13337          scissors,
13338          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
13339           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
13340         {2,
13341          viewports,
13342          1,
13343          scissors,
13344          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
13345           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
13346         {1,
13347          viewports,
13348          0,
13349          scissors,
13350          {"VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
13351           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
13352         {1,
13353          viewports,
13354          2,
13355          scissors,
13356          {"VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
13357           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
13358         {0,
13359          viewports,
13360          0,
13361          scissors,
13362          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
13363           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217"}},
13364         {2,
13365          viewports,
13366          2,
13367          scissors,
13368          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
13369           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217"}},
13370         {0,
13371          viewports,
13372          2,
13373          scissors,
13374          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216", "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
13375           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
13376         {2,
13377          viewports,
13378          0,
13379          scissors,
13380          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216", "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
13381           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
13382         {1, nullptr, 1, scissors, {"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00747"}},
13383         {1, viewports, 1, nullptr, {"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00748"}},
13384         {1,
13385          nullptr,
13386          1,
13387          nullptr,
13388          {"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00747", "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00748"}},
13389         {2,
13390          nullptr,
13391          3,
13392          nullptr,
13393          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216", "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
13394           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220", "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00747",
13395           "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00748"}},
13396         {0,
13397          nullptr,
13398          0,
13399          nullptr,
13400          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
13401           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217"}},
13402     };
13403 
13404     for (const auto &test_case : test_cases) {
13405         const auto break_vp = [&test_case](CreatePipelineHelper &helper) {
13406             helper.vp_state_ci_.viewportCount = test_case.viewport_count;
13407             helper.vp_state_ci_.pViewports = test_case.viewports;
13408             helper.vp_state_ci_.scissorCount = test_case.scissor_count;
13409             helper.vp_state_ci_.pScissors = test_case.scissors;
13410         };
13411         CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids);
13412     }
13413 
13414     vector<TestCase> dyn_test_cases = {
13415         {0,
13416          viewports,
13417          1,
13418          scissors,
13419          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
13420           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
13421         {2,
13422          viewports,
13423          1,
13424          scissors,
13425          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
13426           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
13427         {1,
13428          viewports,
13429          0,
13430          scissors,
13431          {"VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
13432           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
13433         {1,
13434          viewports,
13435          2,
13436          scissors,
13437          {"VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
13438           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
13439         {0,
13440          viewports,
13441          0,
13442          scissors,
13443          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
13444           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217"}},
13445         {2,
13446          viewports,
13447          2,
13448          scissors,
13449          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
13450           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217"}},
13451         {0,
13452          viewports,
13453          2,
13454          scissors,
13455          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216", "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
13456           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
13457         {2,
13458          viewports,
13459          0,
13460          scissors,
13461          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216", "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
13462           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
13463         {2,
13464          nullptr,
13465          3,
13466          nullptr,
13467          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216", "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
13468           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
13469         {0,
13470          nullptr,
13471          0,
13472          nullptr,
13473          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
13474           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217"}},
13475     };
13476 
13477     const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
13478 
13479     for (const auto &test_case : dyn_test_cases) {
13480         const auto break_vp = [&](CreatePipelineHelper &helper) {
13481             VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
13482             dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
13483             dyn_state_ci.dynamicStateCount = size(dyn_states);
13484             dyn_state_ci.pDynamicStates = dyn_states;
13485             helper.dyn_state_ci_ = dyn_state_ci;
13486 
13487             helper.vp_state_ci_.viewportCount = test_case.viewport_count;
13488             helper.vp_state_ci_.pViewports = test_case.viewports;
13489             helper.vp_state_ci_.scissorCount = test_case.scissor_count;
13490             helper.vp_state_ci_.pScissors = test_case.scissors;
13491         };
13492         CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids);
13493     }
13494 }
13495 
13496 // Set Extension dynamic states without enabling the required Extensions.
TEST_F(VkLayerTest,ExtensionDynamicStatesSetWOExtensionEnabled)13497 TEST_F(VkLayerTest, ExtensionDynamicStatesSetWOExtensionEnabled) {
13498     TEST_DESCRIPTION("Create a graphics pipeline with Extension dynamic states without enabling the required Extensions.");
13499 
13500     ASSERT_NO_FATAL_FAILURE(Init());
13501     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13502 
13503     using std::vector;
13504     struct TestCase {
13505         uint32_t dynamic_state_count;
13506         VkDynamicState dynamic_state;
13507 
13508         char const *errmsg;
13509     };
13510 
13511     vector<TestCase> dyn_test_cases = {
13512         {1, VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV,
13513          "contains VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV, but VK_NV_clip_space_w_scaling"},
13514         {1, VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT,
13515          "contains VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT, but VK_EXT_discard_rectangles"},
13516         {1, VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT, "contains VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT, but VK_EXT_sample_locations"},
13517     };
13518 
13519     for (const auto &test_case : dyn_test_cases) {
13520         VkDynamicState state[1];
13521         state[0] = test_case.dynamic_state;
13522         const auto break_vp = [&](CreatePipelineHelper &helper) {
13523             VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
13524             dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
13525             dyn_state_ci.dynamicStateCount = test_case.dynamic_state_count;
13526             dyn_state_ci.pDynamicStates = state;
13527             helper.dyn_state_ci_ = dyn_state_ci;
13528         };
13529         CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.errmsg);
13530     }
13531 }
13532 
TEST_F(VkLayerTest,PSOViewportStateMultiViewportTests)13533 TEST_F(VkLayerTest, PSOViewportStateMultiViewportTests) {
13534     TEST_DESCRIPTION("Test VkPipelineViewportStateCreateInfo viewport and scissor count validation for multiViewport feature");
13535 
13536     ASSERT_NO_FATAL_FAILURE(Init());  // enables all supported features
13537 
13538     if (!m_device->phy().features().multiViewport) {
13539         printf("%s VkPhysicalDeviceFeatures::multiViewport is not supported -- skipping test.\n", kSkipPrefix);
13540         return;
13541     }
13542     // at least 16 viewports supported from here on
13543 
13544     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13545 
13546     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
13547     VkViewport viewports[] = {viewport, viewport};
13548     VkRect2D scissor = {{0, 0}, {64, 64}};
13549     VkRect2D scissors[] = {scissor, scissor};
13550 
13551     using std::vector;
13552     struct TestCase {
13553         uint32_t viewport_count;
13554         VkViewport *viewports;
13555         uint32_t scissor_count;
13556         VkRect2D *scissors;
13557 
13558         vector<std::string> vuids;
13559     };
13560 
13561     vector<TestCase> test_cases = {
13562         {0,
13563          viewports,
13564          2,
13565          scissors,
13566          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-arraylength",
13567           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
13568         {2,
13569          viewports,
13570          0,
13571          scissors,
13572          {"VUID-VkPipelineViewportStateCreateInfo-scissorCount-arraylength",
13573           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
13574         {0,
13575          viewports,
13576          0,
13577          scissors,
13578          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-arraylength",
13579           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-arraylength"}},
13580         {2, nullptr, 2, scissors, {"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00747"}},
13581         {2, viewports, 2, nullptr, {"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00748"}},
13582         {2,
13583          nullptr,
13584          2,
13585          nullptr,
13586          {"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00747", "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00748"}},
13587         {0,
13588          nullptr,
13589          0,
13590          nullptr,
13591          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-arraylength",
13592           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-arraylength"}},
13593     };
13594 
13595     const auto max_viewports = m_device->phy().properties().limits.maxViewports;
13596     const bool max_viewports_maxxed = max_viewports == std::numeric_limits<decltype(max_viewports)>::max();
13597     if (max_viewports_maxxed) {
13598         printf("%s VkPhysicalDeviceLimits::maxViewports is UINT32_MAX -- skipping part of test requiring to exceed maxViewports.\n",
13599                kSkipPrefix);
13600     } else {
13601         const auto too_much_viewports = max_viewports + 1;
13602         // avoid potentially big allocations by using only nullptr
13603         test_cases.push_back({too_much_viewports,
13604                               nullptr,
13605                               2,
13606                               scissors,
13607                               {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01218",
13608                                "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220",
13609                                "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00747"}});
13610         test_cases.push_back({2,
13611                               viewports,
13612                               too_much_viewports,
13613                               nullptr,
13614                               {"VUID-VkPipelineViewportStateCreateInfo-scissorCount-01219",
13615                                "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220",
13616                                "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00748"}});
13617         test_cases.push_back(
13618             {too_much_viewports,
13619              nullptr,
13620              too_much_viewports,
13621              nullptr,
13622              {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01218",
13623               "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01219", "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00747",
13624               "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00748"}});
13625     }
13626 
13627     for (const auto &test_case : test_cases) {
13628         const auto break_vp = [&test_case](CreatePipelineHelper &helper) {
13629             helper.vp_state_ci_.viewportCount = test_case.viewport_count;
13630             helper.vp_state_ci_.pViewports = test_case.viewports;
13631             helper.vp_state_ci_.scissorCount = test_case.scissor_count;
13632             helper.vp_state_ci_.pScissors = test_case.scissors;
13633         };
13634         CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids);
13635     }
13636 
13637     vector<TestCase> dyn_test_cases = {
13638         {0,
13639          viewports,
13640          2,
13641          scissors,
13642          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-arraylength",
13643           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
13644         {2,
13645          viewports,
13646          0,
13647          scissors,
13648          {"VUID-VkPipelineViewportStateCreateInfo-scissorCount-arraylength",
13649           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}},
13650         {0,
13651          viewports,
13652          0,
13653          scissors,
13654          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-arraylength",
13655           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-arraylength"}},
13656         {0,
13657          nullptr,
13658          0,
13659          nullptr,
13660          {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-arraylength",
13661           "VUID-VkPipelineViewportStateCreateInfo-scissorCount-arraylength"}},
13662     };
13663 
13664     if (!max_viewports_maxxed) {
13665         const auto too_much_viewports = max_viewports + 1;
13666         // avoid potentially big allocations by using only nullptr
13667         dyn_test_cases.push_back({too_much_viewports,
13668                                   nullptr,
13669                                   2,
13670                                   scissors,
13671                                   {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01218",
13672                                    "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}});
13673         dyn_test_cases.push_back({2,
13674                                   viewports,
13675                                   too_much_viewports,
13676                                   nullptr,
13677                                   {"VUID-VkPipelineViewportStateCreateInfo-scissorCount-01219",
13678                                    "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220"}});
13679         dyn_test_cases.push_back({too_much_viewports,
13680                                   nullptr,
13681                                   too_much_viewports,
13682                                   nullptr,
13683                                   {"VUID-VkPipelineViewportStateCreateInfo-viewportCount-01218",
13684                                    "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01219"}});
13685     }
13686 
13687     const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
13688 
13689     for (const auto &test_case : dyn_test_cases) {
13690         const auto break_vp = [&](CreatePipelineHelper &helper) {
13691             VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
13692             dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
13693             dyn_state_ci.dynamicStateCount = size(dyn_states);
13694             dyn_state_ci.pDynamicStates = dyn_states;
13695             helper.dyn_state_ci_ = dyn_state_ci;
13696 
13697             helper.vp_state_ci_.viewportCount = test_case.viewport_count;
13698             helper.vp_state_ci_.pViewports = test_case.viewports;
13699             helper.vp_state_ci_.scissorCount = test_case.scissor_count;
13700             helper.vp_state_ci_.pScissors = test_case.scissors;
13701         };
13702         CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids);
13703     }
13704 }
13705 
TEST_F(VkLayerTest,DynViewportAndScissorUndefinedDrawState)13706 TEST_F(VkLayerTest, DynViewportAndScissorUndefinedDrawState) {
13707     TEST_DESCRIPTION("Test viewport and scissor dynamic state that is not set before draw");
13708 
13709     ASSERT_NO_FATAL_FAILURE(Init());
13710 
13711     // TODO: should also test on !multiViewport
13712     if (!m_device->phy().features().multiViewport) {
13713         printf("%s Device does not support multiple viewports/scissors; skipped.\n", kSkipPrefix);
13714         return;
13715     }
13716 
13717     ASSERT_NO_FATAL_FAILURE(InitViewport());
13718     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13719 
13720     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
13721     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13722 
13723     const VkPipelineLayoutObj pipeline_layout(m_device);
13724 
13725     VkPipelineObj pipeline_dyn_vp(m_device);
13726     pipeline_dyn_vp.AddShader(&vs);
13727     pipeline_dyn_vp.AddShader(&fs);
13728     pipeline_dyn_vp.AddDefaultColorAttachment();
13729     pipeline_dyn_vp.MakeDynamic(VK_DYNAMIC_STATE_VIEWPORT);
13730     pipeline_dyn_vp.SetScissor(m_scissors);
13731     ASSERT_VK_SUCCESS(pipeline_dyn_vp.CreateVKPipeline(pipeline_layout.handle(), m_renderPass));
13732 
13733     VkPipelineObj pipeline_dyn_sc(m_device);
13734     pipeline_dyn_sc.AddShader(&vs);
13735     pipeline_dyn_sc.AddShader(&fs);
13736     pipeline_dyn_sc.AddDefaultColorAttachment();
13737     pipeline_dyn_sc.SetViewport(m_viewports);
13738     pipeline_dyn_sc.MakeDynamic(VK_DYNAMIC_STATE_SCISSOR);
13739     ASSERT_VK_SUCCESS(pipeline_dyn_sc.CreateVKPipeline(pipeline_layout.handle(), m_renderPass));
13740 
13741     m_commandBuffer->begin();
13742     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
13743 
13744     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
13745                                          "Dynamic viewport(s) 0 are used by pipeline state object, ");
13746     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_dyn_vp.handle());
13747     vkCmdSetViewport(m_commandBuffer->handle(), 1, 1,
13748                      &m_viewports[0]);  // Forgetting to set needed 0th viewport (PSO viewportCount == 1)
13749     m_commandBuffer->Draw(1, 0, 0, 0);
13750     m_errorMonitor->VerifyFound();
13751 
13752     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic scissor(s) 0 are used by pipeline state object, ");
13753     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_dyn_sc.handle());
13754     vkCmdSetScissor(m_commandBuffer->handle(), 1, 1,
13755                     &m_scissors[0]);  // Forgetting to set needed 0th scissor (PSO scissorCount == 1)
13756     m_commandBuffer->Draw(1, 0, 0, 0);
13757     m_errorMonitor->VerifyFound();
13758 
13759     m_commandBuffer->EndRenderPass();
13760     m_commandBuffer->end();
13761 }
13762 
TEST_F(VkLayerTest,PSOLineWidthInvalid)13763 TEST_F(VkLayerTest, PSOLineWidthInvalid) {
13764     TEST_DESCRIPTION("Test non-1.0 lineWidth errors when pipeline is created and in vkCmdSetLineWidth");
13765     VkPhysicalDeviceFeatures features{};
13766     ASSERT_NO_FATAL_FAILURE(Init(&features));
13767     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13768 
13769     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
13770     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13771     VkPipelineShaderStageCreateInfo shader_state_cis[] = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
13772 
13773     VkPipelineVertexInputStateCreateInfo vi_state_ci = {};
13774     vi_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
13775 
13776     VkPipelineInputAssemblyStateCreateInfo ia_state_ci = {};
13777     ia_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
13778     ia_state_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
13779 
13780     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
13781     VkRect2D scissor = {{0, 0}, {64, 64}};
13782     VkPipelineViewportStateCreateInfo vp_state_ci = {};
13783     vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
13784     vp_state_ci.viewportCount = 1;
13785     vp_state_ci.pViewports = &viewport;
13786     vp_state_ci.scissorCount = 1;
13787     vp_state_ci.pScissors = &scissor;
13788 
13789     VkPipelineRasterizationStateCreateInfo rs_state_ci = {};
13790     rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
13791     rs_state_ci.rasterizerDiscardEnable = VK_FALSE;
13792     // lineWidth to be set by checks
13793 
13794     VkPipelineMultisampleStateCreateInfo ms_state_ci = {};
13795     ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
13796     ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;  // must match subpass att.
13797 
13798     VkPipelineColorBlendAttachmentState cba_state = {};
13799 
13800     VkPipelineColorBlendStateCreateInfo cb_state_ci = {};
13801     cb_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
13802     cb_state_ci.attachmentCount = 1;  // must match count in subpass
13803     cb_state_ci.pAttachments = &cba_state;
13804 
13805     const VkPipelineLayoutObj pipeline_layout(m_device);
13806 
13807     VkGraphicsPipelineCreateInfo gp_ci = {};
13808     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
13809     gp_ci.stageCount = sizeof(shader_state_cis) / sizeof(VkPipelineShaderStageCreateInfo);
13810     gp_ci.pStages = shader_state_cis;
13811     gp_ci.pVertexInputState = &vi_state_ci;
13812     gp_ci.pInputAssemblyState = &ia_state_ci;
13813     gp_ci.pViewportState = &vp_state_ci;
13814     gp_ci.pRasterizationState = &rs_state_ci;
13815     gp_ci.pMultisampleState = &ms_state_ci;
13816     gp_ci.pColorBlendState = &cb_state_ci;
13817     gp_ci.layout = pipeline_layout.handle();
13818     gp_ci.renderPass = renderPass();
13819     gp_ci.subpass = 0;
13820 
13821     const std::vector<float> test_cases = {-1.0f, 0.0f, NearestSmaller(1.0f), NearestGreater(1.0f), NAN};
13822 
13823     // test VkPipelineRasterizationStateCreateInfo::lineWidth
13824     for (const auto test_case : test_cases) {
13825         rs_state_ci.lineWidth = test_case;
13826 
13827         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
13828                                              "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00749");
13829         VkPipeline pipeline;
13830         vkCreateGraphicsPipelines(m_device->device(), VK_NULL_HANDLE, 1, &gp_ci, nullptr, &pipeline);
13831         m_errorMonitor->VerifyFound();
13832     }
13833 
13834     // test vkCmdSetLineWidth
13835     m_commandBuffer->begin();
13836 
13837     for (const auto test_case : test_cases) {
13838         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetLineWidth-lineWidth-00788");
13839         vkCmdSetLineWidth(m_commandBuffer->handle(), test_case);
13840         m_errorMonitor->VerifyFound();
13841     }
13842 }
13843 
TEST_F(VkLayerTest,VUID_VkVertexInputBindingDescription_binding_00618)13844 TEST_F(VkLayerTest, VUID_VkVertexInputBindingDescription_binding_00618) {
13845     TEST_DESCRIPTION(
13846         "Test VUID-VkVertexInputBindingDescription-binding-00618: binding must be less than "
13847         "VkPhysicalDeviceLimits::maxVertexInputBindings");
13848 
13849     ASSERT_NO_FATAL_FAILURE(Init());
13850     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13851 
13852     VkPipelineCache pipeline_cache;
13853     {
13854         VkPipelineCacheCreateInfo create_info{};
13855         create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
13856 
13857         VkResult err = vkCreatePipelineCache(m_device->device(), &create_info, nullptr, &pipeline_cache);
13858         ASSERT_VK_SUCCESS(err);
13859     }
13860 
13861     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
13862     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13863 
13864     VkPipelineShaderStageCreateInfo stages[2]{{}};
13865     stages[0] = vs.GetStageCreateInfo();
13866     stages[1] = fs.GetStageCreateInfo();
13867 
13868     // Test when binding is greater than or equal to VkPhysicalDeviceLimits::maxVertexInputBindings.
13869     VkVertexInputBindingDescription vertex_input_binding_description{};
13870     vertex_input_binding_description.binding = m_device->props.limits.maxVertexInputBindings;
13871 
13872     VkPipelineVertexInputStateCreateInfo vertex_input_state{};
13873     vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
13874     vertex_input_state.pNext = nullptr;
13875     vertex_input_state.vertexBindingDescriptionCount = 1;
13876     vertex_input_state.pVertexBindingDescriptions = &vertex_input_binding_description;
13877     vertex_input_state.vertexAttributeDescriptionCount = 0;
13878     vertex_input_state.pVertexAttributeDescriptions = nullptr;
13879 
13880     VkPipelineInputAssemblyStateCreateInfo input_assembly_state{};
13881     input_assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
13882     input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
13883 
13884     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
13885     VkRect2D scissor = {{0, 0}, {64, 64}};
13886     VkPipelineViewportStateCreateInfo viewport_state{};
13887     viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
13888     viewport_state.viewportCount = 1;
13889     viewport_state.pViewports = &viewport;
13890     viewport_state.scissorCount = 1;
13891     viewport_state.pScissors = &scissor;
13892 
13893     VkPipelineMultisampleStateCreateInfo multisample_state{};
13894     multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
13895     multisample_state.pNext = nullptr;
13896     multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
13897     multisample_state.sampleShadingEnable = 0;
13898     multisample_state.minSampleShading = 1.0;
13899     multisample_state.pSampleMask = nullptr;
13900 
13901     VkPipelineRasterizationStateCreateInfo rasterization_state{};
13902     rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
13903     rasterization_state.polygonMode = VK_POLYGON_MODE_FILL;
13904     rasterization_state.cullMode = VK_CULL_MODE_BACK_BIT;
13905     rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
13906     rasterization_state.depthClampEnable = VK_FALSE;
13907     rasterization_state.rasterizerDiscardEnable = VK_FALSE;
13908     rasterization_state.depthBiasEnable = VK_FALSE;
13909     rasterization_state.lineWidth = 1.0f;
13910 
13911     const VkPipelineLayoutObj pipeline_layout(m_device);
13912 
13913     {
13914         VkGraphicsPipelineCreateInfo create_info{};
13915         create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
13916         create_info.stageCount = 2;
13917         create_info.pStages = stages;
13918         create_info.pVertexInputState = &vertex_input_state;
13919         create_info.pInputAssemblyState = &input_assembly_state;
13920         create_info.pViewportState = &viewport_state;
13921         create_info.pMultisampleState = &multisample_state;
13922         create_info.pRasterizationState = &rasterization_state;
13923         create_info.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
13924         create_info.layout = pipeline_layout.handle();
13925         create_info.renderPass = renderPass();
13926 
13927         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkVertexInputBindingDescription-binding-00618");
13928         VkPipeline pipeline;
13929         vkCreateGraphicsPipelines(m_device->device(), pipeline_cache, 1, &create_info, nullptr, &pipeline);
13930         m_errorMonitor->VerifyFound();
13931     }
13932 
13933     vkDestroyPipelineCache(m_device->device(), pipeline_cache, nullptr);
13934 }
13935 
TEST_F(VkLayerTest,VUID_VkVertexInputBindingDescription_stride_00619)13936 TEST_F(VkLayerTest, VUID_VkVertexInputBindingDescription_stride_00619) {
13937     TEST_DESCRIPTION(
13938         "Test VUID-VkVertexInputBindingDescription-stride-00619: stride must be less than or equal to "
13939         "VkPhysicalDeviceLimits::maxVertexInputBindingStride");
13940 
13941     ASSERT_NO_FATAL_FAILURE(Init());
13942     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
13943 
13944     VkPipelineCache pipeline_cache;
13945     {
13946         VkPipelineCacheCreateInfo create_info{};
13947         create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
13948 
13949         VkResult err = vkCreatePipelineCache(m_device->device(), &create_info, nullptr, &pipeline_cache);
13950         ASSERT_VK_SUCCESS(err);
13951     }
13952 
13953     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
13954     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
13955 
13956     VkPipelineShaderStageCreateInfo stages[2]{{}};
13957     stages[0] = vs.GetStageCreateInfo();
13958     stages[1] = fs.GetStageCreateInfo();
13959 
13960     // Test when stride is greater than VkPhysicalDeviceLimits::maxVertexInputBindingStride.
13961     VkVertexInputBindingDescription vertex_input_binding_description{};
13962     vertex_input_binding_description.stride = m_device->props.limits.maxVertexInputBindingStride + 1;
13963 
13964     VkPipelineVertexInputStateCreateInfo vertex_input_state{};
13965     vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
13966     vertex_input_state.pNext = nullptr;
13967     vertex_input_state.vertexBindingDescriptionCount = 1;
13968     vertex_input_state.pVertexBindingDescriptions = &vertex_input_binding_description;
13969     vertex_input_state.vertexAttributeDescriptionCount = 0;
13970     vertex_input_state.pVertexAttributeDescriptions = nullptr;
13971 
13972     VkPipelineInputAssemblyStateCreateInfo input_assembly_state{};
13973     input_assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
13974     input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
13975 
13976     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
13977     VkRect2D scissor = {{0, 0}, {64, 64}};
13978     VkPipelineViewportStateCreateInfo viewport_state{};
13979     viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
13980     viewport_state.viewportCount = 1;
13981     viewport_state.pViewports = &viewport;
13982     viewport_state.scissorCount = 1;
13983     viewport_state.pScissors = &scissor;
13984 
13985     VkPipelineMultisampleStateCreateInfo multisample_state{};
13986     multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
13987     multisample_state.pNext = nullptr;
13988     multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
13989     multisample_state.sampleShadingEnable = 0;
13990     multisample_state.minSampleShading = 1.0;
13991     multisample_state.pSampleMask = nullptr;
13992 
13993     VkPipelineRasterizationStateCreateInfo rasterization_state{};
13994     rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
13995     rasterization_state.polygonMode = VK_POLYGON_MODE_FILL;
13996     rasterization_state.cullMode = VK_CULL_MODE_BACK_BIT;
13997     rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
13998     rasterization_state.depthClampEnable = VK_FALSE;
13999     rasterization_state.rasterizerDiscardEnable = VK_FALSE;
14000     rasterization_state.depthBiasEnable = VK_FALSE;
14001     rasterization_state.lineWidth = 1.0f;
14002 
14003     const VkPipelineLayoutObj pipeline_layout(m_device);
14004 
14005     {
14006         VkGraphicsPipelineCreateInfo create_info{};
14007         create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
14008         create_info.stageCount = 2;
14009         create_info.pStages = stages;
14010         create_info.pVertexInputState = &vertex_input_state;
14011         create_info.pInputAssemblyState = &input_assembly_state;
14012         create_info.pViewportState = &viewport_state;
14013         create_info.pMultisampleState = &multisample_state;
14014         create_info.pRasterizationState = &rasterization_state;
14015         create_info.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
14016         create_info.layout = pipeline_layout.handle();
14017         create_info.renderPass = renderPass();
14018 
14019         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkVertexInputBindingDescription-stride-00619");
14020         VkPipeline pipeline;
14021         vkCreateGraphicsPipelines(m_device->device(), pipeline_cache, 1, &create_info, nullptr, &pipeline);
14022         m_errorMonitor->VerifyFound();
14023     }
14024 
14025     vkDestroyPipelineCache(m_device->device(), pipeline_cache, nullptr);
14026 }
14027 
TEST_F(VkLayerTest,VUID_VkVertexInputAttributeDescription_location_00620)14028 TEST_F(VkLayerTest, VUID_VkVertexInputAttributeDescription_location_00620) {
14029     TEST_DESCRIPTION(
14030         "Test VUID-VkVertexInputAttributeDescription-location-00620: location must be less than "
14031         "VkPhysicalDeviceLimits::maxVertexInputAttributes");
14032 
14033     ASSERT_NO_FATAL_FAILURE(Init());
14034     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14035 
14036     VkPipelineCache pipeline_cache;
14037     {
14038         VkPipelineCacheCreateInfo create_info{};
14039         create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
14040 
14041         VkResult err = vkCreatePipelineCache(m_device->device(), &create_info, nullptr, &pipeline_cache);
14042         ASSERT_VK_SUCCESS(err);
14043     }
14044 
14045     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
14046     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14047 
14048     VkPipelineShaderStageCreateInfo stages[2]{{}};
14049     stages[0] = vs.GetStageCreateInfo();
14050     stages[1] = fs.GetStageCreateInfo();
14051 
14052     // Test when location is greater than or equal to VkPhysicalDeviceLimits::maxVertexInputAttributes.
14053     VkVertexInputAttributeDescription vertex_input_attribute_description{};
14054     vertex_input_attribute_description.location = m_device->props.limits.maxVertexInputAttributes;
14055 
14056     VkPipelineVertexInputStateCreateInfo vertex_input_state{};
14057     vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
14058     vertex_input_state.pNext = nullptr;
14059     vertex_input_state.vertexBindingDescriptionCount = 0;
14060     vertex_input_state.pVertexBindingDescriptions = nullptr;
14061     vertex_input_state.vertexAttributeDescriptionCount = 1;
14062     vertex_input_state.pVertexAttributeDescriptions = &vertex_input_attribute_description;
14063 
14064     VkPipelineInputAssemblyStateCreateInfo input_assembly_state{};
14065     input_assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
14066     input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
14067 
14068     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
14069     VkRect2D scissor = {{0, 0}, {64, 64}};
14070     VkPipelineViewportStateCreateInfo viewport_state{};
14071     viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
14072     viewport_state.viewportCount = 1;
14073     viewport_state.pViewports = &viewport;
14074     viewport_state.scissorCount = 1;
14075     viewport_state.pScissors = &scissor;
14076 
14077     VkPipelineMultisampleStateCreateInfo multisample_state{};
14078     multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
14079     multisample_state.pNext = nullptr;
14080     multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
14081     multisample_state.sampleShadingEnable = 0;
14082     multisample_state.minSampleShading = 1.0;
14083     multisample_state.pSampleMask = nullptr;
14084 
14085     VkPipelineRasterizationStateCreateInfo rasterization_state{};
14086     rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
14087     rasterization_state.polygonMode = VK_POLYGON_MODE_FILL;
14088     rasterization_state.cullMode = VK_CULL_MODE_BACK_BIT;
14089     rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
14090     rasterization_state.depthClampEnable = VK_FALSE;
14091     rasterization_state.rasterizerDiscardEnable = VK_FALSE;
14092     rasterization_state.depthBiasEnable = VK_FALSE;
14093     rasterization_state.lineWidth = 1.0f;
14094 
14095     const VkPipelineLayoutObj pipeline_layout(m_device);
14096 
14097     {
14098         VkGraphicsPipelineCreateInfo create_info{};
14099         create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
14100         create_info.stageCount = 2;
14101         create_info.pStages = stages;
14102         create_info.pVertexInputState = &vertex_input_state;
14103         create_info.pInputAssemblyState = &input_assembly_state;
14104         create_info.pViewportState = &viewport_state;
14105         create_info.pMultisampleState = &multisample_state;
14106         create_info.pRasterizationState = &rasterization_state;
14107         create_info.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
14108         create_info.layout = pipeline_layout.handle();
14109         create_info.renderPass = renderPass();
14110 
14111         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14112                                              "VUID-VkVertexInputAttributeDescription-location-00620");
14113         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14114                                              "VUID-VkPipelineVertexInputStateCreateInfo-binding-00615");
14115         VkPipeline pipeline;
14116         vkCreateGraphicsPipelines(m_device->device(), pipeline_cache, 1, &create_info, nullptr, &pipeline);
14117         m_errorMonitor->VerifyFound();
14118     }
14119 
14120     vkDestroyPipelineCache(m_device->device(), pipeline_cache, nullptr);
14121 }
14122 
TEST_F(VkLayerTest,VUID_VkVertexInputAttributeDescription_binding_00621)14123 TEST_F(VkLayerTest, VUID_VkVertexInputAttributeDescription_binding_00621) {
14124     TEST_DESCRIPTION(
14125         "Test VUID-VkVertexInputAttributeDescription-binding-00621: binding must be less than "
14126         "VkPhysicalDeviceLimits::maxVertexInputBindings");
14127 
14128     ASSERT_NO_FATAL_FAILURE(Init());
14129     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14130 
14131     VkPipelineCache pipeline_cache;
14132     {
14133         VkPipelineCacheCreateInfo create_info{};
14134         create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
14135 
14136         VkResult err = vkCreatePipelineCache(m_device->device(), &create_info, nullptr, &pipeline_cache);
14137         ASSERT_VK_SUCCESS(err);
14138     }
14139 
14140     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
14141     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14142 
14143     VkPipelineShaderStageCreateInfo stages[2]{{}};
14144     stages[0] = vs.GetStageCreateInfo();
14145     stages[1] = fs.GetStageCreateInfo();
14146 
14147     // Test when binding is greater than or equal to VkPhysicalDeviceLimits::maxVertexInputBindings.
14148     VkVertexInputAttributeDescription vertex_input_attribute_description{};
14149     vertex_input_attribute_description.binding = m_device->props.limits.maxVertexInputBindings;
14150 
14151     VkPipelineVertexInputStateCreateInfo vertex_input_state{};
14152     vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
14153     vertex_input_state.pNext = nullptr;
14154     vertex_input_state.vertexBindingDescriptionCount = 0;
14155     vertex_input_state.pVertexBindingDescriptions = nullptr;
14156     vertex_input_state.vertexAttributeDescriptionCount = 1;
14157     vertex_input_state.pVertexAttributeDescriptions = &vertex_input_attribute_description;
14158 
14159     VkPipelineInputAssemblyStateCreateInfo input_assembly_state{};
14160     input_assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
14161     input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
14162 
14163     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
14164     VkRect2D scissor = {{0, 0}, {64, 64}};
14165     VkPipelineViewportStateCreateInfo viewport_state{};
14166     viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
14167     viewport_state.viewportCount = 1;
14168     viewport_state.pViewports = &viewport;
14169     viewport_state.scissorCount = 1;
14170     viewport_state.pScissors = &scissor;
14171 
14172     VkPipelineMultisampleStateCreateInfo multisample_state{};
14173     multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
14174     multisample_state.pNext = nullptr;
14175     multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
14176     multisample_state.sampleShadingEnable = 0;
14177     multisample_state.minSampleShading = 1.0;
14178     multisample_state.pSampleMask = nullptr;
14179 
14180     VkPipelineRasterizationStateCreateInfo rasterization_state{};
14181     rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
14182     rasterization_state.polygonMode = VK_POLYGON_MODE_FILL;
14183     rasterization_state.cullMode = VK_CULL_MODE_BACK_BIT;
14184     rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
14185     rasterization_state.depthClampEnable = VK_FALSE;
14186     rasterization_state.rasterizerDiscardEnable = VK_FALSE;
14187     rasterization_state.depthBiasEnable = VK_FALSE;
14188     rasterization_state.lineWidth = 1.0f;
14189 
14190     const VkPipelineLayoutObj pipeline_layout(m_device);
14191 
14192     {
14193         VkGraphicsPipelineCreateInfo create_info{};
14194         create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
14195         create_info.stageCount = 2;
14196         create_info.pStages = stages;
14197         create_info.pVertexInputState = &vertex_input_state;
14198         create_info.pInputAssemblyState = &input_assembly_state;
14199         create_info.pViewportState = &viewport_state;
14200         create_info.pMultisampleState = &multisample_state;
14201         create_info.pRasterizationState = &rasterization_state;
14202         create_info.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
14203         create_info.layout = pipeline_layout.handle();
14204         create_info.renderPass = renderPass();
14205 
14206         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkVertexInputAttributeDescription-binding-00621");
14207         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14208                                              "VUID-VkPipelineVertexInputStateCreateInfo-binding-00615");
14209         VkPipeline pipeline;
14210         vkCreateGraphicsPipelines(m_device->device(), pipeline_cache, 1, &create_info, nullptr, &pipeline);
14211         m_errorMonitor->VerifyFound();
14212     }
14213 
14214     vkDestroyPipelineCache(m_device->device(), pipeline_cache, nullptr);
14215 }
14216 
TEST_F(VkLayerTest,VUID_VkVertexInputAttributeDescription_offset_00622)14217 TEST_F(VkLayerTest, VUID_VkVertexInputAttributeDescription_offset_00622) {
14218     TEST_DESCRIPTION(
14219         "Test VUID-VkVertexInputAttributeDescription-offset-00622: offset must be less than or equal to "
14220         "VkPhysicalDeviceLimits::maxVertexInputAttributeOffset");
14221 
14222     EnableDeviceProfileLayer();
14223 
14224     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
14225 
14226     uint32_t maxVertexInputAttributeOffset = 0;
14227     {
14228         VkPhysicalDeviceProperties device_props = {};
14229         vkGetPhysicalDeviceProperties(gpu(), &device_props);
14230         maxVertexInputAttributeOffset = device_props.limits.maxVertexInputAttributeOffset;
14231         if (maxVertexInputAttributeOffset == 0xFFFFFFFF) {
14232             // Attempt to artificially lower maximum offset
14233             PFN_vkSetPhysicalDeviceLimitsEXT fpvkSetPhysicalDeviceLimitsEXT =
14234                 (PFN_vkSetPhysicalDeviceLimitsEXT)vkGetInstanceProcAddr(instance(), "vkSetPhysicalDeviceLimitsEXT");
14235             if (!fpvkSetPhysicalDeviceLimitsEXT) {
14236                 printf("%s All offsets are valid & device_profile_api not found; skipped.\n", kSkipPrefix);
14237                 return;
14238             }
14239             device_props.limits.maxVertexInputAttributeOffset = device_props.limits.maxVertexInputBindingStride - 2;
14240             fpvkSetPhysicalDeviceLimitsEXT(gpu(), &device_props.limits);
14241             maxVertexInputAttributeOffset = device_props.limits.maxVertexInputAttributeOffset;
14242         }
14243     }
14244     ASSERT_NO_FATAL_FAILURE(InitState());
14245     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14246 
14247     VkPipelineCache pipeline_cache;
14248     {
14249         VkPipelineCacheCreateInfo create_info{};
14250         create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
14251 
14252         VkResult err = vkCreatePipelineCache(m_device->device(), &create_info, nullptr, &pipeline_cache);
14253         ASSERT_VK_SUCCESS(err);
14254     }
14255 
14256     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
14257     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
14258 
14259     VkPipelineShaderStageCreateInfo stages[2]{{}};
14260     stages[0] = vs.GetStageCreateInfo();
14261     stages[1] = fs.GetStageCreateInfo();
14262 
14263     VkVertexInputBindingDescription vertex_input_binding_description{};
14264     vertex_input_binding_description.binding = 0;
14265     vertex_input_binding_description.stride = m_device->props.limits.maxVertexInputBindingStride;
14266     vertex_input_binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
14267     // Test when offset is greater than maximum.
14268     VkVertexInputAttributeDescription vertex_input_attribute_description{};
14269     vertex_input_attribute_description.format = VK_FORMAT_R8_UNORM;
14270     vertex_input_attribute_description.offset = maxVertexInputAttributeOffset + 1;
14271 
14272     VkPipelineVertexInputStateCreateInfo vertex_input_state{};
14273     vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
14274     vertex_input_state.pNext = nullptr;
14275     vertex_input_state.vertexBindingDescriptionCount = 1;
14276     vertex_input_state.pVertexBindingDescriptions = &vertex_input_binding_description;
14277     vertex_input_state.vertexAttributeDescriptionCount = 1;
14278     vertex_input_state.pVertexAttributeDescriptions = &vertex_input_attribute_description;
14279 
14280     VkPipelineInputAssemblyStateCreateInfo input_assembly_state{};
14281     input_assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
14282     input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
14283 
14284     VkPipelineMultisampleStateCreateInfo multisample_state{};
14285     multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
14286     multisample_state.pNext = nullptr;
14287     multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
14288     multisample_state.sampleShadingEnable = 0;
14289     multisample_state.minSampleShading = 1.0;
14290     multisample_state.pSampleMask = nullptr;
14291 
14292     VkPipelineRasterizationStateCreateInfo rasterization_state{};
14293     rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
14294     rasterization_state.polygonMode = VK_POLYGON_MODE_FILL;
14295     rasterization_state.cullMode = VK_CULL_MODE_BACK_BIT;
14296     rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
14297     rasterization_state.depthClampEnable = VK_FALSE;
14298     rasterization_state.rasterizerDiscardEnable = VK_TRUE;
14299     rasterization_state.depthBiasEnable = VK_FALSE;
14300     rasterization_state.lineWidth = 1.0f;
14301 
14302     const VkPipelineLayoutObj pipeline_layout(m_device);
14303 
14304     {
14305         VkGraphicsPipelineCreateInfo create_info{};
14306         create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
14307         create_info.stageCount = 2;
14308         create_info.pStages = stages;
14309         create_info.pVertexInputState = &vertex_input_state;
14310         create_info.pInputAssemblyState = &input_assembly_state;
14311         create_info.pViewportState = nullptr;  // no viewport b/c rasterizer is disabled
14312         create_info.pMultisampleState = &multisample_state;
14313         create_info.pRasterizationState = &rasterization_state;
14314         create_info.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
14315         create_info.layout = pipeline_layout.handle();
14316         create_info.renderPass = renderPass();
14317 
14318         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkVertexInputAttributeDescription-offset-00622");
14319         VkPipeline pipeline;
14320         vkCreateGraphicsPipelines(m_device->device(), pipeline_cache, 1, &create_info, nullptr, &pipeline);
14321         m_errorMonitor->VerifyFound();
14322     }
14323 
14324     vkDestroyPipelineCache(m_device->device(), pipeline_cache, nullptr);
14325 }
14326 
TEST_F(VkLayerTest,NullRenderPass)14327 TEST_F(VkLayerTest, NullRenderPass) {
14328     // Bind a NULL RenderPass
14329     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14330                                          "vkCmdBeginRenderPass: required parameter pRenderPassBegin specified as NULL");
14331 
14332     ASSERT_NO_FATAL_FAILURE(Init());
14333     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14334 
14335     m_commandBuffer->begin();
14336     // Don't care about RenderPass handle b/c error should be flagged before
14337     // that
14338     vkCmdBeginRenderPass(m_commandBuffer->handle(), NULL, VK_SUBPASS_CONTENTS_INLINE);
14339 
14340     m_errorMonitor->VerifyFound();
14341 
14342     m_commandBuffer->end();
14343 }
14344 
TEST_F(VkLayerTest,EndCommandBufferWithinRenderPass)14345 TEST_F(VkLayerTest, EndCommandBufferWithinRenderPass) {
14346     TEST_DESCRIPTION("End a command buffer with an active render pass");
14347 
14348     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14349                                          "It is invalid to issue this call inside an active render pass");
14350 
14351     ASSERT_NO_FATAL_FAILURE(Init());
14352     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14353 
14354     m_commandBuffer->begin();
14355     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
14356     vkEndCommandBuffer(m_commandBuffer->handle());
14357 
14358     m_errorMonitor->VerifyFound();
14359 
14360     // End command buffer properly to avoid driver issues. This is safe -- the
14361     // previous vkEndCommandBuffer should not have reached the driver.
14362     m_commandBuffer->EndRenderPass();
14363     m_commandBuffer->end();
14364 
14365     // TODO: Add test for VK_COMMAND_BUFFER_LEVEL_SECONDARY
14366     // TODO: Add test for VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT
14367 }
14368 
TEST_F(VkLayerTest,FillBufferWithinRenderPass)14369 TEST_F(VkLayerTest, FillBufferWithinRenderPass) {
14370     // Call CmdFillBuffer within an active renderpass
14371     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14372                                          "It is invalid to issue this call inside an active render pass");
14373 
14374     ASSERT_NO_FATAL_FAILURE(Init());
14375     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14376 
14377     m_commandBuffer->begin();
14378     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
14379 
14380     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
14381     VkBufferObj dstBuffer;
14382     dstBuffer.init_as_dst(*m_device, (VkDeviceSize)1024, reqs);
14383 
14384     m_commandBuffer->FillBuffer(dstBuffer.handle(), 0, 4, 0x11111111);
14385 
14386     m_errorMonitor->VerifyFound();
14387 
14388     m_commandBuffer->EndRenderPass();
14389     m_commandBuffer->end();
14390 }
14391 
TEST_F(VkLayerTest,UpdateBufferWithinRenderPass)14392 TEST_F(VkLayerTest, UpdateBufferWithinRenderPass) {
14393     // Call CmdUpdateBuffer within an active renderpass
14394     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14395                                          "It is invalid to issue this call inside an active render pass");
14396 
14397     ASSERT_NO_FATAL_FAILURE(Init());
14398     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14399 
14400     m_commandBuffer->begin();
14401     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
14402 
14403     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
14404     VkBufferObj dstBuffer;
14405     dstBuffer.init_as_dst(*m_device, (VkDeviceSize)1024, reqs);
14406 
14407     VkDeviceSize dstOffset = 0;
14408     uint32_t Data[] = {1, 2, 3, 4, 5, 6, 7, 8};
14409     VkDeviceSize dataSize = sizeof(Data) / sizeof(uint32_t);
14410     vkCmdUpdateBuffer(m_commandBuffer->handle(), dstBuffer.handle(), dstOffset, dataSize, &Data);
14411 
14412     m_errorMonitor->VerifyFound();
14413 
14414     m_commandBuffer->EndRenderPass();
14415     m_commandBuffer->end();
14416 }
14417 
TEST_F(VkLayerTest,ClearColorImageWithBadRange)14418 TEST_F(VkLayerTest, ClearColorImageWithBadRange) {
14419     TEST_DESCRIPTION("Record clear color with an invalid VkImageSubresourceRange");
14420 
14421     ASSERT_NO_FATAL_FAILURE(Init());
14422     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14423 
14424     VkImageObj image(m_device);
14425     image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
14426     ASSERT_TRUE(image.create_info().arrayLayers == 1);
14427     ASSERT_TRUE(image.initialized());
14428     image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
14429 
14430     const VkClearColorValue clear_color = {{0.0f, 0.0f, 0.0f, 1.0f}};
14431 
14432     m_commandBuffer->begin();
14433     const auto cb_handle = m_commandBuffer->handle();
14434 
14435     // Try baseMipLevel >= image.mipLevels with VK_REMAINING_MIP_LEVELS
14436     {
14437         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearColorImage-baseMipLevel-01470");
14438         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, VK_REMAINING_MIP_LEVELS, 0, 1};
14439         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
14440         m_errorMonitor->VerifyFound();
14441     }
14442 
14443     // Try baseMipLevel >= image.mipLevels without VK_REMAINING_MIP_LEVELS
14444     {
14445         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearColorImage-baseMipLevel-01470");
14446         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearColorImage-pRanges-01692");
14447         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 0, 1};
14448         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
14449         m_errorMonitor->VerifyFound();
14450     }
14451 
14452     // Try levelCount = 0
14453     {
14454         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearColorImage-pRanges-01692");
14455         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 0, 1};
14456         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
14457         m_errorMonitor->VerifyFound();
14458     }
14459 
14460     // Try baseMipLevel + levelCount > image.mipLevels
14461     {
14462         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearColorImage-pRanges-01692");
14463         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 2, 0, 1};
14464         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
14465         m_errorMonitor->VerifyFound();
14466     }
14467 
14468     // Try baseArrayLayer >= image.arrayLayers with VK_REMAINING_ARRAY_LAYERS
14469     {
14470         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearColorImage-baseArrayLayer-01472");
14471         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, VK_REMAINING_ARRAY_LAYERS};
14472         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
14473         m_errorMonitor->VerifyFound();
14474     }
14475 
14476     // Try baseArrayLayer >= image.arrayLayers without VK_REMAINING_ARRAY_LAYERS
14477     {
14478         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearColorImage-baseArrayLayer-01472");
14479         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearColorImage-pRanges-01693");
14480         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, 1};
14481         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
14482         m_errorMonitor->VerifyFound();
14483     }
14484 
14485     // Try layerCount = 0
14486     {
14487         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearColorImage-pRanges-01693");
14488         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 0};
14489         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
14490         m_errorMonitor->VerifyFound();
14491     }
14492 
14493     // Try baseArrayLayer + layerCount > image.arrayLayers
14494     {
14495         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearColorImage-pRanges-01693");
14496         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 2};
14497         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
14498         m_errorMonitor->VerifyFound();
14499     }
14500 }
14501 
TEST_F(VkLayerTest,ClearDepthStencilWithBadRange)14502 TEST_F(VkLayerTest, ClearDepthStencilWithBadRange) {
14503     TEST_DESCRIPTION("Record clear depth with an invalid VkImageSubresourceRange");
14504 
14505     ASSERT_NO_FATAL_FAILURE(Init());
14506     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14507 
14508     const auto depth_format = FindSupportedDepthStencilFormat(gpu());
14509     if (!depth_format) {
14510         printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
14511         return;
14512     }
14513 
14514     VkImageObj image(m_device);
14515     image.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
14516     ASSERT_TRUE(image.create_info().arrayLayers == 1);
14517     ASSERT_TRUE(image.initialized());
14518     const VkImageAspectFlags ds_aspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
14519     image.SetLayout(ds_aspect, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
14520 
14521     const VkClearDepthStencilValue clear_value = {};
14522 
14523     m_commandBuffer->begin();
14524     const auto cb_handle = m_commandBuffer->handle();
14525 
14526     // Try baseMipLevel >= image.mipLevels with VK_REMAINING_MIP_LEVELS
14527     {
14528         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearDepthStencilImage-baseMipLevel-01474");
14529         const VkImageSubresourceRange range = {ds_aspect, 1, VK_REMAINING_MIP_LEVELS, 0, 1};
14530         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
14531         m_errorMonitor->VerifyFound();
14532     }
14533 
14534     // Try baseMipLevel >= image.mipLevels without VK_REMAINING_MIP_LEVELS
14535     {
14536         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearDepthStencilImage-baseMipLevel-01474");
14537         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearDepthStencilImage-pRanges-01694");
14538         const VkImageSubresourceRange range = {ds_aspect, 1, 1, 0, 1};
14539         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
14540         m_errorMonitor->VerifyFound();
14541     }
14542 
14543     // Try levelCount = 0
14544     {
14545         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearDepthStencilImage-pRanges-01694");
14546         const VkImageSubresourceRange range = {ds_aspect, 0, 0, 0, 1};
14547         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
14548         m_errorMonitor->VerifyFound();
14549     }
14550 
14551     // Try baseMipLevel + levelCount > image.mipLevels
14552     {
14553         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearDepthStencilImage-pRanges-01694");
14554         const VkImageSubresourceRange range = {ds_aspect, 0, 2, 0, 1};
14555         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
14556         m_errorMonitor->VerifyFound();
14557     }
14558 
14559     // Try baseArrayLayer >= image.arrayLayers with VK_REMAINING_ARRAY_LAYERS
14560     {
14561         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14562                                              "VUID-vkCmdClearDepthStencilImage-baseArrayLayer-01476");
14563         const VkImageSubresourceRange range = {ds_aspect, 0, 1, 1, VK_REMAINING_ARRAY_LAYERS};
14564         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
14565         m_errorMonitor->VerifyFound();
14566     }
14567 
14568     // Try baseArrayLayer >= image.arrayLayers without VK_REMAINING_ARRAY_LAYERS
14569     {
14570         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14571                                              "VUID-vkCmdClearDepthStencilImage-baseArrayLayer-01476");
14572         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearDepthStencilImage-pRanges-01695");
14573         const VkImageSubresourceRange range = {ds_aspect, 0, 1, 1, 1};
14574         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
14575         m_errorMonitor->VerifyFound();
14576     }
14577 
14578     // Try layerCount = 0
14579     {
14580         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearDepthStencilImage-pRanges-01695");
14581         const VkImageSubresourceRange range = {ds_aspect, 0, 1, 0, 0};
14582         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
14583         m_errorMonitor->VerifyFound();
14584     }
14585 
14586     // Try baseArrayLayer + layerCount > image.arrayLayers
14587     {
14588         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearDepthStencilImage-pRanges-01695");
14589         const VkImageSubresourceRange range = {ds_aspect, 0, 1, 0, 2};
14590         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
14591         m_errorMonitor->VerifyFound();
14592     }
14593 }
14594 
TEST_F(VkLayerTest,ClearColorImageWithinRenderPass)14595 TEST_F(VkLayerTest, ClearColorImageWithinRenderPass) {
14596     // Call CmdClearColorImage within an active RenderPass
14597     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14598                                          "It is invalid to issue this call inside an active render pass");
14599 
14600     ASSERT_NO_FATAL_FAILURE(Init());
14601     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14602 
14603     m_commandBuffer->begin();
14604     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
14605 
14606     VkClearColorValue clear_color;
14607     memset(clear_color.uint32, 0, sizeof(uint32_t) * 4);
14608     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
14609     const int32_t tex_width = 32;
14610     const int32_t tex_height = 32;
14611     VkImageCreateInfo image_create_info = {};
14612     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
14613     image_create_info.pNext = NULL;
14614     image_create_info.imageType = VK_IMAGE_TYPE_2D;
14615     image_create_info.format = tex_format;
14616     image_create_info.extent.width = tex_width;
14617     image_create_info.extent.height = tex_height;
14618     image_create_info.extent.depth = 1;
14619     image_create_info.mipLevels = 1;
14620     image_create_info.arrayLayers = 1;
14621     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
14622     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
14623     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
14624 
14625     vk_testing::Image dstImage;
14626     dstImage.init(*m_device, (const VkImageCreateInfo &)image_create_info);
14627 
14628     const VkImageSubresourceRange range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT);
14629 
14630     vkCmdClearColorImage(m_commandBuffer->handle(), dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &range);
14631 
14632     m_errorMonitor->VerifyFound();
14633 
14634     m_commandBuffer->EndRenderPass();
14635     m_commandBuffer->end();
14636 }
14637 
TEST_F(VkLayerTest,ClearDepthStencilImageErrors)14638 TEST_F(VkLayerTest, ClearDepthStencilImageErrors) {
14639     // Hit errors related to vkCmdClearDepthStencilImage()
14640     // 1. Use an image that doesn't have VK_IMAGE_USAGE_TRANSFER_DST_BIT set
14641     // 2. Call CmdClearDepthStencilImage within an active RenderPass
14642 
14643     ASSERT_NO_FATAL_FAILURE(Init());
14644     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14645 
14646     auto depth_format = FindSupportedDepthStencilFormat(gpu());
14647     if (!depth_format) {
14648         printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
14649         return;
14650     }
14651 
14652     VkClearDepthStencilValue clear_value = {0};
14653     VkMemoryPropertyFlags reqs = 0;
14654     VkImageCreateInfo image_create_info = vk_testing::Image::create_info();
14655     image_create_info.imageType = VK_IMAGE_TYPE_2D;
14656     image_create_info.format = depth_format;
14657     image_create_info.extent.width = 64;
14658     image_create_info.extent.height = 64;
14659     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
14660     // Error here is that VK_IMAGE_USAGE_TRANSFER_DST_BIT is excluded for DS image that we'll call Clear on below
14661     image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
14662 
14663     vk_testing::Image dst_image_bad_usage;
14664     dst_image_bad_usage.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
14665     const VkImageSubresourceRange range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT);
14666 
14667     m_commandBuffer->begin();
14668     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearDepthStencilImage-image-00009");
14669     vkCmdClearDepthStencilImage(m_commandBuffer->handle(), dst_image_bad_usage.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1,
14670                                 &range);
14671     m_errorMonitor->VerifyFound();
14672 
14673     // Fix usage for next test case
14674     image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
14675     vk_testing::Image dst_image;
14676     dst_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs);
14677 
14678     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
14679 
14680     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearDepthStencilImage-renderpass");
14681     vkCmdClearDepthStencilImage(m_commandBuffer->handle(), dst_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1, &range);
14682     m_errorMonitor->VerifyFound();
14683 
14684     m_commandBuffer->EndRenderPass();
14685     m_commandBuffer->end();
14686 }
14687 
TEST_F(VkLayerTest,ClearColorAttachmentsOutsideRenderPass)14688 TEST_F(VkLayerTest, ClearColorAttachmentsOutsideRenderPass) {
14689     // Call CmdClearAttachmentss outside of an active RenderPass
14690 
14691     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14692                                          "vkCmdClearAttachments(): This call must be issued inside an active render pass");
14693 
14694     ASSERT_NO_FATAL_FAILURE(Init());
14695     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14696 
14697     // Start no RenderPass
14698     m_commandBuffer->begin();
14699 
14700     VkClearAttachment color_attachment;
14701     color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
14702     color_attachment.clearValue.color.float32[0] = 0;
14703     color_attachment.clearValue.color.float32[1] = 0;
14704     color_attachment.clearValue.color.float32[2] = 0;
14705     color_attachment.clearValue.color.float32[3] = 0;
14706     color_attachment.colorAttachment = 0;
14707     VkClearRect clear_rect = {{{0, 0}, {32, 32}}};
14708     vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
14709 
14710     m_errorMonitor->VerifyFound();
14711 }
14712 
TEST_F(VkLayerTest,BufferMemoryBarrierNoBuffer)14713 TEST_F(VkLayerTest, BufferMemoryBarrierNoBuffer) {
14714     // Try to add a buffer memory barrier with no buffer.
14715     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14716                                          "required parameter pBufferMemoryBarriers[0].buffer specified as VK_NULL_HANDLE");
14717 
14718     ASSERT_NO_FATAL_FAILURE(Init());
14719     m_commandBuffer->begin();
14720 
14721     VkBufferMemoryBarrier buf_barrier = {};
14722     buf_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
14723     buf_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
14724     buf_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
14725     buf_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
14726     buf_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
14727     buf_barrier.buffer = VK_NULL_HANDLE;
14728     buf_barrier.offset = 0;
14729     buf_barrier.size = VK_WHOLE_SIZE;
14730     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr,
14731                          1, &buf_barrier, 0, nullptr);
14732 
14733     m_errorMonitor->VerifyFound();
14734 }
14735 
TEST_F(VkLayerTest,InvalidBarriers)14736 TEST_F(VkLayerTest, InvalidBarriers) {
14737     TEST_DESCRIPTION("A variety of ways to get VK_INVALID_BARRIER ");
14738 
14739     ASSERT_NO_FATAL_FAILURE(Init());
14740     auto depth_format = FindSupportedDepthStencilFormat(gpu());
14741     if (!depth_format) {
14742         printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
14743         return;
14744     }
14745     // Add a token self-dependency for this test to avoid unexpected errors
14746     m_addRenderPassSelfDependency = true;
14747     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
14748 
14749     m_commandBuffer->begin();
14750 
14751     // Use image unbound to memory in barrier
14752     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14753                                          " used with no memory bound. Memory should be bound by calling vkBindImageMemory()");
14754     vk_testing::Image unbound_image;
14755     auto unbound_image_info = vk_testing::Image::create_info();
14756     unbound_image_info.format = VK_FORMAT_B8G8R8A8_UNORM;
14757     unbound_image_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
14758     unbound_image.init_no_mem(*m_device, unbound_image_info);
14759     auto unbound_subresource = vk_testing::Image::subresource_range(unbound_image_info, VK_IMAGE_ASPECT_COLOR_BIT);
14760     auto unbound_image_barrier = unbound_image.image_memory_barrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
14761                                                                     VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, unbound_subresource);
14762     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0,
14763                          nullptr, 0, nullptr, 1, &unbound_image_barrier);
14764     m_errorMonitor->VerifyFound();
14765 
14766     // Use buffer unbound to memory in barrier
14767     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14768                                          " used with no memory bound. Memory should be bound by calling vkBindBufferMemory()");
14769     VkBufferObj unbound_buffer;
14770     auto unbound_buffer_info = VkBufferObj::create_info(16, VK_IMAGE_USAGE_TRANSFER_DST_BIT);
14771     unbound_buffer.init_no_mem(*m_device, unbound_buffer_info);
14772     auto unbound_buffer_barrier = unbound_buffer.buffer_memory_barrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, 0, 16);
14773     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0,
14774                          nullptr, 1, &unbound_buffer_barrier, 0, nullptr);
14775     m_errorMonitor->VerifyFound();
14776 
14777     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-newLayout-01198");
14778     VkImageObj image(m_device);
14779     image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
14780     ASSERT_TRUE(image.initialized());
14781     VkImageMemoryBarrier img_barrier = {};
14782     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
14783     img_barrier.pNext = NULL;
14784     img_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
14785     img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
14786     img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
14787     // New layout can't be UNDEFINED
14788     img_barrier.newLayout = VK_IMAGE_LAYOUT_UNDEFINED;
14789     img_barrier.image = m_renderTargets[0]->handle();
14790     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
14791     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
14792     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
14793     img_barrier.subresourceRange.baseArrayLayer = 0;
14794     img_barrier.subresourceRange.baseMipLevel = 0;
14795     img_barrier.subresourceRange.layerCount = 1;
14796     img_barrier.subresourceRange.levelCount = 1;
14797     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
14798                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
14799                          &img_barrier);
14800     m_errorMonitor->VerifyFound();
14801 
14802     // Transition image to color attachment optimal
14803     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
14804     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
14805                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
14806                          &img_barrier);
14807 
14808     // TODO: this looks vestigal or incomplete...
14809     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
14810 
14811     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
14812 
14813     // Can't send buffer memory barrier during a render pass
14814     vkCmdEndRenderPass(m_commandBuffer->handle());
14815 
14816     // Duplicate barriers that change layout
14817     img_barrier.image = image.handle();
14818     img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
14819     img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
14820     VkImageMemoryBarrier img_barriers[2] = {img_barrier, img_barrier};
14821 
14822     // Transitions from UNDEFINED  are valid, even if duplicated
14823     m_errorMonitor->ExpectSuccess();
14824     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
14825                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 2,
14826                          img_barriers);
14827     m_errorMonitor->VerifyNotFound();
14828 
14829     // Duplication of layout transitions (not from undefined) are not valid
14830     img_barriers[0].oldLayout = VK_IMAGE_LAYOUT_GENERAL;
14831     img_barriers[0].newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
14832     img_barriers[1].oldLayout = img_barriers[0].oldLayout;
14833     img_barriers[1].newLayout = img_barriers[0].newLayout;
14834     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-oldLayout-01197");
14835     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
14836                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 2,
14837                          img_barriers);
14838     m_errorMonitor->VerifyFound();
14839 
14840     VkBufferObj buffer;
14841     VkMemoryPropertyFlags mem_reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
14842     buffer.init_as_src_and_dst(*m_device, 256, mem_reqs);
14843     VkBufferMemoryBarrier buf_barrier = {};
14844     buf_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
14845     buf_barrier.pNext = NULL;
14846     buf_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
14847     buf_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
14848     buf_barrier.buffer = buffer.handle();
14849     buf_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
14850     buf_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
14851     buf_barrier.offset = 0;
14852     buf_barrier.size = VK_WHOLE_SIZE;
14853 
14854     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferMemoryBarrier-offset-01187");
14855     // Exceed the buffer size
14856     buf_barrier.offset = buffer.create_info().size + 1;
14857     // Offset greater than total size
14858     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
14859                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1, &buf_barrier, 0,
14860                          nullptr);
14861     m_errorMonitor->VerifyFound();
14862     buf_barrier.offset = 0;
14863 
14864     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferMemoryBarrier-size-01189");
14865     buf_barrier.size = buffer.create_info().size + 1;
14866     // Size greater than total size
14867     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
14868                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1, &buf_barrier, 0,
14869                          nullptr);
14870     m_errorMonitor->VerifyFound();
14871 
14872     // Now exercise barrier aspect bit errors, first DS
14873     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageSubresource-aspectMask-parameter");
14874     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-image-01207");
14875     VkDepthStencilObj ds_image(m_device);
14876     ds_image.Init(m_device, 128, 128, depth_format);
14877     ASSERT_TRUE(ds_image.initialized());
14878     img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
14879     img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
14880     img_barrier.image = ds_image.handle();
14881 
14882     // Not having DEPTH or STENCIL set is an error
14883     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
14884     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
14885                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
14886                          &img_barrier);
14887     m_errorMonitor->VerifyFound();
14888 
14889     // Having only one of depth or stencil set for DS image is an error
14890     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-image-01207");
14891     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
14892     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
14893                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
14894                          &img_barrier);
14895     m_errorMonitor->VerifyFound();
14896 
14897     // Having anything other than DEPTH and STENCIL is an error
14898     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageSubresource-aspectMask-parameter");
14899     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_COLOR_BIT;
14900     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
14901                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
14902                          &img_barrier);
14903     m_errorMonitor->VerifyFound();
14904 
14905     // Now test depth-only
14906     VkFormatProperties format_props;
14907     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D16_UNORM, &format_props);
14908     if (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
14909         VkDepthStencilObj d_image(m_device);
14910         d_image.Init(m_device, 128, 128, VK_FORMAT_D16_UNORM);
14911         ASSERT_TRUE(d_image.initialized());
14912         img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
14913         img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
14914         img_barrier.image = d_image.handle();
14915 
14916         // DEPTH bit must be set
14917         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14918                                              "Depth-only image formats must have the VK_IMAGE_ASPECT_DEPTH_BIT set.");
14919         img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
14920         vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
14921                              VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
14922                              &img_barrier);
14923         m_errorMonitor->VerifyFound();
14924 
14925         // No bits other than DEPTH may be set
14926         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14927                                              "Depth-only image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT set.");
14928         img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_COLOR_BIT;
14929         vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
14930                              VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
14931                              &img_barrier);
14932         m_errorMonitor->VerifyFound();
14933     }
14934 
14935     // Now test stencil-only
14936     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_S8_UINT, &format_props);
14937     if (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
14938         VkDepthStencilObj s_image(m_device);
14939         s_image.Init(m_device, 128, 128, VK_FORMAT_S8_UINT);
14940         ASSERT_TRUE(s_image.initialized());
14941         img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
14942         img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
14943         img_barrier.image = s_image.handle();
14944         // Use of COLOR aspect on depth image is error
14945         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14946                                              "Stencil-only image formats must have the VK_IMAGE_ASPECT_STENCIL_BIT set.");
14947         img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
14948         vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
14949                              VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
14950                              &img_barrier);
14951         m_errorMonitor->VerifyFound();
14952     }
14953 
14954     // Finally test color
14955     VkImageObj c_image(m_device);
14956     c_image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
14957     ASSERT_TRUE(c_image.initialized());
14958     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
14959     img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
14960     img_barrier.image = c_image.handle();
14961 
14962     // COLOR bit must be set
14963     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14964                                          "Color image formats must have the VK_IMAGE_ASPECT_COLOR_BIT set.");
14965     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
14966     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
14967                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
14968                          &img_barrier);
14969     m_errorMonitor->VerifyFound();
14970 
14971     // No bits other than COLOR may be set
14972     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
14973                                          "Color image formats must have ONLY the VK_IMAGE_ASPECT_COLOR_BIT set.");
14974     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
14975     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
14976                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
14977                          &img_barrier);
14978     m_errorMonitor->VerifyFound();
14979 
14980     // A barrier's new and old VkImageLayout must be compatible with an image's VkImageUsageFlags.
14981     {
14982         VkImageObj img_color(m_device);
14983         img_color.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
14984         ASSERT_TRUE(img_color.initialized());
14985 
14986         VkImageObj img_ds(m_device);
14987         img_ds.Init(128, 128, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
14988         ASSERT_TRUE(img_ds.initialized());
14989 
14990         VkImageObj img_xfer_src(m_device);
14991         img_xfer_src.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL);
14992         ASSERT_TRUE(img_xfer_src.initialized());
14993 
14994         VkImageObj img_xfer_dst(m_device);
14995         img_xfer_dst.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
14996         ASSERT_TRUE(img_xfer_dst.initialized());
14997 
14998         VkImageObj img_sampled(m_device);
14999         img_sampled.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL);
15000         ASSERT_TRUE(img_sampled.initialized());
15001 
15002         VkImageObj img_input(m_device);
15003         img_input.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
15004         ASSERT_TRUE(img_input.initialized());
15005 
15006         const struct {
15007             VkImageObj &image_obj;
15008             VkImageLayout bad_layout;
15009             std::string msg_code;
15010         } bad_buffer_layouts[] = {
15011             // clang-format off
15012             // images _without_ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
15013             {img_ds,       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,         "VUID-VkImageMemoryBarrier-oldLayout-01208"},
15014             {img_xfer_src, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,         "VUID-VkImageMemoryBarrier-oldLayout-01208"},
15015             {img_xfer_dst, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,         "VUID-VkImageMemoryBarrier-oldLayout-01208"},
15016             {img_sampled,  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,         "VUID-VkImageMemoryBarrier-oldLayout-01208"},
15017             {img_input,    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,         "VUID-VkImageMemoryBarrier-oldLayout-01208"},
15018             // images _without_ VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
15019             {img_color,    VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, "VUID-VkImageMemoryBarrier-oldLayout-01209"},
15020             {img_xfer_src, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, "VUID-VkImageMemoryBarrier-oldLayout-01209"},
15021             {img_xfer_dst, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, "VUID-VkImageMemoryBarrier-oldLayout-01209"},
15022             {img_sampled,  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, "VUID-VkImageMemoryBarrier-oldLayout-01209"},
15023             {img_input,    VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, "VUID-VkImageMemoryBarrier-oldLayout-01209"},
15024             {img_color,    VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,  "VUID-VkImageMemoryBarrier-oldLayout-01210"},
15025             {img_xfer_src, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,  "VUID-VkImageMemoryBarrier-oldLayout-01210"},
15026             {img_xfer_dst, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,  "VUID-VkImageMemoryBarrier-oldLayout-01210"},
15027             {img_sampled,  VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,  "VUID-VkImageMemoryBarrier-oldLayout-01210"},
15028             {img_input,    VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,  "VUID-VkImageMemoryBarrier-oldLayout-01210"},
15029             // images _without_ VK_IMAGE_USAGE_SAMPLED_BIT or VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
15030             {img_color,    VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,         "VUID-VkImageMemoryBarrier-oldLayout-01211"},
15031             {img_ds,       VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,         "VUID-VkImageMemoryBarrier-oldLayout-01211"},
15032             {img_xfer_src, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,         "VUID-VkImageMemoryBarrier-oldLayout-01211"},
15033             {img_xfer_dst, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,         "VUID-VkImageMemoryBarrier-oldLayout-01211"},
15034             // images _without_ VK_IMAGE_USAGE_TRANSFER_SRC_BIT
15035             {img_color,    VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,             "VUID-VkImageMemoryBarrier-oldLayout-01212"},
15036             {img_ds,       VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,             "VUID-VkImageMemoryBarrier-oldLayout-01212"},
15037             {img_xfer_dst, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,             "VUID-VkImageMemoryBarrier-oldLayout-01212"},
15038             {img_sampled,  VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,             "VUID-VkImageMemoryBarrier-oldLayout-01212"},
15039             {img_input,    VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,             "VUID-VkImageMemoryBarrier-oldLayout-01212"},
15040             // images _without_ VK_IMAGE_USAGE_TRANSFER_DST_BIT
15041             {img_color,    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,             "VUID-VkImageMemoryBarrier-oldLayout-01213"},
15042             {img_ds,       VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,             "VUID-VkImageMemoryBarrier-oldLayout-01213"},
15043             {img_xfer_src, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,             "VUID-VkImageMemoryBarrier-oldLayout-01213"},
15044             {img_sampled,  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,             "VUID-VkImageMemoryBarrier-oldLayout-01213"},
15045             {img_input,    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,             "VUID-VkImageMemoryBarrier-oldLayout-01213"},
15046             // clang-format on
15047         };
15048         const uint32_t layout_count = sizeof(bad_buffer_layouts) / sizeof(bad_buffer_layouts[0]);
15049 
15050         for (uint32_t i = 0; i < layout_count; ++i) {
15051             img_barrier.image = bad_buffer_layouts[i].image_obj.handle();
15052             const VkImageUsageFlags usage = bad_buffer_layouts[i].image_obj.usage();
15053             img_barrier.subresourceRange.aspectMask = (usage == VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
15054                                                           ? (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)
15055                                                           : VK_IMAGE_ASPECT_COLOR_BIT;
15056 
15057             img_barrier.oldLayout = bad_buffer_layouts[i].bad_layout;
15058             img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
15059             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, bad_buffer_layouts[i].msg_code);
15060             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
15061                                  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
15062                                  &img_barrier);
15063             m_errorMonitor->VerifyFound();
15064 
15065             img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
15066             img_barrier.newLayout = bad_buffer_layouts[i].bad_layout;
15067             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, bad_buffer_layouts[i].msg_code);
15068             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
15069                                  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
15070                                  &img_barrier);
15071             m_errorMonitor->VerifyFound();
15072         }
15073 
15074         img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
15075         img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
15076     }
15077     // Attempt barrier where srcAccessMask is not supported by srcStageMask
15078     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-pMemoryBarriers-01184");
15079     // Have lower-order bit that's supported (shader write), but higher-order bit not supported to verify multi-bit validation
15080     buf_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_WRITE_BIT;
15081     buf_barrier.offset = 0;
15082     buf_barrier.size = VK_WHOLE_SIZE;
15083     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
15084                          VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1, &buf_barrier, 0, nullptr);
15085     m_errorMonitor->VerifyFound();
15086     // Attempt barrier where dsAccessMask is not supported by dstStageMask
15087     buf_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
15088     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-pMemoryBarriers-01185");
15089     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
15090                          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1, &buf_barrier, 0,
15091                          nullptr);
15092     m_errorMonitor->VerifyFound();
15093 
15094     // Attempt to mismatch barriers/waitEvents calls with incompatible queues
15095     // Create command pool with incompatible queueflags
15096     const std::vector<VkQueueFamilyProperties> queue_props = m_device->queue_props;
15097     uint32_t queue_family_index = m_device->QueueFamilyMatching(VK_QUEUE_GRAPHICS_BIT, VK_QUEUE_COMPUTE_BIT);
15098     if (queue_family_index == UINT32_MAX) {
15099         printf("%s No non-compute queue supporting graphics found; skipped.\n", kSkipPrefix);
15100         return;  // NOTE: this exits the test function!
15101     }
15102     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-srcStageMask-01183");
15103 
15104     VkCommandPoolObj command_pool(m_device, queue_family_index, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
15105     VkCommandBufferObj bad_command_buffer(m_device, &command_pool);
15106 
15107     bad_command_buffer.begin();
15108     buf_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
15109     // Set two bits that should both be supported as a bonus positive check
15110     buf_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT;
15111     vkCmdPipelineBarrier(bad_command_buffer.handle(), VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
15112                          VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1, &buf_barrier, 0, nullptr);
15113     m_errorMonitor->VerifyFound();
15114 
15115     // Check for error for trying to wait on pipeline stage not supported by this queue. Specifically since our queue is not a
15116     // compute queue, vkCmdWaitEvents cannot have it's source stage mask be VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
15117     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdWaitEvents-srcStageMask-01164");
15118     VkEvent event;
15119     VkEventCreateInfo event_create_info{};
15120     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
15121     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
15122     vkCmdWaitEvents(bad_command_buffer.handle(), 1, &event, /*source stage mask*/ VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
15123                     VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, nullptr, 0, nullptr, 0, nullptr);
15124     m_errorMonitor->VerifyFound();
15125     bad_command_buffer.end();
15126 
15127     vkDestroyEvent(m_device->device(), event, nullptr);
15128 }
15129 
15130 // Helpers for the tests below
ValidOwnershipTransferOp(ErrorMonitor * monitor,VkCommandBufferObj * cb,VkPipelineStageFlags src_stages,VkPipelineStageFlags dst_stages,const VkBufferMemoryBarrier * buf_barrier,const VkImageMemoryBarrier * img_barrier)15131 static void ValidOwnershipTransferOp(ErrorMonitor *monitor, VkCommandBufferObj *cb, VkPipelineStageFlags src_stages,
15132                                      VkPipelineStageFlags dst_stages, const VkBufferMemoryBarrier *buf_barrier,
15133                                      const VkImageMemoryBarrier *img_barrier) {
15134     monitor->ExpectSuccess();
15135     cb->begin();
15136     uint32_t num_buf_barrier = (buf_barrier) ? 1 : 0;
15137     uint32_t num_img_barrier = (img_barrier) ? 1 : 0;
15138     cb->PipelineBarrier(src_stages, dst_stages, 0, 0, nullptr, num_buf_barrier, buf_barrier, num_img_barrier, img_barrier);
15139     cb->end();
15140     cb->QueueCommandBuffer();  // Implicitly waits
15141     monitor->VerifyNotFound();
15142 }
ValidOwnershipTransfer(ErrorMonitor * monitor,VkCommandBufferObj * cb_from,VkCommandBufferObj * cb_to,VkPipelineStageFlags src_stages,VkPipelineStageFlags dst_stages,const VkBufferMemoryBarrier * buf_barrier,const VkImageMemoryBarrier * img_barrier)15143 static void ValidOwnershipTransfer(ErrorMonitor *monitor, VkCommandBufferObj *cb_from, VkCommandBufferObj *cb_to,
15144                                    VkPipelineStageFlags src_stages, VkPipelineStageFlags dst_stages,
15145                                    const VkBufferMemoryBarrier *buf_barrier, const VkImageMemoryBarrier *img_barrier) {
15146     ValidOwnershipTransferOp(monitor, cb_from, src_stages, dst_stages, buf_barrier, img_barrier);
15147     ValidOwnershipTransferOp(monitor, cb_to, src_stages, dst_stages, buf_barrier, img_barrier);
15148 }
15149 
TEST_F(VkPositiveLayerTest,OwnershipTranfersImage)15150 TEST_F(VkPositiveLayerTest, OwnershipTranfersImage) {
15151     TEST_DESCRIPTION("Valid image ownership transfers that shouldn't create errors");
15152     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
15153 
15154     uint32_t no_gfx = m_device->QueueFamilyWithoutCapabilities(VK_QUEUE_GRAPHICS_BIT);
15155     if (no_gfx == UINT32_MAX) {
15156         printf("%s Required queue families not present (non-graphics capable required).\n", kSkipPrefix);
15157         return;
15158     }
15159     VkQueueObj *no_gfx_queue = m_device->queue_family_queues(no_gfx)[0].get();
15160 
15161     VkCommandPoolObj no_gfx_pool(m_device, no_gfx, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
15162     VkCommandBufferObj no_gfx_cb(m_device, &no_gfx_pool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, no_gfx_queue);
15163 
15164     // Create an "exclusive" image owned by the graphics queue.
15165     VkImageObj image(m_device);
15166     VkFlags image_use = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
15167     image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, image_use, VK_IMAGE_TILING_OPTIMAL, 0);
15168     ASSERT_TRUE(image.initialized());
15169     auto image_subres = image.subresource_range(VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1);
15170     auto image_barrier = image.image_memory_barrier(0, 0, image.Layout(), image.Layout(), image_subres);
15171     image_barrier.srcQueueFamilyIndex = m_device->graphics_queue_node_index_;
15172     image_barrier.dstQueueFamilyIndex = no_gfx;
15173 
15174     ValidOwnershipTransfer(m_errorMonitor, m_commandBuffer, &no_gfx_cb, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
15175                            VK_PIPELINE_STAGE_TRANSFER_BIT, nullptr, &image_barrier);
15176 
15177     // Change layouts while changing ownership
15178     image_barrier.srcQueueFamilyIndex = no_gfx;
15179     image_barrier.dstQueueFamilyIndex = m_device->graphics_queue_node_index_;
15180     image_barrier.oldLayout = image.Layout();
15181     // Make sure the new layout is different from the old
15182     if (image_barrier.oldLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
15183         image_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
15184     } else {
15185         image_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
15186     }
15187 
15188     ValidOwnershipTransfer(m_errorMonitor, &no_gfx_cb, m_commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
15189                            VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, nullptr, &image_barrier);
15190 }
15191 
TEST_F(VkPositiveLayerTest,OwnershipTranfersBuffer)15192 TEST_F(VkPositiveLayerTest, OwnershipTranfersBuffer) {
15193     TEST_DESCRIPTION("Valid buffer ownership transfers that shouldn't create errors");
15194     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
15195 
15196     uint32_t no_gfx = m_device->QueueFamilyWithoutCapabilities(VK_QUEUE_GRAPHICS_BIT);
15197     if (no_gfx == UINT32_MAX) {
15198         printf("%s Required queue families not present (non-graphics capable required).\n", kSkipPrefix);
15199         return;
15200     }
15201     VkQueueObj *no_gfx_queue = m_device->queue_family_queues(no_gfx)[0].get();
15202 
15203     VkCommandPoolObj no_gfx_pool(m_device, no_gfx, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
15204     VkCommandBufferObj no_gfx_cb(m_device, &no_gfx_pool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, no_gfx_queue);
15205 
15206     // Create a buffer
15207     const VkDeviceSize buffer_size = 256;
15208     uint8_t data[buffer_size] = {0xFF};
15209     VkConstantBufferObj buffer(m_device, buffer_size, data, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT);
15210     ASSERT_TRUE(buffer.initialized());
15211     auto buffer_barrier = buffer.buffer_memory_barrier(0, 0, 0, VK_WHOLE_SIZE);
15212 
15213     // Let gfx own it.
15214     buffer_barrier.srcQueueFamilyIndex = m_device->graphics_queue_node_index_;
15215     buffer_barrier.dstQueueFamilyIndex = m_device->graphics_queue_node_index_;
15216     ValidOwnershipTransferOp(m_errorMonitor, m_commandBuffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
15217                              &buffer_barrier, nullptr);
15218 
15219     // Transfer it to non-gfx
15220     buffer_barrier.dstQueueFamilyIndex = no_gfx;
15221     ValidOwnershipTransfer(m_errorMonitor, m_commandBuffer, &no_gfx_cb, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
15222                            VK_PIPELINE_STAGE_TRANSFER_BIT, &buffer_barrier, nullptr);
15223 
15224     // Transfer it to gfx
15225     buffer_barrier.srcQueueFamilyIndex = no_gfx;
15226     buffer_barrier.dstQueueFamilyIndex = m_device->graphics_queue_node_index_;
15227     ValidOwnershipTransfer(m_errorMonitor, &no_gfx_cb, m_commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
15228                            VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, &buffer_barrier, nullptr);
15229 }
15230 
15231 class BarrierQueueFamilyTestHelper {
15232    public:
15233     struct QueueFamilyObjs {
15234         uint32_t index;
15235         // We would use std::unique_ptr, but this triggers a compiler error on older compilers
15236         VkQueueObj *queue = nullptr;
15237         VkCommandPoolObj *command_pool = nullptr;
15238         VkCommandBufferObj *command_buffer = nullptr;
15239         VkCommandBufferObj *command_buffer2 = nullptr;
~QueueFamilyObjsBarrierQueueFamilyTestHelper::QueueFamilyObjs15240         ~QueueFamilyObjs() {
15241             delete command_buffer2;
15242             delete command_buffer;
15243             delete command_pool;
15244             delete queue;
15245         }
15246 
InitBarrierQueueFamilyTestHelper::QueueFamilyObjs15247         void Init(VkDeviceObj *device, uint32_t qf_index, VkQueue qf_queue, VkCommandPoolCreateFlags cp_flags) {
15248             index = qf_index;
15249             queue = new VkQueueObj(qf_queue, qf_index);
15250             command_pool = new VkCommandPoolObj(device, qf_index, cp_flags);
15251             command_buffer = new VkCommandBufferObj(device, command_pool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, queue);
15252             command_buffer2 = new VkCommandBufferObj(device, command_pool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, queue);
15253         };
15254     };
15255 
15256     struct Context {
15257         VkLayerTest *layer_test;
15258         uint32_t default_index;
15259         std::unordered_map<uint32_t, QueueFamilyObjs> queue_families;
ContextBarrierQueueFamilyTestHelper::Context15260         Context(VkLayerTest *test, const std::vector<uint32_t> &queue_family_indices) : layer_test(test) {
15261             if (0 == queue_family_indices.size()) {
15262                 return;  // This is invalid
15263             }
15264             VkDeviceObj *device_obj = layer_test->DeviceObj();
15265             queue_families.reserve(queue_family_indices.size());
15266             default_index = queue_family_indices[0];
15267             for (auto qfi : queue_family_indices) {
15268                 VkQueue queue = device_obj->queue_family_queues(qfi)[0]->handle();
15269                 queue_families.emplace(std::make_pair(qfi, QueueFamilyObjs()));
15270                 queue_families[qfi].Init(device_obj, qfi, queue, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
15271             }
15272             Reset();
15273         }
ResetBarrierQueueFamilyTestHelper::Context15274         void Reset() {
15275             layer_test->DeviceObj()->wait();
15276             for (auto &qf : queue_families) {
15277                 vkResetCommandPool(layer_test->device(), qf.second.command_pool->handle(), 0);
15278             }
15279         }
15280     };
15281 
BarrierQueueFamilyTestHelper(Context * context)15282     BarrierQueueFamilyTestHelper(Context *context) : context_(context), image_(context->layer_test->DeviceObj()) {}
15283     // Init with queue families non-null for CONCURRENT sharing mode (which requires them)
Init(std::vector<uint32_t> * families)15284     void Init(std::vector<uint32_t> *families) {
15285         VkDeviceObj *device_obj = context_->layer_test->DeviceObj();
15286         image_.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0, families);
15287         ASSERT_TRUE(image_.initialized());
15288 
15289         image_barrier_ =
15290             image_.image_memory_barrier(VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_TRANSFER_READ_BIT, image_.Layout(), image_.Layout(),
15291                                         image_.subresource_range(VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1));
15292 
15293         VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
15294         buffer_.init_as_src_and_dst(*device_obj, 256, mem_prop, families);
15295         ASSERT_TRUE(buffer_.initialized());
15296         buffer_barrier_ = buffer_.buffer_memory_barrier(VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_TRANSFER_READ_BIT, 0, VK_WHOLE_SIZE);
15297     }
15298 
GetQueueFamilyInfo(Context * context,uint32_t qfi)15299     QueueFamilyObjs *GetQueueFamilyInfo(Context *context, uint32_t qfi) {
15300         QueueFamilyObjs *qf;
15301 
15302         auto qf_it = context->queue_families.find(qfi);
15303         if (qf_it != context->queue_families.end()) {
15304             qf = &(qf_it->second);
15305         } else {
15306             qf = &(context->queue_families[context->default_index]);
15307         }
15308         return qf;
15309     }
15310     enum Modifier {
15311         NONE,
15312         DOUBLE_RECORD,
15313         DOUBLE_COMMAND_BUFFER,
15314     };
15315 
operator ()(std::string img_err,std::string buf_err,uint32_t src,uint32_t dst,bool positive=false,uint32_t queue_family_index=kInvalidQueueFamily,Modifier mod=Modifier::NONE)15316     void operator()(std::string img_err, std::string buf_err, uint32_t src, uint32_t dst, bool positive = false,
15317                     uint32_t queue_family_index = kInvalidQueueFamily, Modifier mod = Modifier::NONE) {
15318         auto monitor = context_->layer_test->Monitor();
15319         monitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT, img_err);
15320         monitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT, buf_err);
15321 
15322         image_barrier_.srcQueueFamilyIndex = src;
15323         image_barrier_.dstQueueFamilyIndex = dst;
15324         buffer_barrier_.srcQueueFamilyIndex = src;
15325         buffer_barrier_.dstQueueFamilyIndex = dst;
15326 
15327         QueueFamilyObjs *qf = GetQueueFamilyInfo(context_, queue_family_index);
15328 
15329         VkCommandBufferObj *command_buffer = qf->command_buffer;
15330         for (int cb_repeat = 0; cb_repeat < (mod == Modifier::DOUBLE_COMMAND_BUFFER ? 2 : 1); cb_repeat++) {
15331             command_buffer->begin();
15332             for (int repeat = 0; repeat < (mod == Modifier::DOUBLE_RECORD ? 2 : 1); repeat++) {
15333                 vkCmdPipelineBarrier(command_buffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
15334                                      VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1, &buffer_barrier_, 1, &image_barrier_);
15335             }
15336             command_buffer->end();
15337             command_buffer = qf->command_buffer2;  // Second pass (if any) goes to the secondary command_buffer.
15338         }
15339 
15340         if (queue_family_index != kInvalidQueueFamily) {
15341             if (mod == Modifier::DOUBLE_COMMAND_BUFFER) {
15342                 // the Fence resolves to VK_NULL_HANLE... i.e. no fence
15343                 qf->queue->submit({{qf->command_buffer, qf->command_buffer2}}, vk_testing::Fence(), positive);
15344             } else {
15345                 qf->command_buffer->QueueCommandBuffer(positive);  // Check for success on positive tests only
15346             }
15347         }
15348 
15349         if (positive) {
15350             monitor->VerifyNotFound();
15351         } else {
15352             monitor->VerifyFound();
15353         }
15354         context_->Reset();
15355     };
15356 
15357    protected:
15358     static const uint32_t kInvalidQueueFamily = UINT32_MAX;
15359     Context *context_;
15360     VkImageObj image_;
15361     VkImageMemoryBarrier image_barrier_;
15362     VkBufferObj buffer_;
15363     VkBufferMemoryBarrier buffer_barrier_;
15364 };
15365 
TEST_F(VkLayerTest,InvalidBarrierQueueFamily)15366 TEST_F(VkLayerTest, InvalidBarrierQueueFamily) {
15367     TEST_DESCRIPTION("Create and submit barriers with invalid queue families");
15368     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
15369 
15370     // Find queues of two families
15371     const uint32_t submit_family = m_device->graphics_queue_node_index_;
15372     const uint32_t invalid = static_cast<uint32_t>(m_device->queue_props.size());
15373     const uint32_t other_family = submit_family != 0 ? 0 : 1;
15374     const bool only_one_family = (invalid == 1) || (m_device->queue_props[other_family].queueCount == 0);
15375 
15376     std::vector<uint32_t> qf_indices{{submit_family, other_family}};
15377     if (only_one_family) {
15378         qf_indices.resize(1);
15379     }
15380     BarrierQueueFamilyTestHelper::Context test_context(this, qf_indices);
15381 
15382     if (m_device->props.apiVersion >= VK_API_VERSION_1_1) {
15383         printf(
15384             "%s Device has apiVersion greater than 1.0 -- skipping test cases that require external memory "
15385             "to be "
15386             "disabled.\n",
15387             kSkipPrefix);
15388     } else {
15389         if (only_one_family) {
15390             printf("%s Single queue family found -- VK_SHARING_MODE_CONCURRENT testcases skipped.\n", kSkipPrefix);
15391         } else {
15392             std::vector<uint32_t> families = {submit_family, other_family};
15393             BarrierQueueFamilyTestHelper conc_test(&test_context);
15394             conc_test.Init(&families);
15395             // core_validation::barrier_queue_families::kSrcAndDestMustBeIgnore
15396             conc_test("VUID-VkImageMemoryBarrier-image-01199", "VUID-VkBufferMemoryBarrier-buffer-01190", VK_QUEUE_FAMILY_IGNORED,
15397                       submit_family);
15398             conc_test("VUID-VkImageMemoryBarrier-image-01199", "VUID-VkBufferMemoryBarrier-buffer-01190", submit_family,
15399                       VK_QUEUE_FAMILY_IGNORED);
15400             conc_test("VUID-VkImageMemoryBarrier-image-01199", "VUID-VkBufferMemoryBarrier-buffer-01190", submit_family,
15401                       submit_family);
15402             // true -> positive test
15403             conc_test("VUID-VkImageMemoryBarrier-image-01199", "VUID-VkBufferMemoryBarrier-buffer-01190", VK_QUEUE_FAMILY_IGNORED,
15404                       VK_QUEUE_FAMILY_IGNORED, true);
15405         }
15406 
15407         BarrierQueueFamilyTestHelper excl_test(&test_context);
15408         excl_test.Init(nullptr);  // no queue families means *exclusive* sharing mode.
15409 
15410         // core_validation::barrier_queue_families::kBothIgnoreOrBothValid
15411         excl_test("VUID-VkImageMemoryBarrier-image-01200", "VUID-VkBufferMemoryBarrier-buffer-01192", VK_QUEUE_FAMILY_IGNORED,
15412                   submit_family);
15413         excl_test("VUID-VkImageMemoryBarrier-image-01200", "VUID-VkBufferMemoryBarrier-buffer-01192", submit_family,
15414                   VK_QUEUE_FAMILY_IGNORED);
15415         // true -> positive test
15416         excl_test("VUID-VkImageMemoryBarrier-image-01200", "VUID-VkBufferMemoryBarrier-buffer-01192", submit_family, submit_family,
15417                   true);
15418         excl_test("VUID-VkImageMemoryBarrier-image-01200", "VUID-VkBufferMemoryBarrier-buffer-01192", VK_QUEUE_FAMILY_IGNORED,
15419                   VK_QUEUE_FAMILY_IGNORED, true);
15420     }
15421 
15422     if (only_one_family) {
15423         printf("%s Single queue family found -- VK_SHARING_MODE_EXCLUSIVE submit testcases skipped.\n", kSkipPrefix);
15424     } else {
15425         BarrierQueueFamilyTestHelper excl_test(&test_context);
15426         excl_test.Init(nullptr);
15427 
15428         // core_validation::barrier_queue_families::kSubmitQueueMustMatchSrcOrDst
15429         excl_test("VUID-VkImageMemoryBarrier-image-01205", "VUID-VkBufferMemoryBarrier-buffer-01196", other_family, other_family,
15430                   false, submit_family);
15431 
15432         // true -> positive test (testing both the index logic and the QFO transfer tracking.
15433         excl_test("POSITIVE_TEST", "POSITIVE_TEST", submit_family, other_family, true, submit_family);
15434         excl_test("POSITIVE_TEST", "POSITIVE_TEST", submit_family, other_family, true, other_family);
15435         excl_test("POSITIVE_TEST", "POSITIVE_TEST", other_family, submit_family, true, other_family);
15436         excl_test("POSITIVE_TEST", "POSITIVE_TEST", other_family, submit_family, true, submit_family);
15437 
15438         // negative testing for QFO transfer tracking
15439         // Duplicate release in one CB
15440         excl_test("UNASSIGNED-VkImageMemoryBarrier-image-00001", "UNASSIGNED-VkBufferMemoryBarrier-buffer-00001", submit_family,
15441                   other_family, false, submit_family, BarrierQueueFamilyTestHelper::DOUBLE_RECORD);
15442         // Duplicate pending release
15443         excl_test("UNASSIGNED-VkImageMemoryBarrier-image-00003", "UNASSIGNED-VkBufferMemoryBarrier-buffer-00003", submit_family,
15444                   other_family, false, submit_family);
15445         // Duplicate acquire in one CB
15446         excl_test("UNASSIGNED-VkImageMemoryBarrier-image-00001", "UNASSIGNED-VkBufferMemoryBarrier-buffer-00001", submit_family,
15447                   other_family, false, other_family, BarrierQueueFamilyTestHelper::DOUBLE_RECORD);
15448         // No pending release
15449         excl_test("UNASSIGNED-VkImageMemoryBarrier-image-00004", "UNASSIGNED-VkBufferMemoryBarrier-buffer-00004", submit_family,
15450                   other_family, false, other_family);
15451         // Duplicate release in two CB
15452         excl_test("UNASSIGNED-VkImageMemoryBarrier-image-00002", "UNASSIGNED-VkBufferMemoryBarrier-buffer-00002", submit_family,
15453                   other_family, false, submit_family, BarrierQueueFamilyTestHelper::DOUBLE_COMMAND_BUFFER);
15454         // Duplicate acquire in two CB
15455         excl_test("POSITIVE_TEST", "POSITIVE_TEST", submit_family, other_family, true, submit_family);  // need a succesful release
15456         excl_test("UNASSIGNED-VkImageMemoryBarrier-image-00002", "UNASSIGNED-VkBufferMemoryBarrier-buffer-00002", submit_family,
15457                   other_family, false, other_family, BarrierQueueFamilyTestHelper::DOUBLE_COMMAND_BUFFER);
15458     }
15459 }
15460 
TEST_F(VkLayerTest,InvalidBarrierQueueFamilyWithMemExt)15461 TEST_F(VkLayerTest, InvalidBarrierQueueFamilyWithMemExt) {
15462     TEST_DESCRIPTION("Create and submit barriers with invalid queue families when memory extension is enabled ");
15463     std::vector<const char *> reqd_instance_extensions = {
15464         {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME}};
15465     for (auto extension_name : reqd_instance_extensions) {
15466         if (InstanceExtensionSupported(extension_name)) {
15467             m_instance_extension_names.push_back(extension_name);
15468         } else {
15469             printf("%s Required instance extension %s not supported, skipping test\n", kSkipPrefix, extension_name);
15470             return;
15471         }
15472     }
15473 
15474     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
15475     // Check for external memory device extensions
15476     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME)) {
15477         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
15478     } else {
15479         printf("%s External memory extension not supported, skipping test\n", kSkipPrefix);
15480         return;
15481     }
15482 
15483     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
15484 
15485     // Find queues of two families
15486     const uint32_t submit_family = m_device->graphics_queue_node_index_;
15487     const uint32_t invalid = static_cast<uint32_t>(m_device->queue_props.size());
15488     const uint32_t other_family = submit_family != 0 ? 0 : 1;
15489     const bool only_one_family = (invalid == 1) || (m_device->queue_props[other_family].queueCount == 0);
15490 
15491     std::vector<uint32_t> qf_indices{{submit_family, other_family}};
15492     if (only_one_family) {
15493         qf_indices.resize(1);
15494     }
15495     BarrierQueueFamilyTestHelper::Context test_context(this, qf_indices);
15496 
15497     if (only_one_family) {
15498         printf("%s Single queue family found -- VK_SHARING_MODE_CONCURRENT testcases skipped.\n", kSkipPrefix);
15499     } else {
15500         std::vector<uint32_t> families = {submit_family, other_family};
15501         BarrierQueueFamilyTestHelper conc_test(&test_context);
15502 
15503         // core_validation::barrier_queue_families::kSrcOrDstMustBeIgnore
15504         conc_test.Init(&families);
15505         conc_test("VUID-VkImageMemoryBarrier-image-01381", "VUID-VkBufferMemoryBarrier-buffer-01191", submit_family, submit_family);
15506         // true -> positive test
15507         conc_test("VUID-VkImageMemoryBarrier-image-01381", "VUID-VkBufferMemoryBarrier-buffer-01191", VK_QUEUE_FAMILY_IGNORED,
15508                   VK_QUEUE_FAMILY_IGNORED, true);
15509         conc_test("VUID-VkImageMemoryBarrier-image-01381", "VUID-VkBufferMemoryBarrier-buffer-01191", VK_QUEUE_FAMILY_IGNORED,
15510                   VK_QUEUE_FAMILY_EXTERNAL_KHR, true);
15511         conc_test("VUID-VkImageMemoryBarrier-image-01381", "VUID-VkBufferMemoryBarrier-buffer-01191", VK_QUEUE_FAMILY_EXTERNAL_KHR,
15512                   VK_QUEUE_FAMILY_IGNORED, true);
15513 
15514         // core_validation::barrier_queue_families::kSpecialOrIgnoreOnly
15515         conc_test("VUID-VkImageMemoryBarrier-image-01766", "VUID-VkBufferMemoryBarrier-buffer-01763", submit_family,
15516                   VK_QUEUE_FAMILY_IGNORED);
15517         conc_test("VUID-VkImageMemoryBarrier-image-01766", "VUID-VkBufferMemoryBarrier-buffer-01763", VK_QUEUE_FAMILY_IGNORED,
15518                   submit_family);
15519         // This is to flag the errors that would be considered only "unexpected" in the parallel case above
15520         // true -> positive test
15521         conc_test("VUID-VkImageMemoryBarrier-image-01766", "VUID-VkBufferMemoryBarrier-buffer-01763", VK_QUEUE_FAMILY_IGNORED,
15522                   VK_QUEUE_FAMILY_EXTERNAL_KHR, true);
15523         conc_test("VUID-VkImageMemoryBarrier-image-01766", "VUID-VkBufferMemoryBarrier-buffer-01763", VK_QUEUE_FAMILY_EXTERNAL_KHR,
15524                   VK_QUEUE_FAMILY_IGNORED, true);
15525     }
15526 
15527     BarrierQueueFamilyTestHelper excl_test(&test_context);
15528     excl_test.Init(nullptr);  // no queue families means *exclusive* sharing mode.
15529 
15530     // core_validation::barrier_queue_families::kSrcIgnoreRequiresDstIgnore
15531     excl_test("VUID-VkImageMemoryBarrier-image-01201", "VUID-VkBufferMemoryBarrier-buffer-01193", VK_QUEUE_FAMILY_IGNORED,
15532               submit_family);
15533     excl_test("VUID-VkImageMemoryBarrier-image-01201", "VUID-VkBufferMemoryBarrier-buffer-01193", VK_QUEUE_FAMILY_IGNORED,
15534               VK_QUEUE_FAMILY_EXTERNAL_KHR);
15535     // true -> positive test
15536     excl_test("VUID-VkImageMemoryBarrier-image-01201", "VUID-VkBufferMemoryBarrier-buffer-01193", VK_QUEUE_FAMILY_IGNORED,
15537               VK_QUEUE_FAMILY_IGNORED, true);
15538 
15539     // core_validation::barrier_queue_families::kDstValidOrSpecialIfNotIgnore
15540     excl_test("VUID-VkImageMemoryBarrier-image-01768", "VUID-VkBufferMemoryBarrier-buffer-01765", submit_family, invalid);
15541     // true -> positive test
15542     excl_test("VUID-VkImageMemoryBarrier-image-01768", "VUID-VkBufferMemoryBarrier-buffer-01765", submit_family, submit_family,
15543               true);
15544     excl_test("VUID-VkImageMemoryBarrier-image-01768", "VUID-VkBufferMemoryBarrier-buffer-01765", submit_family,
15545               VK_QUEUE_FAMILY_IGNORED, true);
15546     excl_test("VUID-VkImageMemoryBarrier-image-01768", "VUID-VkBufferMemoryBarrier-buffer-01765", submit_family,
15547               VK_QUEUE_FAMILY_EXTERNAL_KHR, true);
15548 
15549     // core_validation::barrier_queue_families::kSrcValidOrSpecialIfNotIgnore
15550     excl_test("VUID-VkImageMemoryBarrier-image-01767", "VUID-VkBufferMemoryBarrier-buffer-01764", invalid, submit_family);
15551     // true -> positive test
15552     excl_test("VUID-VkImageMemoryBarrier-image-01767", "VUID-VkBufferMemoryBarrier-buffer-01764", submit_family, submit_family,
15553               true);
15554     excl_test("VUID-VkImageMemoryBarrier-image-01767", "VUID-VkBufferMemoryBarrier-buffer-01764", VK_QUEUE_FAMILY_IGNORED,
15555               VK_QUEUE_FAMILY_IGNORED, true);
15556     excl_test("VUID-VkImageMemoryBarrier-image-01767", "VUID-VkBufferMemoryBarrier-buffer-01764", VK_QUEUE_FAMILY_EXTERNAL_KHR,
15557               submit_family, true);
15558 }
15559 
TEST_F(VkLayerTest,ImageBarrierWithBadRange)15560 TEST_F(VkLayerTest, ImageBarrierWithBadRange) {
15561     TEST_DESCRIPTION("VkImageMemoryBarrier with an invalid subresourceRange");
15562 
15563     ASSERT_NO_FATAL_FAILURE(Init());
15564     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15565 
15566     VkImageObj image(m_device);
15567     image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
15568     ASSERT_TRUE(image.create_info().arrayLayers == 1);
15569     ASSERT_TRUE(image.initialized());
15570 
15571     VkImageMemoryBarrier img_barrier_template = {};
15572     img_barrier_template.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
15573     img_barrier_template.pNext = NULL;
15574     img_barrier_template.srcAccessMask = 0;
15575     img_barrier_template.dstAccessMask = 0;
15576     img_barrier_template.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
15577     img_barrier_template.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
15578     img_barrier_template.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
15579     img_barrier_template.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
15580     img_barrier_template.image = image.handle();
15581     // subresourceRange to be set later for the for the purposes of this test
15582     img_barrier_template.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
15583     img_barrier_template.subresourceRange.baseArrayLayer = 0;
15584     img_barrier_template.subresourceRange.baseMipLevel = 0;
15585     img_barrier_template.subresourceRange.layerCount = 0;
15586     img_barrier_template.subresourceRange.levelCount = 0;
15587 
15588     m_commandBuffer->begin();
15589 
15590     // Nested scope here confuses clang-format, somehow
15591     // clang-format off
15592 
15593     // try for vkCmdPipelineBarrier
15594     {
15595         // Try baseMipLevel >= image.mipLevels with VK_REMAINING_MIP_LEVELS
15596         {
15597             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-subresourceRange-01486");
15598             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, VK_REMAINING_MIP_LEVELS, 0, 1};
15599             VkImageMemoryBarrier img_barrier = img_barrier_template;
15600             img_barrier.subresourceRange = range;
15601             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
15602                                  nullptr, 0, nullptr, 1, &img_barrier);
15603             m_errorMonitor->VerifyFound();
15604         }
15605 
15606         // Try baseMipLevel >= image.mipLevels without VK_REMAINING_MIP_LEVELS
15607         {
15608             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-subresourceRange-01486");
15609             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-subresourceRange-01724");
15610             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 0, 1};
15611             VkImageMemoryBarrier img_barrier = img_barrier_template;
15612             img_barrier.subresourceRange = range;
15613             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
15614                                  nullptr, 0, nullptr, 1, &img_barrier);
15615             m_errorMonitor->VerifyFound();
15616         }
15617 
15618         // Try levelCount = 0
15619         {
15620             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-subresourceRange-01724");
15621             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 0, 1};
15622             VkImageMemoryBarrier img_barrier = img_barrier_template;
15623             img_barrier.subresourceRange = range;
15624             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
15625                                  nullptr, 0, nullptr, 1, &img_barrier);
15626             m_errorMonitor->VerifyFound();
15627         }
15628 
15629         // Try baseMipLevel + levelCount > image.mipLevels
15630         {
15631             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-subresourceRange-01724");
15632             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 2, 0, 1};
15633             VkImageMemoryBarrier img_barrier = img_barrier_template;
15634             img_barrier.subresourceRange = range;
15635             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
15636                                  nullptr, 0, nullptr, 1, &img_barrier);
15637             m_errorMonitor->VerifyFound();
15638         }
15639 
15640         // Try baseArrayLayer >= image.arrayLayers with VK_REMAINING_ARRAY_LAYERS
15641         {
15642             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-subresourceRange-01488");
15643             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, VK_REMAINING_ARRAY_LAYERS};
15644             VkImageMemoryBarrier img_barrier = img_barrier_template;
15645             img_barrier.subresourceRange = range;
15646             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
15647                                  nullptr, 0, nullptr, 1, &img_barrier);
15648             m_errorMonitor->VerifyFound();
15649         }
15650 
15651         // Try baseArrayLayer >= image.arrayLayers without VK_REMAINING_ARRAY_LAYERS
15652         {
15653             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-subresourceRange-01488");
15654             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-subresourceRange-01725");
15655             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, 1};
15656             VkImageMemoryBarrier img_barrier = img_barrier_template;
15657             img_barrier.subresourceRange = range;
15658             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
15659                                  nullptr, 0, nullptr, 1, &img_barrier);
15660             m_errorMonitor->VerifyFound();
15661         }
15662 
15663         // Try layerCount = 0
15664         {
15665             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-subresourceRange-01725");
15666             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 0};
15667             VkImageMemoryBarrier img_barrier = img_barrier_template;
15668             img_barrier.subresourceRange = range;
15669             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
15670                                  nullptr, 0, nullptr, 1, &img_barrier);
15671             m_errorMonitor->VerifyFound();
15672         }
15673 
15674         // Try baseArrayLayer + layerCount > image.arrayLayers
15675         {
15676             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-subresourceRange-01725");
15677             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 2};
15678             VkImageMemoryBarrier img_barrier = img_barrier_template;
15679             img_barrier.subresourceRange = range;
15680             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
15681                                  nullptr, 0, nullptr, 1, &img_barrier);
15682             m_errorMonitor->VerifyFound();
15683         }
15684     }
15685 
15686     // try for vkCmdWaitEvents
15687     {
15688         VkEvent event;
15689         VkEventCreateInfo eci{VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, NULL, 0};
15690         VkResult err = vkCreateEvent(m_device->handle(), &eci, nullptr, &event);
15691         ASSERT_VK_SUCCESS(err);
15692 
15693         // Try baseMipLevel >= image.mipLevels with VK_REMAINING_MIP_LEVELS
15694         {
15695             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-subresourceRange-01486");
15696             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, VK_REMAINING_MIP_LEVELS, 0, 1};
15697             VkImageMemoryBarrier img_barrier = img_barrier_template;
15698             img_barrier.subresourceRange = range;
15699             vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
15700                             VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
15701             m_errorMonitor->VerifyFound();
15702         }
15703 
15704         // Try baseMipLevel >= image.mipLevels without VK_REMAINING_MIP_LEVELS
15705         {
15706             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-subresourceRange-01486");
15707             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-subresourceRange-01724");
15708             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 0, 1};
15709             VkImageMemoryBarrier img_barrier = img_barrier_template;
15710             img_barrier.subresourceRange = range;
15711             vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
15712                             VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
15713             m_errorMonitor->VerifyFound();
15714         }
15715 
15716         // Try levelCount = 0
15717         {
15718             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-subresourceRange-01724");
15719             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 0, 1};
15720             VkImageMemoryBarrier img_barrier = img_barrier_template;
15721             img_barrier.subresourceRange = range;
15722             vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
15723                             VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
15724             m_errorMonitor->VerifyFound();
15725         }
15726 
15727         // Try baseMipLevel + levelCount > image.mipLevels
15728         {
15729             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-subresourceRange-01724");
15730             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 2, 0, 1};
15731             VkImageMemoryBarrier img_barrier = img_barrier_template;
15732             img_barrier.subresourceRange = range;
15733             vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
15734                             VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
15735             m_errorMonitor->VerifyFound();
15736         }
15737 
15738         // Try baseArrayLayer >= image.arrayLayers with VK_REMAINING_ARRAY_LAYERS
15739         {
15740             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-subresourceRange-01488");
15741             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, VK_REMAINING_ARRAY_LAYERS};
15742             VkImageMemoryBarrier img_barrier = img_barrier_template;
15743             img_barrier.subresourceRange = range;
15744             vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
15745                             VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
15746             m_errorMonitor->VerifyFound();
15747         }
15748 
15749         // Try baseArrayLayer >= image.arrayLayers without VK_REMAINING_ARRAY_LAYERS
15750         {
15751             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-subresourceRange-01488");
15752             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-subresourceRange-01725");
15753             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, 1};
15754             VkImageMemoryBarrier img_barrier = img_barrier_template;
15755             img_barrier.subresourceRange = range;
15756             vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
15757                             VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
15758             m_errorMonitor->VerifyFound();
15759         }
15760 
15761         // Try layerCount = 0
15762         {
15763             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-subresourceRange-01725");
15764             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 0};
15765             VkImageMemoryBarrier img_barrier = img_barrier_template;
15766             img_barrier.subresourceRange = range;
15767             vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
15768                             VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
15769             m_errorMonitor->VerifyFound();
15770         }
15771 
15772         // Try baseArrayLayer + layerCount > image.arrayLayers
15773         {
15774             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-subresourceRange-01725");
15775             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 2};
15776             VkImageMemoryBarrier img_barrier = img_barrier_template;
15777             img_barrier.subresourceRange = range;
15778             vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
15779                             VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
15780             m_errorMonitor->VerifyFound();
15781         }
15782 
15783         vkDestroyEvent(m_device->handle(), event, nullptr);
15784     }
15785 // clang-format on
15786 }
15787 
TEST_F(VkLayerTest,ValidationCacheTestBadMerge)15788 TEST_F(VkLayerTest, ValidationCacheTestBadMerge) {
15789     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
15790     if (DeviceExtensionSupported(gpu(), "VK_LAYER_LUNARG_core_validation", VK_EXT_VALIDATION_CACHE_EXTENSION_NAME)) {
15791         m_device_extension_names.push_back(VK_EXT_VALIDATION_CACHE_EXTENSION_NAME);
15792     } else {
15793         printf("%s %s not supported, skipping test\n", kSkipPrefix, VK_EXT_VALIDATION_CACHE_EXTENSION_NAME);
15794         return;
15795     }
15796     ASSERT_NO_FATAL_FAILURE(InitState());
15797 
15798     // Load extension functions
15799     auto fpCreateValidationCache =
15800         (PFN_vkCreateValidationCacheEXT)vkGetDeviceProcAddr(m_device->device(), "vkCreateValidationCacheEXT");
15801     auto fpDestroyValidationCache =
15802         (PFN_vkDestroyValidationCacheEXT)vkGetDeviceProcAddr(m_device->device(), "vkDestroyValidationCacheEXT");
15803     auto fpMergeValidationCaches =
15804         (PFN_vkMergeValidationCachesEXT)vkGetDeviceProcAddr(m_device->device(), "vkMergeValidationCachesEXT");
15805     if (!fpCreateValidationCache || !fpDestroyValidationCache || !fpMergeValidationCaches) {
15806         printf("%s Failed to load function pointers for %s\n", kSkipPrefix, VK_EXT_VALIDATION_CACHE_EXTENSION_NAME);
15807         return;
15808     }
15809 
15810     VkValidationCacheCreateInfoEXT validationCacheCreateInfo;
15811     validationCacheCreateInfo.sType = VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT;
15812     validationCacheCreateInfo.pNext = NULL;
15813     validationCacheCreateInfo.initialDataSize = 0;
15814     validationCacheCreateInfo.pInitialData = NULL;
15815     validationCacheCreateInfo.flags = 0;
15816     VkValidationCacheEXT validationCache = VK_NULL_HANDLE;
15817     VkResult res = fpCreateValidationCache(m_device->device(), &validationCacheCreateInfo, nullptr, &validationCache);
15818     ASSERT_VK_SUCCESS(res);
15819 
15820     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkMergeValidationCachesEXT-dstCache-01536");
15821     res = fpMergeValidationCaches(m_device->device(), validationCache, 1, &validationCache);
15822     m_errorMonitor->VerifyFound();
15823 
15824     fpDestroyValidationCache(m_device->device(), validationCache, nullptr);
15825 }
15826 
TEST_F(VkPositiveLayerTest,LayoutFromPresentWithoutAccessMemoryRead)15827 TEST_F(VkPositiveLayerTest, LayoutFromPresentWithoutAccessMemoryRead) {
15828     // Transition an image away from PRESENT_SRC_KHR without ACCESS_MEMORY_READ
15829     // in srcAccessMask.
15830 
15831     // The required behavior here was a bit unclear in earlier versions of the
15832     // spec, but there is no memory dependency required here, so this should
15833     // work without warnings.
15834 
15835     m_errorMonitor->ExpectSuccess();
15836     ASSERT_NO_FATAL_FAILURE(Init());
15837     VkImageObj image(m_device);
15838     image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT),
15839                VK_IMAGE_TILING_OPTIMAL, 0);
15840     ASSERT_TRUE(image.initialized());
15841 
15842     VkImageMemoryBarrier barrier = {};
15843     VkImageSubresourceRange range;
15844     barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
15845     barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
15846     barrier.dstAccessMask = 0;
15847     barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
15848     barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
15849     barrier.image = image.handle();
15850     range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
15851     range.baseMipLevel = 0;
15852     range.levelCount = 1;
15853     range.baseArrayLayer = 0;
15854     range.layerCount = 1;
15855     barrier.subresourceRange = range;
15856     VkCommandBufferObj cmdbuf(m_device, m_commandPool);
15857     cmdbuf.begin();
15858     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
15859                            &barrier);
15860     barrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
15861     barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
15862     barrier.srcAccessMask = 0;
15863     barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
15864     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
15865                            &barrier);
15866 
15867     m_errorMonitor->VerifyNotFound();
15868 }
15869 
TEST_F(VkLayerTest,IdxBufferAlignmentError)15870 TEST_F(VkLayerTest, IdxBufferAlignmentError) {
15871     // Bind a BeginRenderPass within an active RenderPass
15872     ASSERT_NO_FATAL_FAILURE(Init());
15873     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15874 
15875     uint32_t const indices[] = {0};
15876     VkBufferCreateInfo buf_info = {};
15877     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
15878     buf_info.size = 1024;
15879     buf_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
15880     buf_info.queueFamilyIndexCount = 1;
15881     buf_info.pQueueFamilyIndices = indices;
15882 
15883     VkBuffer buffer;
15884     VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
15885     ASSERT_VK_SUCCESS(err);
15886 
15887     VkMemoryRequirements requirements;
15888     vkGetBufferMemoryRequirements(m_device->device(), buffer, &requirements);
15889 
15890     VkMemoryAllocateInfo alloc_info{};
15891     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
15892     alloc_info.pNext = NULL;
15893     alloc_info.memoryTypeIndex = 0;
15894     alloc_info.allocationSize = requirements.size;
15895     bool pass = m_device->phy().set_memory_type(requirements.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
15896     ASSERT_TRUE(pass);
15897 
15898     VkDeviceMemory memory;
15899     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &memory);
15900     ASSERT_VK_SUCCESS(err);
15901 
15902     err = vkBindBufferMemory(m_device->device(), buffer, memory, 0);
15903     ASSERT_VK_SUCCESS(err);
15904 
15905     m_commandBuffer->begin();
15906     ASSERT_VK_SUCCESS(err);
15907 
15908     // vkCmdBindPipeline(m_commandBuffer->handle(),
15909     // VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
15910     // Should error before calling to driver so don't care about actual data
15911     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdBindIndexBuffer() offset (0x7) does not fall on ");
15912     vkCmdBindIndexBuffer(m_commandBuffer->handle(), buffer, 7, VK_INDEX_TYPE_UINT16);
15913     m_errorMonitor->VerifyFound();
15914 
15915     vkFreeMemory(m_device->device(), memory, NULL);
15916     vkDestroyBuffer(m_device->device(), buffer, NULL);
15917 }
15918 
TEST_F(VkLayerTest,InvalidQueueFamilyIndex)15919 TEST_F(VkLayerTest, InvalidQueueFamilyIndex) {
15920     // Miscellaneous queueFamilyIndex validation tests
15921     ASSERT_NO_FATAL_FAILURE(Init());
15922     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15923     VkBufferCreateInfo buffCI = {};
15924     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
15925     buffCI.size = 1024;
15926     buffCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
15927     buffCI.queueFamilyIndexCount = 2;
15928     // Introduce failure by specifying invalid queue_family_index
15929     uint32_t qfi[2];
15930     qfi[0] = 777;
15931     qfi[1] = 0;
15932 
15933     buffCI.pQueueFamilyIndices = qfi;
15934     buffCI.sharingMode = VK_SHARING_MODE_CONCURRENT;  // qfi only matters in CONCURRENT mode
15935 
15936     VkBuffer ib;
15937     // Test for queue family index out of range
15938     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferCreateInfo-sharingMode-01419");
15939     vkCreateBuffer(m_device->device(), &buffCI, NULL, &ib);
15940     m_errorMonitor->VerifyFound();
15941 
15942     // Test for non-unique QFI in array
15943     qfi[0] = 0;
15944     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferCreateInfo-sharingMode-01419");
15945     vkCreateBuffer(m_device->device(), &buffCI, NULL, &ib);
15946     m_errorMonitor->VerifyFound();
15947 
15948     if (m_device->queue_props.size() > 2) {
15949         VkBuffer ib2;
15950         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "which was not created allowing concurrent");
15951 
15952         // Create buffer shared to queue families 1 and 2, but submitted on queue family 0
15953         buffCI.queueFamilyIndexCount = 2;
15954         qfi[0] = 1;
15955         qfi[1] = 2;
15956         vkCreateBuffer(m_device->device(), &buffCI, NULL, &ib2);
15957         VkDeviceMemory mem;
15958         VkMemoryRequirements mem_reqs;
15959         vkGetBufferMemoryRequirements(m_device->device(), ib2, &mem_reqs);
15960 
15961         VkMemoryAllocateInfo alloc_info = {};
15962         alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
15963         alloc_info.allocationSize = mem_reqs.size;
15964         bool pass = false;
15965         pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
15966         if (!pass) {
15967             printf("%s Failed to allocate required memory.\n", kSkipPrefix);
15968             vkDestroyBuffer(m_device->device(), ib2, NULL);
15969             return;
15970         }
15971         vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
15972         vkBindBufferMemory(m_device->device(), ib2, mem, 0);
15973 
15974         m_commandBuffer->begin();
15975         vkCmdFillBuffer(m_commandBuffer->handle(), ib2, 0, 16, 5);
15976         m_commandBuffer->end();
15977         m_commandBuffer->QueueCommandBuffer(false);
15978         m_errorMonitor->VerifyFound();
15979         vkDestroyBuffer(m_device->device(), ib2, NULL);
15980         vkFreeMemory(m_device->device(), mem, NULL);
15981     }
15982 }
15983 
TEST_F(VkLayerTest,ExecuteCommandsPrimaryCB)15984 TEST_F(VkLayerTest, ExecuteCommandsPrimaryCB) {
15985     TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a primary command buffer (should only be secondary)");
15986 
15987     ASSERT_NO_FATAL_FAILURE(Init());
15988     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
15989 
15990     // An empty primary command buffer
15991     VkCommandBufferObj cb(m_device, m_commandPool);
15992     cb.begin();
15993     cb.end();
15994 
15995     m_commandBuffer->begin();
15996     vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
15997     VkCommandBuffer handle = cb.handle();
15998 
15999     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdExecuteCommands() called w/ Primary Cmd Buffer ");
16000     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &handle);
16001     m_errorMonitor->VerifyFound();
16002 
16003     m_errorMonitor->SetUnexpectedError("All elements of pCommandBuffers must not be in the pending state");
16004 
16005     m_commandBuffer->EndRenderPass();
16006     m_commandBuffer->end();
16007 }
16008 
TEST_F(VkLayerTest,DSUsageBitsErrors)16009 TEST_F(VkLayerTest, DSUsageBitsErrors) {
16010     TEST_DESCRIPTION("Attempt to update descriptor sets for images and buffers that do not have correct usage bits sets.");
16011 
16012     ASSERT_NO_FATAL_FAILURE(Init());
16013     std::array<VkDescriptorPoolSize, VK_DESCRIPTOR_TYPE_RANGE_SIZE> ds_type_count;
16014     for (uint32_t i = 0; i < ds_type_count.size(); ++i) {
16015         ds_type_count[i].type = VkDescriptorType(i);
16016         ds_type_count[i].descriptorCount = 1;
16017     }
16018 
16019     vk_testing::DescriptorPool ds_pool;
16020     ds_pool.init(*m_device, vk_testing::DescriptorPool::create_info(0, VK_DESCRIPTOR_TYPE_RANGE_SIZE, ds_type_count));
16021     ASSERT_TRUE(ds_pool.initialized());
16022 
16023     std::vector<VkDescriptorSetLayoutBinding> dsl_bindings(1);
16024     dsl_bindings[0].binding = 0;
16025     dsl_bindings[0].descriptorType = VkDescriptorType(0);
16026     dsl_bindings[0].descriptorCount = 1;
16027     dsl_bindings[0].stageFlags = VK_SHADER_STAGE_ALL;
16028     dsl_bindings[0].pImmutableSamplers = NULL;
16029 
16030     // Create arrays of layout and descriptor objects
16031     using UpDescriptorSet = std::unique_ptr<vk_testing::DescriptorSet>;
16032     std::vector<UpDescriptorSet> descriptor_sets;
16033     using UpDescriptorSetLayout = std::unique_ptr<VkDescriptorSetLayoutObj>;
16034     std::vector<UpDescriptorSetLayout> ds_layouts;
16035     descriptor_sets.reserve(VK_DESCRIPTOR_TYPE_RANGE_SIZE);
16036     ds_layouts.reserve(VK_DESCRIPTOR_TYPE_RANGE_SIZE);
16037     for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
16038         dsl_bindings[0].descriptorType = VkDescriptorType(i);
16039         ds_layouts.push_back(UpDescriptorSetLayout(new VkDescriptorSetLayoutObj(m_device, dsl_bindings)));
16040         descriptor_sets.push_back(UpDescriptorSet(ds_pool.alloc_sets(*m_device, *ds_layouts.back())));
16041         ASSERT_TRUE(descriptor_sets.back()->initialized());
16042     }
16043 
16044     // Create a buffer & bufferView to be used for invalid updates
16045     const VkDeviceSize buffer_size = 256;
16046     uint8_t data[buffer_size];
16047     VkConstantBufferObj buffer(m_device, buffer_size, data, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT);
16048     VkConstantBufferObj storage_texel_buffer(m_device, buffer_size, data, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
16049     ASSERT_TRUE(buffer.initialized() && storage_texel_buffer.initialized());
16050 
16051     auto buff_view_ci = vk_testing::BufferView::createInfo(buffer.handle(), VK_FORMAT_R8_UNORM);
16052     vk_testing::BufferView buffer_view_obj, storage_texel_buffer_view_obj;
16053     buffer_view_obj.init(*m_device, buff_view_ci);
16054     buff_view_ci.buffer = storage_texel_buffer.handle();
16055     storage_texel_buffer_view_obj.init(*m_device, buff_view_ci);
16056     ASSERT_TRUE(buffer_view_obj.initialized() && storage_texel_buffer_view_obj.initialized());
16057     VkBufferView buffer_view = buffer_view_obj.handle();
16058     VkBufferView storage_texel_buffer_view = storage_texel_buffer_view_obj.handle();
16059 
16060     // Create an image to be used for invalid updates
16061     VkImageObj image_obj(m_device);
16062     image_obj.InitNoLayout(64, 64, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
16063     ASSERT_TRUE(image_obj.initialized());
16064     VkImageView image_view = image_obj.targetView(VK_FORMAT_R8G8B8A8_UNORM);
16065 
16066     VkDescriptorBufferInfo buff_info = {};
16067     buff_info.buffer = buffer.handle();
16068     VkDescriptorImageInfo img_info = {};
16069     img_info.imageView = image_view;
16070     VkWriteDescriptorSet descriptor_write = {};
16071     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
16072     descriptor_write.dstBinding = 0;
16073     descriptor_write.descriptorCount = 1;
16074     descriptor_write.pTexelBufferView = &buffer_view;
16075     descriptor_write.pBufferInfo = &buff_info;
16076     descriptor_write.pImageInfo = &img_info;
16077 
16078     // These error messages align with VkDescriptorType struct
16079     std::string error_codes[] = {
16080         "VUID-VkWriteDescriptorSet-descriptorType-00326",  // placeholder, no error for SAMPLER descriptor
16081         "VUID-VkWriteDescriptorSet-descriptorType-00326",  // COMBINED_IMAGE_SAMPLER
16082         "VUID-VkWriteDescriptorSet-descriptorType-00326",  // SAMPLED_IMAGE
16083         "VUID-VkWriteDescriptorSet-descriptorType-00326",  // STORAGE_IMAGE
16084         "VUID-VkWriteDescriptorSet-descriptorType-00334",  // UNIFORM_TEXEL_BUFFER
16085         "VUID-VkWriteDescriptorSet-descriptorType-00335",  // STORAGE_TEXEL_BUFFER
16086         "VUID-VkWriteDescriptorSet-descriptorType-00330",  // UNIFORM_BUFFER
16087         "VUID-VkWriteDescriptorSet-descriptorType-00331",  // STORAGE_BUFFER
16088         "VUID-VkWriteDescriptorSet-descriptorType-00330",  // UNIFORM_BUFFER_DYNAMIC
16089         "VUID-VkWriteDescriptorSet-descriptorType-00331",  // STORAGE_BUFFER_DYNAMIC
16090         "VUID-VkWriteDescriptorSet-descriptorType-00326"   // INPUT_ATTACHMENT
16091     };
16092     // Start loop at 1 as SAMPLER desc type has no usage bit error
16093     for (uint32_t i = 1; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
16094         if (VkDescriptorType(i) == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) {
16095             // Now check for UNIFORM_TEXEL_BUFFER using storage_texel_buffer_view
16096             descriptor_write.pTexelBufferView = &storage_texel_buffer_view;
16097         }
16098         descriptor_write.descriptorType = VkDescriptorType(i);
16099         descriptor_write.dstSet = descriptor_sets[i]->handle();
16100         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error_codes[i]);
16101 
16102         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
16103 
16104         m_errorMonitor->VerifyFound();
16105         if (VkDescriptorType(i) == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) {
16106             descriptor_write.pTexelBufferView = &buffer_view;
16107         }
16108     }
16109 }
16110 
TEST_F(VkLayerTest,DSBufferInfoErrors)16111 TEST_F(VkLayerTest, DSBufferInfoErrors) {
16112     TEST_DESCRIPTION(
16113         "Attempt to update buffer descriptor set that has incorrect parameters in VkDescriptorBufferInfo struct. This includes:\n"
16114         "1. offset value greater than or equal to buffer size\n"
16115         "2. range value of 0\n"
16116         "3. range value greater than buffer (size - offset)");
16117     VkResult err;
16118 
16119     // GPDDP2 needed for push descriptors support below
16120     bool gpdp2_support = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
16121                                                     VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION);
16122     if (gpdp2_support) {
16123         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
16124     }
16125     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
16126     bool update_template_support = DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME);
16127     if (update_template_support) {
16128         m_device_extension_names.push_back(VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME);
16129     } else {
16130         printf("%s Descriptor Update Template Extensions not supported, template cases skipped.\n", kSkipPrefix);
16131     }
16132 
16133     // Note: Includes workaround for some implementations which incorrectly return 0 maxPushDescriptors
16134     bool push_descriptor_support = gpdp2_support &&
16135                                    DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME) &&
16136                                    (GetPushDescriptorProperties(instance(), gpu()).maxPushDescriptors > 0);
16137     if (push_descriptor_support) {
16138         m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
16139     } else {
16140         printf("%s Push Descriptor Extension not supported, push descriptor cases skipped.\n", kSkipPrefix);
16141     }
16142 
16143     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
16144 
16145     std::vector<VkDescriptorSetLayoutBinding> ds_bindings = {
16146         {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}};
16147     OneOffDescriptorSet ds(m_device, ds_bindings);
16148 
16149     // Create a buffer to be used for invalid updates
16150     VkBufferCreateInfo buff_ci = {};
16151     buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
16152     buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
16153     buff_ci.size = m_device->props.limits.minUniformBufferOffsetAlignment;
16154     buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
16155     VkBuffer buffer;
16156     err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
16157     ASSERT_VK_SUCCESS(err);
16158 
16159     // Have to bind memory to buffer before descriptor update
16160     VkMemoryRequirements mem_reqs;
16161     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
16162     VkMemoryAllocateInfo mem_alloc = {};
16163     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
16164     mem_alloc.pNext = NULL;
16165     mem_alloc.allocationSize = mem_reqs.size;
16166     mem_alloc.memoryTypeIndex = 0;
16167     bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
16168     if (!pass) {
16169         printf("%s Failed to allocate memory.\n", kSkipPrefix);
16170         vkDestroyBuffer(m_device->device(), buffer, NULL);
16171         return;
16172     }
16173 
16174     VkDeviceMemory mem;
16175     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
16176     ASSERT_VK_SUCCESS(err);
16177     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
16178     ASSERT_VK_SUCCESS(err);
16179 
16180     VkDescriptorBufferInfo buff_info = {};
16181     buff_info.buffer = buffer;
16182     VkWriteDescriptorSet descriptor_write = {};
16183     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
16184     descriptor_write.dstBinding = 0;
16185     descriptor_write.descriptorCount = 1;
16186     descriptor_write.pTexelBufferView = nullptr;
16187     descriptor_write.pBufferInfo = &buff_info;
16188     descriptor_write.pImageInfo = nullptr;
16189 
16190     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
16191     descriptor_write.dstSet = ds.set_;
16192 
16193     // Relying on the "return nullptr for non-enabled extensions
16194     auto vkCreateDescriptorUpdateTemplateKHR =
16195         (PFN_vkCreateDescriptorUpdateTemplateKHR)vkGetDeviceProcAddr(m_device->device(), "vkCreateDescriptorUpdateTemplateKHR");
16196     auto vkDestroyDescriptorUpdateTemplateKHR =
16197         (PFN_vkDestroyDescriptorUpdateTemplateKHR)vkGetDeviceProcAddr(m_device->device(), "vkDestroyDescriptorUpdateTemplateKHR");
16198     auto vkUpdateDescriptorSetWithTemplateKHR =
16199         (PFN_vkUpdateDescriptorSetWithTemplateKHR)vkGetDeviceProcAddr(m_device->device(), "vkUpdateDescriptorSetWithTemplateKHR");
16200 
16201     if (update_template_support) {
16202         ASSERT_NE(vkCreateDescriptorUpdateTemplateKHR, nullptr);
16203         ASSERT_NE(vkDestroyDescriptorUpdateTemplateKHR, nullptr);
16204         ASSERT_NE(vkUpdateDescriptorSetWithTemplateKHR, nullptr);
16205     }
16206 
16207     // Setup for update w/ template tests
16208     // Create a template of descriptor set updates
16209     struct SimpleTemplateData {
16210         uint8_t padding[7];
16211         VkDescriptorBufferInfo buff_info;
16212         uint32_t other_padding[4];
16213     };
16214     SimpleTemplateData update_template_data = {};
16215 
16216     VkDescriptorUpdateTemplateEntry update_template_entry = {};
16217     update_template_entry.dstBinding = 0;
16218     update_template_entry.dstArrayElement = 0;
16219     update_template_entry.descriptorCount = 1;
16220     update_template_entry.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
16221     update_template_entry.offset = offsetof(SimpleTemplateData, buff_info);
16222     update_template_entry.stride = sizeof(SimpleTemplateData);
16223 
16224     auto update_template_ci = lvl_init_struct<VkDescriptorUpdateTemplateCreateInfoKHR>();
16225     update_template_ci.descriptorUpdateEntryCount = 1;
16226     update_template_ci.pDescriptorUpdateEntries = &update_template_entry;
16227     update_template_ci.templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET;
16228     update_template_ci.descriptorSetLayout = ds.layout_.handle();
16229 
16230     VkDescriptorUpdateTemplate update_template = VK_NULL_HANDLE;
16231     if (update_template_support) {
16232         auto result = vkCreateDescriptorUpdateTemplateKHR(m_device->device(), &update_template_ci, nullptr, &update_template);
16233         ASSERT_VK_SUCCESS(result);
16234     }
16235 
16236     // VK_KHR_push_descriptor support
16237     auto vkCmdPushDescriptorSetKHR =
16238         (PFN_vkCmdPushDescriptorSetKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR");
16239     auto vkCmdPushDescriptorSetWithTemplateKHR =
16240         (PFN_vkCmdPushDescriptorSetWithTemplateKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetWithTemplateKHR");
16241 
16242     std::unique_ptr<VkDescriptorSetLayoutObj> push_dsl = nullptr;
16243     std::unique_ptr<VkPipelineLayoutObj> pipeline_layout = nullptr;
16244     VkDescriptorUpdateTemplate push_template = VK_NULL_HANDLE;
16245     if (push_descriptor_support) {
16246         ASSERT_NE(vkCmdPushDescriptorSetKHR, nullptr);
16247         push_dsl.reset(
16248             new VkDescriptorSetLayoutObj(m_device, ds_bindings, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR));
16249         pipeline_layout.reset(new VkPipelineLayoutObj(m_device, {push_dsl.get()}));
16250         ASSERT_TRUE(push_dsl->initialized());
16251 
16252         if (update_template_support) {
16253             ASSERT_NE(vkCmdPushDescriptorSetWithTemplateKHR, nullptr);
16254             auto push_template_ci = lvl_init_struct<VkDescriptorUpdateTemplateCreateInfoKHR>();
16255             push_template_ci.descriptorUpdateEntryCount = 1;
16256             push_template_ci.pDescriptorUpdateEntries = &update_template_entry;
16257             push_template_ci.templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR;
16258             push_template_ci.descriptorSetLayout = VK_NULL_HANDLE;
16259             push_template_ci.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
16260             push_template_ci.pipelineLayout = pipeline_layout->handle();
16261             push_template_ci.set = 0;
16262             auto result = vkCreateDescriptorUpdateTemplateKHR(m_device->device(), &push_template_ci, nullptr, &push_template);
16263             ASSERT_VK_SUCCESS(result);
16264         }
16265     }
16266 
16267     auto do_test = [&](const char *desired_failure) {
16268         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, desired_failure);
16269         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
16270         m_errorMonitor->VerifyFound();
16271 
16272         if (push_descriptor_support) {
16273             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, desired_failure);
16274             m_commandBuffer->begin();
16275             vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout->handle(), 0, 1,
16276                                       &descriptor_write);
16277             m_commandBuffer->end();
16278             m_errorMonitor->VerifyFound();
16279         }
16280 
16281         if (update_template_support) {
16282             update_template_data.buff_info = buff_info;  // copy the test case information into our "pData"
16283             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, desired_failure);
16284             vkUpdateDescriptorSetWithTemplateKHR(m_device->device(), ds.set_, update_template, &update_template_data);
16285             m_errorMonitor->VerifyFound();
16286             if (push_descriptor_support) {
16287                 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, desired_failure);
16288                 m_commandBuffer->begin();
16289                 vkCmdPushDescriptorSetWithTemplateKHR(m_commandBuffer->handle(), push_template, pipeline_layout->handle(), 0,
16290                                                       &update_template_data);
16291                 m_commandBuffer->end();
16292                 m_errorMonitor->VerifyFound();
16293             }
16294         }
16295     };
16296 
16297     // Cause error due to offset out of range
16298     buff_info.offset = buff_ci.size;
16299     buff_info.range = VK_WHOLE_SIZE;
16300     do_test("VUID-VkDescriptorBufferInfo-offset-00340");
16301 
16302     // Now cause error due to range of 0
16303     buff_info.offset = 0;
16304     buff_info.range = 0;
16305     do_test("VUID-VkDescriptorBufferInfo-range-00341");
16306 
16307     // Now cause error due to range exceeding buffer size - offset
16308     buff_info.offset = 0;
16309     buff_info.range = buff_ci.size + 1;
16310     do_test("VUID-VkDescriptorBufferInfo-range-00342");
16311 
16312     if (update_template_support) {
16313         vkDestroyDescriptorUpdateTemplateKHR(m_device->device(), update_template, nullptr);
16314         if (push_descriptor_support) {
16315             vkDestroyDescriptorUpdateTemplateKHR(m_device->device(), push_template, nullptr);
16316         }
16317     }
16318     vkFreeMemory(m_device->device(), mem, NULL);
16319     vkDestroyBuffer(m_device->device(), buffer, NULL);
16320 }
16321 
TEST_F(VkLayerTest,DSBufferLimitErrors)16322 TEST_F(VkLayerTest, DSBufferLimitErrors) {
16323     TEST_DESCRIPTION(
16324         "Attempt to update buffer descriptor set that has VkDescriptorBufferInfo values that violate device limits.\n"
16325         "Test cases include:\n"
16326         "1. range of uniform buffer update exceeds maxUniformBufferRange\n"
16327         "2. offset of uniform buffer update is not multiple of minUniformBufferOffsetAlignment\n"
16328         "3. using VK_WHOLE_SIZE with uniform buffer size exceeding maxUniformBufferRange\n"
16329         "4. range of storage buffer update exceeds maxStorageBufferRange\n"
16330         "5. offset of storage buffer update is not multiple of minStorageBufferOffsetAlignment\n"
16331         "6. using VK_WHOLE_SIZE with storage buffer size exceeding maxStorageBufferRange");
16332     VkResult err;
16333 
16334     ASSERT_NO_FATAL_FAILURE(Init());
16335 
16336     struct TestCase {
16337         VkDescriptorType descriptor_type;
16338         VkBufferUsageFlagBits buffer_usage;
16339         VkDeviceSize max_range;
16340         std::string max_range_vu;
16341         VkDeviceSize min_align;
16342         std::string min_align_vu;
16343     };
16344 
16345     for (const auto &test_case : {
16346              TestCase({VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
16347                        m_device->props.limits.maxUniformBufferRange, "VUID-VkWriteDescriptorSet-descriptorType-00332",
16348                        m_device->props.limits.minUniformBufferOffsetAlignment, "VUID-VkWriteDescriptorSet-descriptorType-00327"}),
16349              TestCase({VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
16350                        m_device->props.limits.maxStorageBufferRange, "VUID-VkWriteDescriptorSet-descriptorType-00333",
16351                        m_device->props.limits.minStorageBufferOffsetAlignment, "VUID-VkWriteDescriptorSet-descriptorType-00328"}),
16352          }) {
16353         // Create layout with single buffer
16354         OneOffDescriptorSet ds(m_device, {
16355                                              {0, test_case.descriptor_type, 1, VK_SHADER_STAGE_ALL, nullptr},
16356                                          });
16357 
16358         // Create a buffer to be used for invalid updates
16359         VkBufferCreateInfo bci = {};
16360         bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
16361         bci.usage = test_case.buffer_usage;
16362         bci.size = test_case.max_range + test_case.min_align;  // Make buffer bigger than range limit
16363         bci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
16364         VkBuffer buffer;
16365         err = vkCreateBuffer(m_device->device(), &bci, NULL, &buffer);
16366         ASSERT_VK_SUCCESS(err);
16367 
16368         // Have to bind memory to buffer before descriptor update
16369         VkMemoryRequirements mem_reqs;
16370         vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
16371 
16372         VkMemoryAllocateInfo mem_alloc = {};
16373         mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
16374         mem_alloc.pNext = NULL;
16375         mem_alloc.allocationSize = mem_reqs.size;
16376         bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
16377         if (!pass) {
16378             printf("%s Failed to allocate memory in DSBufferLimitErrors; skipped.\n", kSkipPrefix);
16379             vkDestroyBuffer(m_device->device(), buffer, NULL);
16380             continue;
16381         }
16382 
16383         VkDeviceMemory mem;
16384         err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
16385         if (VK_SUCCESS != err) {
16386             printf("%s Failed to allocate memory in DSBufferLimitErrors; skipped.\n", kSkipPrefix);
16387             vkDestroyBuffer(m_device->device(), buffer, NULL);
16388             continue;
16389         }
16390         err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
16391         ASSERT_VK_SUCCESS(err);
16392 
16393         VkDescriptorBufferInfo buff_info = {};
16394         buff_info.buffer = buffer;
16395         VkWriteDescriptorSet descriptor_write = {};
16396         descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
16397         descriptor_write.dstBinding = 0;
16398         descriptor_write.descriptorCount = 1;
16399         descriptor_write.pTexelBufferView = nullptr;
16400         descriptor_write.pBufferInfo = &buff_info;
16401         descriptor_write.pImageInfo = nullptr;
16402         descriptor_write.descriptorType = test_case.descriptor_type;
16403         descriptor_write.dstSet = ds.set_;
16404 
16405         // Exceed range limit
16406         if (test_case.max_range != UINT32_MAX) {
16407             buff_info.range = test_case.max_range + 1;
16408             buff_info.offset = 0;
16409             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.max_range_vu);
16410             vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
16411             m_errorMonitor->VerifyFound();
16412         }
16413 
16414         // Reduce size of range to acceptable limit and cause offset error
16415         if (test_case.min_align > 1) {
16416             buff_info.range = test_case.max_range;
16417             buff_info.offset = test_case.min_align - 1;
16418             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.min_align_vu);
16419             vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
16420             m_errorMonitor->VerifyFound();
16421         }
16422 
16423         // Exceed effective range limit by using VK_WHOLE_SIZE
16424         buff_info.range = VK_WHOLE_SIZE;
16425         buff_info.offset = 0;
16426         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.max_range_vu);
16427         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
16428         m_errorMonitor->VerifyFound();
16429 
16430         // Cleanup
16431         vkFreeMemory(m_device->device(), mem, NULL);
16432         vkDestroyBuffer(m_device->device(), buffer, NULL);
16433     }
16434 }
16435 
TEST_F(VkLayerTest,DSAspectBitsErrors)16436 TEST_F(VkLayerTest, DSAspectBitsErrors) {
16437     // TODO : Initially only catching case where DEPTH & STENCIL aspect bits
16438     //  are set, but could expand this test to hit more cases.
16439     TEST_DESCRIPTION("Attempt to update descriptor sets for images that do not have correct aspect bits sets.");
16440     VkResult err;
16441 
16442     ASSERT_NO_FATAL_FAILURE(Init());
16443     auto depth_format = FindSupportedDepthStencilFormat(gpu());
16444     if (!depth_format) {
16445         printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
16446         return;
16447     }
16448 
16449     OneOffDescriptorSet ds(m_device, {
16450                                          {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_ALL, nullptr},
16451                                      });
16452 
16453     // Create an image to be used for invalid updates
16454     VkImageObj image_obj(m_device);
16455     image_obj.Init(64, 64, 1, depth_format, VK_IMAGE_USAGE_SAMPLED_BIT);
16456     if (!image_obj.initialized()) {
16457         printf("%s Depth + Stencil format cannot be sampled. Skipped.\n", kSkipPrefix);
16458         return;
16459     }
16460     VkImage image = image_obj.image();
16461 
16462     // Now create view for image
16463     VkImageViewCreateInfo image_view_ci = {};
16464     image_view_ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
16465     image_view_ci.image = image;
16466     image_view_ci.format = depth_format;
16467     image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
16468     image_view_ci.subresourceRange.layerCount = 1;
16469     image_view_ci.subresourceRange.baseArrayLayer = 0;
16470     image_view_ci.subresourceRange.levelCount = 1;
16471     // Setting both depth & stencil aspect bits is illegal for an imageView used
16472     // to populate a descriptor set.
16473     image_view_ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
16474 
16475     VkImageView image_view;
16476     err = vkCreateImageView(m_device->device(), &image_view_ci, NULL, &image_view);
16477     ASSERT_VK_SUCCESS(err);
16478 
16479     VkDescriptorImageInfo img_info = {};
16480     img_info.imageView = image_view;
16481     VkWriteDescriptorSet descriptor_write = {};
16482     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
16483     descriptor_write.dstBinding = 0;
16484     descriptor_write.descriptorCount = 1;
16485     descriptor_write.pTexelBufferView = NULL;
16486     descriptor_write.pBufferInfo = NULL;
16487     descriptor_write.pImageInfo = &img_info;
16488     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
16489     descriptor_write.dstSet = ds.set_;
16490     // TODO(whenning42): Update this check to look for a VUID when this error is
16491     // assigned one.
16492     const char *error_msg = " please only set either VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT ";
16493     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error_msg);
16494 
16495     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
16496 
16497     m_errorMonitor->VerifyFound();
16498     vkDestroyImageView(m_device->device(), image_view, NULL);
16499 }
16500 
TEST_F(VkLayerTest,DSTypeMismatch)16501 TEST_F(VkLayerTest, DSTypeMismatch) {
16502     // Create DS w/ layout of one type and attempt Update w/ mis-matched type
16503     VkResult err;
16504 
16505     m_errorMonitor->SetDesiredFailureMsg(
16506         VK_DEBUG_REPORT_ERROR_BIT_EXT,
16507         " binding #0 with type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER but update type is VK_DESCRIPTOR_TYPE_SAMPLER");
16508 
16509     ASSERT_NO_FATAL_FAILURE(Init());
16510     OneOffDescriptorSet ds(m_device, {
16511                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
16512                                      });
16513 
16514     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
16515     VkSampler sampler;
16516     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
16517     ASSERT_VK_SUCCESS(err);
16518 
16519     VkDescriptorImageInfo info = {};
16520     info.sampler = sampler;
16521 
16522     VkWriteDescriptorSet descriptor_write;
16523     memset(&descriptor_write, 0, sizeof(descriptor_write));
16524     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
16525     descriptor_write.dstSet = ds.set_;
16526     descriptor_write.descriptorCount = 1;
16527     // This is a mismatched type for the layout which expects BUFFER
16528     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
16529     descriptor_write.pImageInfo = &info;
16530 
16531     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
16532 
16533     m_errorMonitor->VerifyFound();
16534 
16535     vkDestroySampler(m_device->device(), sampler, NULL);
16536 }
16537 
TEST_F(VkLayerTest,DSUpdateOutOfBounds)16538 TEST_F(VkLayerTest, DSUpdateOutOfBounds) {
16539     // For overlapping Update, have arrayIndex exceed that of layout
16540     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkWriteDescriptorSet-dstArrayElement-00321");
16541 
16542     ASSERT_NO_FATAL_FAILURE(Init());
16543     OneOffDescriptorSet ds(m_device, {
16544                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
16545                                      });
16546 
16547     VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
16548     if (!buffer_test.GetBufferCurrent()) {
16549         // Something prevented creation of buffer so abort
16550         printf("%s Buffer creation failed, skipping test\n", kSkipPrefix);
16551         return;
16552     }
16553 
16554     // Correctly update descriptor to avoid "NOT_UPDATED" error
16555     VkDescriptorBufferInfo buff_info = {};
16556     buff_info.buffer = buffer_test.GetBuffer();
16557     buff_info.offset = 0;
16558     buff_info.range = 1024;
16559 
16560     VkWriteDescriptorSet descriptor_write;
16561     memset(&descriptor_write, 0, sizeof(descriptor_write));
16562     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
16563     descriptor_write.dstSet = ds.set_;
16564     descriptor_write.dstArrayElement = 1; /* This index out of bounds for the update */
16565     descriptor_write.descriptorCount = 1;
16566     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
16567     descriptor_write.pBufferInfo = &buff_info;
16568 
16569     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
16570 
16571     m_errorMonitor->VerifyFound();
16572 }
16573 
TEST_F(VkLayerTest,InvalidDSUpdateIndex)16574 TEST_F(VkLayerTest, InvalidDSUpdateIndex) {
16575     // Create layout w/ count of 1 and attempt update to that layout w/ binding index 2
16576     VkResult err;
16577 
16578     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkWriteDescriptorSet-dstBinding-00315");
16579 
16580     ASSERT_NO_FATAL_FAILURE(Init());
16581     OneOffDescriptorSet ds(m_device, {
16582                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
16583                                      });
16584 
16585     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
16586     VkSampler sampler;
16587     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
16588     ASSERT_VK_SUCCESS(err);
16589 
16590     VkDescriptorImageInfo info = {};
16591     info.sampler = sampler;
16592 
16593     VkWriteDescriptorSet descriptor_write;
16594     memset(&descriptor_write, 0, sizeof(descriptor_write));
16595     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
16596     descriptor_write.dstSet = ds.set_;
16597     descriptor_write.dstBinding = 2;
16598     descriptor_write.descriptorCount = 1;
16599     // This is the wrong type, but out of bounds will be flagged first
16600     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
16601     descriptor_write.pImageInfo = &info;
16602 
16603     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
16604 
16605     m_errorMonitor->VerifyFound();
16606 
16607     vkDestroySampler(m_device->device(), sampler, NULL);
16608 }
16609 
TEST_F(VkLayerTest,DSUpdateEmptyBinding)16610 TEST_F(VkLayerTest, DSUpdateEmptyBinding) {
16611     // Create layout w/ empty binding and attempt to update it
16612     VkResult err;
16613 
16614     ASSERT_NO_FATAL_FAILURE(Init());
16615 
16616     OneOffDescriptorSet ds(m_device, {
16617                                          {0, VK_DESCRIPTOR_TYPE_SAMPLER, 0 /* !! */, VK_SHADER_STAGE_ALL, nullptr},
16618                                      });
16619 
16620     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
16621     VkSampler sampler;
16622     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
16623     ASSERT_VK_SUCCESS(err);
16624 
16625     VkDescriptorImageInfo info = {};
16626     info.sampler = sampler;
16627 
16628     VkWriteDescriptorSet descriptor_write;
16629     memset(&descriptor_write, 0, sizeof(descriptor_write));
16630     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
16631     descriptor_write.dstSet = ds.set_;
16632     descriptor_write.dstBinding = 0;
16633     descriptor_write.descriptorCount = 1;  // Lie here to avoid parameter_validation error
16634     // This is the wrong type, but empty binding error will be flagged first
16635     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
16636     descriptor_write.pImageInfo = &info;
16637 
16638     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkWriteDescriptorSet-dstBinding-00316");
16639     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
16640     m_errorMonitor->VerifyFound();
16641 
16642     vkDestroySampler(m_device->device(), sampler, NULL);
16643 }
16644 
TEST_F(VkLayerTest,InvalidDSUpdateStruct)16645 TEST_F(VkLayerTest, InvalidDSUpdateStruct) {
16646     // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_*
16647     // types
16648     VkResult err;
16649 
16650     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, ".sType must be VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET");
16651 
16652     ASSERT_NO_FATAL_FAILURE(Init());
16653 
16654     OneOffDescriptorSet ds(m_device, {
16655                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
16656                                      });
16657 
16658     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
16659     VkSampler sampler;
16660     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
16661     ASSERT_VK_SUCCESS(err);
16662 
16663     VkDescriptorImageInfo info = {};
16664     info.sampler = sampler;
16665 
16666     VkWriteDescriptorSet descriptor_write;
16667     memset(&descriptor_write, 0, sizeof(descriptor_write));
16668     descriptor_write.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; /* Intentionally broken struct type */
16669     descriptor_write.dstSet = ds.set_;
16670     descriptor_write.descriptorCount = 1;
16671     // This is the wrong type, but out of bounds will be flagged first
16672     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
16673     descriptor_write.pImageInfo = &info;
16674 
16675     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
16676 
16677     m_errorMonitor->VerifyFound();
16678 
16679     vkDestroySampler(m_device->device(), sampler, NULL);
16680 }
16681 
TEST_F(VkLayerTest,SampleDescriptorUpdateError)16682 TEST_F(VkLayerTest, SampleDescriptorUpdateError) {
16683     // Create a single Sampler descriptor and send it an invalid Sampler
16684     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkWriteDescriptorSet-descriptorType-00325");
16685 
16686     ASSERT_NO_FATAL_FAILURE(Init());
16687     OneOffDescriptorSet ds(m_device, {
16688                                          {0, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
16689                                      });
16690 
16691     VkSampler sampler = (VkSampler)((size_t)0xbaadbeef);  // Sampler with invalid handle
16692 
16693     VkDescriptorImageInfo descriptor_info;
16694     memset(&descriptor_info, 0, sizeof(VkDescriptorImageInfo));
16695     descriptor_info.sampler = sampler;
16696 
16697     VkWriteDescriptorSet descriptor_write;
16698     memset(&descriptor_write, 0, sizeof(descriptor_write));
16699     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
16700     descriptor_write.dstSet = ds.set_;
16701     descriptor_write.dstBinding = 0;
16702     descriptor_write.descriptorCount = 1;
16703     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
16704     descriptor_write.pImageInfo = &descriptor_info;
16705 
16706     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
16707 
16708     m_errorMonitor->VerifyFound();
16709 }
16710 
TEST_F(VkLayerTest,ImageViewDescriptorUpdateError)16711 TEST_F(VkLayerTest, ImageViewDescriptorUpdateError) {
16712     // Create a single combined Image/Sampler descriptor and send it an invalid
16713     // imageView
16714     VkResult err;
16715 
16716     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkWriteDescriptorSet-descriptorType-00326");
16717 
16718     ASSERT_NO_FATAL_FAILURE(Init());
16719     OneOffDescriptorSet ds(m_device, {
16720                                          {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
16721                                      });
16722 
16723     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
16724     VkSampler sampler;
16725     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
16726     ASSERT_VK_SUCCESS(err);
16727 
16728     VkImageView view = (VkImageView)((size_t)0xbaadbeef);  // invalid imageView object
16729 
16730     VkDescriptorImageInfo descriptor_info;
16731     memset(&descriptor_info, 0, sizeof(VkDescriptorImageInfo));
16732     descriptor_info.sampler = sampler;
16733     descriptor_info.imageView = view;
16734 
16735     VkWriteDescriptorSet descriptor_write;
16736     memset(&descriptor_write, 0, sizeof(descriptor_write));
16737     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
16738     descriptor_write.dstSet = ds.set_;
16739     descriptor_write.dstBinding = 0;
16740     descriptor_write.descriptorCount = 1;
16741     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
16742     descriptor_write.pImageInfo = &descriptor_info;
16743 
16744     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
16745 
16746     m_errorMonitor->VerifyFound();
16747 
16748     vkDestroySampler(m_device->device(), sampler, NULL);
16749 }
16750 
TEST_F(VkLayerTest,CopyDescriptorUpdateErrors)16751 TEST_F(VkLayerTest, CopyDescriptorUpdateErrors) {
16752     // Create DS w/ layout of 2 types, write update 1 and attempt to copy-update
16753     // into the other
16754     VkResult err;
16755 
16756     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16757                                          " binding #1 with type VK_DESCRIPTOR_TYPE_SAMPLER. Types do not match.");
16758 
16759     ASSERT_NO_FATAL_FAILURE(Init());
16760     OneOffDescriptorSet ds(m_device, {
16761                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
16762                                          {1, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
16763                                      });
16764 
16765     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
16766     VkSampler sampler;
16767     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
16768     ASSERT_VK_SUCCESS(err);
16769 
16770     VkDescriptorImageInfo info = {};
16771     info.sampler = sampler;
16772 
16773     VkWriteDescriptorSet descriptor_write;
16774     memset(&descriptor_write, 0, sizeof(VkWriteDescriptorSet));
16775     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
16776     descriptor_write.dstSet = ds.set_;
16777     descriptor_write.dstBinding = 1;  // SAMPLER binding from layout above
16778     descriptor_write.descriptorCount = 1;
16779     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
16780     descriptor_write.pImageInfo = &info;
16781     // This write update should succeed
16782     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
16783     // Now perform a copy update that fails due to type mismatch
16784     VkCopyDescriptorSet copy_ds_update;
16785     memset(&copy_ds_update, 0, sizeof(VkCopyDescriptorSet));
16786     copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
16787     copy_ds_update.srcSet = ds.set_;
16788     copy_ds_update.srcBinding = 1;  // Copy from SAMPLER binding
16789     copy_ds_update.dstSet = ds.set_;
16790     copy_ds_update.dstBinding = 0;       // ERROR : copy to UNIFORM binding
16791     copy_ds_update.descriptorCount = 1;  // copy 1 descriptor
16792     vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, &copy_ds_update);
16793 
16794     m_errorMonitor->VerifyFound();
16795     // Now perform a copy update that fails due to binding out of bounds
16796     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " does not have copy update src binding of 3.");
16797     memset(&copy_ds_update, 0, sizeof(VkCopyDescriptorSet));
16798     copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
16799     copy_ds_update.srcSet = ds.set_;
16800     copy_ds_update.srcBinding = 3;  // ERROR : Invalid binding for matching layout
16801     copy_ds_update.dstSet = ds.set_;
16802     copy_ds_update.dstBinding = 0;
16803     copy_ds_update.descriptorCount = 1;  // Copy 1 descriptor
16804     vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, &copy_ds_update);
16805 
16806     m_errorMonitor->VerifyFound();
16807 
16808     // Now perform a copy update that fails due to binding out of bounds
16809     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
16810                                          " binding#1 with offset index of 1 plus update array offset of 0 and update of 5 "
16811                                          "descriptors oversteps total number of descriptors in set: 2.");
16812 
16813     memset(&copy_ds_update, 0, sizeof(VkCopyDescriptorSet));
16814     copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
16815     copy_ds_update.srcSet = ds.set_;
16816     copy_ds_update.srcBinding = 1;
16817     copy_ds_update.dstSet = ds.set_;
16818     copy_ds_update.dstBinding = 0;
16819     copy_ds_update.descriptorCount = 5;  // ERROR copy 5 descriptors (out of bounds for layout)
16820     vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, &copy_ds_update);
16821 
16822     m_errorMonitor->VerifyFound();
16823 
16824     vkDestroySampler(m_device->device(), sampler, NULL);
16825 }
16826 
TEST_F(VkPositiveLayerTest,CopyNonupdatedDescriptors)16827 TEST_F(VkPositiveLayerTest, CopyNonupdatedDescriptors) {
16828     TEST_DESCRIPTION("Copy non-updated descriptors");
16829     unsigned int i;
16830 
16831     ASSERT_NO_FATAL_FAILURE(Init());
16832     OneOffDescriptorSet src_ds(m_device, {
16833                                              {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
16834                                              {1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr},
16835                                              {2, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
16836                                          });
16837     OneOffDescriptorSet dst_ds(m_device, {
16838                                              {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
16839                                              {1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr},
16840                                          });
16841 
16842     m_errorMonitor->ExpectSuccess();
16843 
16844     const unsigned int copy_size = 2;
16845     VkCopyDescriptorSet copy_ds_update[copy_size];
16846     memset(copy_ds_update, 0, sizeof(copy_ds_update));
16847     for (i = 0; i < copy_size; i++) {
16848         copy_ds_update[i].sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
16849         copy_ds_update[i].srcSet = src_ds.set_;
16850         copy_ds_update[i].srcBinding = i;
16851         copy_ds_update[i].dstSet = dst_ds.set_;
16852         copy_ds_update[i].dstBinding = i;
16853         copy_ds_update[i].descriptorCount = 1;
16854     }
16855     vkUpdateDescriptorSets(m_device->device(), 0, NULL, copy_size, copy_ds_update);
16856 
16857     m_errorMonitor->VerifyNotFound();
16858 }
16859 
TEST_F(VkLayerTest,NumSamplesMismatch)16860 TEST_F(VkLayerTest, NumSamplesMismatch) {
16861     // Create CommandBuffer where MSAA samples doesn't match RenderPass
16862     // sampleCount
16863     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Num samples mismatch! ");
16864 
16865     ASSERT_NO_FATAL_FAILURE(Init());
16866     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16867 
16868     OneOffDescriptorSet ds(m_device, {
16869                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
16870                                      });
16871 
16872     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
16873     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
16874     pipe_ms_state_ci.pNext = NULL;
16875     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
16876     pipe_ms_state_ci.sampleShadingEnable = 0;
16877     pipe_ms_state_ci.minSampleShading = 1.0;
16878     pipe_ms_state_ci.pSampleMask = NULL;
16879 
16880     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
16881 
16882     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
16883     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);  // We shouldn't need a fragment shader
16884     // but add it to be able to run on more devices
16885     VkPipelineObj pipe(m_device);
16886     pipe.AddShader(&vs);
16887     pipe.AddShader(&fs);
16888     pipe.AddDefaultColorAttachment();
16889     pipe.SetMSAA(&pipe_ms_state_ci);
16890 
16891     m_errorMonitor->SetUnexpectedError("VUID-VkGraphicsPipelineCreateInfo-subpass-00757");
16892     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
16893 
16894     m_commandBuffer->begin();
16895     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
16896     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
16897 
16898     VkViewport viewport = {0, 0, 16, 16, 0, 1};
16899     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
16900     VkRect2D scissor = {{0, 0}, {16, 16}};
16901     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
16902 
16903     // Render triangle (the error should trigger on the attempt to draw).
16904     m_commandBuffer->Draw(3, 1, 0, 0);
16905 
16906     // Finalize recording of the command buffer
16907     m_commandBuffer->EndRenderPass();
16908     m_commandBuffer->end();
16909 
16910     m_errorMonitor->VerifyFound();
16911 }
16912 
TEST_F(VkLayerTest,DrawWithPipelineIncompatibleWithRenderPass)16913 TEST_F(VkLayerTest, DrawWithPipelineIncompatibleWithRenderPass) {
16914     TEST_DESCRIPTION(
16915         "Hit RenderPass incompatible cases. Initial case is drawing with an active renderpass that's not compatible with the bound "
16916         "pipeline state object's creation renderpass");
16917 
16918     ASSERT_NO_FATAL_FAILURE(Init());
16919     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16920 
16921     OneOffDescriptorSet ds(m_device, {
16922                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
16923                                      });
16924 
16925     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
16926 
16927     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
16928     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);  // We shouldn't need a fragment shader
16929     // but add it to be able to run on more devices
16930     // Create a renderpass that will be incompatible with default renderpass
16931     VkAttachmentReference color_att = {};
16932     color_att.layout = VK_IMAGE_LAYOUT_GENERAL;
16933     VkSubpassDescription subpass = {};
16934     subpass.colorAttachmentCount = 1;
16935     subpass.pColorAttachments = &color_att;
16936     VkRenderPassCreateInfo rpci = {};
16937     rpci.subpassCount = 1;
16938     rpci.pSubpasses = &subpass;
16939     rpci.attachmentCount = 1;
16940     VkAttachmentDescription attach_desc = {};
16941     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
16942     // Format incompatible with PSO RP color attach format B8G8R8A8_UNORM
16943     attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM;
16944     attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
16945     rpci.pAttachments = &attach_desc;
16946     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
16947     VkRenderPass rp;
16948     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
16949     VkPipelineObj pipe(m_device);
16950     pipe.AddShader(&vs);
16951     pipe.AddShader(&fs);
16952     pipe.AddDefaultColorAttachment();
16953     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
16954     m_viewports.push_back(viewport);
16955     pipe.SetViewport(m_viewports);
16956     VkRect2D rect = {{0, 0}, {64, 64}};
16957     m_scissors.push_back(rect);
16958     pipe.SetScissor(m_scissors);
16959     pipe.CreateVKPipeline(pipeline_layout.handle(), rp);
16960 
16961     VkCommandBufferInheritanceInfo cbii = {};
16962     cbii.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
16963     cbii.renderPass = rp;
16964     cbii.subpass = 0;
16965     VkCommandBufferBeginInfo cbbi = {};
16966     cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
16967     cbbi.pInheritanceInfo = &cbii;
16968     vkBeginCommandBuffer(m_commandBuffer->handle(), &cbbi);
16969     vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
16970     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
16971 
16972     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDraw-renderPass-00435");
16973     // Render triangle (the error should trigger on the attempt to draw).
16974     m_commandBuffer->Draw(3, 1, 0, 0);
16975 
16976     // Finalize recording of the command buffer
16977     m_commandBuffer->EndRenderPass();
16978     m_commandBuffer->end();
16979 
16980     m_errorMonitor->VerifyFound();
16981 
16982     vkDestroyRenderPass(m_device->device(), rp, NULL);
16983 }
16984 
TEST_F(VkLayerTest,NumBlendAttachMismatch)16985 TEST_F(VkLayerTest, NumBlendAttachMismatch) {
16986     // Create Pipeline where the number of blend attachments doesn't match the
16987     // number of color attachments.  In this case, we don't add any color
16988     // blend attachments even though we have a color attachment.
16989     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGraphicsPipelineCreateInfo-attachmentCount-00746");
16990 
16991     ASSERT_NO_FATAL_FAILURE(Init());
16992     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
16993 
16994     OneOffDescriptorSet ds(m_device, {
16995                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
16996                                      });
16997 
16998     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
16999     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
17000     pipe_ms_state_ci.pNext = NULL;
17001     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
17002     pipe_ms_state_ci.sampleShadingEnable = 0;
17003     pipe_ms_state_ci.minSampleShading = 1.0;
17004     pipe_ms_state_ci.pSampleMask = NULL;
17005 
17006     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
17007 
17008     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
17009     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);  // We shouldn't need a fragment shader
17010     // but add it to be able to run on more devices
17011     VkPipelineObj pipe(m_device);
17012     pipe.AddShader(&vs);
17013     pipe.AddShader(&fs);
17014     pipe.SetMSAA(&pipe_ms_state_ci);
17015     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
17016     m_errorMonitor->VerifyFound();
17017 }
17018 
TEST_F(VkLayerTest,Bad2DArrayImageType)17019 TEST_F(VkLayerTest, Bad2DArrayImageType) {
17020     TEST_DESCRIPTION("Create an image with a flag specifying 2D_ARRAY_COMPATIBLE but not of imageType 3D.");
17021 
17022     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
17023     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
17024         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
17025     } else {
17026         printf("%s %s is not supported; skipping\n", kSkipPrefix, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
17027         return;
17028     }
17029     ASSERT_NO_FATAL_FAILURE(InitState());
17030 
17031     // Trigger check by setting imagecreateflags to 2d_array_compat and imageType to 2D
17032     VkImageCreateInfo ici = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
17033                              nullptr,
17034                              VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR,
17035                              VK_IMAGE_TYPE_2D,
17036                              VK_FORMAT_R8G8B8A8_UNORM,
17037                              {32, 32, 1},
17038                              1,
17039                              1,
17040                              VK_SAMPLE_COUNT_1_BIT,
17041                              VK_IMAGE_TILING_OPTIMAL,
17042                              VK_IMAGE_USAGE_SAMPLED_BIT,
17043                              VK_SHARING_MODE_EXCLUSIVE,
17044                              0,
17045                              nullptr,
17046                              VK_IMAGE_LAYOUT_UNDEFINED};
17047     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-flags-00950");
17048     VkImage image;
17049     vkCreateImage(m_device->device(), &ici, NULL, &image);
17050     m_errorMonitor->VerifyFound();
17051 }
17052 
TEST_F(VkLayerTest,Maint1BindingSliceOf3DImage)17053 TEST_F(VkLayerTest, Maint1BindingSliceOf3DImage) {
17054     TEST_DESCRIPTION(
17055         "Attempt to bind a slice of a 3D texture in a descriptor set. This is explicitly disallowed by KHR_maintenance1 to keep "
17056         "things simple for drivers.");
17057     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
17058     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
17059         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
17060     } else {
17061         printf("%s %s is not supported; skipping\n", kSkipPrefix, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
17062         return;
17063     }
17064     ASSERT_NO_FATAL_FAILURE(InitState());
17065 
17066     VkResult err;
17067 
17068     OneOffDescriptorSet set(m_device, {
17069                                           {0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
17070                                       });
17071 
17072     VkImageCreateInfo ici = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
17073                              nullptr,
17074                              VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR,
17075                              VK_IMAGE_TYPE_3D,
17076                              VK_FORMAT_R8G8B8A8_UNORM,
17077                              {32, 32, 32},
17078                              1,
17079                              1,
17080                              VK_SAMPLE_COUNT_1_BIT,
17081                              VK_IMAGE_TILING_OPTIMAL,
17082                              VK_IMAGE_USAGE_SAMPLED_BIT,
17083                              VK_SHARING_MODE_EXCLUSIVE,
17084                              0,
17085                              nullptr,
17086                              VK_IMAGE_LAYOUT_UNDEFINED};
17087     VkImageObj image(m_device);
17088     image.init(&ici);
17089     ASSERT_TRUE(image.initialized());
17090 
17091     VkImageViewCreateInfo ivci = {
17092         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
17093         nullptr,
17094         0,
17095         image.handle(),
17096         VK_IMAGE_VIEW_TYPE_2D,
17097         VK_FORMAT_R8G8B8A8_UNORM,
17098         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
17099          VK_COMPONENT_SWIZZLE_IDENTITY},
17100         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
17101     };
17102     VkImageView view;
17103     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
17104     ASSERT_VK_SUCCESS(err);
17105 
17106     // Meat of the test.
17107     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkDescriptorImageInfo-imageView-00343");
17108 
17109     VkDescriptorImageInfo dii = {VK_NULL_HANDLE, view, VK_IMAGE_LAYOUT_GENERAL};
17110     VkWriteDescriptorSet write = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, nullptr, set.set_, 0,      0, 1,
17111                                   VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,       &dii,    nullptr,  nullptr};
17112     vkUpdateDescriptorSets(m_device->device(), 1, &write, 0, nullptr);
17113 
17114     m_errorMonitor->VerifyFound();
17115 
17116     vkDestroyImageView(m_device->device(), view, nullptr);
17117 }
17118 
TEST_F(VkLayerTest,MissingClearAttachment)17119 TEST_F(VkLayerTest, MissingClearAttachment) {
17120     TEST_DESCRIPTION("Points to a wrong colorAttachment index in a VkClearAttachment structure passed to vkCmdClearAttachments");
17121     ASSERT_NO_FATAL_FAILURE(Init());
17122     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearAttachments-aspectMask-02501");
17123 
17124     VKTriangleTest(BsoFailCmdClearAttachments);
17125     m_errorMonitor->VerifyFound();
17126 }
17127 
TEST_F(VkPositiveLayerTest,ConfirmNoVLErrorWhenVkCmdClearAttachmentsCalledInSecondaryCB)17128 TEST_F(VkPositiveLayerTest, ConfirmNoVLErrorWhenVkCmdClearAttachmentsCalledInSecondaryCB) {
17129     TEST_DESCRIPTION(
17130         "This test is to verify that when vkCmdClearAttachments is called by a secondary commandbuffer, the validation layers do "
17131         "not throw an error if the primary commandbuffer begins a renderpass before executing the secondary commandbuffer.");
17132 
17133     ASSERT_NO_FATAL_FAILURE(Init());
17134     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
17135 
17136     VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
17137 
17138     VkCommandBufferBeginInfo info = {};
17139     VkCommandBufferInheritanceInfo hinfo = {};
17140     info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
17141     info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
17142     info.pInheritanceInfo = &hinfo;
17143     hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
17144     hinfo.pNext = NULL;
17145     hinfo.renderPass = renderPass();
17146     hinfo.subpass = 0;
17147     hinfo.framebuffer = m_framebuffer;
17148     hinfo.occlusionQueryEnable = VK_FALSE;
17149     hinfo.queryFlags = 0;
17150     hinfo.pipelineStatistics = 0;
17151 
17152     secondary.begin(&info);
17153     VkClearAttachment color_attachment;
17154     color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17155     color_attachment.clearValue.color.float32[0] = 0.0;
17156     color_attachment.clearValue.color.float32[1] = 0.0;
17157     color_attachment.clearValue.color.float32[2] = 0.0;
17158     color_attachment.clearValue.color.float32[3] = 0.0;
17159     color_attachment.colorAttachment = 0;
17160     VkClearRect clear_rect = {{{0, 0}, {(uint32_t)m_width, (uint32_t)m_height}}, 0, 1};
17161     vkCmdClearAttachments(secondary.handle(), 1, &color_attachment, 1, &clear_rect);
17162     secondary.end();
17163     // Modify clear rect here to verify that it doesn't cause validation error
17164     clear_rect = {{{0, 0}, {99999999, 99999999}}, 0, 0};
17165 
17166     m_commandBuffer->begin();
17167     vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
17168     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
17169     vkCmdEndRenderPass(m_commandBuffer->handle());
17170     m_commandBuffer->end();
17171     m_errorMonitor->VerifyNotFound();
17172 }
17173 
TEST_F(VkLayerTest,CmdClearAttachmentTests)17174 TEST_F(VkLayerTest, CmdClearAttachmentTests) {
17175     TEST_DESCRIPTION("Various tests for validating usage of vkCmdClearAttachments");
17176 
17177     ASSERT_NO_FATAL_FAILURE(Init());
17178     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
17179 
17180     OneOffDescriptorSet ds(m_device, {
17181                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
17182                                      });
17183 
17184     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
17185     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
17186     pipe_ms_state_ci.pNext = NULL;
17187     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
17188     pipe_ms_state_ci.sampleShadingEnable = 0;
17189     pipe_ms_state_ci.minSampleShading = 1.0;
17190     pipe_ms_state_ci.pSampleMask = NULL;
17191 
17192     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
17193 
17194     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
17195     //  We shouldn't need a fragment shader but add it to be able to run
17196     //  on more devices
17197     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
17198 
17199     VkPipelineObj pipe(m_device);
17200     pipe.AddShader(&vs);
17201     pipe.AddShader(&fs);
17202     pipe.AddDefaultColorAttachment();
17203     pipe.SetMSAA(&pipe_ms_state_ci);
17204     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
17205 
17206     m_commandBuffer->begin();
17207     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
17208 
17209     // Main thing we care about for this test is that the VkImage obj we're
17210     // clearing matches Color Attachment of FB
17211     //  Also pass down other dummy params to keep driver and paramchecker happy
17212     VkClearAttachment color_attachment;
17213     color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17214     color_attachment.clearValue.color.float32[0] = 1.0;
17215     color_attachment.clearValue.color.float32[1] = 1.0;
17216     color_attachment.clearValue.color.float32[2] = 1.0;
17217     color_attachment.clearValue.color.float32[3] = 1.0;
17218     color_attachment.colorAttachment = 0;
17219     VkClearRect clear_rect = {{{0, 0}, {(uint32_t)m_width, (uint32_t)m_height}}, 0, 1};
17220 
17221     // Call for full-sized FB Color attachment prior to issuing a Draw
17222     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
17223                                          "vkCmdClearAttachments() issued on command buffer object ");
17224     vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
17225     m_errorMonitor->VerifyFound();
17226 
17227     clear_rect.rect.extent.width = renderPassBeginInfo().renderArea.extent.width + 4;
17228     clear_rect.rect.extent.height = clear_rect.rect.extent.height / 2;
17229     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearAttachments-pRects-00016");
17230     vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
17231     m_errorMonitor->VerifyFound();
17232 
17233     // baseLayer >= view layers
17234     clear_rect.rect.extent.width = (uint32_t)m_width;
17235     clear_rect.baseArrayLayer = 1;
17236     clear_rect.layerCount = 0;
17237     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearAttachments-pRects-00017");
17238     vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
17239     m_errorMonitor->VerifyFound();
17240 
17241     // baseLayer + layerCount > view layers
17242     clear_rect.rect.extent.width = (uint32_t)m_width;
17243     clear_rect.baseArrayLayer = 0;
17244     clear_rect.layerCount = 2;
17245     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearAttachments-pRects-00017");
17246     vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
17247     m_errorMonitor->VerifyFound();
17248 
17249     m_commandBuffer->EndRenderPass();
17250     m_commandBuffer->end();
17251 }
17252 
TEST_F(VkLayerTest,VtxBufferBadIndex)17253 TEST_F(VkLayerTest, VtxBufferBadIndex) {
17254     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
17255                                          "but no vertex buffers are attached to this Pipeline State Object");
17256 
17257     ASSERT_NO_FATAL_FAILURE(Init());
17258     ASSERT_NO_FATAL_FAILURE(InitViewport());
17259     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
17260 
17261     OneOffDescriptorSet ds(m_device, {
17262                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
17263                                      });
17264 
17265     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
17266     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
17267     pipe_ms_state_ci.pNext = NULL;
17268     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
17269     pipe_ms_state_ci.sampleShadingEnable = 0;
17270     pipe_ms_state_ci.minSampleShading = 1.0;
17271     pipe_ms_state_ci.pSampleMask = NULL;
17272 
17273     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
17274 
17275     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
17276     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);  // We shouldn't need a fragment shader
17277     // but add it to be able to run on more devices
17278     VkPipelineObj pipe(m_device);
17279     pipe.AddShader(&vs);
17280     pipe.AddShader(&fs);
17281     pipe.AddDefaultColorAttachment();
17282     pipe.SetMSAA(&pipe_ms_state_ci);
17283     pipe.SetViewport(m_viewports);
17284     pipe.SetScissor(m_scissors);
17285     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
17286 
17287     m_commandBuffer->begin();
17288     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
17289     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
17290     // Don't care about actual data, just need to get to draw to flag error
17291     static const float vbo_data[3] = {1.f, 0.f, 1.f};
17292     VkConstantBufferObj vbo(m_device, sizeof(vbo_data), (const void *)&vbo_data, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
17293     m_commandBuffer->BindVertexBuffer(&vbo, (VkDeviceSize)0, 1);  // VBO idx 1, but no VBO in PSO
17294     m_commandBuffer->Draw(1, 0, 0, 0);
17295 
17296     m_errorMonitor->VerifyFound();
17297 
17298     m_commandBuffer->EndRenderPass();
17299     m_commandBuffer->end();
17300 }
17301 
TEST_F(VkLayerTest,InvalidQueryPoolCreate)17302 TEST_F(VkLayerTest, InvalidQueryPoolCreate) {
17303     TEST_DESCRIPTION("Attempt to create a query pool for PIPELINE_STATISTICS without enabling pipeline stats for the device.");
17304 
17305     ASSERT_NO_FATAL_FAILURE(Init());
17306 
17307     vk_testing::QueueCreateInfoArray queue_info(m_device->queue_props);
17308 
17309     VkDevice local_device;
17310     VkDeviceCreateInfo device_create_info = {};
17311     auto features = m_device->phy().features();
17312     // Intentionally disable pipeline stats
17313     features.pipelineStatisticsQuery = VK_FALSE;
17314     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
17315     device_create_info.pNext = NULL;
17316     device_create_info.queueCreateInfoCount = queue_info.size();
17317     device_create_info.pQueueCreateInfos = queue_info.data();
17318     device_create_info.enabledLayerCount = 0;
17319     device_create_info.ppEnabledLayerNames = NULL;
17320     device_create_info.pEnabledFeatures = &features;
17321     VkResult err = vkCreateDevice(gpu(), &device_create_info, nullptr, &local_device);
17322     ASSERT_VK_SUCCESS(err);
17323 
17324     VkQueryPoolCreateInfo qpci{};
17325     qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
17326     qpci.queryType = VK_QUERY_TYPE_PIPELINE_STATISTICS;
17327     qpci.queryCount = 1;
17328     VkQueryPool query_pool;
17329 
17330     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkQueryPoolCreateInfo-queryType-00791");
17331     vkCreateQueryPool(local_device, &qpci, nullptr, &query_pool);
17332     m_errorMonitor->VerifyFound();
17333 
17334     vkDestroyDevice(local_device, nullptr);
17335 }
17336 
TEST_F(VkLayerTest,UnclosedQuery)17337 TEST_F(VkLayerTest, UnclosedQuery) {
17338     TEST_DESCRIPTION("End a command buffer with a query still in progress.");
17339 
17340     const char *invalid_query = "Ending command buffer with in progress query: queryPool 0x";
17341 
17342     ASSERT_NO_FATAL_FAILURE(Init());
17343 
17344     VkEvent event;
17345     VkEventCreateInfo event_create_info{};
17346     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
17347     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
17348 
17349     VkQueue queue = VK_NULL_HANDLE;
17350     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
17351 
17352     m_commandBuffer->begin();
17353     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_query);
17354 
17355     VkQueryPool query_pool;
17356     VkQueryPoolCreateInfo query_pool_create_info = {};
17357     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
17358     query_pool_create_info.queryType = VK_QUERY_TYPE_OCCLUSION;
17359     query_pool_create_info.queryCount = 1;
17360     vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
17361 
17362     vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0 /*startQuery*/, 1 /*queryCount*/);
17363     vkCmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
17364 
17365     vkEndCommandBuffer(m_commandBuffer->handle());
17366     m_errorMonitor->VerifyFound();
17367 
17368     vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
17369     vkDestroyEvent(m_device->device(), event, nullptr);
17370 }
17371 
TEST_F(VkLayerTest,QueryPreciseBit)17372 TEST_F(VkLayerTest, QueryPreciseBit) {
17373     TEST_DESCRIPTION("Check for correct Query Precise Bit circumstances.");
17374     ASSERT_NO_FATAL_FAILURE(Init());
17375 
17376     // These tests require that the device support pipeline statistics query
17377     VkPhysicalDeviceFeatures device_features = {};
17378     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
17379     if (VK_TRUE != device_features.pipelineStatisticsQuery) {
17380         printf("%s Test requires unsupported pipelineStatisticsQuery feature. Skipped.\n", kSkipPrefix);
17381         return;
17382     }
17383 
17384     std::vector<const char *> device_extension_names;
17385     auto features = m_device->phy().features();
17386 
17387     // Test for precise bit when query type is not OCCLUSION
17388     if (features.occlusionQueryPrecise) {
17389         VkEvent event;
17390         VkEventCreateInfo event_create_info{};
17391         event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
17392         vkCreateEvent(m_device->handle(), &event_create_info, nullptr, &event);
17393 
17394         m_commandBuffer->begin();
17395         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBeginQuery-queryType-00800");
17396 
17397         VkQueryPool query_pool;
17398         VkQueryPoolCreateInfo query_pool_create_info = {};
17399         query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
17400         query_pool_create_info.queryType = VK_QUERY_TYPE_PIPELINE_STATISTICS;
17401         query_pool_create_info.queryCount = 1;
17402         vkCreateQueryPool(m_device->handle(), &query_pool_create_info, nullptr, &query_pool);
17403 
17404         vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
17405         vkCmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, VK_QUERY_CONTROL_PRECISE_BIT);
17406         vkCmdEndQuery(m_commandBuffer->handle(), query_pool, 0);
17407         m_errorMonitor->VerifyFound();
17408 
17409         m_commandBuffer->end();
17410         vkDestroyQueryPool(m_device->handle(), query_pool, nullptr);
17411         vkDestroyEvent(m_device->handle(), event, nullptr);
17412     }
17413 
17414     // Test for precise bit when precise feature is not available
17415     features.occlusionQueryPrecise = false;
17416     VkDeviceObj test_device(0, gpu(), device_extension_names, &features);
17417 
17418     VkCommandPoolCreateInfo pool_create_info{};
17419     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
17420     pool_create_info.queueFamilyIndex = test_device.graphics_queue_node_index_;
17421 
17422     VkCommandPool command_pool;
17423     vkCreateCommandPool(test_device.handle(), &pool_create_info, nullptr, &command_pool);
17424 
17425     VkCommandBufferAllocateInfo cmd = {};
17426     cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
17427     cmd.pNext = NULL;
17428     cmd.commandPool = command_pool;
17429     cmd.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
17430     cmd.commandBufferCount = 1;
17431 
17432     VkCommandBuffer cmd_buffer;
17433     VkResult err = vkAllocateCommandBuffers(test_device.handle(), &cmd, &cmd_buffer);
17434     ASSERT_VK_SUCCESS(err);
17435 
17436     VkEvent event;
17437     VkEventCreateInfo event_create_info{};
17438     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
17439     vkCreateEvent(test_device.handle(), &event_create_info, nullptr, &event);
17440 
17441     VkCommandBufferBeginInfo begin_info = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
17442                                            VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, nullptr};
17443 
17444     vkBeginCommandBuffer(cmd_buffer, &begin_info);
17445     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBeginQuery-queryType-00800");
17446 
17447     VkQueryPool query_pool;
17448     VkQueryPoolCreateInfo query_pool_create_info = {};
17449     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
17450     query_pool_create_info.queryType = VK_QUERY_TYPE_OCCLUSION;
17451     query_pool_create_info.queryCount = 1;
17452     vkCreateQueryPool(test_device.handle(), &query_pool_create_info, nullptr, &query_pool);
17453 
17454     vkCmdResetQueryPool(cmd_buffer, query_pool, 0, 1);
17455     vkCmdBeginQuery(cmd_buffer, query_pool, 0, VK_QUERY_CONTROL_PRECISE_BIT);
17456     vkCmdEndQuery(cmd_buffer, query_pool, 0);
17457     m_errorMonitor->VerifyFound();
17458 
17459     vkEndCommandBuffer(cmd_buffer);
17460     vkDestroyQueryPool(test_device.handle(), query_pool, nullptr);
17461     vkDestroyEvent(test_device.handle(), event, nullptr);
17462     vkDestroyCommandPool(test_device.handle(), command_pool, nullptr);
17463 }
17464 
TEST_F(VkLayerTest,VertexBufferInvalid)17465 TEST_F(VkLayerTest, VertexBufferInvalid) {
17466     TEST_DESCRIPTION(
17467         "Submit a command buffer using deleted vertex buffer, delete a buffer twice, use an invalid offset for each buffer type, "
17468         "and attempt to bind a null buffer");
17469 
17470     const char *deleted_buffer_in_command_buffer = "Cannot submit cmd buffer using deleted buffer ";
17471     const char *invalid_offset_message = "VUID-vkBindBufferMemory-memoryOffset-01036";
17472 
17473     ASSERT_NO_FATAL_FAILURE(Init());
17474     ASSERT_NO_FATAL_FAILURE(InitViewport());
17475     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
17476 
17477     VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
17478     pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
17479     pipe_ms_state_ci.pNext = NULL;
17480     pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
17481     pipe_ms_state_ci.sampleShadingEnable = 0;
17482     pipe_ms_state_ci.minSampleShading = 1.0;
17483     pipe_ms_state_ci.pSampleMask = nullptr;
17484 
17485     const VkPipelineLayoutObj pipeline_layout(m_device);
17486 
17487     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
17488     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
17489     VkPipelineObj pipe(m_device);
17490     pipe.AddShader(&vs);
17491     pipe.AddShader(&fs);
17492     pipe.AddDefaultColorAttachment();
17493     pipe.SetMSAA(&pipe_ms_state_ci);
17494     pipe.SetViewport(m_viewports);
17495     pipe.SetScissor(m_scissors);
17496     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
17497 
17498     m_commandBuffer->begin();
17499     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
17500     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
17501 
17502     {
17503         // Create and bind a vertex buffer in a reduced scope, which will cause
17504         // it to be deleted upon leaving this scope
17505         const float vbo_data[3] = {1.f, 0.f, 1.f};
17506         VkVerticesObj draw_verticies(m_device, 1, 1, sizeof(vbo_data[0]), sizeof(vbo_data) / sizeof(vbo_data[0]), vbo_data);
17507         draw_verticies.BindVertexBuffers(m_commandBuffer->handle());
17508         draw_verticies.AddVertexInputToPipe(pipe);
17509     }
17510 
17511     m_commandBuffer->Draw(1, 0, 0, 0);
17512 
17513     m_commandBuffer->EndRenderPass();
17514     m_commandBuffer->end();
17515 
17516     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, deleted_buffer_in_command_buffer);
17517     m_commandBuffer->QueueCommandBuffer(false);
17518     m_errorMonitor->VerifyFound();
17519 
17520     {
17521         // Create and bind a vertex buffer in a reduced scope, and delete it
17522         // twice, the second through the destructor
17523         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eDoubleDelete);
17524         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyBuffer-buffer-parameter");
17525         buffer_test.TestDoubleDestroy();
17526     }
17527     m_errorMonitor->VerifyFound();
17528 
17529     m_errorMonitor->SetUnexpectedError("value of pCreateInfo->usage must not be 0");
17530     if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidMemoryOffset)) {
17531         // Create and bind a memory buffer with an invalid offset.
17532         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_offset_message);
17533         m_errorMonitor->SetUnexpectedError(
17534             "If buffer was created with the VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT or VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, "
17535             "memoryOffset must be a multiple of VkPhysicalDeviceLimits::minTexelBufferOffsetAlignment");
17536         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VkBufferTest::eInvalidMemoryOffset);
17537         (void)buffer_test;
17538         m_errorMonitor->VerifyFound();
17539     }
17540 
17541     {
17542         // Attempt to bind a null buffer.
17543         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17544                                              "vkBindBufferMemory: required parameter buffer specified as VK_NULL_HANDLE");
17545         VkBufferTest buffer_test(m_device, 0, VkBufferTest::eBindNullBuffer);
17546         (void)buffer_test;
17547         m_errorMonitor->VerifyFound();
17548     }
17549 
17550     {
17551         // Attempt to bind a fake buffer.
17552         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkBindBufferMemory-buffer-parameter");
17553         VkBufferTest buffer_test(m_device, 0, VkBufferTest::eBindFakeBuffer);
17554         (void)buffer_test;
17555         m_errorMonitor->VerifyFound();
17556     }
17557 
17558     {
17559         // Attempt to use an invalid handle to delete a buffer.
17560         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkFreeMemory-memory-parameter");
17561         VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eFreeInvalidHandle);
17562         (void)buffer_test;
17563     }
17564     m_errorMonitor->VerifyFound();
17565 }
17566 
TEST_F(VkLayerTest,BadVertexBufferOffset)17567 TEST_F(VkLayerTest, BadVertexBufferOffset) {
17568     TEST_DESCRIPTION("Submit an offset past the end of a vertex buffer");
17569 
17570     ASSERT_NO_FATAL_FAILURE(Init());
17571     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
17572     static const float vbo_data[3] = {1.f, 0.f, 1.f};
17573     VkConstantBufferObj vbo(m_device, sizeof(vbo_data), (const void *)&vbo_data, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
17574     m_commandBuffer->begin();
17575     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
17576     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBindVertexBuffers-pOffsets-00626");
17577     m_commandBuffer->BindVertexBuffer(&vbo, (VkDeviceSize)(3 * sizeof(float)), 1);  // Offset at the end of the buffer
17578     m_errorMonitor->VerifyFound();
17579 
17580     m_commandBuffer->EndRenderPass();
17581     m_commandBuffer->end();
17582 }
17583 
TEST_F(VkLayerTest,InvalidVertexAttributeAlignment)17584 TEST_F(VkLayerTest, InvalidVertexAttributeAlignment) {
17585     TEST_DESCRIPTION("Check for proper aligment of attribAddress which depends on a bound pipeline and on a bound vertex buffer");
17586 
17587     ASSERT_NO_FATAL_FAILURE(Init());
17588     ASSERT_NO_FATAL_FAILURE(InitViewport());
17589     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
17590 
17591     const VkPipelineLayoutObj pipeline_layout(m_device);
17592 
17593     struct VboEntry {
17594         uint16_t input0[2];
17595         uint32_t input1;
17596         float input2[4];
17597     };
17598 
17599     const unsigned vbo_entry_count = 3;
17600     const VboEntry vbo_data[vbo_entry_count] = {};
17601 
17602     VkConstantBufferObj vbo(m_device, static_cast<int>(sizeof(VboEntry) * vbo_entry_count),
17603                             reinterpret_cast<const void *>(vbo_data), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
17604 
17605     VkVertexInputBindingDescription input_binding;
17606     input_binding.binding = 0;
17607     input_binding.stride = sizeof(VboEntry);
17608     input_binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
17609 
17610     VkVertexInputAttributeDescription input_attribs[3];
17611 
17612     input_attribs[0].binding = 0;
17613     // Location switch between attrib[0] and attrib[1] is intentional
17614     input_attribs[0].location = 1;
17615     input_attribs[0].format = VK_FORMAT_A8B8G8R8_UNORM_PACK32;
17616     input_attribs[0].offset = offsetof(VboEntry, input1);
17617 
17618     input_attribs[1].binding = 0;
17619     input_attribs[1].location = 0;
17620     input_attribs[1].format = VK_FORMAT_R16G16_UNORM;
17621     input_attribs[1].offset = offsetof(VboEntry, input0);
17622 
17623     input_attribs[2].binding = 0;
17624     input_attribs[2].location = 2;
17625     input_attribs[2].format = VK_FORMAT_R32G32B32A32_SFLOAT;
17626     input_attribs[2].offset = offsetof(VboEntry, input2);
17627 
17628     char const *vsSource =
17629         "#version 450\n"
17630         "\n"
17631         "layout(location = 0) in vec2 input0;"
17632         "layout(location = 1) in vec4 input1;"
17633         "layout(location = 2) in vec4 input2;"
17634         "\n"
17635         "void main(){\n"
17636         "   gl_Position = input1 + input2;\n"
17637         "   gl_Position.xy += input0;\n"
17638         "}\n";
17639     char const *fsSource =
17640         "#version 450\n"
17641         "\n"
17642         "layout(location=0) out vec4 color;\n"
17643         "void main(){\n"
17644         "   color = vec4(1);\n"
17645         "}\n";
17646 
17647     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
17648     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
17649 
17650     VkPipelineObj pipe1(m_device);
17651     pipe1.AddDefaultColorAttachment();
17652     pipe1.AddShader(&vs);
17653     pipe1.AddShader(&fs);
17654     pipe1.AddVertexInputBindings(&input_binding, 1);
17655     pipe1.AddVertexInputAttribs(&input_attribs[0], 3);
17656     pipe1.SetViewport(m_viewports);
17657     pipe1.SetScissor(m_scissors);
17658     pipe1.CreateVKPipeline(pipeline_layout.handle(), renderPass());
17659 
17660     input_binding.stride = 6;
17661 
17662     VkPipelineObj pipe2(m_device);
17663     pipe2.AddDefaultColorAttachment();
17664     pipe2.AddShader(&vs);
17665     pipe2.AddShader(&fs);
17666     pipe2.AddVertexInputBindings(&input_binding, 1);
17667     pipe2.AddVertexInputAttribs(&input_attribs[0], 3);
17668     pipe2.SetViewport(m_viewports);
17669     pipe2.SetScissor(m_scissors);
17670     pipe2.CreateVKPipeline(pipeline_layout.handle(), renderPass());
17671 
17672     m_commandBuffer->begin();
17673     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
17674 
17675     // Test with invalid buffer offset
17676     VkDeviceSize offset = 1;
17677     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe1.handle());
17678     vkCmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
17679     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid attribAddress alignment for vertex attribute 0");
17680     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid attribAddress alignment for vertex attribute 1");
17681     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid attribAddress alignment for vertex attribute 2");
17682     m_commandBuffer->Draw(1, 0, 0, 0);
17683     m_errorMonitor->VerifyFound();
17684 
17685     // Test with invalid buffer stride
17686     offset = 0;
17687     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe2.handle());
17688     vkCmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
17689     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid attribAddress alignment for vertex attribute 0");
17690     // Attribute[1] is aligned properly even with a wrong stride
17691     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid attribAddress alignment for vertex attribute 2");
17692     m_commandBuffer->Draw(1, 0, 0, 0);
17693     m_errorMonitor->VerifyFound();
17694 
17695     m_commandBuffer->EndRenderPass();
17696     m_commandBuffer->end();
17697 }
17698 
TEST_F(VkLayerTest,InvalidVertexBindingDescriptions)17699 TEST_F(VkLayerTest, InvalidVertexBindingDescriptions) {
17700     TEST_DESCRIPTION(
17701         "Attempt to create a graphics pipeline where:"
17702         "1) count of vertex bindings exceeds device's maxVertexInputBindings limit"
17703         "2) requested bindings include a duplicate binding value");
17704 
17705     ASSERT_NO_FATAL_FAILURE(Init());
17706     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
17707 
17708     const VkPipelineLayoutObj pipeline_layout(m_device);
17709 
17710     const uint32_t binding_count = m_device->props.limits.maxVertexInputBindings + 1;
17711 
17712     std::vector<VkVertexInputBindingDescription> input_bindings(binding_count);
17713     for (uint32_t i = 0; i < binding_count; ++i) {
17714         input_bindings[i].binding = i;
17715         input_bindings[i].stride = 4;
17716         input_bindings[i].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
17717     }
17718     // Let the last binding description use same binding as the first one
17719     input_bindings[binding_count - 1].binding = 0;
17720 
17721     VkVertexInputAttributeDescription input_attrib;
17722     input_attrib.binding = 0;
17723     input_attrib.location = 0;
17724     input_attrib.format = VK_FORMAT_R32G32B32_SFLOAT;
17725     input_attrib.offset = 0;
17726 
17727     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
17728     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
17729 
17730     VkPipelineObj pipe(m_device);
17731     pipe.AddDefaultColorAttachment();
17732     pipe.AddShader(&vs);
17733     pipe.AddShader(&fs);
17734     pipe.AddVertexInputBindings(input_bindings.data(), binding_count);
17735     pipe.AddVertexInputAttribs(&input_attrib, 1);
17736 
17737     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17738                                          "VUID-VkPipelineVertexInputStateCreateInfo-vertexBindingDescriptionCount-00613");
17739     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17740                                          "VUID-VkPipelineVertexInputStateCreateInfo-pVertexBindingDescriptions-00616");
17741     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
17742     m_errorMonitor->VerifyFound();
17743 }
17744 
TEST_F(VkLayerTest,InvalidVertexAttributeDescriptions)17745 TEST_F(VkLayerTest, InvalidVertexAttributeDescriptions) {
17746     TEST_DESCRIPTION(
17747         "Attempt to create a graphics pipeline where:"
17748         "1) count of vertex attributes exceeds device's maxVertexInputAttributes limit"
17749         "2) requested location include a duplicate location value"
17750         "3) binding used by one attribute is not defined by a binding description");
17751 
17752     ASSERT_NO_FATAL_FAILURE(Init());
17753     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
17754 
17755     const VkPipelineLayoutObj pipeline_layout(m_device);
17756 
17757     VkVertexInputBindingDescription input_binding;
17758     input_binding.binding = 0;
17759     input_binding.stride = 4;
17760     input_binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
17761 
17762     const uint32_t attribute_count = m_device->props.limits.maxVertexInputAttributes + 1;
17763     std::vector<VkVertexInputAttributeDescription> input_attribs(attribute_count);
17764     for (uint32_t i = 0; i < attribute_count; ++i) {
17765         input_attribs[i].binding = 0;
17766         input_attribs[i].location = i;
17767         input_attribs[i].format = VK_FORMAT_R32G32B32_SFLOAT;
17768         input_attribs[i].offset = 0;
17769     }
17770     // Let the last input_attribs description use same location as the first one
17771     input_attribs[attribute_count - 1].location = 0;
17772     // Let the last input_attribs description use binding which is not defined
17773     input_attribs[attribute_count - 1].binding = 1;
17774 
17775     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
17776     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
17777 
17778     VkPipelineObj pipe(m_device);
17779     pipe.AddDefaultColorAttachment();
17780     pipe.AddShader(&vs);
17781     pipe.AddShader(&fs);
17782     pipe.AddVertexInputBindings(&input_binding, 1);
17783     pipe.AddVertexInputAttribs(input_attribs.data(), attribute_count);
17784 
17785     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17786                                          "VUID-VkPipelineVertexInputStateCreateInfo-vertexAttributeDescriptionCount-00614");
17787     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineVertexInputStateCreateInfo-binding-00615");
17788     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
17789                                          "VUID-VkPipelineVertexInputStateCreateInfo-pVertexAttributeDescriptions-00617");
17790     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
17791     m_errorMonitor->VerifyFound();
17792 }
17793 
17794 // INVALID_IMAGE_LAYOUT tests (one other case is hit by MapMemWithoutHostVisibleBit and not here)
TEST_F(VkLayerTest,InvalidImageLayout)17795 TEST_F(VkLayerTest, InvalidImageLayout) {
17796     TEST_DESCRIPTION(
17797         "Hit all possible validation checks associated with the UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout error. "
17798         "Generally these involve having images in the wrong layout when they're copied or transitioned.");
17799     // 3 in ValidateCmdBufImageLayouts
17800     // *  -1 Attempt to submit cmd buf w/ deleted image
17801     // *  -2 Cmd buf submit of image w/ layout not matching first use w/ subresource
17802     // *  -3 Cmd buf submit of image w/ layout not matching first use w/o subresource
17803 
17804     ASSERT_NO_FATAL_FAILURE(Init());
17805     auto depth_format = FindSupportedDepthStencilFormat(gpu());
17806     if (!depth_format) {
17807         printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
17808         return;
17809     }
17810     // Create src & dst images to use for copy operations
17811     VkImage src_image;
17812     VkImage dst_image;
17813     VkImage depth_image;
17814 
17815     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
17816     const int32_t tex_width = 32;
17817     const int32_t tex_height = 32;
17818 
17819     VkImageCreateInfo image_create_info = {};
17820     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
17821     image_create_info.pNext = NULL;
17822     image_create_info.imageType = VK_IMAGE_TYPE_2D;
17823     image_create_info.format = tex_format;
17824     image_create_info.extent.width = tex_width;
17825     image_create_info.extent.height = tex_height;
17826     image_create_info.extent.depth = 1;
17827     image_create_info.mipLevels = 1;
17828     image_create_info.arrayLayers = 4;
17829     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
17830     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
17831     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
17832     image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
17833     image_create_info.flags = 0;
17834 
17835     VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &src_image);
17836     ASSERT_VK_SUCCESS(err);
17837     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
17838     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dst_image);
17839     ASSERT_VK_SUCCESS(err);
17840     image_create_info.format = VK_FORMAT_D16_UNORM;
17841     image_create_info.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
17842     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &depth_image);
17843     ASSERT_VK_SUCCESS(err);
17844 
17845     // Allocate memory
17846     VkMemoryRequirements img_mem_reqs = {};
17847     VkMemoryAllocateInfo mem_alloc = {};
17848     VkDeviceMemory src_image_mem, dst_image_mem, depth_image_mem;
17849     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
17850     mem_alloc.pNext = NULL;
17851     mem_alloc.allocationSize = 0;
17852     mem_alloc.memoryTypeIndex = 0;
17853 
17854     vkGetImageMemoryRequirements(m_device->device(), src_image, &img_mem_reqs);
17855     mem_alloc.allocationSize = img_mem_reqs.size;
17856     bool pass = m_device->phy().set_memory_type(img_mem_reqs.memoryTypeBits, &mem_alloc, 0);
17857     ASSERT_TRUE(pass);
17858     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &src_image_mem);
17859     ASSERT_VK_SUCCESS(err);
17860 
17861     vkGetImageMemoryRequirements(m_device->device(), dst_image, &img_mem_reqs);
17862     mem_alloc.allocationSize = img_mem_reqs.size;
17863     pass = m_device->phy().set_memory_type(img_mem_reqs.memoryTypeBits, &mem_alloc, 0);
17864     ASSERT_VK_SUCCESS(err);
17865     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &dst_image_mem);
17866     ASSERT_VK_SUCCESS(err);
17867 
17868     vkGetImageMemoryRequirements(m_device->device(), depth_image, &img_mem_reqs);
17869     mem_alloc.allocationSize = img_mem_reqs.size;
17870     pass = m_device->phy().set_memory_type(img_mem_reqs.memoryTypeBits, &mem_alloc, 0);
17871     ASSERT_VK_SUCCESS(err);
17872     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &depth_image_mem);
17873     ASSERT_VK_SUCCESS(err);
17874 
17875     err = vkBindImageMemory(m_device->device(), src_image, src_image_mem, 0);
17876     ASSERT_VK_SUCCESS(err);
17877     err = vkBindImageMemory(m_device->device(), dst_image, dst_image_mem, 0);
17878     ASSERT_VK_SUCCESS(err);
17879     err = vkBindImageMemory(m_device->device(), depth_image, depth_image_mem, 0);
17880     ASSERT_VK_SUCCESS(err);
17881 
17882     m_commandBuffer->begin();
17883     VkImageCopy copy_region;
17884     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17885     copy_region.srcSubresource.mipLevel = 0;
17886     copy_region.srcSubresource.baseArrayLayer = 0;
17887     copy_region.srcSubresource.layerCount = 1;
17888     copy_region.srcOffset.x = 0;
17889     copy_region.srcOffset.y = 0;
17890     copy_region.srcOffset.z = 0;
17891     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17892     copy_region.dstSubresource.mipLevel = 0;
17893     copy_region.dstSubresource.baseArrayLayer = 0;
17894     copy_region.dstSubresource.layerCount = 1;
17895     copy_region.dstOffset.x = 0;
17896     copy_region.dstOffset.y = 0;
17897     copy_region.dstOffset.z = 0;
17898     copy_region.extent.width = 1;
17899     copy_region.extent.height = 1;
17900     copy_region.extent.depth = 1;
17901 
17902     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
17903                                          "layout should be VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL instead of GENERAL.");
17904     m_errorMonitor->SetUnexpectedError("layout should be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL instead of GENERAL.");
17905 
17906     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
17907     m_errorMonitor->VerifyFound();
17908     // The first call hits the expected WARNING and skips the call down the chain, so call a second time to call down chain and
17909     // update layer state
17910     m_errorMonitor->SetUnexpectedError("layout should be VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL instead of GENERAL.");
17911     m_errorMonitor->SetUnexpectedError("layout should be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL instead of GENERAL.");
17912     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
17913     // Now cause error due to src image layout changing
17914     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-srcImageLayout-00128");
17915     m_errorMonitor->SetUnexpectedError("is VK_IMAGE_LAYOUT_UNDEFINED but can only be VK_IMAGE_LAYOUT");
17916     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_UNDEFINED, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
17917     m_errorMonitor->VerifyFound();
17918     // Final src error is due to bad layout type
17919     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-srcImageLayout-00129");
17920     m_errorMonitor->SetUnexpectedError(
17921         "with specific layout VK_IMAGE_LAYOUT_UNDEFINED that doesn't match the actual current layout VK_IMAGE_LAYOUT_GENERAL.");
17922     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_UNDEFINED, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
17923     m_errorMonitor->VerifyFound();
17924     // Now verify same checks for dst
17925     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
17926                                          "layout should be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL instead of GENERAL.");
17927     m_errorMonitor->SetUnexpectedError("layout should be VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL instead of GENERAL.");
17928     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
17929     m_errorMonitor->VerifyFound();
17930     // Now cause error due to src image layout changing
17931     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-dstImageLayout-00133");
17932     m_errorMonitor->SetUnexpectedError(
17933         "is VK_IMAGE_LAYOUT_UNDEFINED but can only be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL.");
17934     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_UNDEFINED, 1, &copy_region);
17935     m_errorMonitor->VerifyFound();
17936     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-dstImageLayout-00134");
17937     m_errorMonitor->SetUnexpectedError(
17938         "with specific layout VK_IMAGE_LAYOUT_UNDEFINED that doesn't match the actual current layout VK_IMAGE_LAYOUT_GENERAL.");
17939     m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_UNDEFINED, 1, &copy_region);
17940     m_errorMonitor->VerifyFound();
17941 
17942     // Convert dst and depth images to TRANSFER_DST for subsequent tests
17943     VkImageMemoryBarrier transfer_dst_image_barrier[1] = {};
17944     transfer_dst_image_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
17945     transfer_dst_image_barrier[0].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
17946     transfer_dst_image_barrier[0].newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
17947     transfer_dst_image_barrier[0].srcAccessMask = 0;
17948     transfer_dst_image_barrier[0].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
17949     transfer_dst_image_barrier[0].image = dst_image;
17950     transfer_dst_image_barrier[0].subresourceRange.layerCount = image_create_info.arrayLayers;
17951     transfer_dst_image_barrier[0].subresourceRange.levelCount = image_create_info.mipLevels;
17952     transfer_dst_image_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17953     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
17954                          NULL, 0, NULL, 1, transfer_dst_image_barrier);
17955     transfer_dst_image_barrier[0].image = depth_image;
17956     transfer_dst_image_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
17957     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
17958                          NULL, 0, NULL, 1, transfer_dst_image_barrier);
17959 
17960     // Cause errors due to clearing with invalid image layouts
17961     VkClearColorValue color_clear_value = {};
17962     VkImageSubresourceRange clear_range;
17963     clear_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
17964     clear_range.baseMipLevel = 0;
17965     clear_range.baseArrayLayer = 0;
17966     clear_range.layerCount = 1;
17967     clear_range.levelCount = 1;
17968 
17969     // Fail due to explicitly prohibited layout for color clear (only GENERAL and TRANSFER_DST are permitted).
17970     // Since the image is currently not in UNDEFINED layout, this will emit two errors.
17971     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearColorImage-imageLayout-00005");
17972     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearColorImage-imageLayout-00004");
17973     m_commandBuffer->ClearColorImage(dst_image, VK_IMAGE_LAYOUT_UNDEFINED, &color_clear_value, 1, &clear_range);
17974     m_errorMonitor->VerifyFound();
17975     // Fail due to provided layout not matching actual current layout for color clear.
17976     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearColorImage-imageLayout-00004");
17977     m_commandBuffer->ClearColorImage(dst_image, VK_IMAGE_LAYOUT_GENERAL, &color_clear_value, 1, &clear_range);
17978     m_errorMonitor->VerifyFound();
17979 
17980     VkClearDepthStencilValue depth_clear_value = {};
17981     clear_range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
17982 
17983     // Fail due to explicitly prohibited layout for depth clear (only GENERAL and TRANSFER_DST are permitted).
17984     // Since the image is currently not in UNDEFINED layout, this will emit two errors.
17985     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearDepthStencilImage-imageLayout-00012");
17986     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearDepthStencilImage-imageLayout-00011");
17987     m_commandBuffer->ClearDepthStencilImage(depth_image, VK_IMAGE_LAYOUT_UNDEFINED, &depth_clear_value, 1, &clear_range);
17988     m_errorMonitor->VerifyFound();
17989     // Fail due to provided layout not matching actual current layout for depth clear.
17990     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearDepthStencilImage-imageLayout-00011");
17991     m_commandBuffer->ClearDepthStencilImage(depth_image, VK_IMAGE_LAYOUT_GENERAL, &depth_clear_value, 1, &clear_range);
17992     m_errorMonitor->VerifyFound();
17993 
17994     // Now cause error due to bad image layout transition in PipelineBarrier
17995     VkImageMemoryBarrier image_barrier[1] = {};
17996     image_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
17997     image_barrier[0].oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
17998     image_barrier[0].newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
17999     image_barrier[0].image = src_image;
18000     image_barrier[0].subresourceRange.layerCount = image_create_info.arrayLayers;
18001     image_barrier[0].subresourceRange.levelCount = image_create_info.mipLevels;
18002     image_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
18003     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-oldLayout-01197");
18004     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-oldLayout-01210");
18005     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
18006                          NULL, 0, NULL, 1, image_barrier);
18007     m_errorMonitor->VerifyFound();
18008 
18009     // Finally some layout errors at RenderPass create time
18010     // Just hacking in specific state to get to the errors we want so don't copy this unless you know what you're doing.
18011     VkAttachmentReference attach = {};
18012     // perf warning for GENERAL layout w/ non-DS input attachment
18013     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
18014     VkSubpassDescription subpass = {};
18015     subpass.inputAttachmentCount = 1;
18016     subpass.pInputAttachments = &attach;
18017     VkRenderPassCreateInfo rpci = {};
18018     rpci.subpassCount = 1;
18019     rpci.pSubpasses = &subpass;
18020     rpci.attachmentCount = 1;
18021     VkAttachmentDescription attach_desc = {};
18022     attach_desc.format = VK_FORMAT_UNDEFINED;
18023     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
18024     attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
18025     rpci.pAttachments = &attach_desc;
18026     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
18027     VkRenderPass rp;
18028     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
18029                                          "Layout for input attachment is GENERAL but should be READ_ONLY_OPTIMAL.");
18030     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
18031     m_errorMonitor->VerifyFound();
18032     // error w/ non-general layout
18033     attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
18034 
18035     m_errorMonitor->SetDesiredFailureMsg(
18036         VK_DEBUG_REPORT_ERROR_BIT_EXT,
18037         "Layout for input attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be READ_ONLY_OPTIMAL or GENERAL.");
18038     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
18039     m_errorMonitor->VerifyFound();
18040     subpass.inputAttachmentCount = 0;
18041     subpass.colorAttachmentCount = 1;
18042     subpass.pColorAttachments = &attach;
18043     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
18044     // perf warning for GENERAL layout on color attachment
18045     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
18046                                          "Layout for color attachment is GENERAL but should be COLOR_ATTACHMENT_OPTIMAL.");
18047     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
18048     m_errorMonitor->VerifyFound();
18049     // error w/ non-color opt or GENERAL layout for color attachment
18050     attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
18051     m_errorMonitor->SetDesiredFailureMsg(
18052         VK_DEBUG_REPORT_ERROR_BIT_EXT,
18053         "Layout for color attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be COLOR_ATTACHMENT_OPTIMAL or GENERAL.");
18054     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
18055     m_errorMonitor->VerifyFound();
18056     subpass.colorAttachmentCount = 0;
18057     subpass.pDepthStencilAttachment = &attach;
18058     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
18059     // perf warning for GENERAL layout on DS attachment
18060     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
18061                                          "GENERAL layout for depth attachment may not give optimal performance.");
18062     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
18063     m_errorMonitor->VerifyFound();
18064     // error w/ non-ds opt or GENERAL layout for color attachment
18065     attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
18066     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
18067                                          "Layout for depth attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be "
18068                                          "DEPTH_STENCIL_ATTACHMENT_OPTIMAL, DEPTH_STENCIL_READ_ONLY_OPTIMAL or GENERAL.");
18069     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
18070     m_errorMonitor->VerifyFound();
18071     // For this error we need a valid renderpass so create default one
18072     attach.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
18073     attach.attachment = 0;
18074     attach_desc.format = depth_format;
18075     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
18076     attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
18077     attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
18078     attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
18079     // Can't do a CLEAR load on READ_ONLY initialLayout
18080     attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
18081     attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
18082     attach_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
18083     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
18084                                          "with invalid first layout VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL");
18085     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
18086     m_errorMonitor->VerifyFound();
18087 
18088     vkFreeMemory(m_device->device(), src_image_mem, NULL);
18089     vkFreeMemory(m_device->device(), dst_image_mem, NULL);
18090     vkFreeMemory(m_device->device(), depth_image_mem, NULL);
18091     vkDestroyImage(m_device->device(), src_image, NULL);
18092     vkDestroyImage(m_device->device(), dst_image, NULL);
18093     vkDestroyImage(m_device->device(), depth_image, NULL);
18094 }
18095 
TEST_F(VkLayerTest,InvalidStorageImageLayout)18096 TEST_F(VkLayerTest, InvalidStorageImageLayout) {
18097     TEST_DESCRIPTION("Attempt to update a STORAGE_IMAGE descriptor w/o GENERAL layout.");
18098 
18099     ASSERT_NO_FATAL_FAILURE(Init());
18100 
18101     const VkFormat tex_format = VK_FORMAT_R8G8B8A8_UNORM;
18102     VkImageTiling tiling;
18103     VkFormatProperties format_properties;
18104     vkGetPhysicalDeviceFormatProperties(gpu(), tex_format, &format_properties);
18105     if (format_properties.linearTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) {
18106         tiling = VK_IMAGE_TILING_LINEAR;
18107     } else if (format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) {
18108         tiling = VK_IMAGE_TILING_OPTIMAL;
18109     } else {
18110         printf("%s Device does not support VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; skipped.\n", kSkipPrefix);
18111         return;
18112     }
18113 
18114     OneOffDescriptorSet ds(m_device, {
18115                                          {0, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
18116                                      });
18117 
18118     VkImageObj image(m_device);
18119     image.Init(32, 32, 1, tex_format, VK_IMAGE_USAGE_STORAGE_BIT, tiling, 0);
18120     ASSERT_TRUE(image.initialized());
18121     VkImageView view = image.targetView(tex_format);
18122 
18123     VkDescriptorImageInfo image_info = {};
18124     image_info.imageView = view;
18125     image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
18126 
18127     VkWriteDescriptorSet descriptor_write = {};
18128     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
18129     descriptor_write.dstSet = ds.set_;
18130     descriptor_write.dstBinding = 0;
18131     descriptor_write.descriptorCount = 1;
18132     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
18133     descriptor_write.pImageInfo = &image_info;
18134 
18135     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
18136                                          " of VK_DESCRIPTOR_TYPE_STORAGE_IMAGE type is being updated with layout "
18137                                          "VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL but according to spec ");
18138     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
18139     m_errorMonitor->VerifyFound();
18140 }
18141 
TEST_F(VkLayerTest,NonSimultaneousSecondaryMarksPrimary)18142 TEST_F(VkLayerTest, NonSimultaneousSecondaryMarksPrimary) {
18143     ASSERT_NO_FATAL_FAILURE(Init());
18144     const char *simultaneous_use_message =
18145         "does not have VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set and will cause primary command buffer";
18146 
18147     VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
18148 
18149     secondary.begin();
18150     secondary.end();
18151 
18152     VkCommandBufferBeginInfo cbbi = {
18153         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
18154         nullptr,
18155         VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
18156         nullptr,
18157     };
18158 
18159     m_commandBuffer->begin(&cbbi);
18160     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, simultaneous_use_message);
18161     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
18162     m_errorMonitor->VerifyFound();
18163     m_commandBuffer->end();
18164 }
18165 
TEST_F(VkLayerTest,SimultaneousUseSecondaryTwoExecutes)18166 TEST_F(VkLayerTest, SimultaneousUseSecondaryTwoExecutes) {
18167     ASSERT_NO_FATAL_FAILURE(Init());
18168 
18169     const char *simultaneous_use_message = "without VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set!";
18170 
18171     VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
18172 
18173     VkCommandBufferInheritanceInfo inh = {
18174         VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
18175         nullptr,
18176     };
18177     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, &inh};
18178 
18179     secondary.begin(&cbbi);
18180     secondary.end();
18181 
18182     m_commandBuffer->begin();
18183     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
18184     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, simultaneous_use_message);
18185     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
18186     m_errorMonitor->VerifyFound();
18187     m_commandBuffer->end();
18188 }
18189 
TEST_F(VkLayerTest,SimultaneousUseSecondarySingleExecute)18190 TEST_F(VkLayerTest, SimultaneousUseSecondarySingleExecute) {
18191     ASSERT_NO_FATAL_FAILURE(Init());
18192 
18193     // variation on previous test executing the same CB twice in the same
18194     // CmdExecuteCommands call
18195 
18196     const char *simultaneous_use_message = "without VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set!";
18197 
18198     VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
18199 
18200     VkCommandBufferInheritanceInfo inh = {
18201         VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
18202         nullptr,
18203     };
18204     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, &inh};
18205 
18206     secondary.begin(&cbbi);
18207     secondary.end();
18208 
18209     m_commandBuffer->begin();
18210     VkCommandBuffer cbs[] = {secondary.handle(), secondary.handle()};
18211     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, simultaneous_use_message);
18212     vkCmdExecuteCommands(m_commandBuffer->handle(), 2, cbs);
18213     m_errorMonitor->VerifyFound();
18214     m_commandBuffer->end();
18215 }
18216 
TEST_F(VkLayerTest,SimultaneousUseOneShot)18217 TEST_F(VkLayerTest, SimultaneousUseOneShot) {
18218     TEST_DESCRIPTION("Submit the same command buffer twice in one submit looking for simultaneous use and one time submit errors");
18219     const char *simultaneous_use_message = "is already in use and is not marked for simultaneous use";
18220     const char *one_shot_message = "VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has been submitted";
18221     ASSERT_NO_FATAL_FAILURE(Init());
18222 
18223     VkCommandBuffer cmd_bufs[2];
18224     VkCommandBufferAllocateInfo alloc_info;
18225     alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
18226     alloc_info.pNext = NULL;
18227     alloc_info.commandBufferCount = 2;
18228     alloc_info.commandPool = m_commandPool->handle();
18229     alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
18230     vkAllocateCommandBuffers(m_device->device(), &alloc_info, cmd_bufs);
18231 
18232     VkCommandBufferBeginInfo cb_binfo;
18233     cb_binfo.pNext = NULL;
18234     cb_binfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
18235     cb_binfo.pInheritanceInfo = VK_NULL_HANDLE;
18236     cb_binfo.flags = 0;
18237     vkBeginCommandBuffer(cmd_bufs[0], &cb_binfo);
18238     VkViewport viewport = {0, 0, 16, 16, 0, 1};
18239     vkCmdSetViewport(cmd_bufs[0], 0, 1, &viewport);
18240     vkEndCommandBuffer(cmd_bufs[0]);
18241     VkCommandBuffer duplicates[2] = {cmd_bufs[0], cmd_bufs[0]};
18242 
18243     VkSubmitInfo submit_info = {};
18244     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
18245     submit_info.commandBufferCount = 2;
18246     submit_info.pCommandBuffers = duplicates;
18247     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, simultaneous_use_message);
18248     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
18249     m_errorMonitor->VerifyFound();
18250     vkQueueWaitIdle(m_device->m_queue);
18251 
18252     // Set one time use and now look for one time submit
18253     duplicates[0] = duplicates[1] = cmd_bufs[1];
18254     cb_binfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT | VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
18255     vkBeginCommandBuffer(cmd_bufs[1], &cb_binfo);
18256     vkCmdSetViewport(cmd_bufs[1], 0, 1, &viewport);
18257     vkEndCommandBuffer(cmd_bufs[1]);
18258     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, one_shot_message);
18259     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
18260     m_errorMonitor->VerifyFound();
18261     vkQueueWaitIdle(m_device->m_queue);
18262 }
18263 
TEST_F(VkLayerTest,StageMaskGsTsEnabled)18264 TEST_F(VkLayerTest, StageMaskGsTsEnabled) {
18265     TEST_DESCRIPTION(
18266         "Attempt to use a stageMask w/ geometry shader and tesselation shader bits enabled when those features are disabled on the "
18267         "device.");
18268 
18269     ASSERT_NO_FATAL_FAILURE(Init());
18270     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
18271 
18272     std::vector<const char *> device_extension_names;
18273     auto features = m_device->phy().features();
18274     // Make sure gs & ts are disabled
18275     features.geometryShader = false;
18276     features.tessellationShader = false;
18277     // The sacrificial device object
18278     VkDeviceObj test_device(0, gpu(), device_extension_names, &features);
18279 
18280     VkCommandPoolCreateInfo pool_create_info{};
18281     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
18282     pool_create_info.queueFamilyIndex = test_device.graphics_queue_node_index_;
18283 
18284     VkCommandPool command_pool;
18285     vkCreateCommandPool(test_device.handle(), &pool_create_info, nullptr, &command_pool);
18286 
18287     VkCommandBufferAllocateInfo cmd = {};
18288     cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
18289     cmd.pNext = NULL;
18290     cmd.commandPool = command_pool;
18291     cmd.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
18292     cmd.commandBufferCount = 1;
18293 
18294     VkCommandBuffer cmd_buffer;
18295     VkResult err = vkAllocateCommandBuffers(test_device.handle(), &cmd, &cmd_buffer);
18296     ASSERT_VK_SUCCESS(err);
18297 
18298     VkEvent event;
18299     VkEventCreateInfo evci = {};
18300     evci.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
18301     VkResult result = vkCreateEvent(test_device.handle(), &evci, NULL, &event);
18302     ASSERT_VK_SUCCESS(result);
18303 
18304     VkCommandBufferBeginInfo cbbi = {};
18305     cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
18306     vkBeginCommandBuffer(cmd_buffer, &cbbi);
18307     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetEvent-stageMask-01150");
18308     vkCmdSetEvent(cmd_buffer, event, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT);
18309     m_errorMonitor->VerifyFound();
18310 
18311     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetEvent-stageMask-01151");
18312     vkCmdSetEvent(cmd_buffer, event, VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT);
18313     m_errorMonitor->VerifyFound();
18314 
18315     vkDestroyEvent(test_device.handle(), event, NULL);
18316     vkDestroyCommandPool(test_device.handle(), command_pool, NULL);
18317 }
18318 
TEST_F(VkLayerTest,EventInUseDestroyedSignaled)18319 TEST_F(VkLayerTest, EventInUseDestroyedSignaled) {
18320     ASSERT_NO_FATAL_FAILURE(Init());
18321     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
18322 
18323     m_commandBuffer->begin();
18324 
18325     VkEvent event;
18326     VkEventCreateInfo event_create_info = {};
18327     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
18328     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
18329     vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
18330 
18331     m_commandBuffer->end();
18332     vkDestroyEvent(m_device->device(), event, nullptr);
18333 
18334     VkSubmitInfo submit_info = {};
18335     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
18336     submit_info.commandBufferCount = 1;
18337     submit_info.pCommandBuffers = &m_commandBuffer->handle();
18338     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is invalid because bound");
18339     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
18340     m_errorMonitor->VerifyFound();
18341 }
18342 
TEST_F(VkLayerTest,InUseDestroyedSignaled)18343 TEST_F(VkLayerTest, InUseDestroyedSignaled) {
18344     TEST_DESCRIPTION(
18345         "Use vkCmdExecuteCommands with invalid state in primary and secondary command buffers. Delete objects that are in use. "
18346         "Call VkQueueSubmit with an event that has been deleted.");
18347 
18348     ASSERT_NO_FATAL_FAILURE(Init());
18349     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
18350 
18351     m_errorMonitor->ExpectSuccess();
18352 
18353     VkSemaphoreCreateInfo semaphore_create_info = {};
18354     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
18355     VkSemaphore semaphore;
18356     ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
18357     VkFenceCreateInfo fence_create_info = {};
18358     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
18359     VkFence fence;
18360     ASSERT_VK_SUCCESS(vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence));
18361 
18362     OneOffDescriptorSet ds(m_device, {
18363                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
18364                                      });
18365 
18366     VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
18367 
18368     VkDescriptorBufferInfo buffer_info = {};
18369     buffer_info.buffer = buffer_test.GetBuffer();
18370     buffer_info.offset = 0;
18371     buffer_info.range = 1024;
18372 
18373     VkWriteDescriptorSet write_descriptor_set = {};
18374     write_descriptor_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
18375     write_descriptor_set.dstSet = ds.set_;
18376     write_descriptor_set.descriptorCount = 1;
18377     write_descriptor_set.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
18378     write_descriptor_set.pBufferInfo = &buffer_info;
18379 
18380     vkUpdateDescriptorSets(m_device->device(), 1, &write_descriptor_set, 0, nullptr);
18381 
18382     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
18383     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
18384 
18385     VkPipelineObj pipe(m_device);
18386     pipe.AddDefaultColorAttachment();
18387     pipe.AddShader(&vs);
18388     pipe.AddShader(&fs);
18389 
18390     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
18391 
18392     pipe.CreateVKPipeline(pipeline_layout.handle(), m_renderPass);
18393 
18394     VkEvent event;
18395     VkEventCreateInfo event_create_info = {};
18396     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
18397     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
18398 
18399     m_commandBuffer->begin();
18400 
18401     vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
18402 
18403     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
18404     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &ds.set_, 0,
18405                             NULL);
18406 
18407     m_commandBuffer->end();
18408 
18409     VkSubmitInfo submit_info = {};
18410     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
18411     submit_info.commandBufferCount = 1;
18412     submit_info.pCommandBuffers = &m_commandBuffer->handle();
18413     submit_info.signalSemaphoreCount = 1;
18414     submit_info.pSignalSemaphores = &semaphore;
18415     vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
18416     m_errorMonitor->Reset();  // resume logmsg processing
18417 
18418     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyEvent-event-01145");
18419     vkDestroyEvent(m_device->device(), event, nullptr);
18420     m_errorMonitor->VerifyFound();
18421 
18422     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroySemaphore-semaphore-01137");
18423     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
18424     m_errorMonitor->VerifyFound();
18425 
18426     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Fence 0x");
18427     vkDestroyFence(m_device->device(), fence, nullptr);
18428     m_errorMonitor->VerifyFound();
18429 
18430     vkQueueWaitIdle(m_device->m_queue);
18431     m_errorMonitor->SetUnexpectedError("If semaphore is not VK_NULL_HANDLE, semaphore must be a valid VkSemaphore handle");
18432     m_errorMonitor->SetUnexpectedError("Unable to remove Semaphore obj");
18433     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
18434     m_errorMonitor->SetUnexpectedError("If fence is not VK_NULL_HANDLE, fence must be a valid VkFence handle");
18435     m_errorMonitor->SetUnexpectedError("Unable to remove Fence obj");
18436     vkDestroyFence(m_device->device(), fence, nullptr);
18437     m_errorMonitor->SetUnexpectedError("If event is not VK_NULL_HANDLE, event must be a valid VkEvent handle");
18438     m_errorMonitor->SetUnexpectedError("Unable to remove Event obj");
18439     vkDestroyEvent(m_device->device(), event, nullptr);
18440 }
18441 
TEST_F(VkLayerTest,QueryPoolInUseDestroyedSignaled)18442 TEST_F(VkLayerTest, QueryPoolInUseDestroyedSignaled) {
18443     TEST_DESCRIPTION("Delete in-use query pool.");
18444 
18445     ASSERT_NO_FATAL_FAILURE(Init());
18446     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
18447 
18448     VkQueryPool query_pool;
18449     VkQueryPoolCreateInfo query_pool_ci{};
18450     query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
18451     query_pool_ci.queryType = VK_QUERY_TYPE_TIMESTAMP;
18452     query_pool_ci.queryCount = 1;
18453     vkCreateQueryPool(m_device->device(), &query_pool_ci, nullptr, &query_pool);
18454     m_commandBuffer->begin();
18455     // Reset query pool to create binding with cmd buffer
18456     vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
18457 
18458     m_commandBuffer->end();
18459 
18460     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkGetQueryPoolResults-queryType-00818");
18461     uint32_t data_space[16];
18462     m_errorMonitor->SetUnexpectedError("Cannot get query results on queryPool");
18463     vkGetQueryPoolResults(m_device->handle(), query_pool, 0, 1, sizeof(data_space), &data_space, sizeof(uint32_t),
18464                           VK_QUERY_RESULT_PARTIAL_BIT);
18465     m_errorMonitor->VerifyFound();
18466 
18467     VkSubmitInfo submit_info = {};
18468     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
18469     submit_info.commandBufferCount = 1;
18470     submit_info.pCommandBuffers = &m_commandBuffer->handle();
18471     // Submit cmd buffer and then destroy query pool while in-flight
18472     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
18473 
18474     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyQueryPool-queryPool-00793");
18475     vkDestroyQueryPool(m_device->handle(), query_pool, NULL);
18476     m_errorMonitor->VerifyFound();
18477 
18478     vkQueueWaitIdle(m_device->m_queue);
18479     // Now that cmd buffer done we can safely destroy query_pool
18480     m_errorMonitor->SetUnexpectedError("If queryPool is not VK_NULL_HANDLE, queryPool must be a valid VkQueryPool handle");
18481     m_errorMonitor->SetUnexpectedError("Unable to remove QueryPool obj");
18482     vkDestroyQueryPool(m_device->handle(), query_pool, NULL);
18483 }
18484 
TEST_F(VkLayerTest,PipelineInUseDestroyedSignaled)18485 TEST_F(VkLayerTest, PipelineInUseDestroyedSignaled) {
18486     TEST_DESCRIPTION("Delete in-use pipeline.");
18487 
18488     ASSERT_NO_FATAL_FAILURE(Init());
18489     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
18490 
18491     const VkPipelineLayoutObj pipeline_layout(m_device);
18492 
18493     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyPipeline-pipeline-00765");
18494     // Create PSO to be used for draw-time errors below
18495     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
18496     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
18497     // Store pipeline handle so we can actually delete it before test finishes
18498     VkPipeline delete_this_pipeline;
18499     {  // Scope pipeline so it will be auto-deleted
18500         VkPipelineObj pipe(m_device);
18501         pipe.AddShader(&vs);
18502         pipe.AddShader(&fs);
18503         pipe.AddDefaultColorAttachment();
18504         pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
18505         delete_this_pipeline = pipe.handle();
18506 
18507         m_commandBuffer->begin();
18508         // Bind pipeline to cmd buffer
18509         vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
18510 
18511         m_commandBuffer->end();
18512 
18513         VkSubmitInfo submit_info = {};
18514         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
18515         submit_info.commandBufferCount = 1;
18516         submit_info.pCommandBuffers = &m_commandBuffer->handle();
18517         // Submit cmd buffer and then pipeline destroyed while in-flight
18518         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
18519     }  // Pipeline deletion triggered here
18520     m_errorMonitor->VerifyFound();
18521     // Make sure queue finished and then actually delete pipeline
18522     vkQueueWaitIdle(m_device->m_queue);
18523     m_errorMonitor->SetUnexpectedError("If pipeline is not VK_NULL_HANDLE, pipeline must be a valid VkPipeline handle");
18524     m_errorMonitor->SetUnexpectedError("Unable to remove Pipeline obj");
18525     vkDestroyPipeline(m_device->handle(), delete_this_pipeline, nullptr);
18526 }
18527 
TEST_F(VkLayerTest,CreateImageViewBreaksParameterCompatibilityRequirements)18528 TEST_F(VkLayerTest, CreateImageViewBreaksParameterCompatibilityRequirements) {
18529     TEST_DESCRIPTION(
18530         "Attempts to create an Image View with a view type that does not match the image type it is being created from.");
18531 
18532     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
18533     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
18534         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
18535     }
18536     ASSERT_NO_FATAL_FAILURE(InitState());
18537 
18538     VkPhysicalDeviceMemoryProperties memProps;
18539     vkGetPhysicalDeviceMemoryProperties(m_device->phy().handle(), &memProps);
18540 
18541     // Test mismatch detection for image of type VK_IMAGE_TYPE_1D
18542     VkImageCreateInfo imgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
18543                                  nullptr,
18544                                  VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
18545                                  VK_IMAGE_TYPE_1D,
18546                                  VK_FORMAT_R8G8B8A8_UNORM,
18547                                  {1, 1, 1},
18548                                  1,
18549                                  1,
18550                                  VK_SAMPLE_COUNT_1_BIT,
18551                                  VK_IMAGE_TILING_OPTIMAL,
18552                                  VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
18553                                  VK_SHARING_MODE_EXCLUSIVE,
18554                                  0,
18555                                  nullptr,
18556                                  VK_IMAGE_LAYOUT_UNDEFINED};
18557     VkImageObj image1D(m_device);
18558     image1D.init(&imgInfo);
18559     ASSERT_TRUE(image1D.initialized());
18560 
18561     // Initialize VkImageViewCreateInfo with mismatched viewType
18562     VkImageView imageView;
18563     VkImageViewCreateInfo ivci = {};
18564     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
18565     ivci.image = image1D.handle();
18566     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
18567     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
18568     ivci.subresourceRange.layerCount = 1;
18569     ivci.subresourceRange.baseMipLevel = 0;
18570     ivci.subresourceRange.levelCount = 1;
18571     ivci.subresourceRange.baseArrayLayer = 0;
18572     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
18573 
18574     // Test for error message
18575     m_errorMonitor->SetDesiredFailureMsg(
18576         VK_DEBUG_REPORT_ERROR_BIT_EXT,
18577         "vkCreateImageView(): pCreateInfo->viewType VK_IMAGE_VIEW_TYPE_2D is not compatible with image");
18578     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
18579     m_errorMonitor->VerifyFound();
18580 
18581     // Test mismatch detection for image of type VK_IMAGE_TYPE_2D
18582     imgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
18583                nullptr,
18584                VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
18585                VK_IMAGE_TYPE_2D,
18586                VK_FORMAT_R8G8B8A8_UNORM,
18587                {1, 1, 1},
18588                1,
18589                6,
18590                VK_SAMPLE_COUNT_1_BIT,
18591                VK_IMAGE_TILING_OPTIMAL,
18592                VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
18593                VK_SHARING_MODE_EXCLUSIVE,
18594                0,
18595                nullptr,
18596                VK_IMAGE_LAYOUT_UNDEFINED};
18597     VkImageObj image2D(m_device);
18598     image2D.init(&imgInfo);
18599     ASSERT_TRUE(image2D.initialized());
18600 
18601     // Initialize VkImageViewCreateInfo with mismatched viewType
18602     ivci = {};
18603     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
18604     ivci.image = image2D.handle();
18605     ivci.viewType = VK_IMAGE_VIEW_TYPE_3D;
18606     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
18607     ivci.subresourceRange.layerCount = 1;
18608     ivci.subresourceRange.baseMipLevel = 0;
18609     ivci.subresourceRange.levelCount = 1;
18610     ivci.subresourceRange.baseArrayLayer = 0;
18611     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
18612 
18613     // Test for error message
18614     m_errorMonitor->SetDesiredFailureMsg(
18615         VK_DEBUG_REPORT_ERROR_BIT_EXT,
18616         "vkCreateImageView(): pCreateInfo->viewType VK_IMAGE_VIEW_TYPE_3D is not compatible with image");
18617     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
18618     m_errorMonitor->VerifyFound();
18619 
18620     // Change VkImageViewCreateInfo to different mismatched viewType
18621     ivci.viewType = VK_IMAGE_VIEW_TYPE_CUBE;
18622     ivci.subresourceRange.layerCount = 6;
18623 
18624     // Test for error message
18625     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-image-01003");
18626     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
18627     m_errorMonitor->VerifyFound();
18628 
18629     // Test mismatch detection for image of type VK_IMAGE_TYPE_3D
18630     imgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
18631                nullptr,
18632                VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
18633                VK_IMAGE_TYPE_3D,
18634                VK_FORMAT_R8G8B8A8_UNORM,
18635                {1, 1, 1},
18636                1,
18637                1,
18638                VK_SAMPLE_COUNT_1_BIT,
18639                VK_IMAGE_TILING_OPTIMAL,
18640                VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
18641                VK_SHARING_MODE_EXCLUSIVE,
18642                0,
18643                nullptr,
18644                VK_IMAGE_LAYOUT_UNDEFINED};
18645     VkImageObj image3D(m_device);
18646     image3D.init(&imgInfo);
18647     ASSERT_TRUE(image3D.initialized());
18648 
18649     // Initialize VkImageViewCreateInfo with mismatched viewType
18650     ivci = {};
18651     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
18652     ivci.image = image3D.handle();
18653     ivci.viewType = VK_IMAGE_VIEW_TYPE_1D;
18654     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
18655     ivci.subresourceRange.layerCount = 1;
18656     ivci.subresourceRange.baseMipLevel = 0;
18657     ivci.subresourceRange.levelCount = 1;
18658     ivci.subresourceRange.baseArrayLayer = 0;
18659     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
18660 
18661     // Test for error message
18662     m_errorMonitor->SetDesiredFailureMsg(
18663         VK_DEBUG_REPORT_ERROR_BIT_EXT,
18664         "vkCreateImageView(): pCreateInfo->viewType VK_IMAGE_VIEW_TYPE_1D is not compatible with image");
18665     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
18666     m_errorMonitor->VerifyFound();
18667 
18668     // Change VkImageViewCreateInfo to different mismatched viewType
18669     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
18670 
18671     // Test for error message
18672     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
18673         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-image-01005");
18674     } else {
18675         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-subResourceRange-01021");
18676     }
18677 
18678     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
18679     m_errorMonitor->VerifyFound();
18680 
18681     // Check if the device can make the image required for this test case.
18682     VkImageFormatProperties formProps = {{0, 0, 0}, 0, 0, 0, 0};
18683     VkResult res = vkGetPhysicalDeviceImageFormatProperties(
18684         m_device->phy().handle(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_3D, VK_IMAGE_TILING_OPTIMAL,
18685         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
18686         VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR | VK_IMAGE_CREATE_SPARSE_BINDING_BIT,
18687         &formProps);
18688 
18689     // If not, skip this part of the test.
18690     if (res || !m_device->phy().features().sparseBinding ||
18691         !DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
18692         printf("%s %s is not supported.\n", kSkipPrefix, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
18693         return;
18694     }
18695 
18696     // Initialize VkImageCreateInfo with VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR and VK_IMAGE_CREATE_SPARSE_BINDING_BIT which
18697     // are incompatible create flags.
18698     imgInfo = {
18699         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
18700         nullptr,
18701         VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR | VK_IMAGE_CREATE_SPARSE_BINDING_BIT,
18702         VK_IMAGE_TYPE_3D,
18703         VK_FORMAT_R8G8B8A8_UNORM,
18704         {1, 1, 1},
18705         1,
18706         1,
18707         VK_SAMPLE_COUNT_1_BIT,
18708         VK_IMAGE_TILING_OPTIMAL,
18709         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
18710         VK_SHARING_MODE_EXCLUSIVE,
18711         0,
18712         nullptr,
18713         VK_IMAGE_LAYOUT_UNDEFINED};
18714     VkImage imageSparse;
18715 
18716     // Creating a sparse image means we should not bind memory to it.
18717     res = vkCreateImage(m_device->device(), &imgInfo, NULL, &imageSparse);
18718     ASSERT_FALSE(res);
18719 
18720     // Initialize VkImageViewCreateInfo to create a view that will attempt to utilize VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR.
18721     ivci = {};
18722     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
18723     ivci.image = imageSparse;
18724     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
18725     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
18726     ivci.subresourceRange.layerCount = 1;
18727     ivci.subresourceRange.baseMipLevel = 0;
18728     ivci.subresourceRange.levelCount = 1;
18729     ivci.subresourceRange.baseArrayLayer = 0;
18730     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
18731 
18732     // Test for error message
18733     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
18734                                          " when the VK_IMAGE_CREATE_SPARSE_BINDING_BIT, VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, or "
18735                                          "VK_IMAGE_CREATE_SPARSE_ALIASED_BIT flags are enabled.");
18736     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
18737     m_errorMonitor->VerifyFound();
18738 
18739     // Clean up
18740     vkDestroyImage(m_device->device(), imageSparse, nullptr);
18741 }
18742 
TEST_F(VkLayerTest,CreateImageViewFormatFeatureMismatch)18743 TEST_F(VkLayerTest, CreateImageViewFormatFeatureMismatch) {
18744     TEST_DESCRIPTION("Create view with a format that does not have the same features as the image format.");
18745 
18746     if (!EnableDeviceProfileLayer()) {
18747         printf("%s Failed to enable device profile layer.\n", kSkipPrefix);
18748         return;
18749     }
18750 
18751     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
18752     ASSERT_NO_FATAL_FAILURE(InitState());
18753 
18754     PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr;
18755     PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr;
18756 
18757     // Load required functions
18758     if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) {
18759         printf("%s Failed to device profile layer.\n", kSkipPrefix);
18760         return;
18761     }
18762 
18763     // List of features to be tested
18764     VkFormatFeatureFlagBits features[] = {VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT,
18765                                           VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT};
18766     uint32_t feature_count = 4;
18767     // List of usage cases for each feature test
18768     VkImageUsageFlags usages[] = {VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
18769                                   VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT};
18770     // List of errors that will be thrown in order of tests run
18771     std::string optimal_error_codes[] = {
18772         "VUID-VkImageViewCreateInfo-usage-02274",
18773         "VUID-VkImageViewCreateInfo-usage-02275",
18774         "VUID-VkImageViewCreateInfo-usage-02276",
18775         "VUID-VkImageViewCreateInfo-usage-02277",
18776     };
18777 
18778     VkFormatProperties formatProps;
18779 
18780     // First three tests
18781     uint32_t i = 0;
18782     for (i = 0; i < (feature_count - 1); i++) {
18783         // Modify formats to have mismatched features
18784 
18785         // Format for image
18786         fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32G32B32A32_UINT, &formatProps);
18787         formatProps.optimalTilingFeatures |= features[i];
18788         fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32G32B32A32_UINT, formatProps);
18789 
18790         memset(&formatProps, 0, sizeof(formatProps));
18791 
18792         // Format for view
18793         fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32G32B32A32_SINT, &formatProps);
18794         formatProps.optimalTilingFeatures = features[(i + 1) % feature_count];
18795         fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32G32B32A32_SINT, formatProps);
18796 
18797         // Create image with modified format
18798         VkImageCreateInfo imgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
18799                                      nullptr,
18800                                      VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
18801                                      VK_IMAGE_TYPE_2D,
18802                                      VK_FORMAT_R32G32B32A32_UINT,
18803                                      {1, 1, 1},
18804                                      1,
18805                                      1,
18806                                      VK_SAMPLE_COUNT_1_BIT,
18807                                      VK_IMAGE_TILING_OPTIMAL,
18808                                      usages[i],
18809                                      VK_SHARING_MODE_EXCLUSIVE,
18810                                      0,
18811                                      nullptr,
18812                                      VK_IMAGE_LAYOUT_UNDEFINED};
18813         VkImageObj image(m_device);
18814         image.init(&imgInfo);
18815         ASSERT_TRUE(image.initialized());
18816 
18817         VkImageView imageView;
18818 
18819         // Initialize VkImageViewCreateInfo with modified format
18820         VkImageViewCreateInfo ivci = {};
18821         ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
18822         ivci.image = image.handle();
18823         ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
18824         ivci.format = VK_FORMAT_R32G32B32A32_SINT;
18825         ivci.subresourceRange.layerCount = 1;
18826         ivci.subresourceRange.baseMipLevel = 0;
18827         ivci.subresourceRange.levelCount = 1;
18828         ivci.subresourceRange.baseArrayLayer = 0;
18829         ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
18830 
18831         // Test for error message
18832         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, optimal_error_codes[i]);
18833         VkResult res = vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
18834         m_errorMonitor->VerifyFound();
18835 
18836         if (!res) {
18837             vkDestroyImageView(m_device->device(), imageView, nullptr);
18838         }
18839     }
18840 
18841     // Test for VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT.  Needs special formats
18842 
18843     // Only run this test if format supported
18844     if (!ImageFormatIsSupported(gpu(), VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_TILING_OPTIMAL)) {
18845         printf("%s VK_FORMAT_D24_UNORM_S8_UINT format not supported - skipped.\n", kSkipPrefix);
18846         return;
18847     }
18848     // Modify formats to have mismatched features
18849 
18850     // Format for image
18851     fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_D24_UNORM_S8_UINT, &formatProps);
18852     formatProps.optimalTilingFeatures |= features[i];
18853     fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_D24_UNORM_S8_UINT, formatProps);
18854 
18855     memset(&formatProps, 0, sizeof(formatProps));
18856 
18857     // Format for view
18858     fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_D32_SFLOAT_S8_UINT, &formatProps);
18859     formatProps.optimalTilingFeatures = features[(i + 1) % feature_count];
18860     fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_D32_SFLOAT_S8_UINT, formatProps);
18861 
18862     // Create image with modified format
18863     VkImageCreateInfo imgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
18864                                  nullptr,
18865                                  VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
18866                                  VK_IMAGE_TYPE_2D,
18867                                  VK_FORMAT_D24_UNORM_S8_UINT,
18868                                  {1, 1, 1},
18869                                  1,
18870                                  1,
18871                                  VK_SAMPLE_COUNT_1_BIT,
18872                                  VK_IMAGE_TILING_OPTIMAL,
18873                                  usages[i],
18874                                  VK_SHARING_MODE_EXCLUSIVE,
18875                                  0,
18876                                  nullptr,
18877                                  VK_IMAGE_LAYOUT_UNDEFINED};
18878     VkImageObj image(m_device);
18879     image.init(&imgInfo);
18880     ASSERT_TRUE(image.initialized());
18881 
18882     VkImageView imageView;
18883 
18884     // Initialize VkImageViewCreateInfo with modified format
18885     VkImageViewCreateInfo ivci = {};
18886     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
18887     ivci.image = image.handle();
18888     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
18889     ivci.format = VK_FORMAT_D32_SFLOAT_S8_UINT;
18890     ivci.subresourceRange.layerCount = 1;
18891     ivci.subresourceRange.baseMipLevel = 0;
18892     ivci.subresourceRange.levelCount = 1;
18893     ivci.subresourceRange.baseArrayLayer = 0;
18894     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
18895 
18896     // Test for error message
18897     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, optimal_error_codes[i]);
18898     VkResult res = vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
18899     m_errorMonitor->VerifyFound();
18900 
18901     if (!res) {
18902         vkDestroyImageView(m_device->device(), imageView, nullptr);
18903     }
18904 }
18905 
TEST_F(VkLayerTest,InvalidImageViewUsageCreateInfo)18906 TEST_F(VkLayerTest, InvalidImageViewUsageCreateInfo) {
18907     TEST_DESCRIPTION("Usage modification via a chained VkImageViewUsageCreateInfo struct");
18908 
18909     if (!EnableDeviceProfileLayer()) {
18910         printf("%s Test requires DeviceProfileLayer, unavailable - skipped.\n", kSkipPrefix);
18911         return;
18912     }
18913 
18914     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
18915     if (!DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE2_EXTENSION_NAME)) {
18916         printf("%s Test requires API >= 1.1 or KHR_MAINTENANCE2 extension, unavailable - skipped.\n", kSkipPrefix);
18917         return;
18918     }
18919     m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME);
18920     ASSERT_NO_FATAL_FAILURE(InitState());
18921 
18922     PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr;
18923     PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr;
18924 
18925     // Load required functions
18926     if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) {
18927         printf("%s Required extensions are not avaiable.\n", kSkipPrefix);
18928         return;
18929     }
18930 
18931     VkFormatProperties formatProps;
18932 
18933     // Ensure image format claims support for sampled and storage, excludes color attachment
18934     memset(&formatProps, 0, sizeof(formatProps));
18935     fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32G32B32A32_UINT, &formatProps);
18936     formatProps.optimalTilingFeatures |= (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT);
18937     formatProps.optimalTilingFeatures = formatProps.optimalTilingFeatures & ~VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
18938     fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32G32B32A32_UINT, formatProps);
18939 
18940     // Create image with sampled and storage usages
18941     VkImageCreateInfo imgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
18942                                  nullptr,
18943                                  VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
18944                                  VK_IMAGE_TYPE_2D,
18945                                  VK_FORMAT_R32G32B32A32_UINT,
18946                                  {1, 1, 1},
18947                                  1,
18948                                  1,
18949                                  VK_SAMPLE_COUNT_1_BIT,
18950                                  VK_IMAGE_TILING_OPTIMAL,
18951                                  VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
18952                                  VK_SHARING_MODE_EXCLUSIVE,
18953                                  0,
18954                                  nullptr,
18955                                  VK_IMAGE_LAYOUT_UNDEFINED};
18956     VkImageObj image(m_device);
18957     image.init(&imgInfo);
18958     ASSERT_TRUE(image.initialized());
18959 
18960     // Force the imageview format to exclude storage feature, include color attachment
18961     memset(&formatProps, 0, sizeof(formatProps));
18962     fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32G32B32A32_SINT, &formatProps);
18963     formatProps.optimalTilingFeatures |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
18964     formatProps.optimalTilingFeatures = (formatProps.optimalTilingFeatures & ~VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT);
18965     fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32G32B32A32_SINT, formatProps);
18966 
18967     VkImageViewCreateInfo ivci = {};
18968     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
18969     ivci.image = image.handle();
18970     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
18971     ivci.format = VK_FORMAT_R32G32B32A32_SINT;
18972     ivci.subresourceRange.layerCount = 1;
18973     ivci.subresourceRange.baseMipLevel = 0;
18974     ivci.subresourceRange.levelCount = 1;
18975     ivci.subresourceRange.baseArrayLayer = 0;
18976     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
18977 
18978     // ImageView creation should fail because view format doesn't support all the underlying image's usages
18979     VkImageView imageView;
18980     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-usage-02275");
18981     VkResult res = vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
18982     m_errorMonitor->VerifyFound();
18983 
18984     // Add a chained VkImageViewUsageCreateInfo to override original image usage bits, removing storage
18985     VkImageViewUsageCreateInfo usage_ci = {VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, nullptr, VK_IMAGE_USAGE_SAMPLED_BIT};
18986     // Link the VkImageViewUsageCreateInfo struct into the view's create info pNext chain
18987     ivci.pNext = &usage_ci;
18988 
18989     // ImageView should now succeed without error
18990     m_errorMonitor->ExpectSuccess();
18991     res = vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
18992     m_errorMonitor->VerifyNotFound();
18993     if (VK_SUCCESS == res) {
18994         vkDestroyImageView(m_device->device(), imageView, nullptr);
18995     }
18996 
18997     // Try a zero usage field
18998     usage_ci.usage = 0;
18999     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
19000                                          "vkCreateImageView: Chained VkImageViewUsageCreateInfo usage field must not be 0");
19001     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VkImageViewUsageCreateInfo: value of usage must not be 0");
19002     res = vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
19003     m_errorMonitor->VerifyFound();
19004     if (VK_SUCCESS == res) {
19005         vkDestroyImageView(m_device->device(), imageView, nullptr);
19006     }
19007 
19008     // Try a usage field with a bit not supported by underlying image
19009     usage_ci.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
19010     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewUsageCreateInfo-usage-01587");
19011     res = vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
19012     m_errorMonitor->VerifyFound();
19013     if (VK_SUCCESS == res) {
19014         vkDestroyImageView(m_device->device(), imageView, nullptr);
19015     }
19016 
19017     // Try an illegal bit in usage field
19018     usage_ci.usage = 0x10000000 | VK_IMAGE_USAGE_SAMPLED_BIT;
19019     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewUsageCreateInfo-usage-parameter");
19020     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "UNASSIGNED-GeneralParameterError-UnrecognizedValue");
19021     res = vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
19022     m_errorMonitor->VerifyFound();
19023     if (VK_SUCCESS == res) {
19024         vkDestroyImageView(m_device->device(), imageView, nullptr);
19025     }
19026 }
19027 
TEST_F(VkLayerTest,ImageViewInUseDestroyedSignaled)19028 TEST_F(VkLayerTest, ImageViewInUseDestroyedSignaled) {
19029     TEST_DESCRIPTION("Delete in-use imageView.");
19030 
19031     ASSERT_NO_FATAL_FAILURE(Init());
19032     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
19033 
19034     OneOffDescriptorSet ds(m_device, {
19035                                          {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
19036                                      });
19037 
19038     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
19039     VkSampler sampler;
19040 
19041     VkResult err;
19042     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
19043     ASSERT_VK_SUCCESS(err);
19044 
19045     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
19046 
19047     VkImageObj image(m_device);
19048     image.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
19049     ASSERT_TRUE(image.initialized());
19050 
19051     VkImageView view;
19052     VkImageViewCreateInfo ivci = {};
19053     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
19054     ivci.image = image.handle();
19055     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
19056     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
19057     ivci.subresourceRange.layerCount = 1;
19058     ivci.subresourceRange.baseMipLevel = 0;
19059     ivci.subresourceRange.levelCount = 1;
19060     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
19061 
19062     err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
19063     ASSERT_VK_SUCCESS(err);
19064 
19065     VkDescriptorImageInfo image_info{};
19066     image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
19067     image_info.imageView = view;
19068     image_info.sampler = sampler;
19069 
19070     VkWriteDescriptorSet descriptor_write = {};
19071     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
19072     descriptor_write.dstSet = ds.set_;
19073     descriptor_write.dstBinding = 0;
19074     descriptor_write.descriptorCount = 1;
19075     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
19076     descriptor_write.pImageInfo = &image_info;
19077 
19078     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
19079 
19080     // Create PSO to use the sampler
19081     char const *vsSource =
19082         "#version 450\n"
19083         "\n"
19084         "void main(){\n"
19085         "   gl_Position = vec4(1);\n"
19086         "}\n";
19087     char const *fsSource =
19088         "#version 450\n"
19089         "\n"
19090         "layout(set=0, binding=0) uniform sampler2D s;\n"
19091         "layout(location=0) out vec4 x;\n"
19092         "void main(){\n"
19093         "   x = texture(s, vec2(1));\n"
19094         "}\n";
19095     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
19096     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
19097     VkPipelineObj pipe(m_device);
19098     pipe.AddShader(&vs);
19099     pipe.AddShader(&fs);
19100     pipe.AddDefaultColorAttachment();
19101     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
19102 
19103     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyImageView-imageView-01026");
19104 
19105     m_commandBuffer->begin();
19106     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
19107     // Bind pipeline to cmd buffer
19108     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
19109     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &ds.set_, 0,
19110                             nullptr);
19111 
19112     VkViewport viewport = {0, 0, 16, 16, 0, 1};
19113     VkRect2D scissor = {{0, 0}, {16, 16}};
19114     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
19115     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
19116 
19117     m_commandBuffer->Draw(1, 0, 0, 0);
19118     m_commandBuffer->EndRenderPass();
19119     m_commandBuffer->end();
19120     // Submit cmd buffer then destroy sampler
19121     VkSubmitInfo submit_info = {};
19122     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
19123     submit_info.commandBufferCount = 1;
19124     submit_info.pCommandBuffers = &m_commandBuffer->handle();
19125     // Submit cmd buffer and then destroy imageView while in-flight
19126     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
19127 
19128     vkDestroyImageView(m_device->device(), view, nullptr);
19129     m_errorMonitor->VerifyFound();
19130     vkQueueWaitIdle(m_device->m_queue);
19131     // Now we can actually destroy imageView
19132     m_errorMonitor->SetUnexpectedError("If imageView is not VK_NULL_HANDLE, imageView must be a valid VkImageView handle");
19133     m_errorMonitor->SetUnexpectedError("Unable to remove ImageView obj");
19134     vkDestroyImageView(m_device->device(), view, NULL);
19135     vkDestroySampler(m_device->device(), sampler, nullptr);
19136 }
19137 
TEST_F(VkLayerTest,BufferViewInUseDestroyedSignaled)19138 TEST_F(VkLayerTest, BufferViewInUseDestroyedSignaled) {
19139     TEST_DESCRIPTION("Delete in-use bufferView.");
19140 
19141     ASSERT_NO_FATAL_FAILURE(Init());
19142     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
19143 
19144     OneOffDescriptorSet ds(m_device, {
19145                                          {0, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
19146                                      });
19147 
19148     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
19149 
19150     VkBuffer buffer;
19151     uint32_t queue_family_index = 0;
19152     VkBufferCreateInfo buffer_create_info = {};
19153     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
19154     buffer_create_info.size = 1024;
19155     buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
19156     buffer_create_info.queueFamilyIndexCount = 1;
19157     buffer_create_info.pQueueFamilyIndices = &queue_family_index;
19158 
19159     VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
19160     ASSERT_VK_SUCCESS(err);
19161 
19162     VkMemoryRequirements memory_reqs;
19163     VkDeviceMemory buffer_memory;
19164 
19165     VkMemoryAllocateInfo memory_info = {};
19166     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
19167     memory_info.allocationSize = 0;
19168     memory_info.memoryTypeIndex = 0;
19169 
19170     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
19171     memory_info.allocationSize = memory_reqs.size;
19172     bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
19173     ASSERT_TRUE(pass);
19174 
19175     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
19176     ASSERT_VK_SUCCESS(err);
19177     err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
19178     ASSERT_VK_SUCCESS(err);
19179 
19180     VkBufferView view;
19181     VkBufferViewCreateInfo bvci = {};
19182     bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
19183     bvci.buffer = buffer;
19184     bvci.format = VK_FORMAT_R32_SFLOAT;
19185     bvci.range = VK_WHOLE_SIZE;
19186 
19187     err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view);
19188     ASSERT_VK_SUCCESS(err);
19189 
19190     VkWriteDescriptorSet descriptor_write = {};
19191     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
19192     descriptor_write.dstSet = ds.set_;
19193     descriptor_write.dstBinding = 0;
19194     descriptor_write.descriptorCount = 1;
19195     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
19196     descriptor_write.pTexelBufferView = &view;
19197 
19198     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
19199 
19200     char const *vsSource =
19201         "#version 450\n"
19202         "\n"
19203         "void main(){\n"
19204         "   gl_Position = vec4(1);\n"
19205         "}\n";
19206     char const *fsSource =
19207         "#version 450\n"
19208         "\n"
19209         "layout(set=0, binding=0, r32f) uniform readonly imageBuffer s;\n"
19210         "layout(location=0) out vec4 x;\n"
19211         "void main(){\n"
19212         "   x = imageLoad(s, 0);\n"
19213         "}\n";
19214     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
19215     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
19216     VkPipelineObj pipe(m_device);
19217     pipe.AddShader(&vs);
19218     pipe.AddShader(&fs);
19219     pipe.AddDefaultColorAttachment();
19220     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
19221 
19222     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyBufferView-bufferView-00936");
19223 
19224     m_commandBuffer->begin();
19225     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
19226     VkViewport viewport = {0, 0, 16, 16, 0, 1};
19227     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
19228     VkRect2D scissor = {{0, 0}, {16, 16}};
19229     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
19230     // Bind pipeline to cmd buffer
19231     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
19232     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &ds.set_, 0,
19233                             nullptr);
19234     m_commandBuffer->Draw(1, 0, 0, 0);
19235     m_commandBuffer->EndRenderPass();
19236     m_commandBuffer->end();
19237 
19238     VkSubmitInfo submit_info = {};
19239     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
19240     submit_info.commandBufferCount = 1;
19241     submit_info.pCommandBuffers = &m_commandBuffer->handle();
19242     // Submit cmd buffer and then destroy bufferView while in-flight
19243     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
19244 
19245     vkDestroyBufferView(m_device->device(), view, nullptr);
19246     m_errorMonitor->VerifyFound();
19247     vkQueueWaitIdle(m_device->m_queue);
19248     // Now we can actually destroy bufferView
19249     m_errorMonitor->SetUnexpectedError("If bufferView is not VK_NULL_HANDLE, bufferView must be a valid VkBufferView handle");
19250     m_errorMonitor->SetUnexpectedError("Unable to remove BufferView obj");
19251     vkDestroyBufferView(m_device->device(), view, NULL);
19252     vkDestroyBuffer(m_device->device(), buffer, NULL);
19253     vkFreeMemory(m_device->device(), buffer_memory, NULL);
19254 }
19255 
TEST_F(VkLayerTest,SamplerInUseDestroyedSignaled)19256 TEST_F(VkLayerTest, SamplerInUseDestroyedSignaled) {
19257     TEST_DESCRIPTION("Delete in-use sampler.");
19258 
19259     ASSERT_NO_FATAL_FAILURE(Init());
19260     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
19261 
19262     OneOffDescriptorSet ds(m_device, {
19263                                          {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
19264                                      });
19265 
19266     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
19267     VkSampler sampler;
19268 
19269     VkResult err;
19270     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
19271     ASSERT_VK_SUCCESS(err);
19272 
19273     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
19274 
19275     VkImageObj image(m_device);
19276     image.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
19277     ASSERT_TRUE(image.initialized());
19278 
19279     VkImageView view;
19280     VkImageViewCreateInfo ivci = {};
19281     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
19282     ivci.image = image.handle();
19283     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
19284     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
19285     ivci.subresourceRange.layerCount = 1;
19286     ivci.subresourceRange.baseMipLevel = 0;
19287     ivci.subresourceRange.levelCount = 1;
19288     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
19289 
19290     err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
19291     ASSERT_VK_SUCCESS(err);
19292 
19293     VkDescriptorImageInfo image_info{};
19294     image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
19295     image_info.imageView = view;
19296     image_info.sampler = sampler;
19297 
19298     VkWriteDescriptorSet descriptor_write = {};
19299     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
19300     descriptor_write.dstSet = ds.set_;
19301     descriptor_write.dstBinding = 0;
19302     descriptor_write.descriptorCount = 1;
19303     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
19304     descriptor_write.pImageInfo = &image_info;
19305 
19306     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
19307 
19308     // Create PSO to use the sampler
19309     char const *vsSource =
19310         "#version 450\n"
19311         "\n"
19312         "void main(){\n"
19313         "   gl_Position = vec4(1);\n"
19314         "}\n";
19315     char const *fsSource =
19316         "#version 450\n"
19317         "\n"
19318         "layout(set=0, binding=0) uniform sampler2D s;\n"
19319         "layout(location=0) out vec4 x;\n"
19320         "void main(){\n"
19321         "   x = texture(s, vec2(1));\n"
19322         "}\n";
19323     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
19324     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
19325     VkPipelineObj pipe(m_device);
19326     pipe.AddShader(&vs);
19327     pipe.AddShader(&fs);
19328     pipe.AddDefaultColorAttachment();
19329     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
19330 
19331     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroySampler-sampler-01082");
19332 
19333     m_commandBuffer->begin();
19334     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
19335     // Bind pipeline to cmd buffer
19336     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
19337     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &ds.set_, 0,
19338                             nullptr);
19339 
19340     VkViewport viewport = {0, 0, 16, 16, 0, 1};
19341     VkRect2D scissor = {{0, 0}, {16, 16}};
19342     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
19343     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
19344 
19345     m_commandBuffer->Draw(1, 0, 0, 0);
19346     m_commandBuffer->EndRenderPass();
19347     m_commandBuffer->end();
19348     // Submit cmd buffer then destroy sampler
19349     VkSubmitInfo submit_info = {};
19350     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
19351     submit_info.commandBufferCount = 1;
19352     submit_info.pCommandBuffers = &m_commandBuffer->handle();
19353     // Submit cmd buffer and then destroy sampler while in-flight
19354     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
19355 
19356     vkDestroySampler(m_device->device(), sampler, nullptr);  // Destroyed too soon
19357     m_errorMonitor->VerifyFound();
19358     vkQueueWaitIdle(m_device->m_queue);
19359 
19360     // Now we can actually destroy sampler
19361     m_errorMonitor->SetUnexpectedError("If sampler is not VK_NULL_HANDLE, sampler must be a valid VkSampler handle");
19362     m_errorMonitor->SetUnexpectedError("Unable to remove Sampler obj");
19363     vkDestroySampler(m_device->device(), sampler, NULL);  // Destroyed for real
19364     vkDestroyImageView(m_device->device(), view, NULL);
19365 }
19366 
TEST_F(VkLayerTest,UpdateDestroyDescriptorSetLayout)19367 TEST_F(VkLayerTest, UpdateDestroyDescriptorSetLayout) {
19368     TEST_DESCRIPTION("Attempt updates to descriptor sets with destroyed descriptor set layouts");
19369     // TODO: Update to match the descriptor set layout specific VUIDs/VALIDATION_ERROR_* when present
19370     const auto kWriteDestroyedLayout = "VUID-VkWriteDescriptorSet-dstSet-00320";
19371     const auto kCopyDstDestroyedLayout = "VUID-VkCopyDescriptorSet-dstSet-parameter";
19372     const auto kCopySrcDestroyedLayout = "VUID-VkCopyDescriptorSet-srcSet-parameter";
19373 
19374     ASSERT_NO_FATAL_FAILURE(Init());
19375 
19376     // Set up the descriptor (resource) and write/copy operations to use.
19377     float data[16] = {};
19378     VkConstantBufferObj buffer(m_device, sizeof(data), data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
19379     ASSERT_TRUE(buffer.initialized());
19380 
19381     VkDescriptorBufferInfo info = {};
19382     info.buffer = buffer.handle();
19383     info.range = VK_WHOLE_SIZE;
19384 
19385     VkWriteDescriptorSet write_descriptor = {};
19386     write_descriptor.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
19387     write_descriptor.dstSet = VK_NULL_HANDLE;  // must update this
19388     write_descriptor.dstBinding = 0;
19389     write_descriptor.descriptorCount = 1;
19390     write_descriptor.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
19391     write_descriptor.pBufferInfo = &info;
19392 
19393     VkCopyDescriptorSet copy_descriptor = {};
19394     copy_descriptor.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
19395     copy_descriptor.srcSet = VK_NULL_HANDLE;  // must update
19396     copy_descriptor.srcBinding = 0;
19397     copy_descriptor.dstSet = VK_NULL_HANDLE;  // must update
19398     copy_descriptor.dstBinding = 0;
19399     copy_descriptor.descriptorCount = 1;
19400 
19401     // Create valid and invalid source and destination descriptor sets
19402     std::vector<VkDescriptorSetLayoutBinding> one_uniform_buffer = {
19403         {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
19404     };
19405     OneOffDescriptorSet good_dst(m_device, one_uniform_buffer);
19406     ASSERT_TRUE(good_dst.Initialized());
19407 
19408     OneOffDescriptorSet bad_dst(m_device, one_uniform_buffer);
19409     // Must assert before invalidating it below
19410     ASSERT_TRUE(bad_dst.Initialized());
19411     bad_dst.layout_ = VkDescriptorSetLayoutObj();
19412 
19413     OneOffDescriptorSet good_src(m_device, one_uniform_buffer);
19414     ASSERT_TRUE(good_src.Initialized());
19415 
19416     // Put valid data in the good and bad sources, simultaneously doing a positive test on write and copy operations
19417     m_errorMonitor->ExpectSuccess();
19418     write_descriptor.dstSet = good_src.set_;
19419     vkUpdateDescriptorSets(m_device->device(), 1, &write_descriptor, 0, NULL);
19420     m_errorMonitor->VerifyNotFound();
19421 
19422     OneOffDescriptorSet bad_src(m_device, one_uniform_buffer);
19423     ASSERT_TRUE(bad_src.Initialized());
19424 
19425     // to complete our positive testing use copy, where above we used write.
19426     copy_descriptor.srcSet = good_src.set_;
19427     copy_descriptor.dstSet = bad_src.set_;
19428     vkUpdateDescriptorSets(m_device->device(), 0, nullptr, 1, &copy_descriptor);
19429     bad_src.layout_ = VkDescriptorSetLayoutObj();
19430     m_errorMonitor->VerifyNotFound();
19431 
19432     // Trigger the three invalid use errors
19433     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, kWriteDestroyedLayout);
19434     write_descriptor.dstSet = bad_dst.set_;
19435     vkUpdateDescriptorSets(m_device->device(), 1, &write_descriptor, 0, NULL);
19436     m_errorMonitor->VerifyFound();
19437 
19438     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, kCopyDstDestroyedLayout);
19439     copy_descriptor.dstSet = bad_dst.set_;
19440     vkUpdateDescriptorSets(m_device->device(), 0, nullptr, 1, &copy_descriptor);
19441     m_errorMonitor->VerifyFound();
19442 
19443     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, kCopySrcDestroyedLayout);
19444     copy_descriptor.srcSet = bad_src.set_;
19445     copy_descriptor.dstSet = good_dst.set_;
19446     vkUpdateDescriptorSets(m_device->device(), 0, nullptr, 1, &copy_descriptor);
19447     m_errorMonitor->VerifyFound();
19448 }
19449 
TEST_F(VkLayerTest,QueueForwardProgressFenceWait)19450 TEST_F(VkLayerTest, QueueForwardProgressFenceWait) {
19451     TEST_DESCRIPTION(
19452         "Call VkQueueSubmit with a semaphore that is already signaled but not waited on by the queue. Wait on a fence that has not "
19453         "yet been submitted to a queue.");
19454 
19455     ASSERT_NO_FATAL_FAILURE(Init());
19456     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
19457 
19458     const char *queue_forward_progress_message = " that was previously signaled by queue 0x";
19459     const char *invalid_fence_wait_message = " which has not been submitted on a Queue or during acquire next image.";
19460 
19461     VkCommandBufferObj cb1(m_device, m_commandPool);
19462     cb1.begin();
19463     cb1.end();
19464 
19465     VkSemaphoreCreateInfo semaphore_create_info = {};
19466     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
19467     VkSemaphore semaphore;
19468     ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
19469     VkSubmitInfo submit_info = {};
19470     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
19471     submit_info.commandBufferCount = 1;
19472     submit_info.pCommandBuffers = &cb1.handle();
19473     submit_info.signalSemaphoreCount = 1;
19474     submit_info.pSignalSemaphores = &semaphore;
19475     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
19476 
19477     m_commandBuffer->begin();
19478     m_commandBuffer->end();
19479     submit_info.pCommandBuffers = &m_commandBuffer->handle();
19480     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, queue_forward_progress_message);
19481     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
19482     m_errorMonitor->VerifyFound();
19483 
19484     VkFenceCreateInfo fence_create_info = {};
19485     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
19486     VkFence fence;
19487     ASSERT_VK_SUCCESS(vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence));
19488 
19489     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, invalid_fence_wait_message);
19490     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
19491     m_errorMonitor->VerifyFound();
19492 
19493     vkDeviceWaitIdle(m_device->device());
19494     vkDestroyFence(m_device->device(), fence, nullptr);
19495     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
19496 }
19497 
TEST_F(VkLayerTest,FramebufferIncompatible)19498 TEST_F(VkLayerTest, FramebufferIncompatible) {
19499     TEST_DESCRIPTION(
19500         "Bind a secondary command buffer with a framebuffer that does not match the framebuffer for the active renderpass.");
19501     ASSERT_NO_FATAL_FAILURE(Init());
19502     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
19503 
19504     // A renderpass with one color attachment.
19505     VkAttachmentDescription attachment = {0,
19506                                           VK_FORMAT_B8G8R8A8_UNORM,
19507                                           VK_SAMPLE_COUNT_1_BIT,
19508                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
19509                                           VK_ATTACHMENT_STORE_OP_STORE,
19510                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
19511                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
19512                                           VK_IMAGE_LAYOUT_UNDEFINED,
19513                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
19514 
19515     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
19516 
19517     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
19518 
19519     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
19520 
19521     VkRenderPass rp;
19522     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
19523     ASSERT_VK_SUCCESS(err);
19524 
19525     // A compatible framebuffer.
19526     VkImageObj image(m_device);
19527     image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
19528     ASSERT_TRUE(image.initialized());
19529 
19530     VkImageViewCreateInfo ivci = {
19531         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
19532         nullptr,
19533         0,
19534         image.handle(),
19535         VK_IMAGE_VIEW_TYPE_2D,
19536         VK_FORMAT_B8G8R8A8_UNORM,
19537         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
19538          VK_COMPONENT_SWIZZLE_IDENTITY},
19539         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
19540     };
19541     VkImageView view;
19542     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
19543     ASSERT_VK_SUCCESS(err);
19544 
19545     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
19546     VkFramebuffer fb;
19547     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
19548     ASSERT_VK_SUCCESS(err);
19549 
19550     VkCommandBufferAllocateInfo cbai = {};
19551     cbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
19552     cbai.commandPool = m_commandPool->handle();
19553     cbai.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
19554     cbai.commandBufferCount = 1;
19555 
19556     VkCommandBuffer sec_cb;
19557     err = vkAllocateCommandBuffers(m_device->device(), &cbai, &sec_cb);
19558     ASSERT_VK_SUCCESS(err);
19559     VkCommandBufferBeginInfo cbbi = {};
19560     VkCommandBufferInheritanceInfo cbii = {};
19561     cbii.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
19562     cbii.renderPass = renderPass();
19563     cbii.framebuffer = fb;
19564     cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
19565     cbbi.pNext = NULL;
19566     cbbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
19567     cbbi.pInheritanceInfo = &cbii;
19568     vkBeginCommandBuffer(sec_cb, &cbbi);
19569     vkEndCommandBuffer(sec_cb);
19570 
19571     VkCommandBufferBeginInfo cbbi2 = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, nullptr};
19572     vkBeginCommandBuffer(m_commandBuffer->handle(), &cbbi2);
19573     vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
19574 
19575     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
19576                                          " that is not the same as the primary command buffer's current active framebuffer ");
19577     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &sec_cb);
19578     m_errorMonitor->VerifyFound();
19579     // Cleanup
19580 
19581     vkCmdEndRenderPass(m_commandBuffer->handle());
19582     vkEndCommandBuffer(m_commandBuffer->handle());
19583 
19584     vkDestroyImageView(m_device->device(), view, NULL);
19585     vkDestroyRenderPass(m_device->device(), rp, NULL);
19586     vkDestroyFramebuffer(m_device->device(), fb, NULL);
19587 }
19588 
TEST_F(VkLayerTest,RenderPassMissingAttachment)19589 TEST_F(VkLayerTest, RenderPassMissingAttachment) {
19590     TEST_DESCRIPTION("Begin render pass with missing framebuffer attachment");
19591     ASSERT_NO_FATAL_FAILURE(Init());
19592     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
19593 
19594     // Create a renderPass with a single color attachment
19595     VkAttachmentReference attach = {};
19596     attach.layout = VK_IMAGE_LAYOUT_GENERAL;
19597     VkSubpassDescription subpass = {};
19598     subpass.pColorAttachments = &attach;
19599     VkRenderPassCreateInfo rpci = {};
19600     rpci.subpassCount = 1;
19601     rpci.pSubpasses = &subpass;
19602     rpci.attachmentCount = 1;
19603     VkAttachmentDescription attach_desc = {};
19604     attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
19605     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
19606     attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
19607     rpci.pAttachments = &attach_desc;
19608     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
19609     VkRenderPass rp;
19610     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
19611     ASSERT_VK_SUCCESS(err);
19612 
19613     auto createView = lvl_init_struct<VkImageViewCreateInfo>();
19614     createView.image = m_renderTargets[0]->handle();
19615     createView.viewType = VK_IMAGE_VIEW_TYPE_2D;
19616     createView.format = VK_FORMAT_B8G8R8A8_UNORM;
19617     createView.components.r = VK_COMPONENT_SWIZZLE_R;
19618     createView.components.g = VK_COMPONENT_SWIZZLE_G;
19619     createView.components.b = VK_COMPONENT_SWIZZLE_B;
19620     createView.components.a = VK_COMPONENT_SWIZZLE_A;
19621     createView.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
19622     createView.flags = 0;
19623 
19624     VkImageView iv;
19625     vkCreateImageView(m_device->handle(), &createView, nullptr, &iv);
19626 
19627     auto fb_info = lvl_init_struct<VkFramebufferCreateInfo>();
19628     fb_info.renderPass = rp;
19629     fb_info.attachmentCount = 1;
19630     fb_info.pAttachments = &iv;
19631     fb_info.width = 100;
19632     fb_info.height = 100;
19633     fb_info.layers = 1;
19634 
19635     // Create the framebuffer then destory the view it uses.
19636     VkFramebuffer fb;
19637     err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
19638     vkDestroyImageView(device(), iv, NULL);
19639     ASSERT_VK_SUCCESS(err);
19640 
19641     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkRenderPassBeginInfo-framebuffer-parameter");
19642 
19643     auto rpbi = lvl_init_struct<VkRenderPassBeginInfo>();
19644     rpbi.renderPass = rp;
19645     rpbi.framebuffer = fb;
19646     rpbi.renderArea = {{0, 0}, {32, 32}};
19647 
19648     m_commandBuffer->begin();
19649     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
19650     // Don't call vkCmdEndRenderPass; as the begin has been "skipped" based on the error condition
19651     m_errorMonitor->VerifyFound();
19652     m_commandBuffer->end();
19653 
19654     vkDestroyFramebuffer(m_device->device(), fb, NULL);
19655     vkDestroyRenderPass(m_device->device(), rp, NULL);
19656 }
19657 
TEST_F(VkLayerTest,ColorBlendInvalidLogicOp)19658 TEST_F(VkLayerTest, ColorBlendInvalidLogicOp) {
19659     TEST_DESCRIPTION("Attempt to use invalid VkPipelineColorBlendStateCreateInfo::logicOp value.");
19660 
19661     ASSERT_NO_FATAL_FAILURE(Init());  // enables all supported features
19662     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
19663 
19664     if (!m_device->phy().features().logicOp) {
19665         printf("%s Device does not support logicOp feature; skipped.\n", kSkipPrefix);
19666         return;
19667     }
19668 
19669     const auto set_shading_enable = [](CreatePipelineHelper &helper) {
19670         helper.cb_ci_.logicOpEnable = VK_TRUE;
19671         helper.cb_ci_.logicOp = static_cast<VkLogicOp>(VK_LOGIC_OP_END_RANGE + 1);  // invalid logicOp to be tested
19672     };
19673     CreatePipelineHelper::OneshotTest(*this, set_shading_enable, VK_DEBUG_REPORT_ERROR_BIT_EXT,
19674                                       "VUID-VkPipelineColorBlendStateCreateInfo-logicOpEnable-00607");
19675 }
19676 
TEST_F(VkLayerTest,ColorBlendUnsupportedLogicOp)19677 TEST_F(VkLayerTest, ColorBlendUnsupportedLogicOp) {
19678     TEST_DESCRIPTION("Attempt enabling VkPipelineColorBlendStateCreateInfo::logicOpEnable when logicOp feature is disabled.");
19679 
19680     VkPhysicalDeviceFeatures features{};
19681     ASSERT_NO_FATAL_FAILURE(Init(&features));
19682     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
19683 
19684     const auto set_shading_enable = [](CreatePipelineHelper &helper) { helper.cb_ci_.logicOpEnable = VK_TRUE; };
19685     CreatePipelineHelper::OneshotTest(*this, set_shading_enable, VK_DEBUG_REPORT_ERROR_BIT_EXT,
19686                                       "VUID-VkPipelineColorBlendStateCreateInfo-logicOpEnable-00606");
19687 }
19688 
TEST_F(VkLayerTest,ColorBlendUnsupportedDualSourceBlend)19689 TEST_F(VkLayerTest, ColorBlendUnsupportedDualSourceBlend) {
19690     TEST_DESCRIPTION("Attempt to use dual-source blending when dualSrcBlend feature is disabled.");
19691 
19692     VkPhysicalDeviceFeatures features{};
19693     ASSERT_NO_FATAL_FAILURE(Init(&features));
19694     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
19695 
19696     const auto set_dsb_src_color_enable = [](CreatePipelineHelper &helper) {
19697         helper.cb_attachments_.blendEnable = VK_TRUE;
19698         helper.cb_attachments_.srcColorBlendFactor = VK_BLEND_FACTOR_SRC1_COLOR;  // bad!
19699         helper.cb_attachments_.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
19700         helper.cb_attachments_.colorBlendOp = VK_BLEND_OP_ADD;
19701         helper.cb_attachments_.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
19702         helper.cb_attachments_.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
19703         helper.cb_attachments_.alphaBlendOp = VK_BLEND_OP_ADD;
19704     };
19705     CreatePipelineHelper::OneshotTest(*this, set_dsb_src_color_enable, VK_DEBUG_REPORT_ERROR_BIT_EXT,
19706                                       "VUID-VkPipelineColorBlendAttachmentState-srcColorBlendFactor-00608");
19707 
19708     const auto set_dsb_dst_color_enable = [](CreatePipelineHelper &helper) {
19709         helper.cb_attachments_.blendEnable = VK_TRUE;
19710         helper.cb_attachments_.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_COLOR;
19711         helper.cb_attachments_.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR;  // bad
19712         helper.cb_attachments_.colorBlendOp = VK_BLEND_OP_ADD;
19713         helper.cb_attachments_.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
19714         helper.cb_attachments_.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
19715         helper.cb_attachments_.alphaBlendOp = VK_BLEND_OP_ADD;
19716     };
19717     CreatePipelineHelper::OneshotTest(*this, set_dsb_dst_color_enable, VK_DEBUG_REPORT_ERROR_BIT_EXT,
19718                                       "VUID-VkPipelineColorBlendAttachmentState-dstColorBlendFactor-00609");
19719 
19720     const auto set_dsb_src_alpha_enable = [](CreatePipelineHelper &helper) {
19721         helper.cb_attachments_.blendEnable = VK_TRUE;
19722         helper.cb_attachments_.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_COLOR;
19723         helper.cb_attachments_.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
19724         helper.cb_attachments_.colorBlendOp = VK_BLEND_OP_ADD;
19725         helper.cb_attachments_.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC1_ALPHA;  // bad
19726         helper.cb_attachments_.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
19727         helper.cb_attachments_.alphaBlendOp = VK_BLEND_OP_ADD;
19728     };
19729     CreatePipelineHelper::OneshotTest(*this, set_dsb_src_alpha_enable, VK_DEBUG_REPORT_ERROR_BIT_EXT,
19730                                       "VUID-VkPipelineColorBlendAttachmentState-srcAlphaBlendFactor-00610");
19731 
19732     const auto set_dsb_dst_alpha_enable = [](CreatePipelineHelper &helper) {
19733         helper.cb_attachments_.blendEnable = VK_TRUE;
19734         helper.cb_attachments_.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_COLOR;
19735         helper.cb_attachments_.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
19736         helper.cb_attachments_.colorBlendOp = VK_BLEND_OP_ADD;
19737         helper.cb_attachments_.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
19738         helper.cb_attachments_.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;  // bad!
19739         helper.cb_attachments_.alphaBlendOp = VK_BLEND_OP_ADD;
19740     };
19741     CreatePipelineHelper::OneshotTest(*this, set_dsb_dst_alpha_enable, VK_DEBUG_REPORT_ERROR_BIT_EXT,
19742                                       "VUID-VkPipelineColorBlendAttachmentState-dstAlphaBlendFactor-00611");
19743 }
19744 
19745 #if GTEST_IS_THREADSAFE
19746 struct thread_data_struct {
19747     VkCommandBuffer commandBuffer;
19748     VkDevice device;
19749     VkEvent event;
19750     bool bailout;
19751 };
19752 
AddToCommandBuffer(void * arg)19753 extern "C" void *AddToCommandBuffer(void *arg) {
19754     struct thread_data_struct *data = (struct thread_data_struct *)arg;
19755 
19756     for (int i = 0; i < 80000; i++) {
19757         vkCmdSetEvent(data->commandBuffer, data->event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
19758         if (data->bailout) {
19759             break;
19760         }
19761     }
19762     return NULL;
19763 }
19764 
TEST_F(VkLayerTest,ThreadCommandBufferCollision)19765 TEST_F(VkLayerTest, ThreadCommandBufferCollision) {
19766     test_platform_thread thread;
19767 
19768     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "THREADING ERROR");
19769 
19770     ASSERT_NO_FATAL_FAILURE(Init());
19771     ASSERT_NO_FATAL_FAILURE(InitViewport());
19772     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
19773 
19774     // Calls AllocateCommandBuffers
19775     VkCommandBufferObj commandBuffer(m_device, m_commandPool);
19776 
19777     commandBuffer.begin();
19778 
19779     VkEventCreateInfo event_info;
19780     VkEvent event;
19781     VkResult err;
19782 
19783     memset(&event_info, 0, sizeof(event_info));
19784     event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
19785 
19786     err = vkCreateEvent(device(), &event_info, NULL, &event);
19787     ASSERT_VK_SUCCESS(err);
19788 
19789     err = vkResetEvent(device(), event);
19790     ASSERT_VK_SUCCESS(err);
19791 
19792     struct thread_data_struct data;
19793     data.commandBuffer = commandBuffer.handle();
19794     data.event = event;
19795     data.bailout = false;
19796     m_errorMonitor->SetBailout(&data.bailout);
19797 
19798     // First do some correct operations using multiple threads.
19799     // Add many entries to command buffer from another thread.
19800     test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data);
19801     // Make non-conflicting calls from this thread at the same time.
19802     for (int i = 0; i < 80000; i++) {
19803         uint32_t count;
19804         vkEnumeratePhysicalDevices(instance(), &count, NULL);
19805     }
19806     test_platform_thread_join(thread, NULL);
19807 
19808     // Then do some incorrect operations using multiple threads.
19809     // Add many entries to command buffer from another thread.
19810     test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data);
19811     // Add many entries to command buffer from this thread at the same time.
19812     AddToCommandBuffer(&data);
19813 
19814     test_platform_thread_join(thread, NULL);
19815     commandBuffer.end();
19816 
19817     m_errorMonitor->SetBailout(NULL);
19818 
19819     m_errorMonitor->VerifyFound();
19820 
19821     vkDestroyEvent(device(), event, NULL);
19822 }
19823 #endif  // GTEST_IS_THREADSAFE
19824 
TEST_F(VkLayerTest,InvalidSPIRVCodeSize)19825 TEST_F(VkLayerTest, InvalidSPIRVCodeSize) {
19826     TEST_DESCRIPTION("Test that errors are produced for a spirv modules with invalid code sizes");
19827 
19828     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid SPIR-V header");
19829 
19830     ASSERT_NO_FATAL_FAILURE(Init());
19831     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
19832 
19833     VkShaderModule module;
19834     VkShaderModuleCreateInfo moduleCreateInfo;
19835     struct icd_spv_header spv;
19836 
19837     spv.magic = ICD_SPV_MAGIC;
19838     spv.version = ICD_SPV_VERSION;
19839     spv.gen_magic = 0;
19840 
19841     moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
19842     moduleCreateInfo.pNext = NULL;
19843     moduleCreateInfo.pCode = (const uint32_t *)&spv;
19844     moduleCreateInfo.codeSize = 4;
19845     moduleCreateInfo.flags = 0;
19846     vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module);
19847 
19848     m_errorMonitor->VerifyFound();
19849 
19850     char const *vsSource =
19851         "#version 450\n"
19852         "\n"
19853         "layout(location=0) out float x;\n"
19854         "void main(){\n"
19855         "   gl_Position = vec4(1);\n"
19856         "   x = 0;\n"
19857         "}\n";
19858 
19859     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkShaderModuleCreateInfo-pCode-01376");
19860     std::vector<unsigned int> shader;
19861     VkShaderModuleCreateInfo module_create_info;
19862     VkShaderModule shader_module;
19863     module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
19864     module_create_info.pNext = NULL;
19865     this->GLSLtoSPV(VK_SHADER_STAGE_VERTEX_BIT, vsSource, shader);
19866     module_create_info.pCode = shader.data();
19867     // Introduce failure by making codeSize a non-multiple of 4
19868     module_create_info.codeSize = shader.size() * sizeof(unsigned int) - 1;
19869     module_create_info.flags = 0;
19870     vkCreateShaderModule(m_device->handle(), &module_create_info, NULL, &shader_module);
19871 
19872     m_errorMonitor->VerifyFound();
19873 }
19874 
TEST_F(VkLayerTest,InvalidSPIRVMagic)19875 TEST_F(VkLayerTest, InvalidSPIRVMagic) {
19876     TEST_DESCRIPTION("Test that an error is produced for a spirv module with a bad magic number");
19877 
19878     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid SPIR-V magic number");
19879 
19880     ASSERT_NO_FATAL_FAILURE(Init());
19881     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
19882 
19883     VkShaderModule module;
19884     VkShaderModuleCreateInfo moduleCreateInfo;
19885     struct icd_spv_header spv;
19886 
19887     spv.magic = (uint32_t)~ICD_SPV_MAGIC;
19888     spv.version = ICD_SPV_VERSION;
19889     spv.gen_magic = 0;
19890 
19891     moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
19892     moduleCreateInfo.pNext = NULL;
19893     moduleCreateInfo.pCode = (const uint32_t *)&spv;
19894     moduleCreateInfo.codeSize = sizeof(spv) + 16;
19895     moduleCreateInfo.flags = 0;
19896     vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module);
19897 
19898     m_errorMonitor->VerifyFound();
19899 }
19900 
TEST_F(VkLayerTest,CreatePipelineVertexOutputNotConsumed)19901 TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed) {
19902     TEST_DESCRIPTION("Test that a warning is produced for a vertex output that is not consumed by the fragment stage");
19903     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "not consumed by fragment shader");
19904 
19905     ASSERT_NO_FATAL_FAILURE(Init());
19906     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
19907 
19908     char const *vsSource =
19909         "#version 450\n"
19910         "\n"
19911         "layout(location=0) out float x;\n"
19912         "void main(){\n"
19913         "   gl_Position = vec4(1);\n"
19914         "   x = 0;\n"
19915         "}\n";
19916     char const *fsSource =
19917         "#version 450\n"
19918         "\n"
19919         "layout(location=0) out vec4 color;\n"
19920         "void main(){\n"
19921         "   color = vec4(1);\n"
19922         "}\n";
19923 
19924     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
19925     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
19926 
19927     VkPipelineObj pipe(m_device);
19928     pipe.AddDefaultColorAttachment();
19929     pipe.AddShader(&vs);
19930     pipe.AddShader(&fs);
19931 
19932     VkDescriptorSetObj descriptorSet(m_device);
19933     descriptorSet.AppendDummy();
19934     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
19935 
19936     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
19937 
19938     m_errorMonitor->VerifyFound();
19939 }
19940 
TEST_F(VkPositiveLayerTest,CreatePipelineComplexTypes)19941 TEST_F(VkPositiveLayerTest, CreatePipelineComplexTypes) {
19942     TEST_DESCRIPTION("Smoke test for complex types across VS/FS boundary");
19943     ASSERT_NO_FATAL_FAILURE(Init());
19944     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
19945 
19946     if (!m_device->phy().features().tessellationShader) {
19947         printf("%s Device does not support tessellation shaders; skipped.\n", kSkipPrefix);
19948         return;
19949     }
19950 
19951     m_errorMonitor->ExpectSuccess();
19952 
19953     char const *vsSource =
19954         "#version 450\n"
19955         "void main() {}";
19956     char const *tcsSource =
19957         "#version 450\n"
19958         "layout(vertices=3) out;\n"
19959         "struct S { int x; };\n"
19960         "layout(location=2) patch out B { S s; } b;\n"
19961         "void main() {\n"
19962         "   gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
19963         "   gl_TessLevelInner[0] = 1;\n"
19964         "   b.s.x = 1;\n"
19965         "}\n";
19966 
19967     char const *tesSource =
19968         "#version 450\n"
19969         "layout(triangles, equal_spacing, cw) in;\n"
19970         "struct S { int x; };\n"
19971         "layout(location=2) patch in B { S s; } b;\n"
19972         "void main() { gl_Position = vec4(b.s.x); }\n";
19973 
19974     char const *fsSource =
19975         "#version 450\n"
19976         "layout(location=0) out vec4 c;\n"
19977         "void main() { c = vec4(1); }\n";
19978 
19979     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
19980     VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
19981     VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
19982     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
19983 
19984     VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
19985                                                  VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
19986 
19987     VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
19988 
19989     VkPipelineObj pipe(m_device);
19990 
19991     pipe.AddDefaultColorAttachment();
19992     pipe.AddShader(&vs);
19993     pipe.AddShader(&tcs);
19994     pipe.AddShader(&tes);
19995     pipe.AddShader(&fs);
19996     pipe.SetInputAssembly(&iasci);
19997     pipe.SetTessellation(&tsci);
19998 
19999     VkDescriptorSetObj descriptorSet(m_device);
20000     descriptorSet.AppendDummy();
20001     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
20002 
20003     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
20004 
20005     m_errorMonitor->VerifyNotFound();
20006 }
20007 
TEST_F(VkLayerTest,CreatePipelineCheckShaderBadSpecialization)20008 TEST_F(VkLayerTest, CreatePipelineCheckShaderBadSpecialization) {
20009     TEST_DESCRIPTION("Challenge core_validation with shader validation issues related to vkCreateGraphicsPipelines.");
20010 
20011     ASSERT_NO_FATAL_FAILURE(Init());
20012     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
20013 
20014     const char *bad_specialization_message =
20015         "Specialization entry 0 (for constant id 0) references memory outside provided specialization data ";
20016 
20017     char const *vsSource =
20018         "#version 450\n"
20019         "\n"
20020         "void main(){\n"
20021         "   gl_Position = vec4(1);\n"
20022         "}\n";
20023 
20024     char const *fsSource =
20025         "#version 450\n"
20026         "\n"
20027         "layout (constant_id = 0) const float r = 0.0f;\n"
20028         "layout(location = 0) out vec4 uFragColor;\n"
20029         "void main(){\n"
20030         "   uFragColor = vec4(r,1,0,1);\n"
20031         "}\n";
20032 
20033     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
20034     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
20035 
20036     const VkPipelineLayoutObj pipeline_layout(m_device);
20037 
20038     VkPipelineViewportStateCreateInfo vp_state_create_info = {};
20039     vp_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
20040     vp_state_create_info.viewportCount = 1;
20041     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
20042     vp_state_create_info.pViewports = &viewport;
20043     vp_state_create_info.scissorCount = 1;
20044 
20045     VkDynamicState scissor_state = VK_DYNAMIC_STATE_SCISSOR;
20046 
20047     VkPipelineDynamicStateCreateInfo pipeline_dynamic_state_create_info = {};
20048     pipeline_dynamic_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
20049     pipeline_dynamic_state_create_info.dynamicStateCount = 1;
20050     pipeline_dynamic_state_create_info.pDynamicStates = &scissor_state;
20051 
20052     VkPipelineShaderStageCreateInfo shader_stage_create_info[2] = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
20053 
20054     VkPipelineVertexInputStateCreateInfo vertex_input_create_info = {};
20055     vertex_input_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
20056 
20057     VkPipelineInputAssemblyStateCreateInfo input_assembly_create_info = {};
20058     input_assembly_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
20059     input_assembly_create_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
20060 
20061     VkPipelineRasterizationStateCreateInfo rasterization_state_create_info = {};
20062     rasterization_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
20063     rasterization_state_create_info.pNext = nullptr;
20064     rasterization_state_create_info.lineWidth = 1.0f;
20065     rasterization_state_create_info.rasterizerDiscardEnable = true;
20066 
20067     VkPipelineColorBlendAttachmentState color_blend_attachment_state = {};
20068     color_blend_attachment_state.blendEnable = VK_FALSE;
20069     color_blend_attachment_state.colorWriteMask = 0xf;
20070 
20071     VkPipelineColorBlendStateCreateInfo color_blend_state_create_info = {};
20072     color_blend_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
20073     color_blend_state_create_info.attachmentCount = 1;
20074     color_blend_state_create_info.pAttachments = &color_blend_attachment_state;
20075 
20076     VkGraphicsPipelineCreateInfo graphicspipe_create_info = {};
20077     graphicspipe_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
20078     graphicspipe_create_info.stageCount = 2;
20079     graphicspipe_create_info.pStages = shader_stage_create_info;
20080     graphicspipe_create_info.pVertexInputState = &vertex_input_create_info;
20081     graphicspipe_create_info.pInputAssemblyState = &input_assembly_create_info;
20082     graphicspipe_create_info.pViewportState = &vp_state_create_info;
20083     graphicspipe_create_info.pRasterizationState = &rasterization_state_create_info;
20084     graphicspipe_create_info.pColorBlendState = &color_blend_state_create_info;
20085     graphicspipe_create_info.pDynamicState = &pipeline_dynamic_state_create_info;
20086     graphicspipe_create_info.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
20087     graphicspipe_create_info.layout = pipeline_layout.handle();
20088     graphicspipe_create_info.renderPass = renderPass();
20089 
20090     VkPipelineCacheCreateInfo pipeline_cache_create_info = {};
20091     pipeline_cache_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
20092 
20093     VkPipelineCache pipelineCache;
20094     ASSERT_VK_SUCCESS(vkCreatePipelineCache(m_device->device(), &pipeline_cache_create_info, nullptr, &pipelineCache));
20095 
20096     // This structure maps constant ids to data locations.
20097     const VkSpecializationMapEntry entry =
20098         // id,  offset,                size
20099         {0, 4, sizeof(uint32_t)};  // Challenge core validation by using a bogus offset.
20100 
20101     uint32_t data = 1;
20102 
20103     // Set up the info describing spec map and data
20104     const VkSpecializationInfo specialization_info = {
20105         1,
20106         &entry,
20107         1 * sizeof(float),
20108         &data,
20109     };
20110     shader_stage_create_info[0].pSpecializationInfo = &specialization_info;
20111 
20112     VkPipeline pipeline;
20113     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, bad_specialization_message);
20114     vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &graphicspipe_create_info, nullptr, &pipeline);
20115     m_errorMonitor->VerifyFound();
20116 
20117     vkDestroyPipelineCache(m_device->device(), pipelineCache, nullptr);
20118 }
20119 
TEST_F(VkLayerTest,CreatePipelineCheckShaderDescriptorTypeMismatch)20120 TEST_F(VkLayerTest, CreatePipelineCheckShaderDescriptorTypeMismatch) {
20121     TEST_DESCRIPTION("Challenge core_validation with shader validation issues related to vkCreateGraphicsPipelines.");
20122 
20123     ASSERT_NO_FATAL_FAILURE(Init());
20124     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
20125 
20126     const char *descriptor_type_mismatch_message = "Type mismatch on descriptor slot 0.0 ";
20127 
20128     OneOffDescriptorSet ds(m_device, {
20129                                          {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
20130                                      });
20131 
20132     char const *vsSource =
20133         "#version 450\n"
20134         "\n"
20135         "layout (std140, set = 0, binding = 0) uniform buf {\n"
20136         "    mat4 mvp;\n"
20137         "} ubuf;\n"
20138         "void main(){\n"
20139         "   gl_Position = ubuf.mvp * vec4(1);\n"
20140         "}\n";
20141 
20142     char const *fsSource =
20143         "#version 450\n"
20144         "\n"
20145         "layout(location = 0) out vec4 uFragColor;\n"
20146         "void main(){\n"
20147         "   uFragColor = vec4(0,1,0,1);\n"
20148         "}\n";
20149 
20150     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
20151     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
20152 
20153     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
20154 
20155     VkPipelineObj pipe(m_device);
20156     pipe.AddDefaultColorAttachment();
20157     pipe.AddShader(&vs);
20158     pipe.AddShader(&fs);
20159 
20160     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, descriptor_type_mismatch_message);
20161     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
20162     m_errorMonitor->VerifyFound();
20163 }
20164 
TEST_F(VkLayerTest,CreatePipelineCheckShaderDescriptorNotAccessible)20165 TEST_F(VkLayerTest, CreatePipelineCheckShaderDescriptorNotAccessible) {
20166     TEST_DESCRIPTION(
20167         "Create a pipeline in which a descriptor used by a shader stage does not include that stage in its stageFlags.");
20168 
20169     ASSERT_NO_FATAL_FAILURE(Init());
20170     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
20171 
20172     const char *descriptor_not_accessible_message = "Shader uses descriptor slot 0.0 ";
20173 
20174     OneOffDescriptorSet ds(m_device, {
20175                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT /*!*/, nullptr},
20176                                      });
20177 
20178     char const *vsSource =
20179         "#version 450\n"
20180         "\n"
20181         "layout (std140, set = 0, binding = 0) uniform buf {\n"
20182         "    mat4 mvp;\n"
20183         "} ubuf;\n"
20184         "void main(){\n"
20185         "   gl_Position = ubuf.mvp * vec4(1);\n"
20186         "}\n";
20187 
20188     char const *fsSource =
20189         "#version 450\n"
20190         "\n"
20191         "layout(location = 0) out vec4 uFragColor;\n"
20192         "void main(){\n"
20193         "   uFragColor = vec4(0,1,0,1);\n"
20194         "}\n";
20195 
20196     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
20197     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
20198 
20199     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
20200 
20201     VkPipelineObj pipe(m_device);
20202     pipe.AddDefaultColorAttachment();
20203     pipe.AddShader(&vs);
20204     pipe.AddShader(&fs);
20205 
20206     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, descriptor_not_accessible_message);
20207     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
20208     m_errorMonitor->VerifyFound();
20209 }
20210 
TEST_F(VkLayerTest,CreatePipelineCheckShaderPushConstantNotAccessible)20211 TEST_F(VkLayerTest, CreatePipelineCheckShaderPushConstantNotAccessible) {
20212     TEST_DESCRIPTION(
20213         "Create a graphics pipeline in which a push constant range containing a push constant block member is not accessible from "
20214         "the current shader stage.");
20215 
20216     ASSERT_NO_FATAL_FAILURE(Init());
20217     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
20218 
20219     const char *push_constant_not_accessible_message =
20220         "Push constant range covering variable starting at offset 0 not accessible from stage VK_SHADER_STAGE_VERTEX_BIT";
20221 
20222     char const *vsSource =
20223         "#version 450\n"
20224         "\n"
20225         "layout(push_constant, std430) uniform foo { float x; } consts;\n"
20226         "void main(){\n"
20227         "   gl_Position = vec4(consts.x);\n"
20228         "}\n";
20229 
20230     char const *fsSource =
20231         "#version 450\n"
20232         "\n"
20233         "layout(location = 0) out vec4 uFragColor;\n"
20234         "void main(){\n"
20235         "   uFragColor = vec4(0,1,0,1);\n"
20236         "}\n";
20237 
20238     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
20239     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
20240 
20241     // Set up a push constant range
20242     VkPushConstantRange push_constant_range = {};
20243     // Set to the wrong stage to challenge core_validation
20244     push_constant_range.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
20245     push_constant_range.size = 4;
20246 
20247     const VkPipelineLayoutObj pipeline_layout(m_device, {}, {push_constant_range});
20248 
20249     VkPipelineObj pipe(m_device);
20250     pipe.AddDefaultColorAttachment();
20251     pipe.AddShader(&vs);
20252     pipe.AddShader(&fs);
20253 
20254     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, push_constant_not_accessible_message);
20255     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
20256     m_errorMonitor->VerifyFound();
20257 }
20258 
TEST_F(VkLayerTest,CreatePipelineCheckShaderNotEnabled)20259 TEST_F(VkLayerTest, CreatePipelineCheckShaderNotEnabled) {
20260     TEST_DESCRIPTION(
20261         "Create a graphics pipeline in which a capability declared by the shader requires a feature not enabled on the device.");
20262 
20263     ASSERT_NO_FATAL_FAILURE(Init());
20264     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
20265 
20266     const char *feature_not_enabled_message =
20267         "Shader requires VkPhysicalDeviceFeatures::shaderFloat64 but is not enabled on the device";
20268 
20269     // Some awkward steps are required to test with custom device features.
20270     std::vector<const char *> device_extension_names;
20271     auto features = m_device->phy().features();
20272     // Disable support for 64 bit floats
20273     features.shaderFloat64 = false;
20274     // The sacrificial device object
20275     VkDeviceObj test_device(0, gpu(), device_extension_names, &features);
20276 
20277     char const *vsSource =
20278         "#version 450\n"
20279         "\n"
20280         "void main(){\n"
20281         "   gl_Position = vec4(1);\n"
20282         "}\n";
20283     char const *fsSource =
20284         "#version 450\n"
20285         "\n"
20286         "layout(location=0) out vec4 color;\n"
20287         "void main(){\n"
20288         "   dvec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
20289         "   color = vec4(green);\n"
20290         "}\n";
20291 
20292     VkShaderObj vs(&test_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
20293     VkShaderObj fs(&test_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
20294 
20295     VkRenderpassObj render_pass(&test_device);
20296 
20297     VkPipelineObj pipe(&test_device);
20298     pipe.AddDefaultColorAttachment();
20299     pipe.AddShader(&vs);
20300     pipe.AddShader(&fs);
20301 
20302     const VkPipelineLayoutObj pipeline_layout(&test_device);
20303 
20304     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, feature_not_enabled_message);
20305     pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle());
20306     m_errorMonitor->VerifyFound();
20307 }
20308 
TEST_F(VkLayerTest,CreateShaderModuleCheckBadCapability)20309 TEST_F(VkLayerTest, CreateShaderModuleCheckBadCapability) {
20310     TEST_DESCRIPTION("Create a shader in which a capability declared by the shader is not supported.");
20311     // Note that this failure message comes from spirv-tools, specifically the validator.
20312 
20313     ASSERT_NO_FATAL_FAILURE(Init());
20314     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
20315 
20316     const std::string spv_source = R"(
20317                   OpCapability ImageRect
20318                   OpEntryPoint Vertex %main "main"
20319           %main = OpFunction %void None %3
20320                   OpReturn
20321                   OpFunctionEnd
20322         )";
20323 
20324     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Capability ImageRect is not allowed by Vulkan");
20325 
20326     std::vector<unsigned int> spv;
20327     VkShaderModuleCreateInfo module_create_info;
20328     VkShaderModule shader_module;
20329     module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
20330     module_create_info.pNext = NULL;
20331     ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, spv_source.data(), spv);
20332     module_create_info.pCode = spv.data();
20333     module_create_info.codeSize = spv.size() * sizeof(unsigned int);
20334     module_create_info.flags = 0;
20335 
20336     VkResult err = vkCreateShaderModule(m_device->handle(), &module_create_info, NULL, &shader_module);
20337     m_errorMonitor->VerifyFound();
20338     if (err == VK_SUCCESS) {
20339         vkDestroyShaderModule(m_device->handle(), shader_module, NULL);
20340     }
20341 }
20342 
TEST_F(VkPositiveLayerTest,ShaderRelaxedBlockLayout)20343 TEST_F(VkPositiveLayerTest, ShaderRelaxedBlockLayout) {
20344     // This is a positive test, no errors expected
20345     // Verifies the ability to relax block layout rules with a shader that requires them to be relaxed
20346     TEST_DESCRIPTION("Create a shader that requires relaxed block layout.");
20347 
20348     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
20349 
20350     // The Relaxed Block Layout extension was promoted to core in 1.1.
20351     // Go ahead and check for it and turn it on in case a 1.0 device has it.
20352     if (!DeviceExtensionSupported(gpu(), nullptr, VK_KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME)) {
20353         printf("%s Extension %s not supported, skipping this pass. \n", kSkipPrefix, VK_KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME);
20354         return;
20355     }
20356     m_device_extension_names.push_back(VK_KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME);
20357     ASSERT_NO_FATAL_FAILURE(InitState());
20358     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
20359 
20360     // Vertex shader requiring relaxed layout.
20361     // Without relaxed layout, we would expect a message like:
20362     // "Structure id 2 decorated as Block for variable in Uniform storage class
20363     // must follow standard uniform buffer layout rules: member 1 at offset 4 is not aligned to 16"
20364 
20365     const std::string spv_source = R"(
20366                   OpCapability Shader
20367                   OpMemoryModel Logical GLSL450
20368                   OpEntryPoint Vertex %main "main"
20369                   OpSource GLSL 450
20370                   OpMemberDecorate %S 0 Offset 0
20371                   OpMemberDecorate %S 1 Offset 4
20372                   OpDecorate %S Block
20373                   OpDecorate %B DescriptorSet 0
20374                   OpDecorate %B Binding 0
20375           %void = OpTypeVoid
20376              %3 = OpTypeFunction %void
20377          %float = OpTypeFloat 32
20378        %v3float = OpTypeVector %float 3
20379              %S = OpTypeStruct %float %v3float
20380 %_ptr_Uniform_S = OpTypePointer Uniform %S
20381              %B = OpVariable %_ptr_Uniform_S Uniform
20382           %main = OpFunction %void None %3
20383              %5 = OpLabel
20384                   OpReturn
20385                   OpFunctionEnd
20386         )";
20387 
20388     std::vector<unsigned int> spv;
20389     VkShaderModuleCreateInfo module_create_info;
20390     VkShaderModule shader_module;
20391     module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
20392     module_create_info.pNext = NULL;
20393     ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, spv_source.data(), spv);
20394     module_create_info.pCode = spv.data();
20395     module_create_info.codeSize = spv.size() * sizeof(unsigned int);
20396     module_create_info.flags = 0;
20397 
20398     m_errorMonitor->ExpectSuccess();
20399     VkResult err = vkCreateShaderModule(m_device->handle(), &module_create_info, NULL, &shader_module);
20400     m_errorMonitor->VerifyNotFound();
20401     if (err == VK_SUCCESS) {
20402         vkDestroyShaderModule(m_device->handle(), shader_module, NULL);
20403     }
20404 }
20405 
TEST_F(VkPositiveLayerTest,ShaderScalarBlockLayout)20406 TEST_F(VkPositiveLayerTest, ShaderScalarBlockLayout) {
20407     // This is a positive test, no errors expected
20408     // Verifies the ability to scalar block layout rules with a shader that requires them to be relaxed
20409     TEST_DESCRIPTION("Create a shader that requires scalar block layout.");
20410     // Enable req'd extensions
20411     if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
20412         printf("%s Extension %s not supported, skipping this pass. \n", kSkipPrefix,
20413                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
20414         return;
20415     }
20416     m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
20417     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
20418 
20419     // Check for the Scalar Block Layout extension and turn it on if it's available
20420     if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME)) {
20421         printf("%s Extension %s not supported, skipping this pass. \n", kSkipPrefix, VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME);
20422         return;
20423     }
20424     m_device_extension_names.push_back(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME);
20425 
20426     PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2 =
20427         (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
20428 
20429     auto scalar_block_features = lvl_init_struct<VkPhysicalDeviceScalarBlockLayoutFeaturesEXT>(NULL);
20430     scalar_block_features.scalarBlockLayout = VK_TRUE;
20431     auto query_features2 = lvl_init_struct<VkPhysicalDeviceFeatures2>(&scalar_block_features);
20432     vkGetPhysicalDeviceFeatures2(gpu(), &query_features2);
20433 
20434     auto set_features2 = lvl_init_struct<VkPhysicalDeviceFeatures2>(&scalar_block_features);
20435 
20436     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &set_features2));
20437     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
20438 
20439     // Vertex shader requiring scalar layout.
20440     // Without scalar layout, we would expect a message like:
20441     // "Structure id 2 decorated as Block for variable in Uniform storage class
20442     // must follow standard uniform buffer layout rules: member 1 at offset 4 is not aligned to 16"
20443 
20444     const std::string spv_source = R"(
20445                   OpCapability Shader
20446                   OpMemoryModel Logical GLSL450
20447                   OpEntryPoint Vertex %main "main"
20448                   OpSource GLSL 450
20449                   OpMemberDecorate %S 0 Offset 0
20450                   OpMemberDecorate %S 1 Offset 4
20451                   OpMemberDecorate %S 2 Offset 8
20452                   OpDecorate %S Block
20453                   OpDecorate %B DescriptorSet 0
20454                   OpDecorate %B Binding 0
20455           %void = OpTypeVoid
20456              %3 = OpTypeFunction %void
20457          %float = OpTypeFloat 32
20458        %v3float = OpTypeVector %float 3
20459              %S = OpTypeStruct %float %float %v3float
20460 %_ptr_Uniform_S = OpTypePointer Uniform %S
20461              %B = OpVariable %_ptr_Uniform_S Uniform
20462           %main = OpFunction %void None %3
20463              %5 = OpLabel
20464                   OpReturn
20465                   OpFunctionEnd
20466         )";
20467 
20468     std::vector<unsigned int> spv;
20469     VkShaderModuleCreateInfo module_create_info;
20470     VkShaderModule shader_module;
20471     module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
20472     module_create_info.pNext = NULL;
20473     ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, spv_source.data(), spv);
20474     module_create_info.pCode = spv.data();
20475     module_create_info.codeSize = spv.size() * sizeof(unsigned int);
20476     module_create_info.flags = 0;
20477 
20478     m_errorMonitor->ExpectSuccess();
20479     VkResult err = vkCreateShaderModule(m_device->handle(), &module_create_info, NULL, &shader_module);
20480     m_errorMonitor->VerifyNotFound();
20481     if (err == VK_SUCCESS) {
20482         vkDestroyShaderModule(m_device->handle(), shader_module, NULL);
20483     }
20484 }
20485 
TEST_F(VkPositiveLayerTest,SpirvGroupDecorations)20486 TEST_F(VkPositiveLayerTest, SpirvGroupDecorations) {
20487     TEST_DESCRIPTION("Test shader validation support for group decorations.");
20488     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
20489     ASSERT_NO_FATAL_FAILURE(InitState());
20490     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
20491 
20492     const std::string spv_source = R"(
20493               OpCapability Shader
20494                OpMemoryModel Logical GLSL450
20495                OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
20496                OpExecutionMode %main LocalSize 1 1 1
20497                OpSource GLSL 430
20498                OpName %main "main"
20499                OpName %gl_GlobalInvocationID "gl_GlobalInvocationID"
20500                OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
20501                OpDecorate %_runtimearr_float ArrayStride 4
20502                OpDecorate %4 BufferBlock
20503                OpDecorate %5 Offset 0
20504           %4 = OpDecorationGroup
20505           %5 = OpDecorationGroup
20506                OpGroupDecorate %4 %_struct_6 %_struct_7 %_struct_8 %_struct_9 %_struct_10 %_struct_11
20507                OpGroupMemberDecorate %5 %_struct_6 0 %_struct_7 0 %_struct_8 0 %_struct_9 0 %_struct_10 0 %_struct_11 0
20508                OpDecorate %12 DescriptorSet 0
20509                OpDecorate %13 DescriptorSet 0
20510                OpDecorate %13 NonWritable
20511                OpDecorate %13 Restrict
20512          %14 = OpDecorationGroup
20513          %12 = OpDecorationGroup
20514          %13 = OpDecorationGroup
20515                OpGroupDecorate %12 %15
20516                OpGroupDecorate %12 %15
20517                OpGroupDecorate %12 %15
20518                OpDecorate %15 DescriptorSet 0
20519                OpDecorate %15 Binding 5
20520                OpGroupDecorate %14 %16
20521                OpDecorate %16 DescriptorSet 0
20522                OpDecorate %16 Binding 0
20523                OpGroupDecorate %12 %17
20524                OpDecorate %17 Binding 1
20525                OpGroupDecorate %13 %18 %19
20526                OpDecorate %18 Binding 2
20527                OpDecorate %19 Binding 3
20528                OpGroupDecorate %14 %20
20529                OpGroupDecorate %12 %20
20530                OpGroupDecorate %13 %20
20531                OpDecorate %20 Binding 4
20532        %bool = OpTypeBool
20533        %void = OpTypeVoid
20534          %23 = OpTypeFunction %void
20535        %uint = OpTypeInt 32 0
20536         %int = OpTypeInt 32 1
20537       %float = OpTypeFloat 32
20538      %v3uint = OpTypeVector %uint 3
20539     %v3float = OpTypeVector %float 3
20540 %_ptr_Input_v3uint = OpTypePointer Input %v3uint
20541 %_ptr_Uniform_int = OpTypePointer Uniform %int
20542 %_ptr_Uniform_float = OpTypePointer Uniform %float
20543 %_runtimearr_int = OpTypeRuntimeArray %int
20544 %_runtimearr_float = OpTypeRuntimeArray %float
20545 %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
20546       %int_0 = OpConstant %int 0
20547   %_struct_6 = OpTypeStruct %_runtimearr_float
20548 %_ptr_Uniform__struct_6 = OpTypePointer Uniform %_struct_6
20549          %15 = OpVariable %_ptr_Uniform__struct_6 Uniform
20550   %_struct_7 = OpTypeStruct %_runtimearr_float
20551 %_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
20552          %16 = OpVariable %_ptr_Uniform__struct_7 Uniform
20553   %_struct_8 = OpTypeStruct %_runtimearr_float
20554 %_ptr_Uniform__struct_8 = OpTypePointer Uniform %_struct_8
20555          %17 = OpVariable %_ptr_Uniform__struct_8 Uniform
20556   %_struct_9 = OpTypeStruct %_runtimearr_float
20557 %_ptr_Uniform__struct_9 = OpTypePointer Uniform %_struct_9
20558          %18 = OpVariable %_ptr_Uniform__struct_9 Uniform
20559  %_struct_10 = OpTypeStruct %_runtimearr_float
20560 %_ptr_Uniform__struct_10 = OpTypePointer Uniform %_struct_10
20561          %19 = OpVariable %_ptr_Uniform__struct_10 Uniform
20562  %_struct_11 = OpTypeStruct %_runtimearr_float
20563 %_ptr_Uniform__struct_11 = OpTypePointer Uniform %_struct_11
20564          %20 = OpVariable %_ptr_Uniform__struct_11 Uniform
20565        %main = OpFunction %void None %23
20566          %40 = OpLabel
20567          %41 = OpLoad %v3uint %gl_GlobalInvocationID
20568          %42 = OpCompositeExtract %uint %41 0
20569          %43 = OpAccessChain %_ptr_Uniform_float %16 %int_0 %42
20570          %44 = OpAccessChain %_ptr_Uniform_float %17 %int_0 %42
20571          %45 = OpAccessChain %_ptr_Uniform_float %18 %int_0 %42
20572          %46 = OpAccessChain %_ptr_Uniform_float %19 %int_0 %42
20573          %47 = OpAccessChain %_ptr_Uniform_float %20 %int_0 %42
20574          %48 = OpAccessChain %_ptr_Uniform_float %15 %int_0 %42
20575          %49 = OpLoad %float %43
20576          %50 = OpLoad %float %44
20577          %51 = OpLoad %float %45
20578          %52 = OpLoad %float %46
20579          %53 = OpLoad %float %47
20580          %54 = OpFAdd %float %49 %50
20581          %55 = OpFAdd %float %54 %51
20582          %56 = OpFAdd %float %55 %52
20583          %57 = OpFAdd %float %56 %53
20584                OpStore %48 %57
20585                OpReturn
20586                OpFunctionEnd
20587 )";
20588 
20589     // CreateDescriptorSetLayout
20590     VkDescriptorSetLayoutBinding dslb[6] = {};
20591     for (auto i = 0; i < 6; i++) {
20592         dslb[i].binding = i;
20593         dslb[i].descriptorCount = 1;
20594         dslb[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
20595         dslb[i].pImmutableSamplers = NULL;
20596         dslb[i].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_ALL;
20597     }
20598 
20599     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
20600     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
20601     ds_layout_ci.flags = 0;
20602     ds_layout_ci.bindingCount = 6;
20603     ds_layout_ci.pBindings = dslb;
20604 
20605     VkDescriptorSetLayout ds_layout = {};
20606     vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
20607 
20608     // CreatePipelineLayout
20609     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
20610     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
20611     pipeline_layout_ci.pNext = NULL;
20612     pipeline_layout_ci.flags = 0;
20613     pipeline_layout_ci.setLayoutCount = 1;
20614     pipeline_layout_ci.pSetLayouts = &ds_layout;
20615     VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
20616     vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
20617 
20618     // Create DescriptorPool
20619     VkDescriptorPoolSize ds_type_count = {};
20620     ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
20621     ds_type_count.descriptorCount = 6;
20622 
20623     VkDescriptorPoolCreateInfo ds_pool_ci = {};
20624     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
20625     ds_pool_ci.pNext = NULL;
20626     ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
20627     ds_pool_ci.maxSets = 1;
20628     ds_pool_ci.poolSizeCount = 1;
20629     ds_pool_ci.pPoolSizes = &ds_type_count;
20630 
20631     VkDescriptorPool ds_pool = VK_NULL_HANDLE;
20632     vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
20633 
20634     // AllocateDescriptorSets
20635     VkDescriptorSetAllocateInfo ds_alloc_info = {};
20636     ds_alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
20637     ds_alloc_info.descriptorSetCount = 1;
20638     ds_alloc_info.descriptorPool = ds_pool;
20639     ds_alloc_info.pSetLayouts = &ds_layout;
20640 
20641     VkDescriptorSet descriptorSet;
20642     vkAllocateDescriptorSets(m_device->device(), &ds_alloc_info, &descriptorSet);
20643 
20644     // CreateShaderModule
20645     std::vector<unsigned int> spv;
20646     VkShaderModuleCreateInfo module_create_info;
20647     VkShaderModule shader_module;
20648     module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
20649     module_create_info.pNext = NULL;
20650     ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, spv_source.data(), spv);
20651     module_create_info.pCode = spv.data();
20652     module_create_info.codeSize = spv.size() * sizeof(unsigned int);
20653     module_create_info.flags = 0;
20654     vkCreateShaderModule(m_device->handle(), &module_create_info, NULL, &shader_module);
20655 
20656     // CreateComputePipelines
20657     VkComputePipelineCreateInfo pipeline_info = {};
20658     pipeline_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
20659     pipeline_info.pNext = nullptr;
20660     pipeline_info.flags = 0;
20661     pipeline_info.layout = pipeline_layout;
20662     pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
20663     pipeline_info.basePipelineIndex = -1;
20664     pipeline_info.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
20665     pipeline_info.stage.pNext = nullptr;
20666     pipeline_info.stage.flags = 0;
20667     pipeline_info.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
20668     pipeline_info.stage.module = shader_module;
20669     pipeline_info.stage.pName = "main";
20670     pipeline_info.stage.pSpecializationInfo = nullptr;
20671     VkPipeline cs_pipeline;
20672 
20673     m_errorMonitor->ExpectSuccess();
20674     vkCreateComputePipelines(device(), VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &cs_pipeline);
20675     m_errorMonitor->VerifyNotFound();
20676 
20677     vkDestroyPipeline(device(), cs_pipeline, nullptr);
20678     vkDestroyShaderModule(device(), shader_module, nullptr);
20679     vkDestroyDescriptorPool(device(), ds_pool, nullptr);
20680     vkDestroyPipelineLayout(device(), pipeline_layout, nullptr);
20681     vkDestroyDescriptorSetLayout(device(), ds_layout, nullptr);
20682 }
20683 
TEST_F(VkPositiveLayerTest,CreatePipelineCheckShaderCapabilityExtension1of2)20684 TEST_F(VkPositiveLayerTest, CreatePipelineCheckShaderCapabilityExtension1of2) {
20685     // This is a positive test, no errors expected
20686     // Verifies the ability to deal with a shader that declares a non-unique SPIRV capability ID
20687     TEST_DESCRIPTION("Create a shader in which uses a non-unique capability ID extension, 1 of 2");
20688 
20689     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
20690     if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME)) {
20691         printf("%s Extension %s not supported, skipping this pass. \n", kSkipPrefix,
20692                VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME);
20693         return;
20694     }
20695     m_device_extension_names.push_back(VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME);
20696     ASSERT_NO_FATAL_FAILURE(InitState());
20697 
20698     // These tests require that the device support multiViewport
20699     if (!m_device->phy().features().multiViewport) {
20700         printf("%s Device does not support multiViewport, test skipped.\n", kSkipPrefix);
20701         return;
20702     }
20703     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
20704 
20705     // Vertex shader using viewport array capability
20706     char const *vsSource =
20707         "#version 450\n"
20708         "#extension GL_ARB_shader_viewport_layer_array : enable\n"
20709         "void main() {\n"
20710         "    gl_ViewportIndex = 1;\n"
20711         "}\n";
20712 
20713     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
20714 
20715     VkPipelineObj pipe(m_device);
20716     pipe.AddDefaultColorAttachment();
20717     pipe.AddShader(&vs);
20718 
20719     const VkPipelineLayoutObj pipe_layout(m_device, {});
20720 
20721     m_errorMonitor->ExpectSuccess();
20722     pipe.CreateVKPipeline(pipe_layout.handle(), renderPass());
20723     m_errorMonitor->VerifyNotFound();
20724 }
20725 
TEST_F(VkPositiveLayerTest,CreatePipelineCheckShaderCapabilityExtension2of2)20726 TEST_F(VkPositiveLayerTest, CreatePipelineCheckShaderCapabilityExtension2of2) {
20727     // This is a positive test, no errors expected
20728     // Verifies the ability to deal with a shader that declares a non-unique SPIRV capability ID
20729     TEST_DESCRIPTION("Create a shader in which uses a non-unique capability ID extension, 2 of 2");
20730 
20731     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
20732     if (!DeviceExtensionSupported(gpu(), nullptr, VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME)) {
20733         printf("%s Extension %s not supported, skipping this pass. \n", kSkipPrefix, VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME);
20734         return;
20735     }
20736     m_device_extension_names.push_back(VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME);
20737     ASSERT_NO_FATAL_FAILURE(InitState());
20738 
20739     // These tests require that the device support multiViewport
20740     if (!m_device->phy().features().multiViewport) {
20741         printf("%s Device does not support multiViewport, test skipped.\n", kSkipPrefix);
20742         return;
20743     }
20744     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
20745 
20746     // Vertex shader using viewport array capability
20747     char const *vsSource =
20748         "#version 450\n"
20749         "#extension GL_ARB_shader_viewport_layer_array : enable\n"
20750         "void main() {\n"
20751         "    gl_ViewportIndex = 1;\n"
20752         "}\n";
20753 
20754     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
20755 
20756     VkPipelineObj pipe(m_device);
20757     pipe.AddDefaultColorAttachment();
20758     pipe.AddShader(&vs);
20759 
20760     const VkPipelineLayoutObj pipe_layout(m_device, {});
20761 
20762     m_errorMonitor->ExpectSuccess();
20763     pipe.CreateVKPipeline(pipe_layout.handle(), renderPass());
20764     m_errorMonitor->VerifyNotFound();
20765 }
20766 
TEST_F(VkLayerTest,CreatePipelineFragmentInputNotProvided)20767 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided) {
20768     TEST_DESCRIPTION(
20769         "Test that an error is produced for a fragment shader input which is not present in the outputs of the previous stage");
20770 
20771     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not written by vertex shader");
20772 
20773     ASSERT_NO_FATAL_FAILURE(Init());
20774     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
20775 
20776     char const *vsSource =
20777         "#version 450\n"
20778         "\n"
20779         "void main(){\n"
20780         "   gl_Position = vec4(1);\n"
20781         "}\n";
20782     char const *fsSource =
20783         "#version 450\n"
20784         "\n"
20785         "layout(location=0) in float x;\n"
20786         "layout(location=0) out vec4 color;\n"
20787         "void main(){\n"
20788         "   color = vec4(x);\n"
20789         "}\n";
20790 
20791     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
20792     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
20793 
20794     VkPipelineObj pipe(m_device);
20795     pipe.AddDefaultColorAttachment();
20796     pipe.AddShader(&vs);
20797     pipe.AddShader(&fs);
20798 
20799     VkDescriptorSetObj descriptorSet(m_device);
20800     descriptorSet.AppendDummy();
20801     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
20802 
20803     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
20804 
20805     m_errorMonitor->VerifyFound();
20806 }
20807 
TEST_F(VkLayerTest,CreatePipelineFragmentInputNotProvidedInBlock)20808 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvidedInBlock) {
20809     TEST_DESCRIPTION(
20810         "Test that an error is produced for a fragment shader input within an interace block, which is not present in the outputs "
20811         "of the previous stage.");
20812     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not written by vertex shader");
20813 
20814     ASSERT_NO_FATAL_FAILURE(Init());
20815     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
20816 
20817     char const *vsSource =
20818         "#version 450\n"
20819         "\n"
20820         "void main(){\n"
20821         "   gl_Position = vec4(1);\n"
20822         "}\n";
20823     char const *fsSource =
20824         "#version 450\n"
20825         "\n"
20826         "in block { layout(location=0) float x; } ins;\n"
20827         "layout(location=0) out vec4 color;\n"
20828         "void main(){\n"
20829         "   color = vec4(ins.x);\n"
20830         "}\n";
20831 
20832     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
20833     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
20834 
20835     VkPipelineObj pipe(m_device);
20836     pipe.AddDefaultColorAttachment();
20837     pipe.AddShader(&vs);
20838     pipe.AddShader(&fs);
20839 
20840     VkDescriptorSetObj descriptorSet(m_device);
20841     descriptorSet.AppendDummy();
20842     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
20843 
20844     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
20845 
20846     m_errorMonitor->VerifyFound();
20847 }
20848 
TEST_F(VkLayerTest,CreatePipelineVsFsTypeMismatchArraySize)20849 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchArraySize) {
20850     TEST_DESCRIPTION("Test that an error is produced for mismatched array sizes across the vertex->fragment shader interface");
20851     m_errorMonitor->SetDesiredFailureMsg(
20852         VK_DEBUG_REPORT_ERROR_BIT_EXT,
20853         "Type mismatch on location 0.0: 'ptr to output arr[2] of float32' vs 'ptr to input arr[1] of float32'");
20854 
20855     ASSERT_NO_FATAL_FAILURE(Init());
20856     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
20857 
20858     char const *vsSource =
20859         "#version 450\n"
20860         "\n"
20861         "layout(location=0) out float x[2];\n"
20862         "void main(){\n"
20863         "   x[0] = 0; x[1] = 0;\n"
20864         "   gl_Position = vec4(1);\n"
20865         "}\n";
20866     char const *fsSource =
20867         "#version 450\n"
20868         "\n"
20869         "layout(location=0) in float x[1];\n"
20870         "layout(location=0) out vec4 color;\n"
20871         "void main(){\n"
20872         "   color = vec4(x[0]);\n"
20873         "}\n";
20874 
20875     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
20876     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
20877 
20878     VkPipelineObj pipe(m_device);
20879     pipe.AddDefaultColorAttachment();
20880     pipe.AddShader(&vs);
20881     pipe.AddShader(&fs);
20882 
20883     VkDescriptorSetObj descriptorSet(m_device);
20884     descriptorSet.AppendDummy();
20885     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
20886 
20887     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
20888 
20889     m_errorMonitor->VerifyFound();
20890 }
20891 
TEST_F(VkLayerTest,CreatePipelineVsFsTypeMismatch)20892 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch) {
20893     TEST_DESCRIPTION("Test that an error is produced for mismatched types across the vertex->fragment shader interface");
20894     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0");
20895 
20896     ASSERT_NO_FATAL_FAILURE(Init());
20897     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
20898 
20899     char const *vsSource =
20900         "#version 450\n"
20901         "\n"
20902         "layout(location=0) out int x;\n"
20903         "void main(){\n"
20904         "   x = 0;\n"
20905         "   gl_Position = vec4(1);\n"
20906         "}\n";
20907     char const *fsSource =
20908         "#version 450\n"
20909         "\n"
20910         "layout(location=0) in float x;\n" /* VS writes int */
20911         "layout(location=0) out vec4 color;\n"
20912         "void main(){\n"
20913         "   color = vec4(x);\n"
20914         "}\n";
20915 
20916     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
20917     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
20918 
20919     VkPipelineObj pipe(m_device);
20920     pipe.AddDefaultColorAttachment();
20921     pipe.AddShader(&vs);
20922     pipe.AddShader(&fs);
20923 
20924     VkDescriptorSetObj descriptorSet(m_device);
20925     descriptorSet.AppendDummy();
20926     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
20927 
20928     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
20929 
20930     m_errorMonitor->VerifyFound();
20931 }
20932 
TEST_F(VkLayerTest,CreatePipelineVsFsTypeMismatchInBlock)20933 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchInBlock) {
20934     TEST_DESCRIPTION(
20935         "Test that an error is produced for mismatched types across the vertex->fragment shader interface, when the variable is "
20936         "contained within an interface block");
20937     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0");
20938 
20939     ASSERT_NO_FATAL_FAILURE(Init());
20940     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
20941 
20942     char const *vsSource =
20943         "#version 450\n"
20944         "\n"
20945         "out block { layout(location=0) int x; } outs;\n"
20946         "void main(){\n"
20947         "   outs.x = 0;\n"
20948         "   gl_Position = vec4(1);\n"
20949         "}\n";
20950     char const *fsSource =
20951         "#version 450\n"
20952         "\n"
20953         "in block { layout(location=0) float x; } ins;\n" /* VS writes int */
20954         "layout(location=0) out vec4 color;\n"
20955         "void main(){\n"
20956         "   color = vec4(ins.x);\n"
20957         "}\n";
20958 
20959     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
20960     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
20961 
20962     VkPipelineObj pipe(m_device);
20963     pipe.AddDefaultColorAttachment();
20964     pipe.AddShader(&vs);
20965     pipe.AddShader(&fs);
20966 
20967     VkDescriptorSetObj descriptorSet(m_device);
20968     descriptorSet.AppendDummy();
20969     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
20970 
20971     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
20972 
20973     m_errorMonitor->VerifyFound();
20974 }
20975 
TEST_F(VkLayerTest,CreatePipelineVsFsMismatchByLocation)20976 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByLocation) {
20977     TEST_DESCRIPTION(
20978         "Test that an error is produced for location mismatches across the vertex->fragment shader interface; This should manifest "
20979         "as a not-written/not-consumed pair, but flushes out broken walking of the interfaces");
20980     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0.0 which is not written by vertex shader");
20981 
20982     ASSERT_NO_FATAL_FAILURE(Init());
20983     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
20984 
20985     char const *vsSource =
20986         "#version 450\n"
20987         "\n"
20988         "out block { layout(location=1) float x; } outs;\n"
20989         "void main(){\n"
20990         "   outs.x = 0;\n"
20991         "   gl_Position = vec4(1);\n"
20992         "}\n";
20993     char const *fsSource =
20994         "#version 450\n"
20995         "\n"
20996         "in block { layout(location=0) float x; } ins;\n"
20997         "layout(location=0) out vec4 color;\n"
20998         "void main(){\n"
20999         "   color = vec4(ins.x);\n"
21000         "}\n";
21001 
21002     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
21003     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
21004 
21005     VkPipelineObj pipe(m_device);
21006     pipe.AddDefaultColorAttachment();
21007     pipe.AddShader(&vs);
21008     pipe.AddShader(&fs);
21009 
21010     VkDescriptorSetObj descriptorSet(m_device);
21011     descriptorSet.AppendDummy();
21012     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
21013 
21014     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21015 
21016     m_errorMonitor->VerifyFound();
21017 }
21018 
TEST_F(VkLayerTest,CreatePipelineVsFsMismatchByComponent)21019 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByComponent) {
21020     TEST_DESCRIPTION(
21021         "Test that an error is produced for component mismatches across the vertex->fragment shader interface. It's not enough to "
21022         "have the same set of locations in use; matching is defined in terms of spirv variables.");
21023     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0.1 which is not written by vertex shader");
21024 
21025     ASSERT_NO_FATAL_FAILURE(Init());
21026     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
21027 
21028     char const *vsSource =
21029         "#version 450\n"
21030         "\n"
21031         "out block { layout(location=0, component=0) float x; } outs;\n"
21032         "void main(){\n"
21033         "   outs.x = 0;\n"
21034         "   gl_Position = vec4(1);\n"
21035         "}\n";
21036     char const *fsSource =
21037         "#version 450\n"
21038         "\n"
21039         "in block { layout(location=0, component=1) float x; } ins;\n"
21040         "layout(location=0) out vec4 color;\n"
21041         "void main(){\n"
21042         "   color = vec4(ins.x);\n"
21043         "}\n";
21044 
21045     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
21046     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
21047 
21048     VkPipelineObj pipe(m_device);
21049     pipe.AddDefaultColorAttachment();
21050     pipe.AddShader(&vs);
21051     pipe.AddShader(&fs);
21052 
21053     VkDescriptorSetObj descriptorSet(m_device);
21054     descriptorSet.AppendDummy();
21055     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
21056 
21057     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21058 
21059     m_errorMonitor->VerifyFound();
21060 }
21061 
TEST_F(VkLayerTest,CreatePipelineVsFsMismatchByPrecision)21062 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByPrecision) {
21063     TEST_DESCRIPTION("Test that the RelaxedPrecision decoration is validated to match");
21064 
21065     ASSERT_NO_FATAL_FAILURE(Init());
21066     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
21067 
21068     char const *vsSource =
21069         "#version 450\n"
21070         "layout(location=0) out mediump float x;\n"
21071         "void main() { gl_Position = vec4(0); x = 1.0; }\n";
21072     char const *fsSource =
21073         "#version 450\n"
21074         "layout(location=0) in highp float x;\n"
21075         "layout(location=0) out vec4 color;\n"
21076         "void main() { color = vec4(x); }\n";
21077 
21078     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
21079     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
21080 
21081     VkPipelineObj pipe(m_device);
21082     pipe.AddDefaultColorAttachment();
21083     pipe.AddShader(&vs);
21084     pipe.AddShader(&fs);
21085 
21086     VkDescriptorSetObj descriptorSet(m_device);
21087     descriptorSet.AppendDummy();
21088     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
21089 
21090     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "differ in precision");
21091 
21092     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21093 
21094     m_errorMonitor->VerifyFound();
21095 }
21096 
TEST_F(VkLayerTest,CreatePipelineVsFsMismatchByPrecisionBlock)21097 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByPrecisionBlock) {
21098     TEST_DESCRIPTION("Test that the RelaxedPrecision decoration is validated to match");
21099 
21100     ASSERT_NO_FATAL_FAILURE(Init());
21101     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
21102 
21103     char const *vsSource =
21104         "#version 450\n"
21105         "out block { layout(location=0) mediump float x; };\n"
21106         "void main() { gl_Position = vec4(0); x = 1.0; }\n";
21107     char const *fsSource =
21108         "#version 450\n"
21109         "in block { layout(location=0) highp float x; };\n"
21110         "layout(location=0) out vec4 color;\n"
21111         "void main() { color = vec4(x); }\n";
21112 
21113     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
21114     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
21115 
21116     VkPipelineObj pipe(m_device);
21117     pipe.AddDefaultColorAttachment();
21118     pipe.AddShader(&vs);
21119     pipe.AddShader(&fs);
21120 
21121     VkDescriptorSetObj descriptorSet(m_device);
21122     descriptorSet.AppendDummy();
21123     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
21124 
21125     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "differ in precision");
21126 
21127     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21128 
21129     m_errorMonitor->VerifyFound();
21130 }
21131 
TEST_F(VkLayerTest,CreatePipelineAttribNotConsumed)21132 TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed) {
21133     TEST_DESCRIPTION("Test that a warning is produced for a vertex attribute which is not consumed by the vertex shader");
21134     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by vertex shader");
21135 
21136     ASSERT_NO_FATAL_FAILURE(Init());
21137     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
21138 
21139     VkVertexInputBindingDescription input_binding;
21140     memset(&input_binding, 0, sizeof(input_binding));
21141 
21142     VkVertexInputAttributeDescription input_attrib;
21143     memset(&input_attrib, 0, sizeof(input_attrib));
21144     input_attrib.format = VK_FORMAT_R32_SFLOAT;
21145 
21146     char const *vsSource =
21147         "#version 450\n"
21148         "\n"
21149         "void main(){\n"
21150         "   gl_Position = vec4(1);\n"
21151         "}\n";
21152     char const *fsSource =
21153         "#version 450\n"
21154         "\n"
21155         "layout(location=0) out vec4 color;\n"
21156         "void main(){\n"
21157         "   color = vec4(1);\n"
21158         "}\n";
21159 
21160     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
21161     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
21162 
21163     VkPipelineObj pipe(m_device);
21164     pipe.AddDefaultColorAttachment();
21165     pipe.AddShader(&vs);
21166     pipe.AddShader(&fs);
21167 
21168     pipe.AddVertexInputBindings(&input_binding, 1);
21169     pipe.AddVertexInputAttribs(&input_attrib, 1);
21170 
21171     VkDescriptorSetObj descriptorSet(m_device);
21172     descriptorSet.AppendDummy();
21173     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
21174 
21175     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21176 
21177     m_errorMonitor->VerifyFound();
21178 }
21179 
TEST_F(VkLayerTest,CreatePipelineAttribLocationMismatch)21180 TEST_F(VkLayerTest, CreatePipelineAttribLocationMismatch) {
21181     TEST_DESCRIPTION(
21182         "Test that a warning is produced for a location mismatch on vertex attributes. This flushes out bad behavior in the "
21183         "interface walker");
21184     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by vertex shader");
21185 
21186     ASSERT_NO_FATAL_FAILURE(Init());
21187     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
21188 
21189     VkVertexInputBindingDescription input_binding;
21190     memset(&input_binding, 0, sizeof(input_binding));
21191 
21192     VkVertexInputAttributeDescription input_attrib;
21193     memset(&input_attrib, 0, sizeof(input_attrib));
21194     input_attrib.format = VK_FORMAT_R32_SFLOAT;
21195 
21196     char const *vsSource =
21197         "#version 450\n"
21198         "\n"
21199         "layout(location=1) in float x;\n"
21200         "void main(){\n"
21201         "   gl_Position = vec4(x);\n"
21202         "}\n";
21203     char const *fsSource =
21204         "#version 450\n"
21205         "\n"
21206         "layout(location=0) out vec4 color;\n"
21207         "void main(){\n"
21208         "   color = vec4(1);\n"
21209         "}\n";
21210 
21211     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
21212     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
21213 
21214     VkPipelineObj pipe(m_device);
21215     pipe.AddDefaultColorAttachment();
21216     pipe.AddShader(&vs);
21217     pipe.AddShader(&fs);
21218 
21219     pipe.AddVertexInputBindings(&input_binding, 1);
21220     pipe.AddVertexInputAttribs(&input_attrib, 1);
21221 
21222     VkDescriptorSetObj descriptorSet(m_device);
21223     descriptorSet.AppendDummy();
21224     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
21225 
21226     m_errorMonitor->SetUnexpectedError("Vertex shader consumes input at location 1 but not provided");
21227     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21228 
21229     m_errorMonitor->VerifyFound();
21230 }
21231 
TEST_F(VkLayerTest,CreatePipelineAttribNotProvided)21232 TEST_F(VkLayerTest, CreatePipelineAttribNotProvided) {
21233     TEST_DESCRIPTION("Test that an error is produced for a vertex shader input which is not provided by a vertex attribute");
21234     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
21235                                          "Vertex shader consumes input at location 0 but not provided");
21236 
21237     ASSERT_NO_FATAL_FAILURE(Init());
21238     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
21239 
21240     char const *vsSource =
21241         "#version 450\n"
21242         "\n"
21243         "layout(location=0) in vec4 x;\n" /* not provided */
21244         "void main(){\n"
21245         "   gl_Position = x;\n"
21246         "}\n";
21247     char const *fsSource =
21248         "#version 450\n"
21249         "\n"
21250         "layout(location=0) out vec4 color;\n"
21251         "void main(){\n"
21252         "   color = vec4(1);\n"
21253         "}\n";
21254 
21255     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
21256     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
21257 
21258     VkPipelineObj pipe(m_device);
21259     pipe.AddDefaultColorAttachment();
21260     pipe.AddShader(&vs);
21261     pipe.AddShader(&fs);
21262 
21263     VkDescriptorSetObj descriptorSet(m_device);
21264     descriptorSet.AppendDummy();
21265     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
21266 
21267     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21268 
21269     m_errorMonitor->VerifyFound();
21270 }
21271 
TEST_F(VkLayerTest,CreatePipelineAttribTypeMismatch)21272 TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch) {
21273     TEST_DESCRIPTION(
21274         "Test that an error is produced for a mismatch between the fundamental type (float/int/uint) of an attribute and the "
21275         "vertex shader input that consumes it");
21276     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0 does not match vertex shader input type");
21277 
21278     ASSERT_NO_FATAL_FAILURE(Init());
21279     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
21280 
21281     VkVertexInputBindingDescription input_binding;
21282     memset(&input_binding, 0, sizeof(input_binding));
21283 
21284     VkVertexInputAttributeDescription input_attrib;
21285     memset(&input_attrib, 0, sizeof(input_attrib));
21286     input_attrib.format = VK_FORMAT_R32_SFLOAT;
21287 
21288     char const *vsSource =
21289         "#version 450\n"
21290         "\n"
21291         "layout(location=0) in int x;\n" /* attrib provided float */
21292         "void main(){\n"
21293         "   gl_Position = vec4(x);\n"
21294         "}\n";
21295     char const *fsSource =
21296         "#version 450\n"
21297         "\n"
21298         "layout(location=0) out vec4 color;\n"
21299         "void main(){\n"
21300         "   color = vec4(1);\n"
21301         "}\n";
21302 
21303     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
21304     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
21305 
21306     VkPipelineObj pipe(m_device);
21307     pipe.AddDefaultColorAttachment();
21308     pipe.AddShader(&vs);
21309     pipe.AddShader(&fs);
21310 
21311     pipe.AddVertexInputBindings(&input_binding, 1);
21312     pipe.AddVertexInputAttribs(&input_attrib, 1);
21313 
21314     VkDescriptorSetObj descriptorSet(m_device);
21315     descriptorSet.AppendDummy();
21316     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
21317 
21318     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21319 
21320     m_errorMonitor->VerifyFound();
21321 }
21322 
TEST_F(VkLayerTest,CreatePipelineDuplicateStage)21323 TEST_F(VkLayerTest, CreatePipelineDuplicateStage) {
21324     TEST_DESCRIPTION("Test that an error is produced for a pipeline containing multiple shaders for the same stage");
21325     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
21326                                          "Multiple shaders provided for stage VK_SHADER_STAGE_VERTEX_BIT");
21327 
21328     ASSERT_NO_FATAL_FAILURE(Init());
21329     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
21330 
21331     char const *vsSource =
21332         "#version 450\n"
21333         "\n"
21334         "void main(){\n"
21335         "   gl_Position = vec4(1);\n"
21336         "}\n";
21337     char const *fsSource =
21338         "#version 450\n"
21339         "\n"
21340         "layout(location=0) out vec4 color;\n"
21341         "void main(){\n"
21342         "   color = vec4(1);\n"
21343         "}\n";
21344 
21345     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
21346     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
21347 
21348     VkPipelineObj pipe(m_device);
21349     pipe.AddDefaultColorAttachment();
21350     pipe.AddShader(&vs);
21351     pipe.AddShader(&vs);  // intentionally duplicate vertex shader attachment
21352     pipe.AddShader(&fs);
21353 
21354     VkDescriptorSetObj descriptorSet(m_device);
21355     descriptorSet.AppendDummy();
21356     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
21357 
21358     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21359 
21360     m_errorMonitor->VerifyFound();
21361 }
21362 
TEST_F(VkLayerTest,CreatePipelineMissingEntrypoint)21363 TEST_F(VkLayerTest, CreatePipelineMissingEntrypoint) {
21364     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "No entrypoint found named `foo`");
21365 
21366     ASSERT_NO_FATAL_FAILURE(Init());
21367     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
21368 
21369     char const *vsSource =
21370         "#version 450\n"
21371         "void main(){\n"
21372         "   gl_Position = vec4(0);\n"
21373         "}\n";
21374     char const *fsSource =
21375         "#version 450\n"
21376         "\n"
21377         "layout(location=0) out vec4 color;\n"
21378         "void main(){\n"
21379         "   color = vec4(1);\n"
21380         "}\n";
21381 
21382     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
21383     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this, "foo");
21384 
21385     VkPipelineObj pipe(m_device);
21386     pipe.AddDefaultColorAttachment();
21387     pipe.AddShader(&vs);
21388     pipe.AddShader(&fs);
21389 
21390     VkDescriptorSetObj descriptorSet(m_device);
21391     descriptorSet.AppendDummy();
21392     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
21393 
21394     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21395 
21396     m_errorMonitor->VerifyFound();
21397 }
21398 
TEST_F(VkLayerTest,CreatePipelineDepthStencilRequired)21399 TEST_F(VkLayerTest, CreatePipelineDepthStencilRequired) {
21400     m_errorMonitor->SetDesiredFailureMsg(
21401         VK_DEBUG_REPORT_ERROR_BIT_EXT,
21402         "pDepthStencilState is NULL when rasterization is enabled and subpass uses a depth/stencil attachment");
21403 
21404     ASSERT_NO_FATAL_FAILURE(Init());
21405     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
21406 
21407     char const *vsSource =
21408         "#version 450\n"
21409         "void main(){ gl_Position = vec4(0); }\n";
21410     char const *fsSource =
21411         "#version 450\n"
21412         "\n"
21413         "layout(location=0) out vec4 color;\n"
21414         "void main(){\n"
21415         "   color = vec4(1);\n"
21416         "}\n";
21417 
21418     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
21419     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
21420 
21421     VkPipelineObj pipe(m_device);
21422     pipe.AddDefaultColorAttachment();
21423     pipe.AddShader(&vs);
21424     pipe.AddShader(&fs);
21425 
21426     VkDescriptorSetObj descriptorSet(m_device);
21427     descriptorSet.AppendDummy();
21428     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
21429 
21430     VkAttachmentDescription attachments[] = {
21431         {
21432             0,
21433             VK_FORMAT_B8G8R8A8_UNORM,
21434             VK_SAMPLE_COUNT_1_BIT,
21435             VK_ATTACHMENT_LOAD_OP_DONT_CARE,
21436             VK_ATTACHMENT_STORE_OP_DONT_CARE,
21437             VK_ATTACHMENT_LOAD_OP_DONT_CARE,
21438             VK_ATTACHMENT_STORE_OP_DONT_CARE,
21439             VK_IMAGE_LAYOUT_UNDEFINED,
21440             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
21441         },
21442         {
21443             0,
21444             VK_FORMAT_D16_UNORM,
21445             VK_SAMPLE_COUNT_1_BIT,
21446             VK_ATTACHMENT_LOAD_OP_DONT_CARE,
21447             VK_ATTACHMENT_STORE_OP_DONT_CARE,
21448             VK_ATTACHMENT_LOAD_OP_DONT_CARE,
21449             VK_ATTACHMENT_STORE_OP_DONT_CARE,
21450             VK_IMAGE_LAYOUT_UNDEFINED,
21451             VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
21452         },
21453     };
21454     VkAttachmentReference refs[] = {
21455         {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
21456         {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL},
21457     };
21458     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &refs[0], nullptr, &refs[1], 0, nullptr};
21459     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr};
21460     VkRenderPass rp;
21461     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
21462     ASSERT_VK_SUCCESS(err);
21463 
21464     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), rp);
21465 
21466     m_errorMonitor->VerifyFound();
21467 
21468     vkDestroyRenderPass(m_device->device(), rp, nullptr);
21469 }
21470 
TEST_F(VkLayerTest,CreatePipelineTessPatchDecorationMismatch)21471 TEST_F(VkLayerTest, CreatePipelineTessPatchDecorationMismatch) {
21472     TEST_DESCRIPTION(
21473         "Test that an error is produced for a variable output from the TCS without the patch decoration, but consumed in the TES "
21474         "with the decoration.");
21475     m_errorMonitor->SetDesiredFailureMsg(
21476         VK_DEBUG_REPORT_ERROR_BIT_EXT,
21477         "is per-vertex in tessellation control shader stage but per-patch in tessellation evaluation shader stage");
21478 
21479     ASSERT_NO_FATAL_FAILURE(Init());
21480     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
21481 
21482     if (!m_device->phy().features().tessellationShader) {
21483         printf("%s Device does not support tessellation shaders; skipped.\n", kSkipPrefix);
21484         return;
21485     }
21486 
21487     char const *vsSource =
21488         "#version 450\n"
21489         "void main(){}\n";
21490     char const *tcsSource =
21491         "#version 450\n"
21492         "layout(location=0) out int x[];\n"
21493         "layout(vertices=3) out;\n"
21494         "void main(){\n"
21495         "   gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
21496         "   gl_TessLevelInner[0] = 1;\n"
21497         "   x[gl_InvocationID] = gl_InvocationID;\n"
21498         "}\n";
21499     char const *tesSource =
21500         "#version 450\n"
21501         "layout(triangles, equal_spacing, cw) in;\n"
21502         "layout(location=0) patch in int x;\n"
21503         "void main(){\n"
21504         "   gl_Position.xyz = gl_TessCoord;\n"
21505         "   gl_Position.w = x;\n"
21506         "}\n";
21507     char const *fsSource =
21508         "#version 450\n"
21509         "layout(location=0) out vec4 color;\n"
21510         "void main(){\n"
21511         "   color = vec4(1);\n"
21512         "}\n";
21513 
21514     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
21515     VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
21516     VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
21517     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
21518 
21519     VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
21520                                                  VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
21521 
21522     VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
21523 
21524     VkPipelineObj pipe(m_device);
21525     pipe.SetInputAssembly(&iasci);
21526     pipe.SetTessellation(&tsci);
21527     pipe.AddDefaultColorAttachment();
21528     pipe.AddShader(&vs);
21529     pipe.AddShader(&tcs);
21530     pipe.AddShader(&tes);
21531     pipe.AddShader(&fs);
21532 
21533     VkDescriptorSetObj descriptorSet(m_device);
21534     descriptorSet.AppendDummy();
21535     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
21536 
21537     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21538 
21539     m_errorMonitor->VerifyFound();
21540 }
21541 
TEST_F(VkLayerTest,CreatePipelineTessErrors)21542 TEST_F(VkLayerTest, CreatePipelineTessErrors) {
21543     TEST_DESCRIPTION("Test various errors when creating a graphics pipeline with tessellation stages active.");
21544 
21545     ASSERT_NO_FATAL_FAILURE(Init());
21546     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
21547 
21548     if (!m_device->phy().features().tessellationShader) {
21549         printf("%s Device does not support tessellation shaders; skipped.\n", kSkipPrefix);
21550         return;
21551     }
21552 
21553     char const *vsSource =
21554         "#version 450\n"
21555         "void main(){}\n";
21556     char const *tcsSource =
21557         "#version 450\n"
21558         "layout(vertices=3) out;\n"
21559         "void main(){\n"
21560         "   gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
21561         "   gl_TessLevelInner[0] = 1;\n"
21562         "}\n";
21563     char const *tesSource =
21564         "#version 450\n"
21565         "layout(triangles, equal_spacing, cw) in;\n"
21566         "void main(){\n"
21567         "   gl_Position.xyz = gl_TessCoord;\n"
21568         "   gl_Position.w = 0;\n"
21569         "}\n";
21570     char const *fsSource =
21571         "#version 450\n"
21572         "layout(location=0) out vec4 color;\n"
21573         "void main(){\n"
21574         "   color = vec4(1);\n"
21575         "}\n";
21576 
21577     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
21578     VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
21579     VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
21580     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
21581 
21582     VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
21583                                                  VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
21584 
21585     VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
21586 
21587     VkDescriptorSetObj descriptorSet(m_device);
21588     descriptorSet.AppendDummy();
21589     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
21590 
21591     {
21592         VkPipelineObj pipe(m_device);
21593         VkPipelineInputAssemblyStateCreateInfo iasci_bad = iasci;
21594         iasci_bad.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;  // otherwise we get a failure about invalid topology
21595         pipe.SetInputAssembly(&iasci_bad);
21596         pipe.AddDefaultColorAttachment();
21597         pipe.AddShader(&vs);
21598         pipe.AddShader(&fs);
21599 
21600         // Pass a tess control shader without a tess eval shader
21601         pipe.AddShader(&tcs);
21602         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGraphicsPipelineCreateInfo-pStages-00729");
21603         pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21604         m_errorMonitor->VerifyFound();
21605     }
21606 
21607     {
21608         VkPipelineObj pipe(m_device);
21609         VkPipelineInputAssemblyStateCreateInfo iasci_bad = iasci;
21610         iasci_bad.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;  // otherwise we get a failure about invalid topology
21611         pipe.SetInputAssembly(&iasci_bad);
21612         pipe.AddDefaultColorAttachment();
21613         pipe.AddShader(&vs);
21614         pipe.AddShader(&fs);
21615 
21616         // Pass a tess eval shader without a tess control shader
21617         pipe.AddShader(&tes);
21618         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGraphicsPipelineCreateInfo-pStages-00730");
21619         pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21620         m_errorMonitor->VerifyFound();
21621     }
21622 
21623     {
21624         VkPipelineObj pipe(m_device);
21625         pipe.SetInputAssembly(&iasci);
21626         pipe.AddDefaultColorAttachment();
21627         pipe.AddShader(&vs);
21628         pipe.AddShader(&fs);
21629 
21630         // Pass patch topology without tessellation shaders
21631         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGraphicsPipelineCreateInfo-topology-00737");
21632         pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21633         m_errorMonitor->VerifyFound();
21634 
21635         pipe.AddShader(&tcs);
21636         pipe.AddShader(&tes);
21637         // Pass a NULL pTessellationState (with active tessellation shader stages)
21638         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGraphicsPipelineCreateInfo-pStages-00731");
21639         pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21640         m_errorMonitor->VerifyFound();
21641 
21642         // Pass an invalid pTessellationState (bad sType)
21643         VkPipelineTessellationStateCreateInfo tsci_bad = tsci;
21644         tsci_bad.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
21645         pipe.SetTessellation(&tsci_bad);
21646         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
21647                                              "VUID-VkPipelineTessellationStateCreateInfo-sType-sType");
21648         pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21649         m_errorMonitor->VerifyFound();
21650         // Pass out-of-range patchControlPoints
21651         tsci_bad = tsci;
21652         tsci_bad.patchControlPoints = 0;
21653         pipe.SetTessellation(&tsci);
21654         pipe.SetTessellation(&tsci_bad);
21655         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
21656                                              "VUID-VkPipelineTessellationStateCreateInfo-patchControlPoints-01214");
21657         pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21658         m_errorMonitor->VerifyFound();
21659         tsci_bad.patchControlPoints = m_device->props.limits.maxTessellationPatchSize + 1;
21660         pipe.SetTessellation(&tsci_bad);
21661         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
21662                                              "VUID-VkPipelineTessellationStateCreateInfo-patchControlPoints-01214");
21663         pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21664         m_errorMonitor->VerifyFound();
21665         pipe.SetTessellation(&tsci);
21666 
21667         // Pass an invalid primitive topology
21668         VkPipelineInputAssemblyStateCreateInfo iasci_bad = iasci;
21669         iasci_bad.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
21670         pipe.SetInputAssembly(&iasci_bad);
21671         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGraphicsPipelineCreateInfo-pStages-00736");
21672         pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21673         m_errorMonitor->VerifyFound();
21674         pipe.SetInputAssembly(&iasci);
21675     }
21676 }
21677 
TEST_F(VkLayerTest,CreatePipelineAttribBindingConflict)21678 TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict) {
21679     TEST_DESCRIPTION(
21680         "Test that an error is produced for a vertex attribute setup where multiple bindings provide the same location");
21681     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
21682                                          "Duplicate vertex input binding descriptions for binding 0");
21683 
21684     ASSERT_NO_FATAL_FAILURE(Init());
21685     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
21686 
21687     /* Two binding descriptions for binding 0 */
21688     VkVertexInputBindingDescription input_bindings[2];
21689     memset(input_bindings, 0, sizeof(input_bindings));
21690 
21691     VkVertexInputAttributeDescription input_attrib;
21692     memset(&input_attrib, 0, sizeof(input_attrib));
21693     input_attrib.format = VK_FORMAT_R32_SFLOAT;
21694 
21695     char const *vsSource =
21696         "#version 450\n"
21697         "\n"
21698         "layout(location=0) in float x;\n" /* attrib provided float */
21699         "void main(){\n"
21700         "   gl_Position = vec4(x);\n"
21701         "}\n";
21702     char const *fsSource =
21703         "#version 450\n"
21704         "\n"
21705         "layout(location=0) out vec4 color;\n"
21706         "void main(){\n"
21707         "   color = vec4(1);\n"
21708         "}\n";
21709 
21710     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
21711     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
21712 
21713     VkPipelineObj pipe(m_device);
21714     pipe.AddDefaultColorAttachment();
21715     pipe.AddShader(&vs);
21716     pipe.AddShader(&fs);
21717 
21718     pipe.AddVertexInputBindings(input_bindings, 2);
21719     pipe.AddVertexInputAttribs(&input_attrib, 1);
21720 
21721     VkDescriptorSetObj descriptorSet(m_device);
21722     descriptorSet.AppendDummy();
21723     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
21724 
21725     m_errorMonitor->SetUnexpectedError("VUID-VkPipelineVertexInputStateCreateInfo-pVertexBindingDescriptions-00616 ");
21726     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21727 
21728     m_errorMonitor->VerifyFound();
21729 }
21730 
TEST_F(VkLayerTest,CreatePipelineFragmentOutputNotWritten)21731 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten) {
21732     TEST_DESCRIPTION(
21733         "Test that an error is produced for a fragment shader which does not provide an output for one of the pipeline's color "
21734         "attachments");
21735     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "Attachment 0 not written by fragment shader");
21736 
21737     ASSERT_NO_FATAL_FAILURE(Init());
21738 
21739     char const *vsSource =
21740         "#version 450\n"
21741         "\n"
21742         "void main(){\n"
21743         "   gl_Position = vec4(1);\n"
21744         "}\n";
21745     char const *fsSource =
21746         "#version 450\n"
21747         "\n"
21748         "void main(){\n"
21749         "}\n";
21750 
21751     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
21752     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
21753 
21754     VkPipelineObj pipe(m_device);
21755     pipe.AddShader(&vs);
21756     pipe.AddShader(&fs);
21757 
21758     /* set up CB 0, not written */
21759     pipe.AddDefaultColorAttachment();
21760     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
21761 
21762     VkDescriptorSetObj descriptorSet(m_device);
21763     descriptorSet.AppendDummy();
21764     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
21765 
21766     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21767 
21768     m_errorMonitor->VerifyFound();
21769 }
21770 
TEST_F(VkPositiveLayerTest,CreatePipelineFragmentOutputNotWrittenButMasked)21771 TEST_F(VkPositiveLayerTest, CreatePipelineFragmentOutputNotWrittenButMasked) {
21772     TEST_DESCRIPTION(
21773         "Test that no error is produced when the fragment shader fails to declare an output, but the corresponding attachment's "
21774         "write mask is 0.");
21775     m_errorMonitor->ExpectSuccess();
21776 
21777     ASSERT_NO_FATAL_FAILURE(Init());
21778 
21779     char const *vsSource =
21780         "#version 450\n"
21781         "\n"
21782         "void main(){\n"
21783         "   gl_Position = vec4(1);\n"
21784         "}\n";
21785     char const *fsSource =
21786         "#version 450\n"
21787         "\n"
21788         "void main(){\n"
21789         "}\n";
21790 
21791     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
21792     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
21793 
21794     VkPipelineObj pipe(m_device);
21795     pipe.AddShader(&vs);
21796     pipe.AddShader(&fs);
21797 
21798     /* set up CB 0, not written, but also masked */
21799     pipe.AddDefaultColorAttachment(0);
21800     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
21801 
21802     VkDescriptorSetObj descriptorSet(m_device);
21803     descriptorSet.AppendDummy();
21804     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
21805 
21806     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21807 
21808     m_errorMonitor->VerifyNotFound();
21809 }
21810 
TEST_F(VkLayerTest,CreatePipelineFragmentOutputNotConsumed)21811 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed) {
21812     TEST_DESCRIPTION(
21813         "Test that a warning is produced for a fragment shader which provides a spurious output with no matching attachment");
21814     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
21815                                          "fragment shader writes to output location 1 with no matching attachment");
21816 
21817     ASSERT_NO_FATAL_FAILURE(Init());
21818 
21819     char const *vsSource =
21820         "#version 450\n"
21821         "\n"
21822         "void main(){\n"
21823         "   gl_Position = vec4(1);\n"
21824         "}\n";
21825     char const *fsSource =
21826         "#version 450\n"
21827         "\n"
21828         "layout(location=0) out vec4 x;\n"
21829         "layout(location=1) out vec4 y;\n" /* no matching attachment for this */
21830         "void main(){\n"
21831         "   x = vec4(1);\n"
21832         "   y = vec4(1);\n"
21833         "}\n";
21834 
21835     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
21836     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
21837 
21838     VkPipelineObj pipe(m_device);
21839     pipe.AddShader(&vs);
21840     pipe.AddShader(&fs);
21841 
21842     /* set up CB 0, not written */
21843     pipe.AddDefaultColorAttachment();
21844     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
21845     /* FS writes CB 1, but we don't configure it */
21846 
21847     VkDescriptorSetObj descriptorSet(m_device);
21848     descriptorSet.AppendDummy();
21849     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
21850 
21851     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21852 
21853     m_errorMonitor->VerifyFound();
21854 }
21855 
TEST_F(VkLayerTest,CreatePipelineFragmentOutputNotConsumedButAlphaToCoverageEnabled)21856 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumedButAlphaToCoverageEnabled) {
21857     TEST_DESCRIPTION(
21858         "Test that no warning is produced when writing to non-existing color attachment if alpha to coverage is enabled.");
21859 
21860     m_errorMonitor->ExpectSuccess(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT);
21861 
21862     ASSERT_NO_FATAL_FAILURE(Init());
21863 
21864     char const *vsSource =
21865         "#version 450\n"
21866         "\n"
21867         "void main(){\n"
21868         "   gl_Position = vec4(1);\n"
21869         "}\n";
21870     char const *fsSource =
21871         "#version 450\n"
21872         "\n"
21873         "layout(location=0) out vec4 x;\n"
21874         "void main(){\n"
21875         "   x = vec4(1);\n"
21876         "}\n";
21877 
21878     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
21879     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
21880 
21881     VkPipelineObj pipe(m_device);
21882     pipe.AddShader(&vs);
21883     pipe.AddShader(&fs);
21884 
21885     VkPipelineMultisampleStateCreateInfo ms_state_ci = {};
21886     ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
21887     ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
21888     ms_state_ci.alphaToCoverageEnable = VK_TRUE;
21889     pipe.SetMSAA(&ms_state_ci);
21890 
21891     ASSERT_NO_FATAL_FAILURE(InitRenderTarget(0u));
21892 
21893     VkDescriptorSetObj descriptorSet(m_device);
21894     descriptorSet.AppendDummy();
21895     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
21896 
21897     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21898 
21899     m_errorMonitor->VerifyNotFound();
21900 }
21901 
TEST_F(VkLayerTest,CreatePipelineFragmentNoOutputLocation0ButAlphaToCoverageEnabled)21902 TEST_F(VkLayerTest, CreatePipelineFragmentNoOutputLocation0ButAlphaToCoverageEnabled) {
21903     TEST_DESCRIPTION("Test that an error is produced when alpha to coverage is enabled but no output at location 0 is declared.");
21904 
21905     m_errorMonitor->SetDesiredFailureMsg(
21906         VK_DEBUG_REPORT_ERROR_BIT_EXT,
21907         "fragment shader doesn't declare alpha output at location 0 even though alpha to coverage is enabled.");
21908 
21909     ASSERT_NO_FATAL_FAILURE(Init());
21910 
21911     char const *vsSource =
21912         "#version 450\n"
21913         "\n"
21914         "void main(){\n"
21915         "   gl_Position = vec4(1);\n"
21916         "}\n";
21917     char const *fsSource =
21918         "#version 450\n"
21919         "\n"
21920         "void main(){\n"
21921         "}\n";
21922 
21923     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
21924     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
21925 
21926     VkPipelineObj pipe(m_device);
21927     pipe.AddShader(&vs);
21928     pipe.AddShader(&fs);
21929 
21930     VkPipelineMultisampleStateCreateInfo ms_state_ci = {};
21931     ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
21932     ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
21933     ms_state_ci.alphaToCoverageEnable = VK_TRUE;
21934     pipe.SetMSAA(&ms_state_ci);
21935 
21936     ASSERT_NO_FATAL_FAILURE(InitRenderTarget(0u));
21937 
21938     VkDescriptorSetObj descriptorSet(m_device);
21939     descriptorSet.AppendDummy();
21940     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
21941 
21942     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21943 
21944     m_errorMonitor->VerifyFound();
21945 }
21946 
TEST_F(VkLayerTest,CreatePipelineFragmentNoAlphaLocation0ButAlphaToCoverageEnabled)21947 TEST_F(VkLayerTest, CreatePipelineFragmentNoAlphaLocation0ButAlphaToCoverageEnabled) {
21948     TEST_DESCRIPTION(
21949         "Test that an error is produced when alpha to coverage is enabled but output at location 0 doesn't have alpha channel.");
21950 
21951     m_errorMonitor->SetDesiredFailureMsg(
21952         VK_DEBUG_REPORT_ERROR_BIT_EXT,
21953         "fragment shader doesn't declare alpha output at location 0 even though alpha to coverage is enabled.");
21954 
21955     ASSERT_NO_FATAL_FAILURE(Init());
21956 
21957     char const *vsSource =
21958         "#version 450\n"
21959         "\n"
21960         "void main(){\n"
21961         "   gl_Position = vec4(1);\n"
21962         "}\n";
21963     char const *fsSource =
21964         "#version 450\n"
21965         "layout(location=0) out vec3 x;\n"
21966         "\n"
21967         "void main(){\n"
21968         "   x = vec3(1);\n"
21969         "}\n";
21970 
21971     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
21972     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
21973 
21974     VkPipelineObj pipe(m_device);
21975     pipe.AddShader(&vs);
21976     pipe.AddShader(&fs);
21977 
21978     VkPipelineMultisampleStateCreateInfo ms_state_ci = {};
21979     ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
21980     ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
21981     ms_state_ci.alphaToCoverageEnable = VK_TRUE;
21982     pipe.SetMSAA(&ms_state_ci);
21983 
21984     ASSERT_NO_FATAL_FAILURE(InitRenderTarget(0u));
21985 
21986     VkDescriptorSetObj descriptorSet(m_device);
21987     descriptorSet.AppendDummy();
21988     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
21989 
21990     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
21991 
21992     m_errorMonitor->VerifyFound();
21993 }
21994 
TEST_F(VkLayerTest,CreatePipelineFragmentOutputTypeMismatch)21995 TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch) {
21996     TEST_DESCRIPTION(
21997         "Test that an error is produced for a mismatch between the fundamental type of an fragment shader output variable, and the "
21998         "format of the corresponding attachment");
21999     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "does not match fragment shader output type");
22000 
22001     ASSERT_NO_FATAL_FAILURE(Init());
22002 
22003     char const *vsSource =
22004         "#version 450\n"
22005         "\n"
22006         "void main(){\n"
22007         "   gl_Position = vec4(1);\n"
22008         "}\n";
22009     char const *fsSource =
22010         "#version 450\n"
22011         "\n"
22012         "layout(location=0) out ivec4 x;\n" /* not UNORM */
22013         "void main(){\n"
22014         "   x = ivec4(1);\n"
22015         "}\n";
22016 
22017     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
22018     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
22019 
22020     VkPipelineObj pipe(m_device);
22021     pipe.AddShader(&vs);
22022     pipe.AddShader(&fs);
22023 
22024     /* set up CB 0; type is UNORM by default */
22025     pipe.AddDefaultColorAttachment();
22026     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
22027 
22028     VkDescriptorSetObj descriptorSet(m_device);
22029     descriptorSet.AppendDummy();
22030     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
22031 
22032     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
22033 
22034     m_errorMonitor->VerifyFound();
22035 }
22036 
TEST_F(VkLayerTest,CreatePipelineExceedMaxVertexOutputComponents)22037 TEST_F(VkLayerTest, CreatePipelineExceedMaxVertexOutputComponents) {
22038     TEST_DESCRIPTION(
22039         "Test that an error is produced when the number of output components from the vertex stage exceeds the device limit");
22040     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
22041                                          "Vertex shader exceeds "
22042                                          "VkPhysicalDeviceLimits::maxVertexOutputComponents");
22043 
22044     ASSERT_NO_FATAL_FAILURE(Init());
22045 
22046     const uint32_t maxVsOutComp = m_device->props.limits.maxVertexOutputComponents;
22047     std::string vsSourceStr = "#version 450\n\n";
22048     const uint32_t numVec4 = maxVsOutComp / 4;
22049     uint32_t location = 0;
22050     for (uint32_t i = 0; i < numVec4; i++) {
22051         vsSourceStr += "layout(location=" + std::to_string(location) + ") out vec4 v" + std::to_string(i) + ";\n";
22052         location += 1;
22053     }
22054     const uint32_t remainder = maxVsOutComp % 4;
22055     if (remainder != 0) {
22056         if (remainder == 1) {
22057             vsSourceStr += "layout(location=" + std::to_string(location) + ") out float" + " vn;\n";
22058         } else {
22059             vsSourceStr += "layout(location=" + std::to_string(location) + ") out vec" + std::to_string(remainder) + " vn;\n";
22060         }
22061         location += 1;
22062     }
22063     vsSourceStr += "layout(location=" + std::to_string(location) +
22064                    ") out vec4 exceedLimit;\n"
22065                    "\n"
22066                    "void main(){\n"
22067                    "    gl_Position = vec4(1);\n"
22068                    "}\n";
22069 
22070     std::string fsSourceStr =
22071         "#version 450\n"
22072         "\n"
22073         "layout(location=0) out vec4 color;\n"
22074         "\n"
22075         "void main(){\n"
22076         "    color = vec4(1);\n"
22077         "}\n";
22078 
22079     VkShaderObj vs(m_device, vsSourceStr.c_str(), VK_SHADER_STAGE_VERTEX_BIT, this);
22080     VkShaderObj fs(m_device, fsSourceStr.c_str(), VK_SHADER_STAGE_FRAGMENT_BIT, this);
22081 
22082     VkPipelineObj pipe(m_device);
22083     pipe.AddShader(&vs);
22084     pipe.AddShader(&fs);
22085 
22086     // Set up CB 0; type is UNORM by default
22087     pipe.AddDefaultColorAttachment();
22088     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
22089 
22090     VkDescriptorSetObj descriptorSet(m_device);
22091     descriptorSet.AppendDummy();
22092     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
22093 
22094     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
22095 
22096     m_errorMonitor->VerifyFound();
22097 }
22098 
TEST_F(VkLayerTest,CreatePipelineExceedMaxTessellationControlInputOutputComponents)22099 TEST_F(VkLayerTest, CreatePipelineExceedMaxTessellationControlInputOutputComponents) {
22100     TEST_DESCRIPTION(
22101         "Test that errors are produced when the number of per-vertex input and/or output components to the tessellation control "
22102         "stage exceeds the device limit");
22103     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
22104                                          "Tessellation control shader exceeds "
22105                                          "VkPhysicalDeviceLimits::maxTessellationControlPerVertexInputComponents");
22106     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
22107                                          "Tessellation control shader exceeds "
22108                                          "VkPhysicalDeviceLimits::maxTessellationControlPerVertexOutputComponents");
22109 
22110     ASSERT_NO_FATAL_FAILURE(Init());
22111 
22112     VkPhysicalDeviceFeatures feat;
22113     vkGetPhysicalDeviceFeatures(gpu(), &feat);
22114     if (!feat.tessellationShader) {
22115         printf("%s tessellation shader stage(s) unsupported.\n", kSkipPrefix);
22116         return;
22117     }
22118 
22119     std::string vsSourceStr =
22120         "#version 450\n"
22121         "\n"
22122         "void main(){\n"
22123         "    gl_Position = vec4(1);\n"
22124         "}\n";
22125 
22126     // Tessellation control stage
22127     std::string tcsSourceStr =
22128         "#version 450\n"
22129         "\n";
22130     // Input components
22131     const uint32_t maxTescInComp = m_device->props.limits.maxTessellationControlPerVertexInputComponents;
22132     const uint32_t numInVec4 = maxTescInComp / 4;
22133     uint32_t inLocation = 0;
22134     for (uint32_t i = 0; i < numInVec4; i++) {
22135         tcsSourceStr += "layout(location=" + std::to_string(inLocation) + ") in vec4 v" + std::to_string(i) + "In[];\n";
22136         inLocation += 1;
22137     }
22138     const uint32_t inRemainder = maxTescInComp % 4;
22139     if (inRemainder != 0) {
22140         if (inRemainder == 1) {
22141             tcsSourceStr += "layout(location=" + std::to_string(inLocation) + ") in float" + " vnIn[];\n";
22142         } else {
22143             tcsSourceStr +=
22144                 "layout(location=" + std::to_string(inLocation) + ") in vec" + std::to_string(inRemainder) + " vnIn[];\n";
22145         }
22146         inLocation += 1;
22147     }
22148     tcsSourceStr += "layout(location=" + std::to_string(inLocation) + ") in vec4 exceedLimitIn[];\n\n";
22149     // Output components
22150     const uint32_t maxTescOutComp = m_device->props.limits.maxTessellationControlPerVertexOutputComponents;
22151     const uint32_t numOutVec4 = maxTescOutComp / 4;
22152     uint32_t outLocation = 0;
22153     for (uint32_t i = 0; i < numOutVec4; i++) {
22154         tcsSourceStr += "layout(location=" + std::to_string(outLocation) + ") out vec4 v" + std::to_string(i) + "Out[3];\n";
22155         outLocation += 1;
22156     }
22157     const uint32_t outRemainder = maxTescOutComp % 4;
22158     if (outRemainder != 0) {
22159         if (outRemainder == 1) {
22160             tcsSourceStr += "layout(location=" + std::to_string(outLocation) + ") out float" + " vnOut[3];\n";
22161         } else {
22162             tcsSourceStr +=
22163                 "layout(location=" + std::to_string(outLocation) + ") out vec" + std::to_string(outRemainder) + " vnOut[3];\n";
22164         }
22165         outLocation += 1;
22166     }
22167     tcsSourceStr += "layout(location=" + std::to_string(outLocation) + ") out vec4 exceedLimitOut[3];\n";
22168     tcsSourceStr += "layout(vertices=3) out;\n";
22169     // Finalize
22170     tcsSourceStr +=
22171         "\n"
22172         "void main(){\n"
22173         "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
22174         "}\n";
22175 
22176     std::string tesSourceStr =
22177         "#version 450\n"
22178         "\n"
22179         "layout(triangles) in;"
22180         "\n"
22181         "void main(){\n"
22182         "    gl_Position = vec4(1);\n"
22183         "}\n";
22184 
22185     std::string fsSourceStr =
22186         "#version 450\n"
22187         "\n"
22188         "layout(location=0) out vec4 color;"
22189         "\n"
22190         "void main(){\n"
22191         "    color = vec4(1);\n"
22192         "}\n";
22193 
22194     VkShaderObj vs(m_device, vsSourceStr.c_str(), VK_SHADER_STAGE_VERTEX_BIT, this);
22195     VkShaderObj tcs(m_device, tcsSourceStr.c_str(), VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
22196     VkShaderObj tes(m_device, tesSourceStr.c_str(), VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
22197     VkShaderObj fs(m_device, fsSourceStr.c_str(), VK_SHADER_STAGE_FRAGMENT_BIT, this);
22198 
22199     VkPipelineObj pipe(m_device);
22200     pipe.AddShader(&vs);
22201     pipe.AddShader(&tcs);
22202     pipe.AddShader(&tes);
22203     pipe.AddShader(&fs);
22204 
22205     // Set up CB 0; type is UNORM by default
22206     pipe.AddDefaultColorAttachment();
22207     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
22208 
22209     VkDescriptorSetObj descriptorSet(m_device);
22210     descriptorSet.AppendDummy();
22211     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
22212 
22213     VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo = {};
22214     inputAssemblyInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
22215     inputAssemblyInfo.pNext = NULL;
22216     inputAssemblyInfo.flags = 0;
22217     inputAssemblyInfo.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
22218     inputAssemblyInfo.primitiveRestartEnable = VK_FALSE;
22219     pipe.SetInputAssembly(&inputAssemblyInfo);
22220 
22221     VkPipelineTessellationStateCreateInfo tessInfo = {};
22222     tessInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
22223     tessInfo.pNext = NULL;
22224     tessInfo.flags = 0;
22225     tessInfo.patchControlPoints = 3;
22226     pipe.SetTessellation(&tessInfo);
22227 
22228     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
22229 
22230     m_errorMonitor->VerifyFound();
22231 }
22232 
TEST_F(VkLayerTest,CreatePipelineExceedMaxTessellationEvaluationInputOutputComponents)22233 TEST_F(VkLayerTest, CreatePipelineExceedMaxTessellationEvaluationInputOutputComponents) {
22234     TEST_DESCRIPTION(
22235         "Test that errors are produced when the number of input and/or output components to the tessellation evaluation stage "
22236         "exceeds the device limit");
22237     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
22238                                          "Tessellation evaluation shader exceeds "
22239                                          "VkPhysicalDeviceLimits::maxTessellationEvaluationInputComponents");
22240     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
22241                                          "Tessellation evaluation shader exceeds "
22242                                          "VkPhysicalDeviceLimits::maxTessellationEvaluationOutputComponents");
22243 
22244     ASSERT_NO_FATAL_FAILURE(Init());
22245 
22246     VkPhysicalDeviceFeatures feat;
22247     vkGetPhysicalDeviceFeatures(gpu(), &feat);
22248     if (!feat.tessellationShader) {
22249         printf("%s tessellation shader stage(s) unsupported.\n", kSkipPrefix);
22250         return;
22251     }
22252 
22253     std::string vsSourceStr =
22254         "#version 450\n"
22255         "\n"
22256         "void main(){\n"
22257         "    gl_Position = vec4(1);\n"
22258         "}\n";
22259 
22260     std::string tcsSourceStr =
22261         "#version 450\n"
22262         "\n"
22263         "layout (vertices = 3) out;\n"
22264         "\n"
22265         "void main(){\n"
22266         "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
22267         "}\n";
22268 
22269     // Tessellation evaluation stage
22270     std::string tesSourceStr =
22271         "#version 450\n"
22272         "\n"
22273         "layout (triangles) in;\n"
22274         "\n";
22275     // Input components
22276     const uint32_t maxTeseInComp = m_device->props.limits.maxTessellationEvaluationInputComponents;
22277     const uint32_t numInVec4 = maxTeseInComp / 4;
22278     uint32_t inLocation = 0;
22279     for (uint32_t i = 0; i < numInVec4; i++) {
22280         tesSourceStr += "layout(location=" + std::to_string(inLocation) + ") in vec4 v" + std::to_string(i) + "In[];\n";
22281         inLocation += 1;
22282     }
22283     const uint32_t inRemainder = maxTeseInComp % 4;
22284     if (inRemainder != 0) {
22285         if (inRemainder == 1) {
22286             tesSourceStr += "layout(location=" + std::to_string(inLocation) + ") in float" + " vnIn[];\n";
22287         } else {
22288             tesSourceStr +=
22289                 "layout(location=" + std::to_string(inLocation) + ") in vec" + std::to_string(inRemainder) + " vnIn[];\n";
22290         }
22291         inLocation += 1;
22292     }
22293     tesSourceStr += "layout(location=" + std::to_string(inLocation) + ") in vec4 exceedLimitIn[];\n\n";
22294     // Output components
22295     const uint32_t maxTeseOutComp = m_device->props.limits.maxTessellationEvaluationOutputComponents;
22296     const uint32_t numOutVec4 = maxTeseOutComp / 4;
22297     uint32_t outLocation = 0;
22298     for (uint32_t i = 0; i < numOutVec4; i++) {
22299         tesSourceStr += "layout(location=" + std::to_string(outLocation) + ") out vec4 v" + std::to_string(i) + "Out;\n";
22300         outLocation += 1;
22301     }
22302     const uint32_t outRemainder = maxTeseOutComp % 4;
22303     if (outRemainder != 0) {
22304         if (outRemainder == 1) {
22305             tesSourceStr += "layout(location=" + std::to_string(outLocation) + ") out float" + " vnOut;\n";
22306         } else {
22307             tesSourceStr +=
22308                 "layout(location=" + std::to_string(outLocation) + ") out vec" + std::to_string(outRemainder) + " vnOut;\n";
22309         }
22310         outLocation += 1;
22311     }
22312     tesSourceStr += "layout(location=" + std::to_string(outLocation) + ") out vec4 exceedLimitOut;\n";
22313     // Finalize
22314     tesSourceStr +=
22315         "\n"
22316         "void main(){\n"
22317         "    gl_Position = vec4(1);\n"
22318         "}\n";
22319 
22320     std::string fsSourceStr =
22321         "#version 450\n"
22322         "\n"
22323         "layout(location=0) out vec4 color;"
22324         "\n"
22325         "void main(){\n"
22326         "    color = vec4(1);\n"
22327         "}\n";
22328 
22329     VkShaderObj vs(m_device, vsSourceStr.c_str(), VK_SHADER_STAGE_VERTEX_BIT, this);
22330     VkShaderObj tcs(m_device, tcsSourceStr.c_str(), VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
22331     VkShaderObj tes(m_device, tesSourceStr.c_str(), VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
22332     VkShaderObj fs(m_device, fsSourceStr.c_str(), VK_SHADER_STAGE_FRAGMENT_BIT, this);
22333 
22334     VkPipelineObj pipe(m_device);
22335     pipe.AddShader(&vs);
22336     pipe.AddShader(&tcs);
22337     pipe.AddShader(&tes);
22338     pipe.AddShader(&fs);
22339 
22340     // Set up CB 0; type is UNORM by default
22341     pipe.AddDefaultColorAttachment();
22342     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
22343 
22344     VkDescriptorSetObj descriptorSet(m_device);
22345     descriptorSet.AppendDummy();
22346     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
22347 
22348     VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo = {};
22349     inputAssemblyInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
22350     inputAssemblyInfo.pNext = NULL;
22351     inputAssemblyInfo.flags = 0;
22352     inputAssemblyInfo.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
22353     inputAssemblyInfo.primitiveRestartEnable = VK_FALSE;
22354     pipe.SetInputAssembly(&inputAssemblyInfo);
22355 
22356     VkPipelineTessellationStateCreateInfo tessInfo = {};
22357     tessInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
22358     tessInfo.pNext = NULL;
22359     tessInfo.flags = 0;
22360     tessInfo.patchControlPoints = 3;
22361     pipe.SetTessellation(&tessInfo);
22362 
22363     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
22364 
22365     m_errorMonitor->VerifyFound();
22366 }
22367 
TEST_F(VkLayerTest,CreatePipelineExceedMaxGeometryInputOutputComponents)22368 TEST_F(VkLayerTest, CreatePipelineExceedMaxGeometryInputOutputComponents) {
22369     TEST_DESCRIPTION(
22370         "Test that errors are produced when the number of input and/or output components to the geometry stage exceeds the device "
22371         "limit");
22372     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
22373                                          "Geometry shader exceeds "
22374                                          "VkPhysicalDeviceLimits::maxGeometryInputComponents");
22375     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
22376                                          "Geometry shader exceeds "
22377                                          "VkPhysicalDeviceLimits::maxGeometryOutputComponents");
22378 
22379     ASSERT_NO_FATAL_FAILURE(Init());
22380 
22381     VkPhysicalDeviceFeatures feat;
22382     vkGetPhysicalDeviceFeatures(gpu(), &feat);
22383     if (!feat.geometryShader) {
22384         printf("%s geometry shader stage unsupported.\n", kSkipPrefix);
22385         return;
22386     }
22387 
22388     std::string vsSourceStr =
22389         "#version 450\n"
22390         "\n"
22391         "void main(){\n"
22392         "    gl_Position = vec4(1);\n"
22393         "}\n";
22394 
22395     std::string gsSourceStr =
22396         "#version 450\n"
22397         "\n"
22398         "layout(triangles) in;\n"
22399         "layout(invocations=1) in;\n";
22400     // Input components
22401     const uint32_t maxGeomInComp = m_device->props.limits.maxGeometryInputComponents;
22402     const uint32_t numInVec4 = maxGeomInComp / 4;
22403     uint32_t inLocation = 0;
22404     for (uint32_t i = 0; i < numInVec4; i++) {
22405         gsSourceStr += "layout(location=" + std::to_string(inLocation) + ") in vec4 v" + std::to_string(i) + "In[];\n";
22406         inLocation += 1;
22407     }
22408     const uint32_t inRemainder = maxGeomInComp % 4;
22409     if (inRemainder != 0) {
22410         if (inRemainder == 1) {
22411             gsSourceStr += "layout(location=" + std::to_string(inLocation) + ") in float" + " vnIn[];\n";
22412         } else {
22413             gsSourceStr +=
22414                 "layout(location=" + std::to_string(inLocation) + ") in vec" + std::to_string(inRemainder) + " vnIn[];\n";
22415         }
22416         inLocation += 1;
22417     }
22418     gsSourceStr += "layout(location=" + std::to_string(inLocation) + ") in vec4 exceedLimitIn[];\n\n";
22419     // Output components
22420     const uint32_t maxGeomOutComp = m_device->props.limits.maxGeometryOutputComponents;
22421     const uint32_t numOutVec4 = maxGeomOutComp / 4;
22422     uint32_t outLocation = 0;
22423     for (uint32_t i = 0; i < numOutVec4; i++) {
22424         gsSourceStr += "layout(location=" + std::to_string(outLocation) + ") out vec4 v" + std::to_string(i) + "Out;\n";
22425         outLocation += 1;
22426     }
22427     const uint32_t outRemainder = maxGeomOutComp % 4;
22428     if (outRemainder != 0) {
22429         if (outRemainder == 1) {
22430             gsSourceStr += "layout(location=" + std::to_string(outLocation) + ") out float" + " vnOut;\n";
22431         } else {
22432             gsSourceStr +=
22433                 "layout(location=" + std::to_string(outLocation) + ") out vec" + std::to_string(outRemainder) + " vnOut;\n";
22434         }
22435         outLocation += 1;
22436     }
22437     gsSourceStr += "layout(location=" + std::to_string(outLocation) + ") out vec4 exceedLimitOut;\n";
22438     // Finalize
22439     gsSourceStr +=
22440         "layout(triangle_strip, max_vertices=3) out;\n"
22441         "\n"
22442         "void main(){\n"
22443         "    exceedLimitOut = vec4(1);\n"
22444         "}\n";
22445 
22446     std::string fsSourceStr =
22447         "#version 450\n"
22448         "\n"
22449         "layout(location=0) out vec4 color;"
22450         "\n"
22451         "void main(){\n"
22452         "    color = vec4(1);\n"
22453         "}\n";
22454 
22455     VkShaderObj vs(m_device, vsSourceStr.c_str(), VK_SHADER_STAGE_VERTEX_BIT, this);
22456     VkShaderObj gs(m_device, gsSourceStr.c_str(), VK_SHADER_STAGE_GEOMETRY_BIT, this);
22457     VkShaderObj fs(m_device, fsSourceStr.c_str(), VK_SHADER_STAGE_FRAGMENT_BIT, this);
22458 
22459     VkPipelineObj pipe(m_device);
22460     pipe.AddShader(&vs);
22461     pipe.AddShader(&gs);
22462     pipe.AddShader(&fs);
22463 
22464     // Set up CB 0; type is UNORM by default
22465     pipe.AddDefaultColorAttachment();
22466     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
22467 
22468     VkDescriptorSetObj descriptorSet(m_device);
22469     descriptorSet.AppendDummy();
22470     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
22471 
22472     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
22473     m_errorMonitor->VerifyFound();
22474 }
22475 
TEST_F(VkLayerTest,CreatePipelineExceedMaxFragmentInputComponents)22476 TEST_F(VkLayerTest, CreatePipelineExceedMaxFragmentInputComponents) {
22477     TEST_DESCRIPTION(
22478         "Test that an error is produced when the number of input components from the fragment stage exceeds the device limit");
22479     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
22480                                          "Fragment shader exceeds "
22481                                          "VkPhysicalDeviceLimits::maxFragmentInputComponents");
22482 
22483     ASSERT_NO_FATAL_FAILURE(Init());
22484 
22485     std::string vsSourceStr =
22486         "#version 450\n"
22487         "\n"
22488         "void main(){\n"
22489         "    gl_Position = vec4(1);\n"
22490         "}\n";
22491 
22492     const uint32_t maxFsInComp = m_device->props.limits.maxFragmentInputComponents;
22493     std::string fsSourceStr = "#version 450\n\n";
22494     const uint32_t numVec4 = maxFsInComp / 4;
22495     uint32_t location = 0;
22496     for (uint32_t i = 0; i < numVec4; i++) {
22497         fsSourceStr += "layout(location=" + std::to_string(location) + ") in vec4 v" + std::to_string(i) + ";\n";
22498         location += 1;
22499     }
22500     const uint32_t remainder = maxFsInComp % 4;
22501     if (remainder != 0) {
22502         if (remainder == 1) {
22503             fsSourceStr += "layout(location=" + std::to_string(location) + ") in float" + " vn;\n";
22504         } else {
22505             fsSourceStr += "layout(location=" + std::to_string(location) + ") in vec" + std::to_string(remainder) + " vn;\n";
22506         }
22507         location += 1;
22508     }
22509     fsSourceStr += "layout(location=" + std::to_string(location) +
22510                    ") in vec4 exceedLimit;\n"
22511                    "\n"
22512                    "layout(location=0) out vec4 color;"
22513                    "\n"
22514                    "void main(){\n"
22515                    "    color = vec4(1);\n"
22516                    "}\n";
22517 
22518     VkShaderObj vs(m_device, vsSourceStr.c_str(), VK_SHADER_STAGE_VERTEX_BIT, this);
22519     VkShaderObj fs(m_device, fsSourceStr.c_str(), VK_SHADER_STAGE_FRAGMENT_BIT, this);
22520 
22521     VkPipelineObj pipe(m_device);
22522     pipe.AddShader(&vs);
22523     pipe.AddShader(&fs);
22524 
22525     // Set up CB 0; type is UNORM by default
22526     pipe.AddDefaultColorAttachment();
22527     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
22528 
22529     VkDescriptorSetObj descriptorSet(m_device);
22530     descriptorSet.AppendDummy();
22531     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
22532 
22533     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
22534 
22535     m_errorMonitor->VerifyFound();
22536 }
22537 
TEST_F(VkLayerTest,CreatePipelineUniformBlockNotProvided)22538 TEST_F(VkLayerTest, CreatePipelineUniformBlockNotProvided) {
22539     TEST_DESCRIPTION(
22540         "Test that an error is produced for a shader consuming a uniform block which has no corresponding binding in the pipeline "
22541         "layout");
22542     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not declared in pipeline layout");
22543 
22544     ASSERT_NO_FATAL_FAILURE(Init());
22545 
22546     char const *vsSource =
22547         "#version 450\n"
22548         "\n"
22549         "void main(){\n"
22550         "   gl_Position = vec4(1);\n"
22551         "}\n";
22552     char const *fsSource =
22553         "#version 450\n"
22554         "\n"
22555         "layout(location=0) out vec4 x;\n"
22556         "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
22557         "void main(){\n"
22558         "   x = vec4(bar.y);\n"
22559         "}\n";
22560 
22561     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
22562     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
22563 
22564     VkPipelineObj pipe(m_device);
22565     pipe.AddShader(&vs);
22566     pipe.AddShader(&fs);
22567 
22568     /* set up CB 0; type is UNORM by default */
22569     pipe.AddDefaultColorAttachment();
22570     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
22571 
22572     VkDescriptorSetObj descriptorSet(m_device);
22573     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
22574 
22575     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
22576 
22577     m_errorMonitor->VerifyFound();
22578 }
22579 
TEST_F(VkLayerTest,CreatePipelinePushConstantsNotInLayout)22580 TEST_F(VkLayerTest, CreatePipelinePushConstantsNotInLayout) {
22581     TEST_DESCRIPTION(
22582         "Test that an error is produced for a shader consuming push constants which are not provided in the pipeline layout");
22583     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not declared in layout");
22584 
22585     ASSERT_NO_FATAL_FAILURE(Init());
22586 
22587     char const *vsSource =
22588         "#version 450\n"
22589         "\n"
22590         "layout(push_constant, std430) uniform foo { float x; } consts;\n"
22591         "void main(){\n"
22592         "   gl_Position = vec4(consts.x);\n"
22593         "}\n";
22594     char const *fsSource =
22595         "#version 450\n"
22596         "\n"
22597         "layout(location=0) out vec4 x;\n"
22598         "void main(){\n"
22599         "   x = vec4(1);\n"
22600         "}\n";
22601 
22602     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
22603     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
22604 
22605     VkPipelineObj pipe(m_device);
22606     pipe.AddShader(&vs);
22607     pipe.AddShader(&fs);
22608 
22609     /* set up CB 0; type is UNORM by default */
22610     pipe.AddDefaultColorAttachment();
22611     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
22612 
22613     VkDescriptorSetObj descriptorSet(m_device);
22614     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
22615 
22616     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
22617 
22618     /* should have generated an error -- no push constant ranges provided! */
22619     m_errorMonitor->VerifyFound();
22620 }
22621 
TEST_F(VkLayerTest,CreatePipelineInputAttachmentMissing)22622 TEST_F(VkLayerTest, CreatePipelineInputAttachmentMissing) {
22623     TEST_DESCRIPTION(
22624         "Test that an error is produced for a shader consuming an input attachment which is not included in the subpass "
22625         "description");
22626     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
22627                                          "consumes input attachment index 0 but not provided in subpass");
22628 
22629     ASSERT_NO_FATAL_FAILURE(Init());
22630 
22631     char const *vsSource =
22632         "#version 450\n"
22633         "\n"
22634         "void main(){\n"
22635         "    gl_Position = vec4(1);\n"
22636         "}\n";
22637     char const *fsSource =
22638         "#version 450\n"
22639         "\n"
22640         "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
22641         "layout(location=0) out vec4 color;\n"
22642         "void main() {\n"
22643         "   color = subpassLoad(x);\n"
22644         "}\n";
22645 
22646     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
22647     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
22648 
22649     VkPipelineObj pipe(m_device);
22650     pipe.AddShader(&vs);
22651     pipe.AddShader(&fs);
22652     pipe.AddDefaultColorAttachment();
22653     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
22654 
22655     VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
22656     const VkDescriptorSetLayoutObj dsl(m_device, {dslb});
22657 
22658     const VkPipelineLayoutObj pl(m_device, {&dsl});
22659 
22660     // error here.
22661     pipe.CreateVKPipeline(pl.handle(), renderPass());
22662 
22663     m_errorMonitor->VerifyFound();
22664 }
22665 
TEST_F(VkLayerTest,CreatePipelineInputAttachmentTypeMismatch)22666 TEST_F(VkLayerTest, CreatePipelineInputAttachmentTypeMismatch) {
22667     TEST_DESCRIPTION(
22668         "Test that an error is produced for a shader consuming an input attachment with a format having a different fundamental "
22669         "type");
22670     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
22671                                          "input attachment 0 format of VK_FORMAT_R8G8B8A8_UINT does not match");
22672 
22673     ASSERT_NO_FATAL_FAILURE(Init());
22674 
22675     char const *vsSource =
22676         "#version 450\n"
22677         "\n"
22678         "void main(){\n"
22679         "    gl_Position = vec4(1);\n"
22680         "}\n";
22681     char const *fsSource =
22682         "#version 450\n"
22683         "\n"
22684         "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
22685         "layout(location=0) out vec4 color;\n"
22686         "void main() {\n"
22687         "   color = subpassLoad(x);\n"
22688         "}\n";
22689 
22690     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
22691     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
22692 
22693     VkPipelineObj pipe(m_device);
22694     pipe.AddShader(&vs);
22695     pipe.AddShader(&fs);
22696     pipe.AddDefaultColorAttachment();
22697     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
22698 
22699     VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
22700     const VkDescriptorSetLayoutObj dsl(m_device, {dslb});
22701 
22702     const VkPipelineLayoutObj pl(m_device, {&dsl});
22703 
22704     VkAttachmentDescription descs[2] = {
22705         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
22706          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
22707          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
22708         {0, VK_FORMAT_R8G8B8A8_UINT, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
22709          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
22710     };
22711     VkAttachmentReference color = {
22712         0,
22713         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
22714     };
22715     VkAttachmentReference input = {
22716         1,
22717         VK_IMAGE_LAYOUT_GENERAL,
22718     };
22719 
22720     VkSubpassDescription sd = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr};
22721 
22722     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr};
22723     VkRenderPass rp;
22724     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
22725     ASSERT_VK_SUCCESS(err);
22726 
22727     // error here.
22728     pipe.CreateVKPipeline(pl.handle(), rp);
22729 
22730     m_errorMonitor->VerifyFound();
22731 
22732     vkDestroyRenderPass(m_device->device(), rp, nullptr);
22733 }
22734 
TEST_F(VkLayerTest,CreatePipelineInputAttachmentMissingArray)22735 TEST_F(VkLayerTest, CreatePipelineInputAttachmentMissingArray) {
22736     TEST_DESCRIPTION(
22737         "Test that an error is produced for a shader consuming an input attachment which is not included in the subpass "
22738         "description -- array case");
22739     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
22740                                          "consumes input attachment index 0 but not provided in subpass");
22741 
22742     ASSERT_NO_FATAL_FAILURE(Init());
22743 
22744     char const *vsSource =
22745         "#version 450\n"
22746         "\n"
22747         "void main(){\n"
22748         "    gl_Position = vec4(1);\n"
22749         "}\n";
22750     char const *fsSource =
22751         "#version 450\n"
22752         "\n"
22753         "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput xs[1];\n"
22754         "layout(location=0) out vec4 color;\n"
22755         "void main() {\n"
22756         "   color = subpassLoad(xs[0]);\n"
22757         "}\n";
22758 
22759     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
22760     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
22761 
22762     VkPipelineObj pipe(m_device);
22763     pipe.AddShader(&vs);
22764     pipe.AddShader(&fs);
22765     pipe.AddDefaultColorAttachment();
22766     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
22767 
22768     VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
22769     const VkDescriptorSetLayoutObj dsl(m_device, {dslb});
22770 
22771     const VkPipelineLayoutObj pl(m_device, {&dsl});
22772 
22773     // error here.
22774     pipe.CreateVKPipeline(pl.handle(), renderPass());
22775 
22776     m_errorMonitor->VerifyFound();
22777 }
22778 
TEST_F(VkLayerTest,CreateComputePipelineMissingDescriptor)22779 TEST_F(VkLayerTest, CreateComputePipelineMissingDescriptor) {
22780     TEST_DESCRIPTION(
22781         "Test that an error is produced for a compute pipeline consuming a descriptor which is not provided in the pipeline "
22782         "layout");
22783     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Shader uses descriptor slot 0.0");
22784 
22785     ASSERT_NO_FATAL_FAILURE(Init());
22786 
22787     char const *csSource =
22788         "#version 450\n"
22789         "\n"
22790         "layout(local_size_x=1) in;\n"
22791         "layout(set=0, binding=0) buffer block { vec4 x; };\n"
22792         "void main(){\n"
22793         "   x = vec4(1);\n"
22794         "}\n";
22795 
22796     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
22797 
22798     VkDescriptorSetObj descriptorSet(m_device);
22799     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
22800 
22801     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
22802                                         nullptr,
22803                                         0,
22804                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
22805                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
22806                                         descriptorSet.GetPipelineLayout(),
22807                                         VK_NULL_HANDLE,
22808                                         -1};
22809 
22810     VkPipeline pipe;
22811     VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
22812 
22813     m_errorMonitor->VerifyFound();
22814 
22815     if (err == VK_SUCCESS) {
22816         vkDestroyPipeline(m_device->device(), pipe, nullptr);
22817     }
22818 }
22819 
TEST_F(VkLayerTest,CreateComputePipelineDescriptorTypeMismatch)22820 TEST_F(VkLayerTest, CreateComputePipelineDescriptorTypeMismatch) {
22821     TEST_DESCRIPTION("Test that an error is produced for a pipeline consuming a descriptor-backed resource of a mismatched type");
22822     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
22823                                          "but descriptor of type VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER");
22824 
22825     ASSERT_NO_FATAL_FAILURE(Init());
22826 
22827     VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr};
22828     const VkDescriptorSetLayoutObj dsl(m_device, {binding});
22829 
22830     const VkPipelineLayoutObj pl(m_device, {&dsl});
22831 
22832     char const *csSource =
22833         "#version 450\n"
22834         "\n"
22835         "layout(local_size_x=1) in;\n"
22836         "layout(set=0, binding=0) buffer block { vec4 x; };\n"
22837         "void main() {\n"
22838         "   x.x = 1.0f;\n"
22839         "}\n";
22840     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
22841 
22842     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
22843                                         nullptr,
22844                                         0,
22845                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
22846                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
22847                                         pl.handle(),
22848                                         VK_NULL_HANDLE,
22849                                         -1};
22850 
22851     VkPipeline pipe;
22852     VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
22853 
22854     m_errorMonitor->VerifyFound();
22855 
22856     if (err == VK_SUCCESS) {
22857         vkDestroyPipeline(m_device->device(), pipe, nullptr);
22858     }
22859 }
22860 
TEST_F(VkLayerTest,DrawTimeImageViewTypeMismatchWithPipeline)22861 TEST_F(VkLayerTest, DrawTimeImageViewTypeMismatchWithPipeline) {
22862     TEST_DESCRIPTION(
22863         "Test that an error is produced when an image view type does not match the dimensionality declared in the shader");
22864 
22865     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "requires an image view of type VK_IMAGE_VIEW_TYPE_3D");
22866 
22867     ASSERT_NO_FATAL_FAILURE(Init());
22868     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
22869 
22870     char const *vsSource =
22871         "#version 450\n"
22872         "\n"
22873         "void main() { gl_Position = vec4(0); }\n";
22874     char const *fsSource =
22875         "#version 450\n"
22876         "\n"
22877         "layout(set=0, binding=0) uniform sampler3D s;\n"
22878         "layout(location=0) out vec4 color;\n"
22879         "void main() {\n"
22880         "   color = texture(s, vec3(0));\n"
22881         "}\n";
22882     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
22883     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
22884 
22885     VkPipelineObj pipe(m_device);
22886     pipe.AddShader(&vs);
22887     pipe.AddShader(&fs);
22888     pipe.AddDefaultColorAttachment();
22889 
22890     VkTextureObj texture(m_device, nullptr);
22891     VkSamplerObj sampler(m_device);
22892 
22893     VkDescriptorSetObj descriptorSet(m_device);
22894     descriptorSet.AppendSamplerTexture(&sampler, &texture);
22895     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
22896 
22897     VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
22898     ASSERT_VK_SUCCESS(err);
22899 
22900     m_commandBuffer->begin();
22901     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
22902 
22903     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
22904     m_commandBuffer->BindDescriptorSet(descriptorSet);
22905 
22906     VkViewport viewport = {0, 0, 16, 16, 0, 1};
22907     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
22908     VkRect2D scissor = {{0, 0}, {16, 16}};
22909     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
22910 
22911     // error produced here.
22912     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
22913 
22914     m_errorMonitor->VerifyFound();
22915 
22916     m_commandBuffer->EndRenderPass();
22917     m_commandBuffer->end();
22918 }
22919 
TEST_F(VkLayerTest,DrawTimeImageMultisampleMismatchWithPipeline)22920 TEST_F(VkLayerTest, DrawTimeImageMultisampleMismatchWithPipeline) {
22921     TEST_DESCRIPTION(
22922         "Test that an error is produced when a multisampled images are consumed via singlesample images types in the shader, or "
22923         "vice versa.");
22924 
22925     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "requires bound image to have multiple samples");
22926 
22927     ASSERT_NO_FATAL_FAILURE(Init());
22928     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
22929 
22930     char const *vsSource =
22931         "#version 450\n"
22932         "\n"
22933         "void main() { gl_Position = vec4(0); }\n";
22934     char const *fsSource =
22935         "#version 450\n"
22936         "\n"
22937         "layout(set=0, binding=0) uniform sampler2DMS s;\n"
22938         "layout(location=0) out vec4 color;\n"
22939         "void main() {\n"
22940         "   color = texelFetch(s, ivec2(0), 0);\n"
22941         "}\n";
22942     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
22943     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
22944 
22945     VkPipelineObj pipe(m_device);
22946     pipe.AddShader(&vs);
22947     pipe.AddShader(&fs);
22948     pipe.AddDefaultColorAttachment();
22949 
22950     VkTextureObj texture(m_device, nullptr);  // THIS LINE CAUSES CRASH ON MALI
22951     VkSamplerObj sampler(m_device);
22952 
22953     VkDescriptorSetObj descriptorSet(m_device);
22954     descriptorSet.AppendSamplerTexture(&sampler, &texture);
22955     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
22956 
22957     VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
22958     ASSERT_VK_SUCCESS(err);
22959 
22960     m_commandBuffer->begin();
22961     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
22962 
22963     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
22964     m_commandBuffer->BindDescriptorSet(descriptorSet);
22965 
22966     VkViewport viewport = {0, 0, 16, 16, 0, 1};
22967     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
22968     VkRect2D scissor = {{0, 0}, {16, 16}};
22969     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
22970 
22971     // error produced here.
22972     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
22973 
22974     m_errorMonitor->VerifyFound();
22975 
22976     m_commandBuffer->EndRenderPass();
22977     m_commandBuffer->end();
22978 }
22979 
TEST_F(VkLayerTest,DrawTimeImageComponentTypeMismatchWithPipeline)22980 TEST_F(VkLayerTest, DrawTimeImageComponentTypeMismatchWithPipeline) {
22981     TEST_DESCRIPTION(
22982         "Test that an error is produced when the component type of an imageview disagrees with the type in the shader.");
22983 
22984     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SINT component type, but bound descriptor");
22985 
22986     ASSERT_NO_FATAL_FAILURE(Init());
22987     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
22988 
22989     char const *vsSource =
22990         "#version 450\n"
22991         "\n"
22992         "void main() { gl_Position = vec4(0); }\n";
22993     char const *fsSource =
22994         "#version 450\n"
22995         "\n"
22996         "layout(set=0, binding=0) uniform isampler2D s;\n"
22997         "layout(location=0) out vec4 color;\n"
22998         "void main() {\n"
22999         "   color = texelFetch(s, ivec2(0), 0);\n"
23000         "}\n";
23001     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
23002     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
23003 
23004     VkPipelineObj pipe(m_device);
23005     pipe.AddShader(&vs);
23006     pipe.AddShader(&fs);
23007     pipe.AddDefaultColorAttachment();
23008 
23009     VkTextureObj texture(m_device, nullptr);  // UNORM texture by default, incompatible with isampler2D
23010     VkSamplerObj sampler(m_device);
23011 
23012     VkDescriptorSetObj descriptorSet(m_device);
23013     descriptorSet.AppendSamplerTexture(&sampler, &texture);
23014     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
23015 
23016     VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
23017     ASSERT_VK_SUCCESS(err);
23018 
23019     m_commandBuffer->begin();
23020     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
23021 
23022     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
23023     m_commandBuffer->BindDescriptorSet(descriptorSet);
23024 
23025     VkViewport viewport = {0, 0, 16, 16, 0, 1};
23026     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
23027     VkRect2D scissor = {{0, 0}, {16, 16}};
23028     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
23029 
23030     // error produced here.
23031     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
23032 
23033     m_errorMonitor->VerifyFound();
23034 
23035     m_commandBuffer->EndRenderPass();
23036     m_commandBuffer->end();
23037 }
23038 
TEST_F(VkLayerTest,AttachmentDescriptionUndefinedFormat)23039 TEST_F(VkLayerTest, AttachmentDescriptionUndefinedFormat) {
23040     TEST_DESCRIPTION("Create a render pass with an attachment description format set to VK_FORMAT_UNDEFINED");
23041 
23042     ASSERT_NO_FATAL_FAILURE(Init());
23043     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
23044 
23045     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "format is VK_FORMAT_UNDEFINED");
23046 
23047     VkAttachmentReference color_attach = {};
23048     color_attach.layout = VK_IMAGE_LAYOUT_GENERAL;
23049     color_attach.attachment = 0;
23050     VkSubpassDescription subpass = {};
23051     subpass.colorAttachmentCount = 1;
23052     subpass.pColorAttachments = &color_attach;
23053 
23054     VkRenderPassCreateInfo rpci = {};
23055     rpci.subpassCount = 1;
23056     rpci.pSubpasses = &subpass;
23057     rpci.attachmentCount = 1;
23058     VkAttachmentDescription attach_desc = {};
23059     attach_desc.format = VK_FORMAT_UNDEFINED;
23060     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
23061     attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
23062     rpci.pAttachments = &attach_desc;
23063     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
23064     VkRenderPass rp;
23065     VkResult result = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
23066 
23067     m_errorMonitor->VerifyFound();
23068 
23069     if (result == VK_SUCCESS) {
23070         vkDestroyRenderPass(m_device->device(), rp, NULL);
23071     }
23072 }
23073 
TEST_F(VkLayerTest,CreateImageViewNoMemoryBoundToImage)23074 TEST_F(VkLayerTest, CreateImageViewNoMemoryBoundToImage) {
23075     VkResult err;
23076     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
23077                                          " used with no memory bound. Memory should be bound by calling vkBindImageMemory().");
23078 
23079     ASSERT_NO_FATAL_FAILURE(Init());
23080 
23081     // Create an image and try to create a view with no memory backing the image
23082     VkImage image;
23083 
23084     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
23085     const int32_t tex_width = 32;
23086     const int32_t tex_height = 32;
23087 
23088     VkImageCreateInfo image_create_info = {};
23089     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
23090     image_create_info.pNext = NULL;
23091     image_create_info.imageType = VK_IMAGE_TYPE_2D;
23092     image_create_info.format = tex_format;
23093     image_create_info.extent.width = tex_width;
23094     image_create_info.extent.height = tex_height;
23095     image_create_info.extent.depth = 1;
23096     image_create_info.mipLevels = 1;
23097     image_create_info.arrayLayers = 1;
23098     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
23099     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
23100     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
23101     image_create_info.flags = 0;
23102 
23103     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
23104     ASSERT_VK_SUCCESS(err);
23105 
23106     VkImageViewCreateInfo image_view_create_info = {};
23107     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
23108     image_view_create_info.image = image;
23109     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
23110     image_view_create_info.format = tex_format;
23111     image_view_create_info.subresourceRange.layerCount = 1;
23112     image_view_create_info.subresourceRange.baseMipLevel = 0;
23113     image_view_create_info.subresourceRange.levelCount = 1;
23114     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
23115 
23116     VkImageView view;
23117     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
23118 
23119     m_errorMonitor->VerifyFound();
23120     vkDestroyImage(m_device->device(), image, NULL);
23121     // If last error is success, it still created the view, so delete it.
23122     if (err == VK_SUCCESS) {
23123         vkDestroyImageView(m_device->device(), view, NULL);
23124     }
23125 }
23126 
TEST_F(VkLayerTest,InvalidImageViewAspect)23127 TEST_F(VkLayerTest, InvalidImageViewAspect) {
23128     TEST_DESCRIPTION("Create an image and try to create a view with an invalid aspectMask");
23129     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageSubresource-aspectMask-parameter");
23130 
23131     ASSERT_NO_FATAL_FAILURE(Init());
23132 
23133     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
23134     VkImageObj image(m_device);
23135     image.Init(32, 32, 1, tex_format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_LINEAR, 0);
23136     ASSERT_TRUE(image.initialized());
23137 
23138     VkImageViewCreateInfo image_view_create_info = {};
23139     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
23140     image_view_create_info.image = image.handle();
23141     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
23142     image_view_create_info.format = tex_format;
23143     image_view_create_info.subresourceRange.baseMipLevel = 0;
23144     image_view_create_info.subresourceRange.levelCount = 1;
23145     image_view_create_info.subresourceRange.layerCount = 1;
23146     // Cause an error by setting an invalid image aspect
23147     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
23148 
23149     VkImageView view;
23150     vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
23151 
23152     m_errorMonitor->VerifyFound();
23153 }
23154 
TEST_F(VkLayerTest,ExerciseGetImageSubresourceLayout)23155 TEST_F(VkLayerTest, ExerciseGetImageSubresourceLayout) {
23156     TEST_DESCRIPTION("Test vkGetImageSubresourceLayout() valid usages");
23157 
23158     ASSERT_NO_FATAL_FAILURE(Init());
23159     VkSubresourceLayout subres_layout = {};
23160 
23161     // VU 00732: image must have been created with tiling equal to VK_IMAGE_TILING_LINEAR
23162     {
23163         const VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL;  // ERROR: violates VU 00732
23164         VkImageObj img(m_device);
23165         img.InitNoLayout(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, tiling);
23166         ASSERT_TRUE(img.initialized());
23167 
23168         VkImageSubresource subres = {};
23169         subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
23170         subres.mipLevel = 0;
23171         subres.arrayLayer = 0;
23172 
23173         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkGetImageSubresourceLayout-image-00996");
23174         vkGetImageSubresourceLayout(m_device->device(), img.image(), &subres, &subres_layout);
23175         m_errorMonitor->VerifyFound();
23176     }
23177 
23178     // VU 00733: The aspectMask member of pSubresource must only have a single bit set
23179     {
23180         VkImageObj img(m_device);
23181         img.InitNoLayout(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
23182         ASSERT_TRUE(img.initialized());
23183 
23184         VkImageSubresource subres = {};
23185         subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_METADATA_BIT;  // ERROR: triggers VU 00733
23186         subres.mipLevel = 0;
23187         subres.arrayLayer = 0;
23188 
23189         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkGetImageSubresourceLayout-aspectMask-00997");
23190         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageSubresource-aspectMask-parameter");
23191         vkGetImageSubresourceLayout(m_device->device(), img.image(), &subres, &subres_layout);
23192         m_errorMonitor->VerifyFound();
23193     }
23194 
23195     // 00739 mipLevel must be less than the mipLevels specified in VkImageCreateInfo when the image was created
23196     {
23197         VkImageObj img(m_device);
23198         img.InitNoLayout(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
23199         ASSERT_TRUE(img.initialized());
23200 
23201         VkImageSubresource subres = {};
23202         subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
23203         subres.mipLevel = 1;  // ERROR: triggers VU 00739
23204         subres.arrayLayer = 0;
23205 
23206         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkGetImageSubresourceLayout-mipLevel-01716");
23207         vkGetImageSubresourceLayout(m_device->device(), img.image(), &subres, &subres_layout);
23208         m_errorMonitor->VerifyFound();
23209     }
23210 
23211     // 00740 arrayLayer must be less than the arrayLayers specified in VkImageCreateInfo when the image was created
23212     {
23213         VkImageObj img(m_device);
23214         img.InitNoLayout(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
23215         ASSERT_TRUE(img.initialized());
23216 
23217         VkImageSubresource subres = {};
23218         subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
23219         subres.mipLevel = 0;
23220         subres.arrayLayer = 1;  // ERROR: triggers VU 00740
23221 
23222         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkGetImageSubresourceLayout-arrayLayer-01717");
23223         vkGetImageSubresourceLayout(m_device->device(), img.image(), &subres, &subres_layout);
23224         m_errorMonitor->VerifyFound();
23225     }
23226 }
23227 
TEST_F(VkLayerTest,CopyImageLayerCountMismatch)23228 TEST_F(VkLayerTest, CopyImageLayerCountMismatch) {
23229     TEST_DESCRIPTION(
23230         "Try to copy between images with the source subresource having a different layerCount than the destination subresource");
23231     ASSERT_NO_FATAL_FAILURE(Init());
23232 
23233     // Create two images to copy between
23234     VkImageObj src_image_obj(m_device);
23235     VkImageObj dst_image_obj(m_device);
23236 
23237     VkImageCreateInfo image_create_info = {};
23238     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
23239     image_create_info.pNext = NULL;
23240     image_create_info.imageType = VK_IMAGE_TYPE_2D;
23241     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
23242     image_create_info.extent.width = 32;
23243     image_create_info.extent.height = 32;
23244     image_create_info.extent.depth = 1;
23245     image_create_info.mipLevels = 1;
23246     image_create_info.arrayLayers = 4;
23247     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
23248     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
23249     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
23250     image_create_info.flags = 0;
23251 
23252     src_image_obj.init(&image_create_info);
23253     ASSERT_TRUE(src_image_obj.initialized());
23254 
23255     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
23256     dst_image_obj.init(&image_create_info);
23257     ASSERT_TRUE(dst_image_obj.initialized());
23258 
23259     m_commandBuffer->begin();
23260     VkImageCopy copyRegion;
23261     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
23262     copyRegion.srcSubresource.mipLevel = 0;
23263     copyRegion.srcSubresource.baseArrayLayer = 0;
23264     copyRegion.srcSubresource.layerCount = 1;
23265     copyRegion.srcOffset.x = 0;
23266     copyRegion.srcOffset.y = 0;
23267     copyRegion.srcOffset.z = 0;
23268     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
23269     copyRegion.dstSubresource.mipLevel = 0;
23270     copyRegion.dstSubresource.baseArrayLayer = 0;
23271     // Introduce failure by forcing the dst layerCount to differ from src
23272     copyRegion.dstSubresource.layerCount = 3;
23273     copyRegion.dstOffset.x = 0;
23274     copyRegion.dstOffset.y = 0;
23275     copyRegion.dstOffset.z = 0;
23276     copyRegion.extent.width = 1;
23277     copyRegion.extent.height = 1;
23278     copyRegion.extent.depth = 1;
23279 
23280     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-extent-00140");
23281     m_commandBuffer->CopyImage(src_image_obj.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image_obj.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
23282                                &copyRegion);
23283     m_errorMonitor->VerifyFound();
23284 }
23285 
TEST_F(VkLayerTest,ImageLayerUnsupportedFormat)23286 TEST_F(VkLayerTest, ImageLayerUnsupportedFormat) {
23287     TEST_DESCRIPTION("Creating images with unsupported formats ");
23288 
23289     ASSERT_NO_FATAL_FAILURE(Init());
23290     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
23291 
23292     // Create image with unsupported format - Expect FORMAT_UNSUPPORTED
23293     VkImageCreateInfo image_create_info = {};
23294     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
23295     image_create_info.imageType = VK_IMAGE_TYPE_2D;
23296     image_create_info.format = VK_FORMAT_UNDEFINED;
23297     image_create_info.extent.width = 32;
23298     image_create_info.extent.height = 32;
23299     image_create_info.extent.depth = 1;
23300     image_create_info.mipLevels = 1;
23301     image_create_info.arrayLayers = 1;
23302     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
23303     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
23304     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
23305 
23306     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-format-00943");
23307 
23308     VkImage image;
23309     vkCreateImage(m_device->handle(), &image_create_info, NULL, &image);
23310     m_errorMonitor->VerifyFound();
23311 }
23312 
TEST_F(VkLayerTest,CreateImageViewFormatMismatchUnrelated)23313 TEST_F(VkLayerTest, CreateImageViewFormatMismatchUnrelated) {
23314     TEST_DESCRIPTION("Create an image with a color format, then try to create a depth view of it");
23315 
23316     if (!EnableDeviceProfileLayer()) {
23317         printf("%s Failed to enable device profile layer.\n", kSkipPrefix);
23318         return;
23319     }
23320 
23321     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
23322     ASSERT_NO_FATAL_FAILURE(InitState());
23323 
23324     // Load required functions
23325     PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT =
23326         (PFN_vkSetPhysicalDeviceFormatPropertiesEXT)vkGetInstanceProcAddr(instance(), "vkSetPhysicalDeviceFormatPropertiesEXT");
23327     PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT =
23328         (PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT)vkGetInstanceProcAddr(instance(),
23329                                                                                   "vkGetOriginalPhysicalDeviceFormatPropertiesEXT");
23330 
23331     if (!(fpvkSetPhysicalDeviceFormatPropertiesEXT) || !(fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) {
23332         printf("%s Can't find device_profile_api functions; skipped.\n", kSkipPrefix);
23333         return;
23334     }
23335 
23336     auto depth_format = FindSupportedDepthStencilFormat(gpu());
23337     if (!depth_format) {
23338         printf("%s Couldn't find depth stencil image format.\n", kSkipPrefix);
23339         return;
23340     }
23341 
23342     VkFormatProperties formatProps;
23343 
23344     fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), depth_format, &formatProps);
23345     formatProps.optimalTilingFeatures |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
23346     fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), depth_format, formatProps);
23347 
23348     VkImageObj image(m_device);
23349     image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
23350     ASSERT_TRUE(image.initialized());
23351 
23352     VkImageView imgView;
23353     VkImageViewCreateInfo imgViewInfo = {};
23354     imgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
23355     imgViewInfo.image = image.handle();
23356     imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
23357     imgViewInfo.format = depth_format;
23358     imgViewInfo.subresourceRange.layerCount = 1;
23359     imgViewInfo.subresourceRange.baseMipLevel = 0;
23360     imgViewInfo.subresourceRange.levelCount = 1;
23361     imgViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
23362 
23363     // Can't use depth format for view into color image - Expect INVALID_FORMAT
23364     m_errorMonitor->SetDesiredFailureMsg(
23365         VK_DEBUG_REPORT_ERROR_BIT_EXT,
23366         "Formats MUST be IDENTICAL unless VK_IMAGE_CREATE_MUTABLE_FORMAT BIT was set on image creation.");
23367     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
23368     m_errorMonitor->VerifyFound();
23369 }
23370 
TEST_F(VkLayerTest,CreateImageViewNoMutableFormatBit)23371 TEST_F(VkLayerTest, CreateImageViewNoMutableFormatBit) {
23372     TEST_DESCRIPTION("Create an image view with a different format, when the image does not have MUTABLE_FORMAT bit");
23373 
23374     if (!EnableDeviceProfileLayer()) {
23375         printf("%s Couldn't enable device profile layer.\n", kSkipPrefix);
23376         return;
23377     }
23378 
23379     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
23380     ASSERT_NO_FATAL_FAILURE(InitState());
23381 
23382     PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr;
23383     PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr;
23384 
23385     // Load required functions
23386     if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) {
23387         printf("%s Required extensions are not present.\n", kSkipPrefix);
23388         return;
23389     }
23390 
23391     VkImageObj image(m_device);
23392     image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
23393     ASSERT_TRUE(image.initialized());
23394 
23395     VkFormatProperties formatProps;
23396 
23397     fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_B8G8R8A8_UINT, &formatProps);
23398     formatProps.optimalTilingFeatures |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
23399     fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_B8G8R8A8_UINT, formatProps);
23400 
23401     VkImageView imgView;
23402     VkImageViewCreateInfo imgViewInfo = {};
23403     imgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
23404     imgViewInfo.image = image.handle();
23405     imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
23406     imgViewInfo.format = VK_FORMAT_B8G8R8A8_UINT;
23407     imgViewInfo.subresourceRange.layerCount = 1;
23408     imgViewInfo.subresourceRange.baseMipLevel = 0;
23409     imgViewInfo.subresourceRange.levelCount = 1;
23410     imgViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
23411 
23412     // Same compatibility class but no MUTABLE_FORMAT bit - Expect
23413     // VIEW_CREATE_ERROR
23414     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-image-01019");
23415     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
23416     m_errorMonitor->VerifyFound();
23417 }
23418 
TEST_F(VkLayerTest,CreateImageViewDifferentClass)23419 TEST_F(VkLayerTest, CreateImageViewDifferentClass) {
23420     TEST_DESCRIPTION("Passing bad parameters to CreateImageView");
23421 
23422     ASSERT_NO_FATAL_FAILURE(Init());
23423 
23424     if (!(m_device->format_properties(VK_FORMAT_R8_UINT).optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) {
23425         printf("%s Device does not support R8_UINT as color attachment; skipped", kSkipPrefix);
23426         return;
23427     }
23428 
23429     VkImageCreateInfo mutImgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
23430                                     nullptr,
23431                                     VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
23432                                     VK_IMAGE_TYPE_2D,
23433                                     VK_FORMAT_R8_UINT,
23434                                     {128, 128, 1},
23435                                     1,
23436                                     1,
23437                                     VK_SAMPLE_COUNT_1_BIT,
23438                                     VK_IMAGE_TILING_OPTIMAL,
23439                                     VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
23440                                     VK_SHARING_MODE_EXCLUSIVE,
23441                                     0,
23442                                     nullptr,
23443                                     VK_IMAGE_LAYOUT_UNDEFINED};
23444     VkImageObj mutImage(m_device);
23445     mutImage.init(&mutImgInfo);
23446     ASSERT_TRUE(mutImage.initialized());
23447 
23448     VkImageView imgView;
23449     VkImageViewCreateInfo imgViewInfo = {};
23450     imgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
23451     imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
23452     imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
23453     imgViewInfo.subresourceRange.layerCount = 1;
23454     imgViewInfo.subresourceRange.baseMipLevel = 0;
23455     imgViewInfo.subresourceRange.levelCount = 1;
23456     imgViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
23457     imgViewInfo.image = mutImage.handle();
23458 
23459     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-image-01018");
23460     vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView);
23461     m_errorMonitor->VerifyFound();
23462 }
23463 
TEST_F(VkLayerTest,MultiplaneIncompatibleViewFormat)23464 TEST_F(VkLayerTest, MultiplaneIncompatibleViewFormat) {
23465     TEST_DESCRIPTION("Postive/negative tests of multiplane imageview format compatibility");
23466 
23467     // Enable KHR multiplane req'd extensions
23468     bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
23469                                                     VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
23470     if (mp_extensions) {
23471         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
23472     }
23473     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
23474     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
23475     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
23476     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
23477     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
23478     if (mp_extensions) {
23479         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
23480         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
23481         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
23482         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
23483     } else {
23484         printf("%s test requires KHR multiplane extensions, not available.  Skipping.\n", kSkipPrefix);
23485         return;
23486     }
23487     ASSERT_NO_FATAL_FAILURE(InitState());
23488 
23489     VkImageCreateInfo ci = {};
23490     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
23491     ci.pNext = NULL;
23492     ci.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
23493     ci.imageType = VK_IMAGE_TYPE_2D;
23494     ci.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
23495     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
23496     ci.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
23497     ci.extent = {128, 128, 1};
23498     ci.mipLevels = 1;
23499     ci.arrayLayers = 1;
23500     ci.samples = VK_SAMPLE_COUNT_1_BIT;
23501     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
23502     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
23503 
23504     // Verify format
23505     VkFormatFeatureFlags features = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
23506     bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
23507     if (!supported) {
23508         printf("%s Multiplane image format not supported.  Skipping test.\n", kSkipPrefix);
23509         return;
23510     }
23511 
23512     VkImageObj image_obj(m_device);
23513     image_obj.init(&ci);
23514     ASSERT_TRUE(image_obj.initialized());
23515 
23516     VkImageViewCreateInfo ivci = {};
23517     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
23518     ivci.image = image_obj.image();
23519     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
23520     ivci.format = VK_FORMAT_R8_SNORM;  // Compat is VK_FORMAT_R8_UNORM
23521     ivci.subresourceRange.layerCount = 1;
23522     ivci.subresourceRange.baseMipLevel = 0;
23523     ivci.subresourceRange.levelCount = 1;
23524     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
23525 
23526     // Incompatible format error
23527     VkImageView imageView = VK_NULL_HANDLE;
23528     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-image-01586");
23529     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
23530     m_errorMonitor->VerifyFound();
23531     vkDestroyImageView(m_device->device(), imageView, NULL);  // VK_NULL_HANDLE allowed
23532     imageView = VK_NULL_HANDLE;
23533 
23534     // Correct format succeeds
23535     ivci.format = VK_FORMAT_R8_UNORM;
23536     m_errorMonitor->ExpectSuccess();
23537     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
23538     m_errorMonitor->VerifyNotFound();
23539     vkDestroyImageView(m_device->device(), imageView, NULL);  // VK_NULL_HANDLE allowed
23540     imageView = VK_NULL_HANDLE;
23541 
23542     // Try a multiplane imageview
23543     ivci.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
23544     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
23545     m_errorMonitor->ExpectSuccess();
23546     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
23547     m_errorMonitor->VerifyNotFound();
23548     vkDestroyImageView(m_device->device(), imageView, NULL);  // VK_NULL_HANDLE allowed
23549 }
23550 
TEST_F(VkLayerTest,CreateImageViewInvalidSubresourceRange)23551 TEST_F(VkLayerTest, CreateImageViewInvalidSubresourceRange) {
23552     TEST_DESCRIPTION("Passing bad image subrange to CreateImageView");
23553 
23554     ASSERT_NO_FATAL_FAILURE(Init());
23555 
23556     VkImageObj image(m_device);
23557     image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
23558     ASSERT_TRUE(image.create_info().arrayLayers == 1);
23559     ASSERT_TRUE(image.initialized());
23560 
23561     VkImageView img_view;
23562     VkImageViewCreateInfo img_view_info_template = {};
23563     img_view_info_template.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
23564     img_view_info_template.image = image.handle();
23565     img_view_info_template.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
23566     img_view_info_template.format = image.format();
23567     // subresourceRange to be filled later for the purposes of this test
23568     img_view_info_template.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
23569     img_view_info_template.subresourceRange.baseMipLevel = 0;
23570     img_view_info_template.subresourceRange.levelCount = 0;
23571     img_view_info_template.subresourceRange.baseArrayLayer = 0;
23572     img_view_info_template.subresourceRange.layerCount = 0;
23573 
23574     // Try baseMipLevel >= image.mipLevels with VK_REMAINING_MIP_LEVELS
23575     {
23576         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-subresourceRange-01478");
23577         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, VK_REMAINING_MIP_LEVELS, 0, 1};
23578         VkImageViewCreateInfo img_view_info = img_view_info_template;
23579         img_view_info.subresourceRange = range;
23580         vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view);
23581         m_errorMonitor->VerifyFound();
23582     }
23583 
23584     // Try baseMipLevel >= image.mipLevels without VK_REMAINING_MIP_LEVELS
23585     {
23586         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-subresourceRange-01478");
23587         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-subresourceRange-01718");
23588         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 0, 1};
23589         VkImageViewCreateInfo img_view_info = img_view_info_template;
23590         img_view_info.subresourceRange = range;
23591         vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view);
23592         m_errorMonitor->VerifyFound();
23593     }
23594 
23595     // Try levelCount = 0
23596     {
23597         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-subresourceRange-01718");
23598         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 0, 1};
23599         VkImageViewCreateInfo img_view_info = img_view_info_template;
23600         img_view_info.subresourceRange = range;
23601         vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view);
23602         m_errorMonitor->VerifyFound();
23603     }
23604 
23605     // Try baseMipLevel + levelCount > image.mipLevels
23606     {
23607         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-subresourceRange-01718");
23608         const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 2, 0, 1};
23609         VkImageViewCreateInfo img_view_info = img_view_info_template;
23610         img_view_info.subresourceRange = range;
23611         vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view);
23612         m_errorMonitor->VerifyFound();
23613     }
23614 
23615     // These tests rely on having the Maintenance1 extension not being enabled, and are invalid on all but version 1.0
23616     if (m_device->props.apiVersion < VK_API_VERSION_1_1) {
23617         // Try baseArrayLayer >= image.arrayLayers with VK_REMAINING_ARRAY_LAYERS
23618         {
23619             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
23620                                                  "VUID-VkImageViewCreateInfo-subresourceRange-01480");
23621             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, VK_REMAINING_ARRAY_LAYERS};
23622             VkImageViewCreateInfo img_view_info = img_view_info_template;
23623             img_view_info.subresourceRange = range;
23624             vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view);
23625             m_errorMonitor->VerifyFound();
23626         }
23627 
23628         // Try baseArrayLayer >= image.arrayLayers without VK_REMAINING_ARRAY_LAYERS
23629         {
23630             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
23631                                                  "VUID-VkImageViewCreateInfo-subresourceRange-01480");
23632             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
23633                                                  "VUID-VkImageViewCreateInfo-subresourceRange-01719");
23634             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, 1};
23635             VkImageViewCreateInfo img_view_info = img_view_info_template;
23636             img_view_info.subresourceRange = range;
23637             vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view);
23638             m_errorMonitor->VerifyFound();
23639         }
23640 
23641         // Try layerCount = 0
23642         {
23643             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
23644                                                  "VUID-VkImageViewCreateInfo-subresourceRange-01719");
23645             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 0};
23646             VkImageViewCreateInfo img_view_info = img_view_info_template;
23647             img_view_info.subresourceRange = range;
23648             vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view);
23649             m_errorMonitor->VerifyFound();
23650         }
23651 
23652         // Try baseArrayLayer + layerCount > image.arrayLayers
23653         {
23654             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
23655                                                  "VUID-VkImageViewCreateInfo-subresourceRange-01719");
23656             const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 2};
23657             VkImageViewCreateInfo img_view_info = img_view_info_template;
23658             img_view_info.subresourceRange = range;
23659             vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view);
23660             m_errorMonitor->VerifyFound();
23661         }
23662     }
23663 }
23664 
TEST_F(VkLayerTest,CompressedImageMipCopyTests)23665 TEST_F(VkLayerTest, CompressedImageMipCopyTests) {
23666     TEST_DESCRIPTION("Image/Buffer copies for higher mip levels");
23667 
23668     ASSERT_NO_FATAL_FAILURE(Init());
23669 
23670     VkPhysicalDeviceFeatures device_features = {};
23671     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
23672     VkFormat compressed_format = VK_FORMAT_UNDEFINED;
23673     if (device_features.textureCompressionBC) {
23674         compressed_format = VK_FORMAT_BC3_SRGB_BLOCK;
23675     } else if (device_features.textureCompressionETC2) {
23676         compressed_format = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
23677     } else if (device_features.textureCompressionASTC_LDR) {
23678         compressed_format = VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
23679     } else {
23680         printf("%s No compressed formats supported - CompressedImageMipCopyTests skipped.\n", kSkipPrefix);
23681         return;
23682     }
23683 
23684     VkImageCreateInfo ci;
23685     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
23686     ci.pNext = NULL;
23687     ci.flags = 0;
23688     ci.imageType = VK_IMAGE_TYPE_2D;
23689     ci.format = compressed_format;
23690     ci.extent = {32, 32, 1};
23691     ci.mipLevels = 6;
23692     ci.arrayLayers = 1;
23693     ci.samples = VK_SAMPLE_COUNT_1_BIT;
23694     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
23695     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
23696     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
23697     ci.queueFamilyIndexCount = 0;
23698     ci.pQueueFamilyIndices = NULL;
23699     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
23700 
23701     VkImageObj image(m_device);
23702     image.init(&ci);
23703     ASSERT_TRUE(image.initialized());
23704 
23705     VkImageObj odd_image(m_device);
23706     ci.extent = {31, 32, 1};  // Mips are [31,32] [15,16] [7,8] [3,4], [1,2] [1,1]
23707     odd_image.init(&ci);
23708     ASSERT_TRUE(odd_image.initialized());
23709 
23710     // Allocate buffers
23711     VkMemoryPropertyFlags reqs = 0;
23712     VkBufferObj buffer_1024, buffer_64, buffer_16, buffer_8;
23713     buffer_1024.init_as_src_and_dst(*m_device, 1024, reqs);
23714     buffer_64.init_as_src_and_dst(*m_device, 64, reqs);
23715     buffer_16.init_as_src_and_dst(*m_device, 16, reqs);
23716     buffer_8.init_as_src_and_dst(*m_device, 8, reqs);
23717 
23718     VkBufferImageCopy region = {};
23719     region.bufferRowLength = 0;
23720     region.bufferImageHeight = 0;
23721     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
23722     region.imageSubresource.layerCount = 1;
23723     region.imageOffset = {0, 0, 0};
23724     region.bufferOffset = 0;
23725 
23726     // start recording
23727     m_commandBuffer->begin();
23728 
23729     // Mip level copies that work - 5 levels
23730     m_errorMonitor->ExpectSuccess();
23731 
23732     // Mip 0 should fit in 1k buffer - 1k texels @ 1b each
23733     region.imageExtent = {32, 32, 1};
23734     region.imageSubresource.mipLevel = 0;
23735     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_1024.handle(), 1, &region);
23736     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_1024.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
23737 
23738     // Mip 2 should fit in 64b buffer - 64 texels @ 1b each
23739     region.imageExtent = {8, 8, 1};
23740     region.imageSubresource.mipLevel = 2;
23741     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64.handle(), 1, &region);
23742     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
23743 
23744     // Mip 3 should fit in 16b buffer - 16 texels @ 1b each
23745     region.imageExtent = {4, 4, 1};
23746     region.imageSubresource.mipLevel = 3;
23747     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
23748     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
23749 
23750     // Mip 4&5 should fit in 16b buffer with no complaint - 4 & 1 texels @ 1b each
23751     region.imageExtent = {2, 2, 1};
23752     region.imageSubresource.mipLevel = 4;
23753     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
23754     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
23755 
23756     region.imageExtent = {1, 1, 1};
23757     region.imageSubresource.mipLevel = 5;
23758     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
23759     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
23760     m_errorMonitor->VerifyNotFound();
23761 
23762     // Buffer must accommodate a full compressed block, regardless of texel count
23763     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImageToBuffer-pRegions-00183");
23764     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_8.handle(), 1, &region);
23765     m_errorMonitor->VerifyFound();
23766     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyBufferToImage-pRegions-00171");
23767     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_8.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
23768     m_errorMonitor->VerifyFound();
23769 
23770     // Copy width < compressed block size, but not the full mip width
23771     region.imageExtent = {1, 2, 1};
23772     region.imageSubresource.mipLevel = 4;
23773     m_errorMonitor->SetDesiredFailureMsg(
23774         VK_DEBUG_REPORT_ERROR_BIT_EXT,
23775         "VUID-VkBufferImageCopy-imageExtent-00207");  // width not a multiple of compressed block width
23776     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
23777                                          "VUID-vkCmdCopyImageToBuffer-imageOffset-01794");  // image transfer granularity
23778     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
23779     m_errorMonitor->VerifyFound();
23780     m_errorMonitor->SetDesiredFailureMsg(
23781         VK_DEBUG_REPORT_ERROR_BIT_EXT,
23782         "VUID-VkBufferImageCopy-imageExtent-00207");  // width not a multiple of compressed block width
23783     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
23784                                          "VUID-vkCmdCopyBufferToImage-imageOffset-01793");  // image transfer granularity
23785     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
23786     m_errorMonitor->VerifyFound();
23787 
23788     // Copy height < compressed block size but not the full mip height
23789     region.imageExtent = {2, 1, 1};
23790     m_errorMonitor->SetDesiredFailureMsg(
23791         VK_DEBUG_REPORT_ERROR_BIT_EXT,
23792         "VUID-VkBufferImageCopy-imageExtent-00208");  // height not a multiple of compressed block width
23793     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
23794                                          "VUID-vkCmdCopyImageToBuffer-imageOffset-01794");  // image transfer granularity
23795     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
23796     m_errorMonitor->VerifyFound();
23797     m_errorMonitor->SetDesiredFailureMsg(
23798         VK_DEBUG_REPORT_ERROR_BIT_EXT,
23799         "VUID-VkBufferImageCopy-imageExtent-00208");  // height not a multiple of compressed block width
23800     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
23801                                          "VUID-vkCmdCopyBufferToImage-imageOffset-01793");  // image transfer granularity
23802     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
23803     m_errorMonitor->VerifyFound();
23804 
23805     // Offsets must be multiple of compressed block size
23806     region.imageOffset = {1, 1, 0};
23807     region.imageExtent = {1, 1, 1};
23808     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
23809                                          "VUID-VkBufferImageCopy-imageOffset-00205");  // imageOffset not a multiple of block size
23810     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
23811                                          "VUID-vkCmdCopyImageToBuffer-imageOffset-01794");  // image transfer granularity
23812     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
23813     m_errorMonitor->VerifyFound();
23814     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
23815                                          "VUID-VkBufferImageCopy-imageOffset-00205");  // imageOffset not a multiple of block size
23816     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
23817                                          "VUID-vkCmdCopyBufferToImage-imageOffset-01793");  // image transfer granularity
23818     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
23819     m_errorMonitor->VerifyFound();
23820 
23821     // Offset + extent width = mip width - should succeed
23822     region.imageOffset = {4, 4, 0};
23823     region.imageExtent = {3, 4, 1};
23824     region.imageSubresource.mipLevel = 2;
23825     m_errorMonitor->ExpectSuccess();
23826     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
23827     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
23828     m_errorMonitor->VerifyNotFound();
23829 
23830     // Offset + extent width > mip width, but still within the final compressed block - should succeed
23831     region.imageExtent = {4, 4, 1};
23832     m_errorMonitor->ExpectSuccess();
23833     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
23834     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
23835     m_errorMonitor->VerifyNotFound();
23836 
23837     // Offset + extent width < mip width and not a multiple of block width - should fail
23838     region.imageExtent = {3, 3, 1};
23839     m_errorMonitor->SetDesiredFailureMsg(
23840         VK_DEBUG_REPORT_ERROR_BIT_EXT,
23841         "VUID-VkBufferImageCopy-imageExtent-00208");  // offset+extent not a multiple of block width
23842     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
23843                                          "VUID-vkCmdCopyImageToBuffer-imageOffset-01794");  // image transfer granularity
23844     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
23845     m_errorMonitor->VerifyFound();
23846     m_errorMonitor->SetDesiredFailureMsg(
23847         VK_DEBUG_REPORT_ERROR_BIT_EXT,
23848         "VUID-VkBufferImageCopy-imageExtent-00208");  // offset+extent not a multiple of block width
23849     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
23850                                          "VUID-vkCmdCopyBufferToImage-imageOffset-01793");  // image transfer granularity
23851     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
23852     m_errorMonitor->VerifyFound();
23853 }
23854 
TEST_F(VkLayerTest,ImageBufferCopyTests)23855 TEST_F(VkLayerTest, ImageBufferCopyTests) {
23856     TEST_DESCRIPTION("Image to buffer and buffer to image tests");
23857     ASSERT_NO_FATAL_FAILURE(Init());
23858 
23859     // Bail if any dimension of transfer granularity is 0.
23860     auto index = m_device->graphics_queue_node_index_;
23861     auto queue_family_properties = m_device->phy().queue_properties();
23862     if ((queue_family_properties[index].minImageTransferGranularity.depth == 0) ||
23863         (queue_family_properties[index].minImageTransferGranularity.width == 0) ||
23864         (queue_family_properties[index].minImageTransferGranularity.height == 0)) {
23865         printf("%s Subresource copies are disallowed when xfer granularity (x|y|z) is 0. Skipped.\n", kSkipPrefix);
23866         return;
23867     }
23868 
23869     VkImageObj image_64k(m_device);        // 128^2 texels, 64k
23870     VkImageObj image_16k(m_device);        // 64^2 texels, 16k
23871     VkImageObj image_16k_depth(m_device);  // 64^2 texels, depth, 16k
23872     VkImageObj ds_image_4D_1S(m_device);   // 256^2 texels, 512kb (256k depth, 64k stencil, 192k pack)
23873     VkImageObj ds_image_3D_1S(m_device);   // 256^2 texels, 256kb (192k depth, 64k stencil)
23874     VkImageObj ds_image_2D(m_device);      // 256^2 texels, 128k (128k depth)
23875     VkImageObj ds_image_1S(m_device);      // 256^2 texels, 64k (64k stencil)
23876 
23877     image_64k.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UINT,
23878                    VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
23879                    VK_IMAGE_TILING_OPTIMAL, 0);
23880     image_16k.Init(64, 64, 1, VK_FORMAT_R8G8B8A8_UINT,
23881                    VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
23882                    VK_IMAGE_TILING_OPTIMAL, 0);
23883     ASSERT_TRUE(image_64k.initialized());
23884     ASSERT_TRUE(image_16k.initialized());
23885 
23886     // Verify all needed Depth/Stencil formats are supported
23887     bool missing_ds_support = false;
23888     VkFormatProperties props = {0, 0, 0};
23889     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D32_SFLOAT_S8_UINT, &props);
23890     missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
23891     missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
23892     missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
23893     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D24_UNORM_S8_UINT, &props);
23894     missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
23895     missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
23896     missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
23897     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D16_UNORM, &props);
23898     missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
23899     missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
23900     missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
23901     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_S8_UINT, &props);
23902     missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
23903     missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
23904     missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
23905 
23906     if (!missing_ds_support) {
23907         image_16k_depth.Init(64, 64, 1, VK_FORMAT_D24_UNORM_S8_UINT,
23908                              VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
23909         ASSERT_TRUE(image_16k_depth.initialized());
23910 
23911         ds_image_4D_1S.Init(
23912             256, 256, 1, VK_FORMAT_D32_SFLOAT_S8_UINT,
23913             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
23914             VK_IMAGE_TILING_OPTIMAL, 0);
23915         ASSERT_TRUE(ds_image_4D_1S.initialized());
23916 
23917         ds_image_3D_1S.Init(
23918             256, 256, 1, VK_FORMAT_D24_UNORM_S8_UINT,
23919             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
23920             VK_IMAGE_TILING_OPTIMAL, 0);
23921         ASSERT_TRUE(ds_image_3D_1S.initialized());
23922 
23923         ds_image_2D.Init(
23924             256, 256, 1, VK_FORMAT_D16_UNORM,
23925             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
23926             VK_IMAGE_TILING_OPTIMAL, 0);
23927         ASSERT_TRUE(ds_image_2D.initialized());
23928 
23929         ds_image_1S.Init(
23930             256, 256, 1, VK_FORMAT_S8_UINT,
23931             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
23932             VK_IMAGE_TILING_OPTIMAL, 0);
23933         ASSERT_TRUE(ds_image_1S.initialized());
23934     }
23935 
23936     // Allocate buffers
23937     VkBufferObj buffer_256k, buffer_128k, buffer_64k, buffer_16k;
23938     VkMemoryPropertyFlags reqs = 0;
23939     buffer_256k.init_as_src_and_dst(*m_device, 262144, reqs);  // 256k
23940     buffer_128k.init_as_src_and_dst(*m_device, 131072, reqs);  // 128k
23941     buffer_64k.init_as_src_and_dst(*m_device, 65536, reqs);    // 64k
23942     buffer_16k.init_as_src_and_dst(*m_device, 16384, reqs);    // 16k
23943 
23944     VkBufferImageCopy region = {};
23945     region.bufferRowLength = 0;
23946     region.bufferImageHeight = 0;
23947     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
23948     region.imageSubresource.layerCount = 1;
23949     region.imageOffset = {0, 0, 0};
23950     region.imageExtent = {64, 64, 1};
23951     region.bufferOffset = 0;
23952 
23953     // attempt copies before putting command buffer in recording state
23954     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyBufferToImage-commandBuffer-recording");
23955     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
23956     m_errorMonitor->VerifyFound();
23957 
23958     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImageToBuffer-commandBuffer-recording");
23959     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1, &region);
23960     m_errorMonitor->VerifyFound();
23961 
23962     // start recording
23963     m_commandBuffer->begin();
23964 
23965     // successful copies
23966     m_errorMonitor->ExpectSuccess();
23967     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
23968     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
23969     region.imageOffset.x = 16;  // 16k copy, offset requires larger image
23970     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
23971     region.imageExtent.height = 78;  // > 16k copy requires larger buffer & image
23972     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
23973     region.imageOffset.x = 0;
23974     region.imageExtent.height = 64;
23975     region.bufferOffset = 256;  // 16k copy with buffer offset, requires larger buffer
23976     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1, &region);
23977     m_errorMonitor->VerifyNotFound();
23978 
23979     // image/buffer too small (extent too large) on copy to image
23980     region.imageExtent = {65, 64, 1};
23981     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
23982                                          "VUID-vkCmdCopyBufferToImage-pRegions-00171");  // buffer too small
23983     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
23984     m_errorMonitor->VerifyFound();
23985 
23986     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
23987                                          "VUID-vkCmdCopyBufferToImage-pRegions-00172");  // image too small
23988     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
23989     m_errorMonitor->VerifyFound();
23990 
23991     // image/buffer too small (offset) on copy to image
23992     region.imageExtent = {64, 64, 1};
23993     region.imageOffset = {0, 4, 0};
23994     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
23995                                          "VUID-vkCmdCopyBufferToImage-pRegions-00171");  // buffer too small
23996     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
23997     m_errorMonitor->VerifyFound();
23998 
23999     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
24000                                          "VUID-vkCmdCopyBufferToImage-pRegions-00172");  // image too small
24001     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
24002     m_errorMonitor->VerifyFound();
24003 
24004     // image/buffer too small on copy to buffer
24005     region.imageExtent = {64, 64, 1};
24006     region.imageOffset = {0, 0, 0};
24007     region.bufferOffset = 4;
24008     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
24009                                          "VUID-vkCmdCopyImageToBuffer-pRegions-00183");  // buffer too small
24010     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
24011     m_errorMonitor->VerifyFound();
24012 
24013     region.imageExtent = {64, 65, 1};
24014     region.bufferOffset = 0;
24015     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
24016                                          "VUID-vkCmdCopyImageToBuffer-pRegions-00182");  // image too small
24017     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1, &region);
24018     m_errorMonitor->VerifyFound();
24019 
24020     // buffer size OK but rowlength causes loose packing
24021     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImageToBuffer-pRegions-00183");
24022     region.imageExtent = {64, 64, 1};
24023     region.bufferRowLength = 68;
24024     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
24025     m_errorMonitor->VerifyFound();
24026 
24027     // An extent with zero area should produce a warning, but no error
24028     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_ERROR_BIT_EXT, "} has zero area");
24029     region.imageExtent.width = 0;
24030     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
24031     m_errorMonitor->VerifyFound();
24032 
24033     // aspect bits
24034     region.imageExtent = {64, 64, 1};
24035     region.bufferRowLength = 0;
24036     region.bufferImageHeight = 0;
24037     if (!missing_ds_support) {
24038         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
24039                                              "VUID-VkBufferImageCopy-aspectMask-00212");  // more than 1 aspect bit set
24040         region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
24041         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_depth.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
24042                                &region);
24043         m_errorMonitor->VerifyFound();
24044 
24045         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
24046                                              "VUID-VkBufferImageCopy-aspectMask-00211");  // different mis-matched aspect
24047         region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
24048         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_depth.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
24049                                &region);
24050         m_errorMonitor->VerifyFound();
24051     }
24052 
24053     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
24054                                          "VUID-VkBufferImageCopy-aspectMask-00211");  // mis-matched aspect
24055     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
24056     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
24057     m_errorMonitor->VerifyFound();
24058     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
24059 
24060     // Out-of-range mip levels should fail
24061     region.imageSubresource.mipLevel = image_16k.create_info().mipLevels + 1;
24062     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImageToBuffer-imageSubresource-01703");
24063     m_errorMonitor->SetDesiredFailureMsg(
24064         VK_DEBUG_REPORT_ERROR_BIT_EXT,
24065         "VUID-vkCmdCopyImageToBuffer-pRegions-00182");  // unavoidable "region exceeds image bounds" for non-existent mip
24066     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
24067     m_errorMonitor->VerifyFound();
24068     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyBufferToImage-imageSubresource-01701");
24069     m_errorMonitor->SetDesiredFailureMsg(
24070         VK_DEBUG_REPORT_ERROR_BIT_EXT,
24071         "VUID-vkCmdCopyBufferToImage-pRegions-00172");  // unavoidable "region exceeds image bounds" for non-existent mip
24072     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
24073     m_errorMonitor->VerifyFound();
24074     region.imageSubresource.mipLevel = 0;
24075 
24076     // Out-of-range array layers should fail
24077     region.imageSubresource.baseArrayLayer = image_16k.create_info().arrayLayers;
24078     region.imageSubresource.layerCount = 1;
24079     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImageToBuffer-imageSubresource-01704");
24080     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
24081     m_errorMonitor->VerifyFound();
24082     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyBufferToImage-imageSubresource-01702");
24083     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
24084     m_errorMonitor->VerifyFound();
24085     region.imageSubresource.baseArrayLayer = 0;
24086 
24087     // Layout mismatch should fail
24088     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImageToBuffer-srcImageLayout-00189");
24089     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer_16k.handle(),
24090                            1, &region);
24091     m_errorMonitor->VerifyFound();
24092     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyBufferToImage-dstImageLayout-00180");
24093     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
24094                            1, &region);
24095     m_errorMonitor->VerifyFound();
24096 
24097     // Test Depth/Stencil copies
24098     if (missing_ds_support) {
24099         printf("%s Depth / Stencil formats unsupported - skipping D/S tests.\n", kSkipPrefix);
24100     } else {
24101         VkBufferImageCopy ds_region = {};
24102         ds_region.bufferOffset = 0;
24103         ds_region.bufferRowLength = 0;
24104         ds_region.bufferImageHeight = 0;
24105         ds_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
24106         ds_region.imageSubresource.mipLevel = 0;
24107         ds_region.imageSubresource.baseArrayLayer = 0;
24108         ds_region.imageSubresource.layerCount = 1;
24109         ds_region.imageOffset = {0, 0, 0};
24110         ds_region.imageExtent = {256, 256, 1};
24111 
24112         // Depth copies that should succeed
24113         m_errorMonitor->ExpectSuccess();  // Extract 4b depth per texel, pack into 256k buffer
24114         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
24115                                buffer_256k.handle(), 1, &ds_region);
24116         m_errorMonitor->VerifyNotFound();
24117 
24118         m_errorMonitor->ExpectSuccess();  // Extract 3b depth per texel, pack (loose) into 256k buffer
24119         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
24120                                buffer_256k.handle(), 1, &ds_region);
24121         m_errorMonitor->VerifyNotFound();
24122 
24123         m_errorMonitor->ExpectSuccess();  // Copy 2b depth per texel, into 128k buffer
24124         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_2D.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
24125                                buffer_128k.handle(), 1, &ds_region);
24126         m_errorMonitor->VerifyNotFound();
24127 
24128         // Depth copies that should fail
24129         ds_region.bufferOffset = 4;
24130         m_errorMonitor->SetDesiredFailureMsg(
24131             VK_DEBUG_REPORT_ERROR_BIT_EXT,
24132             "VUID-vkCmdCopyImageToBuffer-pRegions-00183");  // Extract 4b depth per texel, pack into 256k buffer
24133         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
24134                                buffer_256k.handle(), 1, &ds_region);
24135         m_errorMonitor->VerifyFound();
24136 
24137         m_errorMonitor->SetDesiredFailureMsg(
24138             VK_DEBUG_REPORT_ERROR_BIT_EXT,
24139             "VUID-vkCmdCopyImageToBuffer-pRegions-00183");  // Extract 3b depth per texel, pack (loose) into 256k buffer
24140         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
24141                                buffer_256k.handle(), 1, &ds_region);
24142         m_errorMonitor->VerifyFound();
24143 
24144         m_errorMonitor->SetDesiredFailureMsg(
24145             VK_DEBUG_REPORT_ERROR_BIT_EXT,
24146             "VUID-vkCmdCopyImageToBuffer-pRegions-00183");  // Copy 2b depth per texel, into 128k buffer
24147         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_2D.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
24148                                buffer_128k.handle(), 1, &ds_region);
24149         m_errorMonitor->VerifyFound();
24150 
24151         // Stencil copies that should succeed
24152         ds_region.bufferOffset = 0;
24153         ds_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
24154         m_errorMonitor->ExpectSuccess();  // Extract 1b stencil per texel, pack into 64k buffer
24155         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
24156                                buffer_64k.handle(), 1, &ds_region);
24157         m_errorMonitor->VerifyNotFound();
24158 
24159         m_errorMonitor->ExpectSuccess();  // Extract 1b stencil per texel, pack into 64k buffer
24160         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
24161                                buffer_64k.handle(), 1, &ds_region);
24162         m_errorMonitor->VerifyNotFound();
24163 
24164         m_errorMonitor->ExpectSuccess();  // Copy 1b depth per texel, into 64k buffer
24165         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
24166                                buffer_64k.handle(), 1, &ds_region);
24167         m_errorMonitor->VerifyNotFound();
24168 
24169         // Stencil copies that should fail
24170         m_errorMonitor->SetDesiredFailureMsg(
24171             VK_DEBUG_REPORT_ERROR_BIT_EXT,
24172             "VUID-vkCmdCopyImageToBuffer-pRegions-00183");  // Extract 1b stencil per texel, pack into 64k buffer
24173         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
24174                                buffer_16k.handle(), 1, &ds_region);
24175         m_errorMonitor->VerifyFound();
24176 
24177         m_errorMonitor->SetDesiredFailureMsg(
24178             VK_DEBUG_REPORT_ERROR_BIT_EXT,
24179             "VUID-vkCmdCopyImageToBuffer-pRegions-00183");  // Extract 1b stencil per texel, pack into 64k buffer
24180         ds_region.bufferRowLength = 260;
24181         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
24182                                buffer_64k.handle(), 1, &ds_region);
24183         m_errorMonitor->VerifyFound();
24184 
24185         ds_region.bufferRowLength = 0;
24186         ds_region.bufferOffset = 4;
24187         m_errorMonitor->SetDesiredFailureMsg(
24188             VK_DEBUG_REPORT_ERROR_BIT_EXT,
24189             "VUID-vkCmdCopyImageToBuffer-pRegions-00183");  // Copy 1b depth per texel, into 64k buffer
24190         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
24191                                buffer_64k.handle(), 1, &ds_region);
24192         m_errorMonitor->VerifyFound();
24193     }
24194 
24195     // Test compressed formats, if supported
24196     VkPhysicalDeviceFeatures device_features = {};
24197     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
24198     if (!(device_features.textureCompressionBC || device_features.textureCompressionETC2 ||
24199           device_features.textureCompressionASTC_LDR)) {
24200         printf("%s No compressed formats supported - block compression tests skipped.\n", kSkipPrefix);
24201     } else {
24202         VkImageObj image_16k_4x4comp(m_device);   // 128^2 texels as 32^2 compressed (4x4) blocks, 16k
24203         VkImageObj image_NPOT_4x4comp(m_device);  // 130^2 texels as 33^2 compressed (4x4) blocks
24204         if (device_features.textureCompressionBC) {
24205             image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_BC3_SRGB_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL,
24206                                    0);
24207             image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_BC3_SRGB_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL,
24208                                     0);
24209         } else if (device_features.textureCompressionETC2) {
24210             image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
24211                                    VK_IMAGE_TILING_OPTIMAL, 0);
24212             image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
24213                                     VK_IMAGE_TILING_OPTIMAL, 0);
24214         } else {
24215             image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
24216                                    VK_IMAGE_TILING_OPTIMAL, 0);
24217             image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
24218                                     VK_IMAGE_TILING_OPTIMAL, 0);
24219         }
24220         ASSERT_TRUE(image_16k_4x4comp.initialized());
24221 
24222         // Just fits
24223         m_errorMonitor->ExpectSuccess();
24224         region.imageExtent = {128, 128, 1};
24225         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(),
24226                                1, &region);
24227         m_errorMonitor->VerifyNotFound();
24228 
24229         // with offset, too big for buffer
24230         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImageToBuffer-pRegions-00183");
24231         region.bufferOffset = 16;
24232         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(),
24233                                1, &region);
24234         m_errorMonitor->VerifyFound();
24235         region.bufferOffset = 0;
24236 
24237         // extents that are not a multiple of compressed block size
24238         m_errorMonitor->SetDesiredFailureMsg(
24239             VK_DEBUG_REPORT_ERROR_BIT_EXT,
24240             "VUID-VkBufferImageCopy-imageExtent-00207");  // extent width not a multiple of block size
24241         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
24242                                              "VUID-vkCmdCopyImageToBuffer-imageOffset-01794");  // image transfer granularity
24243         region.imageExtent.width = 66;
24244         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(),
24245                                1, &region);
24246         m_errorMonitor->VerifyFound();
24247         region.imageExtent.width = 128;
24248 
24249         m_errorMonitor->SetDesiredFailureMsg(
24250             VK_DEBUG_REPORT_ERROR_BIT_EXT,
24251             "VUID-VkBufferImageCopy-imageExtent-00208");  // extent height not a multiple of block size
24252         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
24253                                              "VUID-vkCmdCopyImageToBuffer-imageOffset-01794");  // image transfer granularity
24254         region.imageExtent.height = 2;
24255         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(),
24256                                1, &region);
24257         m_errorMonitor->VerifyFound();
24258         region.imageExtent.height = 128;
24259 
24260         // TODO: All available compressed formats are 2D, with block depth of 1. Unable to provoke VU_01277.
24261 
24262         // non-multiple extents are allowed if at the far edge of a non-block-multiple image - these should pass
24263         m_errorMonitor->ExpectSuccess();
24264         region.imageExtent.width = 66;
24265         region.imageOffset.x = 64;
24266         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(),
24267                                1, &region);
24268         region.imageExtent.width = 16;
24269         region.imageOffset.x = 0;
24270         region.imageExtent.height = 2;
24271         region.imageOffset.y = 128;
24272         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(),
24273                                1, &region);
24274         m_errorMonitor->VerifyNotFound();
24275         region.imageOffset = {0, 0, 0};
24276 
24277         // buffer offset must be a multiple of texel block size (16)
24278         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferImageCopy-bufferOffset-00206");
24279         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferImageCopy-bufferOffset-00193");
24280         region.imageExtent = {64, 64, 1};
24281         region.bufferOffset = 24;
24282         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(),
24283                                1, &region);
24284         m_errorMonitor->VerifyFound();
24285 
24286         // rowlength not a multiple of block width (4)
24287         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferImageCopy-bufferRowLength-00203");
24288         region.bufferOffset = 0;
24289         region.bufferRowLength = 130;
24290         region.bufferImageHeight = 0;
24291         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(),
24292                                1, &region);
24293         m_errorMonitor->VerifyFound();
24294 
24295         // imageheight not a multiple of block height (4)
24296         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferImageCopy-bufferImageHeight-00204");
24297         region.bufferRowLength = 0;
24298         region.bufferImageHeight = 130;
24299         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(),
24300                                1, &region);
24301         m_errorMonitor->VerifyFound();
24302     }
24303 }
24304 
TEST_F(VkLayerTest,MiscImageLayerTests)24305 TEST_F(VkLayerTest, MiscImageLayerTests) {
24306     TEST_DESCRIPTION("Image-related tests that don't belong elsewhere");
24307 
24308     ASSERT_NO_FATAL_FAILURE(Init());
24309 
24310     // TODO: Ideally we should check if a format is supported, before using it.
24311     VkImageObj image(m_device);
24312     image.Init(128, 128, 1, VK_FORMAT_R16G16B16A16_UINT, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);  // 64bpp
24313     ASSERT_TRUE(image.initialized());
24314     VkBufferObj buffer;
24315     VkMemoryPropertyFlags reqs = 0;
24316     buffer.init_as_src(*m_device, 128 * 128 * 8, reqs);
24317     VkBufferImageCopy region = {};
24318     region.bufferRowLength = 128;
24319     region.bufferImageHeight = 128;
24320     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
24321     // layerCount can't be 0 - Expect MISMATCHED_IMAGE_ASPECT
24322     region.imageSubresource.layerCount = 1;
24323     region.imageExtent.height = 4;
24324     region.imageExtent.width = 4;
24325     region.imageExtent.depth = 1;
24326 
24327     VkImageObj image2(m_device);
24328     image2.Init(128, 128, 1, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);  // 16bpp
24329     ASSERT_TRUE(image2.initialized());
24330     VkBufferObj buffer2;
24331     VkMemoryPropertyFlags reqs2 = 0;
24332     buffer2.init_as_src(*m_device, 128 * 128 * 2, reqs2);
24333     VkBufferImageCopy region2 = {};
24334     region2.bufferRowLength = 128;
24335     region2.bufferImageHeight = 128;
24336     region2.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
24337     // layerCount can't be 0 - Expect MISMATCHED_IMAGE_ASPECT
24338     region2.imageSubresource.layerCount = 1;
24339     region2.imageExtent.height = 4;
24340     region2.imageExtent.width = 4;
24341     region2.imageExtent.depth = 1;
24342     m_commandBuffer->begin();
24343 
24344     // Image must have offset.z of 0 and extent.depth of 1
24345     // Introduce failure by setting imageExtent.depth to 0
24346     region.imageExtent.depth = 0;
24347     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferImageCopy-srcImage-00201");
24348     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
24349                            &region);
24350     m_errorMonitor->VerifyFound();
24351 
24352     region.imageExtent.depth = 1;
24353 
24354     // Image must have offset.z of 0 and extent.depth of 1
24355     // Introduce failure by setting imageOffset.z to 4
24356     // Note: Also (unavoidably) triggers 'region exceeds image' #1228
24357     region.imageOffset.z = 4;
24358     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferImageCopy-srcImage-00201");
24359     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyBufferToImage-pRegions-00172");
24360     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
24361                            &region);
24362     m_errorMonitor->VerifyFound();
24363 
24364     region.imageOffset.z = 0;
24365     // BufferOffset must be a multiple of the calling command's VkImage parameter's texel size
24366     // Introduce failure by setting bufferOffset to 1 and 1/2 texels
24367     region.bufferOffset = 4;
24368     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferImageCopy-bufferOffset-00193");
24369     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
24370                            &region);
24371     m_errorMonitor->VerifyFound();
24372 
24373     // BufferOffset must be a multiple of 4
24374     // Introduce failure by setting bufferOffset to a value not divisible by 4
24375     region2.bufferOffset = 6;
24376     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferImageCopy-bufferOffset-00194");
24377     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer2.handle(), image2.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
24378                            &region2);
24379     m_errorMonitor->VerifyFound();
24380 
24381     // BufferRowLength must be 0, or greater than or equal to the width member of imageExtent
24382     region.bufferOffset = 0;
24383     region.imageExtent.height = 128;
24384     region.imageExtent.width = 128;
24385     // Introduce failure by setting bufferRowLength > 0 but less than width
24386     region.bufferRowLength = 64;
24387     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferImageCopy-bufferRowLength-00195");
24388     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
24389                            &region);
24390     m_errorMonitor->VerifyFound();
24391 
24392     // BufferImageHeight must be 0, or greater than or equal to the height member of imageExtent
24393     region.bufferRowLength = 128;
24394     // Introduce failure by setting bufferRowHeight > 0 but less than height
24395     region.bufferImageHeight = 64;
24396     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferImageCopy-bufferImageHeight-00196");
24397     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
24398                            &region);
24399     m_errorMonitor->VerifyFound();
24400 
24401     region.bufferImageHeight = 128;
24402     VkImageObj intImage1(m_device);
24403     intImage1.Init(128, 128, 1, VK_FORMAT_R8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
24404     intImage1.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
24405     VkImageObj intImage2(m_device);
24406     intImage2.Init(128, 128, 1, VK_FORMAT_R8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
24407     intImage2.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
24408     VkImageBlit blitRegion = {};
24409     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
24410     blitRegion.srcSubresource.baseArrayLayer = 0;
24411     blitRegion.srcSubresource.layerCount = 1;
24412     blitRegion.srcSubresource.mipLevel = 0;
24413     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
24414     blitRegion.dstSubresource.baseArrayLayer = 0;
24415     blitRegion.dstSubresource.layerCount = 1;
24416     blitRegion.dstSubresource.mipLevel = 0;
24417     blitRegion.srcOffsets[0] = {128, 0, 0};
24418     blitRegion.srcOffsets[1] = {128, 128, 1};
24419     blitRegion.dstOffsets[0] = {0, 128, 0};
24420     blitRegion.dstOffsets[1] = {128, 128, 1};
24421 
24422     // Look for NULL-blit warning
24423     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
24424                                          "vkCmdBlitImage(): pRegions[0].srcOffsets specify a zero-volume area.");
24425     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
24426                                          "vkCmdBlitImage(): pRegions[0].dstOffsets specify a zero-volume area.");
24427     vkCmdBlitImage(m_commandBuffer->handle(), intImage1.handle(), intImage1.Layout(), intImage2.handle(), intImage2.Layout(), 1,
24428                    &blitRegion, VK_FILTER_LINEAR);
24429     m_errorMonitor->VerifyFound();
24430 }
24431 
GPDIFPHelper(VkPhysicalDevice dev,const VkImageCreateInfo * ci,VkImageFormatProperties * limits=nullptr)24432 VkResult GPDIFPHelper(VkPhysicalDevice dev, const VkImageCreateInfo *ci, VkImageFormatProperties *limits = nullptr) {
24433     VkImageFormatProperties tmp_limits;
24434     limits = limits ? limits : &tmp_limits;
24435     return vkGetPhysicalDeviceImageFormatProperties(dev, ci->format, ci->imageType, ci->tiling, ci->usage, ci->flags, limits);
24436 }
24437 
TEST_F(VkLayerTest,CreateImageMiscErrors)24438 TEST_F(VkLayerTest, CreateImageMiscErrors) {
24439     TEST_DESCRIPTION("Misc leftover valid usage errors in VkImageCreateInfo struct");
24440 
24441     VkPhysicalDeviceFeatures features{};
24442     ASSERT_NO_FATAL_FAILURE(Init(&features));
24443 
24444     VkImage null_image;  // throwaway target for all the vkCreateImage
24445 
24446     VkImageCreateInfo tmp_img_ci = {};
24447     tmp_img_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
24448     tmp_img_ci.flags = 0;                          // assumably any is supported
24449     tmp_img_ci.imageType = VK_IMAGE_TYPE_2D;       // any is supported
24450     tmp_img_ci.format = VK_FORMAT_R8G8B8A8_UNORM;  // has mandatory support for all usages
24451     tmp_img_ci.extent = {64, 64, 1};               // limit is 256 for 3D, or 4096
24452     tmp_img_ci.mipLevels = 1;                      // any is supported
24453     tmp_img_ci.arrayLayers = 1;                    // limit is 256
24454     tmp_img_ci.samples = VK_SAMPLE_COUNT_1_BIT;    // needs to be 1 if TILING_LINEAR
24455     // if VK_IMAGE_TILING_LINEAR imageType must be 2D, usage must be TRANSFER, and levels layers samplers all 1
24456     tmp_img_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
24457     tmp_img_ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;  // depends on format
24458     tmp_img_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
24459     const VkImageCreateInfo safe_image_ci = tmp_img_ci;
24460 
24461     ASSERT_VK_SUCCESS(GPDIFPHelper(gpu(), &safe_image_ci));
24462 
24463     {
24464         VkImageCreateInfo image_ci = safe_image_ci;
24465         image_ci.sharingMode = VK_SHARING_MODE_CONCURRENT;
24466         image_ci.queueFamilyIndexCount = 2;
24467         image_ci.pQueueFamilyIndices = nullptr;
24468 
24469         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-sharingMode-00941");
24470         vkCreateImage(m_device->handle(), &image_ci, NULL, &null_image);
24471         m_errorMonitor->VerifyFound();
24472     }
24473 
24474     {
24475         VkImageCreateInfo image_ci = safe_image_ci;
24476         image_ci.sharingMode = VK_SHARING_MODE_CONCURRENT;
24477         image_ci.queueFamilyIndexCount = 1;
24478         const uint32_t queue_family = 0;
24479         image_ci.pQueueFamilyIndices = &queue_family;
24480 
24481         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-sharingMode-00942");
24482         vkCreateImage(m_device->handle(), &image_ci, NULL, &null_image);
24483         m_errorMonitor->VerifyFound();
24484     }
24485 
24486     {
24487         VkImageCreateInfo image_ci = safe_image_ci;
24488         image_ci.format = VK_FORMAT_UNDEFINED;
24489 
24490         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-format-00943");
24491         vkCreateImage(m_device->handle(), &image_ci, NULL, &null_image);
24492         m_errorMonitor->VerifyFound();
24493     }
24494 
24495     {
24496         VkImageCreateInfo image_ci = safe_image_ci;
24497         image_ci.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
24498         image_ci.arrayLayers = 6;
24499         image_ci.imageType = VK_IMAGE_TYPE_1D;
24500         image_ci.extent = {64, 1, 1};
24501 
24502         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-flags-00949");
24503         vkCreateImage(m_device->handle(), &image_ci, NULL, &null_image);
24504         m_errorMonitor->VerifyFound();
24505 
24506         image_ci = safe_image_ci;
24507         image_ci.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
24508         image_ci.imageType = VK_IMAGE_TYPE_3D;
24509         image_ci.extent = {4, 4, 4};
24510 
24511         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-flags-00949");
24512         vkCreateImage(m_device->handle(), &image_ci, NULL, &null_image);
24513         m_errorMonitor->VerifyFound();
24514     }
24515 
24516     {
24517         VkImageCreateInfo image_ci = safe_image_ci;
24518         image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;  // always has 4 samples support
24519         image_ci.samples = VK_SAMPLE_COUNT_4_BIT;
24520         image_ci.imageType = VK_IMAGE_TYPE_3D;
24521         image_ci.extent = {4, 4, 4};
24522 
24523         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-samples-02257");
24524         vkCreateImage(m_device->handle(), &image_ci, NULL, &null_image);
24525         m_errorMonitor->VerifyFound();
24526 
24527         image_ci = safe_image_ci;
24528         image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;  // always has 4 samples support
24529         image_ci.samples = VK_SAMPLE_COUNT_4_BIT;
24530         image_ci.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
24531         image_ci.arrayLayers = 6;
24532 
24533         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-samples-02257");
24534         vkCreateImage(m_device->handle(), &image_ci, NULL, &null_image);
24535         m_errorMonitor->VerifyFound();
24536 
24537         image_ci = safe_image_ci;
24538         image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;  // always has 4 samples support
24539         image_ci.samples = VK_SAMPLE_COUNT_4_BIT;
24540         image_ci.tiling = VK_IMAGE_TILING_LINEAR;
24541 
24542         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-samples-02257");
24543         vkCreateImage(m_device->handle(), &image_ci, NULL, &null_image);
24544         m_errorMonitor->VerifyFound();
24545 
24546         image_ci = safe_image_ci;
24547         image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;  // always has 4 samples support
24548         image_ci.samples = VK_SAMPLE_COUNT_4_BIT;
24549         image_ci.mipLevels = 2;
24550 
24551         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-samples-02257");
24552         vkCreateImage(m_device->handle(), &image_ci, NULL, &null_image);
24553         m_errorMonitor->VerifyFound();
24554     }
24555 
24556     {
24557         VkImageCreateInfo image_ci = safe_image_ci;
24558         image_ci.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
24559         image_ci.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
24560 
24561         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-usage-00963");
24562         vkCreateImage(m_device->handle(), &image_ci, NULL, &null_image);
24563         m_errorMonitor->VerifyFound();
24564 
24565         image_ci.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
24566 
24567         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-usage-00966");
24568         vkCreateImage(m_device->handle(), &image_ci, NULL, &null_image);
24569         m_errorMonitor->VerifyFound();
24570 
24571         image_ci.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
24572         image_ci.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
24573 
24574         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-usage-00963");
24575         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-usage-00966");
24576         vkCreateImage(m_device->handle(), &image_ci, NULL, &null_image);
24577         m_errorMonitor->VerifyFound();
24578     }
24579 
24580     {
24581         VkImageCreateInfo image_ci = safe_image_ci;
24582         image_ci.flags = VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
24583 
24584         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-flags-00969");
24585         vkCreateImage(m_device->handle(), &image_ci, NULL, &null_image);
24586         m_errorMonitor->VerifyFound();
24587     }
24588 
24589     // InitialLayout not VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREDEFINED
24590     {
24591         VkImageCreateInfo image_ci = safe_image_ci;
24592         image_ci.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
24593 
24594         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-initialLayout-00993");
24595         vkCreateImage(m_device->handle(), &image_ci, NULL, &null_image);
24596         m_errorMonitor->VerifyFound();
24597     }
24598 }
24599 
TEST_F(VkLayerTest,CreateImageMinLimitsViolation)24600 TEST_F(VkLayerTest, CreateImageMinLimitsViolation) {
24601     TEST_DESCRIPTION("Create invalid image with invalid parameters violation minimum limit, such as being zero.");
24602 
24603     ASSERT_NO_FATAL_FAILURE(Init());
24604 
24605     VkImage null_image;  // throwaway target for all the vkCreateImage
24606 
24607     VkImageCreateInfo tmp_img_ci = {};
24608     tmp_img_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
24609     tmp_img_ci.flags = 0;                          // assumably any is supported
24610     tmp_img_ci.imageType = VK_IMAGE_TYPE_2D;       // any is supported
24611     tmp_img_ci.format = VK_FORMAT_R8G8B8A8_UNORM;  // has mandatory support for all usages
24612     tmp_img_ci.extent = {1, 1, 1};                 // limit is 256 for 3D, or 4096
24613     tmp_img_ci.mipLevels = 1;                      // any is supported
24614     tmp_img_ci.arrayLayers = 1;                    // limit is 256
24615     tmp_img_ci.samples = VK_SAMPLE_COUNT_1_BIT;    // needs to be 1 if TILING_LINEAR
24616     // if VK_IMAGE_TILING_LINEAR imageType must be 2D, usage must be TRANSFER, and levels layers samplers all 1
24617     tmp_img_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
24618     tmp_img_ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;  // depends on format
24619     tmp_img_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
24620     const VkImageCreateInfo safe_image_ci = tmp_img_ci;
24621 
24622     enum Dimension { kWidth = 0x1, kHeight = 0x2, kDepth = 0x4 };
24623 
24624     for (underlying_type<Dimension>::type bad_dimensions = 0x1; bad_dimensions < 0x8; ++bad_dimensions) {
24625         VkExtent3D extent = {1, 1, 1};
24626 
24627         if (bad_dimensions & kWidth) {
24628             extent.width = 0;
24629             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-extent-00944");
24630         }
24631 
24632         if (bad_dimensions & kHeight) {
24633             extent.height = 0;
24634             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-extent-00945");
24635         }
24636 
24637         if (bad_dimensions & kDepth) {
24638             extent.depth = 0;
24639             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-extent-00946");
24640         }
24641 
24642         VkImageCreateInfo bad_image_ci = safe_image_ci;
24643         bad_image_ci.imageType = VK_IMAGE_TYPE_3D;  // has to be 3D otherwise it might trigger the non-1 error instead
24644         bad_image_ci.extent = extent;
24645 
24646         vkCreateImage(m_device->device(), &bad_image_ci, NULL, &null_image);
24647 
24648         m_errorMonitor->VerifyFound();
24649     }
24650 
24651     {
24652         VkImageCreateInfo bad_image_ci = safe_image_ci;
24653         bad_image_ci.mipLevels = 0;
24654 
24655         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-mipLevels-00947");
24656         vkCreateImage(m_device->device(), &bad_image_ci, NULL, &null_image);
24657         m_errorMonitor->VerifyFound();
24658     }
24659 
24660     {
24661         VkImageCreateInfo bad_image_ci = safe_image_ci;
24662         bad_image_ci.arrayLayers = 0;
24663 
24664         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-arrayLayers-00948");
24665         vkCreateImage(m_device->device(), &bad_image_ci, NULL, &null_image);
24666         m_errorMonitor->VerifyFound();
24667     }
24668 
24669     {
24670         VkImageCreateInfo bad_image_ci = safe_image_ci;
24671         bad_image_ci.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
24672         bad_image_ci.arrayLayers = 5;
24673 
24674         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-imageType-00954");
24675         vkCreateImage(m_device->device(), &bad_image_ci, NULL, &null_image);
24676         m_errorMonitor->VerifyFound();
24677 
24678         bad_image_ci.arrayLayers = 6;
24679         bad_image_ci.extent = {64, 63, 1};
24680 
24681         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-imageType-00954");
24682         vkCreateImage(m_device->device(), &bad_image_ci, NULL, &null_image);
24683         m_errorMonitor->VerifyFound();
24684     }
24685 
24686     {
24687         VkImageCreateInfo bad_image_ci = safe_image_ci;
24688         bad_image_ci.imageType = VK_IMAGE_TYPE_1D;
24689         bad_image_ci.extent = {64, 2, 1};
24690 
24691         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-imageType-00956");
24692         vkCreateImage(m_device->device(), &bad_image_ci, NULL, &null_image);
24693         m_errorMonitor->VerifyFound();
24694 
24695         bad_image_ci.imageType = VK_IMAGE_TYPE_1D;
24696         bad_image_ci.extent = {64, 1, 2};
24697 
24698         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-imageType-00956");
24699         vkCreateImage(m_device->device(), &bad_image_ci, NULL, &null_image);
24700         m_errorMonitor->VerifyFound();
24701 
24702         bad_image_ci.imageType = VK_IMAGE_TYPE_2D;
24703         bad_image_ci.extent = {64, 64, 2};
24704 
24705         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-imageType-00957");
24706         vkCreateImage(m_device->device(), &bad_image_ci, NULL, &null_image);
24707         m_errorMonitor->VerifyFound();
24708 
24709         bad_image_ci.imageType = VK_IMAGE_TYPE_2D;
24710         bad_image_ci.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
24711         bad_image_ci.arrayLayers = 6;
24712         bad_image_ci.extent = {64, 64, 2};
24713 
24714         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-imageType-00957");
24715         vkCreateImage(m_device->device(), &bad_image_ci, NULL, &null_image);
24716         m_errorMonitor->VerifyFound();
24717     }
24718 
24719     {
24720         VkImageCreateInfo bad_image_ci = safe_image_ci;
24721         bad_image_ci.imageType = VK_IMAGE_TYPE_3D;
24722         bad_image_ci.arrayLayers = 2;
24723 
24724         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-imageType-00961");
24725         vkCreateImage(m_device->device(), &bad_image_ci, NULL, &null_image);
24726         m_errorMonitor->VerifyFound();
24727     }
24728 }
24729 
FindFormatLinearWithoutMips(VkPhysicalDevice gpu,VkImageCreateInfo image_ci)24730 VkFormat FindFormatLinearWithoutMips(VkPhysicalDevice gpu, VkImageCreateInfo image_ci) {
24731     image_ci.tiling = VK_IMAGE_TILING_LINEAR;
24732 
24733     const VkFormat first_vk_format = static_cast<VkFormat>(1);
24734     const VkFormat last_vk_format = static_cast<VkFormat>(130);  // avoid compressed/feature protected, otherwise 184
24735 
24736     for (VkFormat format = first_vk_format; format <= last_vk_format; format = static_cast<VkFormat>(format + 1)) {
24737         image_ci.format = format;
24738 
24739         // WORKAROUND for dev_sim and mock_icd not containing valid format limits yet
24740         VkFormatProperties format_props;
24741         vkGetPhysicalDeviceFormatProperties(gpu, format, &format_props);
24742         const VkFormatFeatureFlags core_filter = 0x1FFF;
24743         const auto features = (image_ci.tiling == VK_IMAGE_TILING_LINEAR) ? format_props.linearTilingFeatures & core_filter
24744                                                                           : format_props.optimalTilingFeatures & core_filter;
24745         if (!(features & core_filter)) continue;
24746 
24747         VkImageFormatProperties img_limits;
24748         if (VK_SUCCESS == GPDIFPHelper(gpu, &image_ci, &img_limits) && img_limits.maxMipLevels == 1) return format;
24749     }
24750 
24751     return VK_FORMAT_UNDEFINED;
24752 }
24753 
FindFormatWithoutSamples(VkPhysicalDevice gpu,VkImageCreateInfo & image_ci)24754 bool FindFormatWithoutSamples(VkPhysicalDevice gpu, VkImageCreateInfo &image_ci) {
24755     const VkFormat first_vk_format = static_cast<VkFormat>(1);
24756     const VkFormat last_vk_format = static_cast<VkFormat>(130);  // avoid compressed/feature protected, otherwise 184
24757 
24758     for (VkFormat format = first_vk_format; format <= last_vk_format; format = static_cast<VkFormat>(format + 1)) {
24759         image_ci.format = format;
24760 
24761         // WORKAROUND for dev_sim and mock_icd not containing valid format limits yet
24762         VkFormatProperties format_props;
24763         vkGetPhysicalDeviceFormatProperties(gpu, format, &format_props);
24764         const VkFormatFeatureFlags core_filter = 0x1FFF;
24765         const auto features = (image_ci.tiling == VK_IMAGE_TILING_LINEAR) ? format_props.linearTilingFeatures & core_filter
24766                                                                           : format_props.optimalTilingFeatures & core_filter;
24767         if (!(features & core_filter)) continue;
24768 
24769         for (VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_64_BIT; samples > 0;
24770              samples = static_cast<VkSampleCountFlagBits>(samples >> 1)) {
24771             image_ci.samples = samples;
24772             VkImageFormatProperties img_limits;
24773             if (VK_SUCCESS == GPDIFPHelper(gpu, &image_ci, &img_limits) && !(img_limits.sampleCounts & samples)) return true;
24774         }
24775     }
24776 
24777     return false;
24778 }
24779 
TEST_F(VkLayerTest,CreateImageMaxLimitsViolation)24780 TEST_F(VkLayerTest, CreateImageMaxLimitsViolation) {
24781     TEST_DESCRIPTION("Create invalid image with invalid parameters exceeding physical device limits.");
24782 
24783     ASSERT_NO_FATAL_FAILURE(Init());
24784 
24785     VkImage null_image;  // throwaway target for all the vkCreateImage
24786 
24787     VkImageCreateInfo tmp_img_ci = {};
24788     tmp_img_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
24789     tmp_img_ci.flags = 0;                          // assumably any is supported
24790     tmp_img_ci.imageType = VK_IMAGE_TYPE_2D;       // any is supported
24791     tmp_img_ci.format = VK_FORMAT_R8G8B8A8_UNORM;  // has mandatory support for all usages
24792     tmp_img_ci.extent = {1, 1, 1};                 // limit is 256 for 3D, or 4096
24793     tmp_img_ci.mipLevels = 1;                      // any is supported
24794     tmp_img_ci.arrayLayers = 1;                    // limit is 256
24795     tmp_img_ci.samples = VK_SAMPLE_COUNT_1_BIT;    // needs to be 1 if TILING_LINEAR
24796     // if VK_IMAGE_TILING_LINEAR imageType must be 2D, usage must be TRANSFER, and levels layers samplers all 1
24797     tmp_img_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
24798     tmp_img_ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;  // depends on format
24799     tmp_img_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
24800     const VkImageCreateInfo safe_image_ci = tmp_img_ci;
24801 
24802     ASSERT_VK_SUCCESS(GPDIFPHelper(gpu(), &safe_image_ci));
24803 
24804     const VkPhysicalDeviceLimits &dev_limits = m_device->props.limits;
24805 
24806     {
24807         VkImageCreateInfo image_ci = safe_image_ci;
24808         image_ci.extent = {8, 8, 1};
24809         image_ci.mipLevels = 4 + 1;  // 4 = log2(8) + 1
24810 
24811         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-mipLevels-00958");
24812         vkCreateImage(m_device->handle(), &image_ci, NULL, &null_image);
24813         m_errorMonitor->VerifyFound();
24814 
24815         image_ci.extent = {8, 15, 1};
24816         image_ci.mipLevels = 4 + 1;  // 4 = floor(log2(15)) + 1
24817 
24818         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-mipLevels-00958");
24819         vkCreateImage(m_device->handle(), &image_ci, NULL, &null_image);
24820         m_errorMonitor->VerifyFound();
24821     }
24822 
24823     {
24824         VkImageCreateInfo image_ci = safe_image_ci;
24825         image_ci.tiling = VK_IMAGE_TILING_LINEAR;
24826         image_ci.extent = {64, 64, 1};
24827         image_ci.format = FindFormatLinearWithoutMips(gpu(), image_ci);
24828         image_ci.mipLevels = 2;
24829 
24830         if (image_ci.format != VK_FORMAT_UNDEFINED) {
24831             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-mipLevels-02255");
24832             vkCreateImage(m_device->handle(), &image_ci, NULL, &null_image);
24833             m_errorMonitor->VerifyFound();
24834         } else {
24835             printf("%s Cannot find a format to test maxMipLevels limit; skipping part of test.\n", kSkipPrefix);
24836         }
24837     }
24838 
24839     {
24840         VkImageCreateInfo image_ci = safe_image_ci;
24841 
24842         VkImageFormatProperties img_limits;
24843         ASSERT_VK_SUCCESS(GPDIFPHelper(gpu(), &image_ci, &img_limits));
24844 
24845         if (img_limits.maxArrayLayers != UINT32_MAX) {
24846             image_ci.arrayLayers = img_limits.maxArrayLayers + 1;
24847 
24848             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-arrayLayers-02256");
24849             vkCreateImage(m_device->handle(), &image_ci, NULL, &null_image);
24850             m_errorMonitor->VerifyFound();
24851         } else {
24852             printf("%s VkImageFormatProperties::maxArrayLayers is already UINT32_MAX; skipping part of test.\n", kSkipPrefix);
24853         }
24854     }
24855 
24856     {
24857         VkImageCreateInfo image_ci = safe_image_ci;
24858         bool found = FindFormatWithoutSamples(gpu(), image_ci);
24859 
24860         if (found) {
24861             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-samples-02258");
24862             vkCreateImage(m_device->handle(), &image_ci, NULL, &null_image);
24863             m_errorMonitor->VerifyFound();
24864         } else {
24865             printf("%s Could not find a format with some unsupported samples; skipping part of test.\n", kSkipPrefix);
24866         }
24867     }
24868 
24869     {
24870         VkImageCreateInfo image_ci = safe_image_ci;
24871         image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;  // (any attachment bit)
24872 
24873         VkImageFormatProperties img_limits;
24874         ASSERT_VK_SUCCESS(GPDIFPHelper(gpu(), &image_ci, &img_limits));
24875 
24876         if (dev_limits.maxFramebufferWidth != UINT32_MAX) {
24877             image_ci.extent = {dev_limits.maxFramebufferWidth + 1, 64, 1};
24878 
24879             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-usage-00964");
24880             vkCreateImage(m_device->handle(), &image_ci, NULL, &null_image);
24881             m_errorMonitor->VerifyFound();
24882         } else {
24883             printf("%s VkPhysicalDeviceLimits::maxFramebufferWidth is already UINT32_MAX; skipping part of test.\n", kSkipPrefix);
24884         }
24885 
24886         if (dev_limits.maxFramebufferHeight != UINT32_MAX) {
24887             image_ci.usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;  // try different one too
24888             image_ci.extent = {64, dev_limits.maxFramebufferHeight + 1, 1};
24889 
24890             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-usage-00965");
24891             vkCreateImage(m_device->handle(), &image_ci, NULL, &null_image);
24892             m_errorMonitor->VerifyFound();
24893         } else {
24894             printf("%s VkPhysicalDeviceLimits::maxFramebufferHeight is already UINT32_MAX; skipping part of test.\n", kSkipPrefix);
24895         }
24896     }
24897 }
24898 
FindUnsupportedImage(VkPhysicalDevice gpu,VkImageCreateInfo & image_ci)24899 bool FindUnsupportedImage(VkPhysicalDevice gpu, VkImageCreateInfo &image_ci) {
24900     const VkFormat first_vk_format = static_cast<VkFormat>(1);
24901     const VkFormat last_vk_format = static_cast<VkFormat>(130);  // avoid compressed/feature protected, otherwise 184
24902 
24903     const std::vector<VkImageTiling> tilings = {VK_IMAGE_TILING_LINEAR, VK_IMAGE_TILING_OPTIMAL};
24904     for (const auto tiling : tilings) {
24905         image_ci.tiling = tiling;
24906 
24907         for (VkFormat format = first_vk_format; format <= last_vk_format; format = static_cast<VkFormat>(format + 1)) {
24908             image_ci.format = format;
24909 
24910             VkFormatProperties format_props;
24911             vkGetPhysicalDeviceFormatProperties(gpu, format, &format_props);
24912 
24913             const VkFormatFeatureFlags core_filter = 0x1FFF;
24914             const auto features = (tiling == VK_IMAGE_TILING_LINEAR) ? format_props.linearTilingFeatures & core_filter
24915                                                                      : format_props.optimalTilingFeatures & core_filter;
24916             if (!(features & core_filter)) continue;  // We wand supported by features, but not by ImageFormatProperties
24917 
24918             // get as many usage flags as possible
24919             image_ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
24920             if (features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) image_ci.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
24921             if (features & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) image_ci.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
24922             if (features & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) image_ci.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
24923             if (features & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
24924                 image_ci.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
24925 
24926             VkImageFormatProperties img_limits;
24927             if (VK_ERROR_FORMAT_NOT_SUPPORTED == GPDIFPHelper(gpu, &image_ci, &img_limits)) {
24928                 return true;
24929             }
24930         }
24931     }
24932 
24933     return false;
24934 }
24935 
FindFormatWithoutFeatures(VkPhysicalDevice gpu,VkImageTiling tiling,VkFormatFeatureFlags undesired_features=UINT32_MAX)24936 VkFormat FindFormatWithoutFeatures(VkPhysicalDevice gpu, VkImageTiling tiling,
24937                                    VkFormatFeatureFlags undesired_features = UINT32_MAX) {
24938     const VkFormat first_vk_format = static_cast<VkFormat>(1);
24939     const VkFormat last_vk_format = static_cast<VkFormat>(130);  // avoid compressed/feature protected, otherwise 184
24940 
24941     for (VkFormat format = first_vk_format; format <= last_vk_format; format = static_cast<VkFormat>(format + 1)) {
24942         VkFormatProperties format_props;
24943         vkGetPhysicalDeviceFormatProperties(gpu, format, &format_props);
24944 
24945         const VkFormatFeatureFlags core_filter = 0x1FFF;
24946         const auto features = (tiling == VK_IMAGE_TILING_LINEAR) ? format_props.linearTilingFeatures & core_filter
24947                                                                  : format_props.optimalTilingFeatures & core_filter;
24948 
24949         const auto valid_features = features & core_filter;
24950         if (undesired_features == UINT32_MAX) {
24951             if (!valid_features) return format;
24952         } else {
24953             if (valid_features && !(valid_features & undesired_features)) return format;
24954         }
24955     }
24956 
24957     return VK_FORMAT_UNDEFINED;
24958 }
24959 
TEST_F(VkLayerTest,CopyImageTypeExtentMismatch)24960 TEST_F(VkLayerTest, CopyImageTypeExtentMismatch) {
24961     // Image copy tests where format type and extents don't match
24962     ASSERT_NO_FATAL_FAILURE(Init());
24963 
24964     VkImageCreateInfo ci;
24965     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
24966     ci.pNext = NULL;
24967     ci.flags = 0;
24968     ci.imageType = VK_IMAGE_TYPE_1D;
24969     ci.format = VK_FORMAT_R8G8B8A8_UNORM;
24970     ci.extent = {32, 1, 1};
24971     ci.mipLevels = 1;
24972     ci.arrayLayers = 1;
24973     ci.samples = VK_SAMPLE_COUNT_1_BIT;
24974     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
24975     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
24976     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
24977     ci.queueFamilyIndexCount = 0;
24978     ci.pQueueFamilyIndices = NULL;
24979     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
24980 
24981     // Create 1D image
24982     VkImageObj image_1D(m_device);
24983     image_1D.init(&ci);
24984     ASSERT_TRUE(image_1D.initialized());
24985 
24986     // 2D image
24987     ci.imageType = VK_IMAGE_TYPE_2D;
24988     ci.extent = {32, 32, 1};
24989     VkImageObj image_2D(m_device);
24990     image_2D.init(&ci);
24991     ASSERT_TRUE(image_2D.initialized());
24992 
24993     // 3D image
24994     ci.imageType = VK_IMAGE_TYPE_3D;
24995     ci.extent = {32, 32, 8};
24996     VkImageObj image_3D(m_device);
24997     image_3D.init(&ci);
24998     ASSERT_TRUE(image_3D.initialized());
24999 
25000     // 2D image array
25001     ci.imageType = VK_IMAGE_TYPE_2D;
25002     ci.extent = {32, 32, 1};
25003     ci.arrayLayers = 8;
25004     VkImageObj image_2D_array(m_device);
25005     image_2D_array.init(&ci);
25006     ASSERT_TRUE(image_2D_array.initialized());
25007 
25008     m_commandBuffer->begin();
25009 
25010     VkImageCopy copy_region;
25011     copy_region.extent = {32, 1, 1};
25012     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
25013     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
25014     copy_region.srcSubresource.mipLevel = 0;
25015     copy_region.dstSubresource.mipLevel = 0;
25016     copy_region.srcSubresource.baseArrayLayer = 0;
25017     copy_region.dstSubresource.baseArrayLayer = 0;
25018     copy_region.srcSubresource.layerCount = 1;
25019     copy_region.dstSubresource.layerCount = 1;
25020     copy_region.srcOffset = {0, 0, 0};
25021     copy_region.dstOffset = {0, 0, 0};
25022 
25023     // Sanity check
25024     m_errorMonitor->ExpectSuccess();
25025     m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25026                                &copy_region);
25027     m_errorMonitor->VerifyNotFound();
25028 
25029     // 1D texture w/ offset.y > 0. Source = VU 09c00124, dest = 09c00130
25030     copy_region.srcOffset.y = 1;
25031     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-00146");
25032     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcOffset-00145");  // also y-dim overrun
25033     m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25034                                &copy_region);
25035     m_errorMonitor->VerifyFound();
25036     copy_region.srcOffset.y = 0;
25037     copy_region.dstOffset.y = 1;
25038     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstImage-00152");
25039     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstOffset-00151");  // also y-dim overrun
25040     m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25041                                &copy_region);
25042     m_errorMonitor->VerifyFound();
25043     copy_region.dstOffset.y = 0;
25044 
25045     // 1D texture w/ extent.height > 1. Source = VU 09c00124, dest = 09c00130
25046     copy_region.extent.height = 2;
25047     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-00146");
25048     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcOffset-00145");  // also y-dim overrun
25049     m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25050                                &copy_region);
25051     m_errorMonitor->VerifyFound();
25052     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstImage-00152");
25053     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstOffset-00151");  // also y-dim overrun
25054     m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25055                                &copy_region);
25056     m_errorMonitor->VerifyFound();
25057     copy_region.extent.height = 1;
25058 
25059     // 1D texture w/ offset.z > 0. Source = VU 09c00df2, dest = 09c00df4
25060     copy_region.srcOffset.z = 1;
25061     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-01785");
25062     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcOffset-00147");  // also z-dim overrun
25063     m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25064                                &copy_region);
25065     m_errorMonitor->VerifyFound();
25066     copy_region.srcOffset.z = 0;
25067     copy_region.dstOffset.z = 1;
25068     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstImage-01786");
25069     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstOffset-00153");  // also z-dim overrun
25070     m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25071                                &copy_region);
25072     m_errorMonitor->VerifyFound();
25073     copy_region.dstOffset.z = 0;
25074 
25075     // 1D texture w/ extent.depth > 1. Source = VU 09c00df2, dest = 09c00df4
25076     copy_region.extent.depth = 2;
25077     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-01785");
25078     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
25079                                          "VUID-VkImageCopy-srcOffset-00147");  // also z-dim overrun (src)
25080     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
25081                                          "VUID-VkImageCopy-dstOffset-00153");  // also z-dim overrun (dst)
25082     m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25083                                &copy_region);
25084     m_errorMonitor->VerifyFound();
25085     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstImage-01786");
25086     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
25087                                          "VUID-VkImageCopy-srcOffset-00147");  // also z-dim overrun (src)
25088     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
25089                                          "VUID-VkImageCopy-dstOffset-00153");  // also z-dim overrun (dst)
25090     m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25091                                &copy_region);
25092     m_errorMonitor->VerifyFound();
25093     copy_region.extent.depth = 1;
25094 
25095     // 2D texture w/ offset.z > 0. Source = VU 09c00df6, dest = 09c00df8
25096     copy_region.extent = {16, 16, 1};
25097     copy_region.srcOffset.z = 4;
25098     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-01787");
25099     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
25100                                          "VUID-VkImageCopy-srcOffset-00147");  // also z-dim overrun (src)
25101     m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25102                                &copy_region);
25103     m_errorMonitor->VerifyFound();
25104     copy_region.srcOffset.z = 0;
25105     copy_region.dstOffset.z = 1;
25106     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstImage-01788");
25107     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
25108                                          "VUID-VkImageCopy-dstOffset-00153");  // also z-dim overrun (dst)
25109     m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25110                                &copy_region);
25111     m_errorMonitor->VerifyFound();
25112     copy_region.dstOffset.z = 0;
25113 
25114     // 3D texture accessing an array layer other than 0. VU 09c0011a
25115     copy_region.extent = {4, 4, 1};
25116     copy_region.srcSubresource.baseArrayLayer = 1;
25117     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-00141");
25118     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
25119                                          "VUID-vkCmdCopyImage-srcSubresource-01698");  // also 'too many layers'
25120     m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25121                                &copy_region);
25122     m_errorMonitor->VerifyFound();
25123     m_commandBuffer->end();
25124 }
25125 
TEST_F(VkLayerTest,CopyImageTypeExtentMismatchMaintenance1)25126 TEST_F(VkLayerTest, CopyImageTypeExtentMismatchMaintenance1) {
25127     // Image copy tests where format type and extents don't match and the Maintenance1 extension is enabled
25128     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
25129     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
25130         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
25131     } else {
25132         printf("%s Maintenance1 extension cannot be enabled, test skipped.\n", kSkipPrefix);
25133         return;
25134     }
25135     ASSERT_NO_FATAL_FAILURE(InitState());
25136 
25137     VkFormat image_format = VK_FORMAT_R8G8B8A8_UNORM;
25138     VkFormatProperties format_props;
25139     // TODO: Remove this check if or when devsim handles extensions.
25140     // The chosen format has mandatory support the transfer src and dst format features when Maitenance1 is enabled. However, our
25141     // use of devsim and the mock ICD violate this guarantee.
25142     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), image_format, &format_props);
25143     if (!(format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT)) {
25144         printf("%s Maintenance1 extension is not supported.\n", kSkipPrefix);
25145         return;
25146     }
25147 
25148     VkImageCreateInfo ci;
25149     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
25150     ci.pNext = NULL;
25151     ci.flags = 0;
25152     ci.imageType = VK_IMAGE_TYPE_1D;
25153     ci.format = image_format;
25154     ci.extent = {32, 1, 1};
25155     ci.mipLevels = 1;
25156     ci.arrayLayers = 1;
25157     ci.samples = VK_SAMPLE_COUNT_1_BIT;
25158     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
25159     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
25160     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
25161     ci.queueFamilyIndexCount = 0;
25162     ci.pQueueFamilyIndices = NULL;
25163     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
25164 
25165     // Create 1D image
25166     VkImageObj image_1D(m_device);
25167     image_1D.init(&ci);
25168     ASSERT_TRUE(image_1D.initialized());
25169 
25170     // 2D image
25171     ci.imageType = VK_IMAGE_TYPE_2D;
25172     ci.extent = {32, 32, 1};
25173     VkImageObj image_2D(m_device);
25174     image_2D.init(&ci);
25175     ASSERT_TRUE(image_2D.initialized());
25176 
25177     // 3D image
25178     ci.imageType = VK_IMAGE_TYPE_3D;
25179     ci.extent = {32, 32, 8};
25180     VkImageObj image_3D(m_device);
25181     image_3D.init(&ci);
25182     ASSERT_TRUE(image_3D.initialized());
25183 
25184     // 2D image array
25185     ci.imageType = VK_IMAGE_TYPE_2D;
25186     ci.extent = {32, 32, 1};
25187     ci.arrayLayers = 8;
25188     VkImageObj image_2D_array(m_device);
25189     image_2D_array.init(&ci);
25190     ASSERT_TRUE(image_2D_array.initialized());
25191 
25192     m_commandBuffer->begin();
25193 
25194     VkImageCopy copy_region;
25195     copy_region.extent = {32, 1, 1};
25196     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
25197     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
25198     copy_region.srcSubresource.mipLevel = 0;
25199     copy_region.dstSubresource.mipLevel = 0;
25200     copy_region.srcSubresource.baseArrayLayer = 0;
25201     copy_region.dstSubresource.baseArrayLayer = 0;
25202     copy_region.srcSubresource.layerCount = 1;
25203     copy_region.dstSubresource.layerCount = 1;
25204     copy_region.srcOffset = {0, 0, 0};
25205     copy_region.dstOffset = {0, 0, 0};
25206 
25207     // Copy from layer not present
25208     copy_region.srcSubresource.baseArrayLayer = 4;
25209     copy_region.srcSubresource.layerCount = 6;
25210     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-srcSubresource-01698");
25211     m_commandBuffer->CopyImage(image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25212                                &copy_region);
25213     m_errorMonitor->VerifyFound();
25214     copy_region.srcSubresource.baseArrayLayer = 0;
25215     copy_region.srcSubresource.layerCount = 1;
25216 
25217     // Copy to layer not present
25218     copy_region.dstSubresource.baseArrayLayer = 1;
25219     copy_region.dstSubresource.layerCount = 8;
25220     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-dstSubresource-01699");
25221     m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25222                                &copy_region);
25223     m_errorMonitor->VerifyFound();
25224     copy_region.dstSubresource.layerCount = 1;
25225 
25226     m_commandBuffer->end();
25227 }
25228 
TEST_F(VkLayerTest,CopyImageCompressedBlockAlignment)25229 TEST_F(VkLayerTest, CopyImageCompressedBlockAlignment) {
25230     // Image copy tests on compressed images with block alignment errors
25231     SetTargetApiVersion(VK_API_VERSION_1_1);
25232     ASSERT_NO_FATAL_FAILURE(Init());
25233 
25234     // Select a compressed format and verify support
25235     VkPhysicalDeviceFeatures device_features = {};
25236     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
25237     VkFormat compressed_format = VK_FORMAT_UNDEFINED;
25238     if (device_features.textureCompressionBC) {
25239         compressed_format = VK_FORMAT_BC3_SRGB_BLOCK;
25240     } else if (device_features.textureCompressionETC2) {
25241         compressed_format = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
25242     } else if (device_features.textureCompressionASTC_LDR) {
25243         compressed_format = VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
25244     }
25245 
25246     VkImageCreateInfo ci;
25247     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
25248     ci.pNext = NULL;
25249     ci.flags = 0;
25250     ci.imageType = VK_IMAGE_TYPE_2D;
25251     ci.format = compressed_format;
25252     ci.extent = {64, 64, 1};
25253     ci.mipLevels = 1;
25254     ci.arrayLayers = 1;
25255     ci.samples = VK_SAMPLE_COUNT_1_BIT;
25256     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
25257     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
25258     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
25259     ci.queueFamilyIndexCount = 0;
25260     ci.pQueueFamilyIndices = NULL;
25261     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
25262 
25263     VkImageFormatProperties img_prop = {};
25264     if (VK_SUCCESS != vkGetPhysicalDeviceImageFormatProperties(m_device->phy().handle(), ci.format, ci.imageType, ci.tiling,
25265                                                                ci.usage, ci.flags, &img_prop)) {
25266         printf("%s No compressed formats supported - CopyImageCompressedBlockAlignment skipped.\n", kSkipPrefix);
25267         return;
25268     }
25269 
25270     // Create images
25271     VkImageObj image_1(m_device);
25272     image_1.init(&ci);
25273     ASSERT_TRUE(image_1.initialized());
25274 
25275     ci.extent = {62, 62, 1};  // slightly smaller and not divisible by block size
25276     VkImageObj image_2(m_device);
25277     image_2.init(&ci);
25278     ASSERT_TRUE(image_2.initialized());
25279 
25280     m_commandBuffer->begin();
25281 
25282     VkImageCopy copy_region;
25283     copy_region.extent = {48, 48, 1};
25284     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
25285     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
25286     copy_region.srcSubresource.mipLevel = 0;
25287     copy_region.dstSubresource.mipLevel = 0;
25288     copy_region.srcSubresource.baseArrayLayer = 0;
25289     copy_region.dstSubresource.baseArrayLayer = 0;
25290     copy_region.srcSubresource.layerCount = 1;
25291     copy_region.dstSubresource.layerCount = 1;
25292     copy_region.srcOffset = {0, 0, 0};
25293     copy_region.dstOffset = {0, 0, 0};
25294 
25295     // Sanity check
25296     m_errorMonitor->ExpectSuccess();
25297     m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
25298     m_errorMonitor->VerifyNotFound();
25299 
25300     std::string vuid;
25301     bool ycbcr = (DeviceExtensionEnabled(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME) ||
25302                   (DeviceValidationVersion() >= VK_API_VERSION_1_1));
25303 
25304     // Src, Dest offsets must be multiples of compressed block sizes {4, 4, 1}
25305     // Image transfer granularity gets set to compressed block size, so an ITG error is also (unavoidably) triggered.
25306     vuid = ycbcr ? "VUID-VkImageCopy-srcImage-01727" : "VUID-VkImageCopy-srcOffset-00157";
25307     copy_region.srcOffset = {2, 4, 0};  // source width
25308     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
25309     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
25310                                          "VUID-vkCmdCopyImage-srcOffset-01783");  // srcOffset image transfer granularity
25311     m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
25312     m_errorMonitor->VerifyFound();
25313     copy_region.srcOffset = {12, 1, 0};  // source height
25314     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
25315     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
25316                                          "VUID-vkCmdCopyImage-srcOffset-01783");  // srcOffset image transfer granularity
25317     m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
25318     m_errorMonitor->VerifyFound();
25319     copy_region.srcOffset = {0, 0, 0};
25320 
25321     vuid = ycbcr ? "VUID-VkImageCopy-dstImage-01731" : "VUID-VkImageCopy-dstOffset-00162";
25322     copy_region.dstOffset = {1, 0, 0};  // dest width
25323     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
25324     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
25325                                          "VUID-vkCmdCopyImage-dstOffset-01784");  // dstOffset image transfer granularity
25326     m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
25327     m_errorMonitor->VerifyFound();
25328     copy_region.dstOffset = {4, 1, 0};  // dest height
25329     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
25330     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
25331                                          "VUID-vkCmdCopyImage-dstOffset-01784");  // dstOffset image transfer granularity
25332     m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
25333     m_errorMonitor->VerifyFound();
25334     copy_region.dstOffset = {0, 0, 0};
25335 
25336     // Copy extent must be multiples of compressed block sizes {4, 4, 1} if not full width/height
25337     vuid = ycbcr ? "VUID-VkImageCopy-srcImage-01728" : "VUID-VkImageCopy-extent-00158";
25338     copy_region.extent = {62, 60, 1};  // source width
25339     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
25340     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
25341                                          "VUID-vkCmdCopyImage-srcOffset-01783");  // src extent image transfer granularity
25342     m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
25343     m_errorMonitor->VerifyFound();
25344     vuid = ycbcr ? "VUID-VkImageCopy-srcImage-01729" : "VUID-VkImageCopy-extent-00159";
25345     copy_region.extent = {60, 62, 1};  // source height
25346     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
25347     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
25348                                          "VUID-vkCmdCopyImage-srcOffset-01783");  // src extent image transfer granularity
25349     m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
25350     m_errorMonitor->VerifyFound();
25351 
25352     vuid = ycbcr ? "VUID-VkImageCopy-dstImage-01732" : "VUID-VkImageCopy-extent-00163";
25353     copy_region.extent = {62, 60, 1};  // dest width
25354     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
25355     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
25356                                          "VUID-vkCmdCopyImage-dstOffset-01784");  // dst extent image transfer granularity
25357     m_commandBuffer->CopyImage(image_2.image(), VK_IMAGE_LAYOUT_GENERAL, image_1.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
25358     m_errorMonitor->VerifyFound();
25359     vuid = ycbcr ? "VUID-VkImageCopy-dstImage-01733" : "VUID-VkImageCopy-extent-00164";
25360     copy_region.extent = {60, 62, 1};  // dest height
25361     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
25362     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
25363                                          "VUID-vkCmdCopyImage-dstOffset-01784");  // dst extent image transfer granularity
25364     m_commandBuffer->CopyImage(image_2.image(), VK_IMAGE_LAYOUT_GENERAL, image_1.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
25365     m_errorMonitor->VerifyFound();
25366 
25367     // Note: "VUID-VkImageCopy-extent-00160", "VUID-VkImageCopy-extent-00165", "VUID-VkImageCopy-srcImage-01730",
25368     // "VUID-VkImageCopy-dstImage-01734"
25369     //       There are currently no supported compressed formats with a block depth other than 1,
25370     //       so impossible to create a 'not a multiple' condition for depth.
25371     m_commandBuffer->end();
25372 }
25373 
TEST_F(VkLayerTest,CopyImageSinglePlane422Alignment)25374 TEST_F(VkLayerTest, CopyImageSinglePlane422Alignment) {
25375     // Image copy tests on single-plane _422 formats with block alignment errors
25376 
25377     // Enable KHR multiplane req'd extensions
25378     bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
25379                                                     VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
25380     if (mp_extensions) {
25381         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
25382     }
25383     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
25384     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
25385     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
25386     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
25387     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
25388     if (mp_extensions) {
25389         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
25390         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
25391         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
25392         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
25393     } else {
25394         printf("%s test requires KHR multiplane extensions, not available.  Skipping.\n", kSkipPrefix);
25395         return;
25396     }
25397     ASSERT_NO_FATAL_FAILURE(InitState());
25398 
25399     // Select a _422 format and verify support
25400     VkImageCreateInfo ci = {};
25401     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
25402     ci.pNext = NULL;
25403     ci.flags = 0;
25404     ci.imageType = VK_IMAGE_TYPE_2D;
25405     ci.format = VK_FORMAT_G8B8G8R8_422_UNORM_KHR;
25406     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
25407     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
25408     ci.mipLevels = 1;
25409     ci.arrayLayers = 1;
25410     ci.samples = VK_SAMPLE_COUNT_1_BIT;
25411     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
25412     ci.queueFamilyIndexCount = 0;
25413     ci.pQueueFamilyIndices = NULL;
25414     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
25415 
25416     // Verify formats
25417     VkFormatFeatureFlags features = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
25418     bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
25419     if (!supported) {
25420         printf("%s Single-plane _422 image format not supported.  Skipping test.\n", kSkipPrefix);
25421         return;  // Assume there's low ROI on searching for different mp formats
25422     }
25423 
25424     // Create images
25425     ci.extent = {64, 64, 1};
25426     VkImageObj image_422(m_device);
25427     image_422.init(&ci);
25428     ASSERT_TRUE(image_422.initialized());
25429 
25430     ci.extent = {64, 64, 1};
25431     ci.format = VK_FORMAT_R8G8B8A8_UNORM;
25432     VkImageObj image_ucmp(m_device);
25433     image_ucmp.init(&ci);
25434     ASSERT_TRUE(image_ucmp.initialized());
25435 
25436     m_commandBuffer->begin();
25437 
25438     VkImageCopy copy_region;
25439     copy_region.extent = {48, 48, 1};
25440     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
25441     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
25442     copy_region.srcSubresource.mipLevel = 0;
25443     copy_region.dstSubresource.mipLevel = 0;
25444     copy_region.srcSubresource.baseArrayLayer = 0;
25445     copy_region.dstSubresource.baseArrayLayer = 0;
25446     copy_region.srcSubresource.layerCount = 1;
25447     copy_region.dstSubresource.layerCount = 1;
25448     copy_region.srcOffset = {0, 0, 0};
25449     copy_region.dstOffset = {0, 0, 0};
25450 
25451     // Src offsets must be multiples of compressed block sizes
25452     copy_region.srcOffset = {3, 4, 0};  // source offset x
25453     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-01727");
25454     m_commandBuffer->CopyImage(image_422.image(), VK_IMAGE_LAYOUT_GENERAL, image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25455                                &copy_region);
25456     m_errorMonitor->VerifyFound();
25457     copy_region.srcOffset = {0, 0, 0};
25458 
25459     // Dst offsets must be multiples of compressed block sizes
25460     copy_region.dstOffset = {1, 0, 0};
25461     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstImage-01731");
25462     m_commandBuffer->CopyImage(image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, image_422.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25463                                &copy_region);
25464     m_errorMonitor->VerifyFound();
25465     copy_region.dstOffset = {0, 0, 0};
25466 
25467     // Copy extent must be multiples of compressed block sizes if not full width/height
25468     copy_region.extent = {31, 60, 1};  // 422 source, extent.x
25469     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-01728");
25470     m_commandBuffer->CopyImage(image_422.image(), VK_IMAGE_LAYOUT_GENERAL, image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25471                                &copy_region);
25472     m_errorMonitor->VerifyFound();
25473 
25474     // 422 dest, extent.x
25475     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstImage-01732");
25476     m_commandBuffer->CopyImage(image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, image_422.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25477                                &copy_region);
25478     m_errorMonitor->VerifyFound();
25479     copy_region.dstOffset = {0, 0, 0};
25480 
25481     m_commandBuffer->end();
25482 }
25483 
TEST_F(VkLayerTest,MultiplaneImageSamplerConversionMismatch)25484 TEST_F(VkLayerTest, MultiplaneImageSamplerConversionMismatch) {
25485     TEST_DESCRIPTION("Create sampler with ycbcr conversion and use with an image created without ycrcb conversion");
25486 
25487     // Enable KHR multiplane req'd extensions
25488     bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
25489                                                     VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION);
25490     if (mp_extensions) {
25491         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
25492     }
25493     SetTargetApiVersion(VK_API_VERSION_1_1);
25494     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
25495     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
25496     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
25497     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
25498     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
25499     if (mp_extensions) {
25500         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
25501         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
25502         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
25503         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
25504     } else {
25505         printf("%s test requires KHR multiplane extensions, not available.  Skipping.\n", kSkipPrefix);
25506         return;
25507     }
25508 
25509     // Enable Ycbcr Conversion Features
25510     VkPhysicalDeviceSamplerYcbcrConversionFeatures ycbcr_features = {};
25511     ycbcr_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
25512     ycbcr_features.samplerYcbcrConversion = VK_TRUE;
25513     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &ycbcr_features));
25514 
25515     const VkImageCreateInfo ci = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
25516                                   NULL,
25517                                   0,
25518                                   VK_IMAGE_TYPE_2D,
25519                                   VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR,
25520                                   {128, 128, 1},
25521                                   1,
25522                                   1,
25523                                   VK_SAMPLE_COUNT_1_BIT,
25524                                   VK_IMAGE_TILING_LINEAR,
25525                                   VK_IMAGE_USAGE_SAMPLED_BIT,
25526                                   VK_SHARING_MODE_EXCLUSIVE,
25527                                   VK_IMAGE_LAYOUT_UNDEFINED};
25528 
25529     // Verify formats
25530     bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
25531     if (!supported) {
25532         printf("%s Multiplane image format not supported.  Skipping test.\n", kSkipPrefix);
25533         return;
25534     }
25535 
25536     // Create Ycbcr conversion
25537     VkSamplerYcbcrConversionCreateInfo ycbcr_create_info = {VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
25538                                                             NULL,
25539                                                             VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR,
25540                                                             VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY,
25541                                                             VK_SAMPLER_YCBCR_RANGE_ITU_FULL,
25542                                                             {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
25543                                                              VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY},
25544                                                             VK_CHROMA_LOCATION_COSITED_EVEN,
25545                                                             VK_CHROMA_LOCATION_COSITED_EVEN,
25546                                                             VK_FILTER_NEAREST,
25547                                                             false};
25548     VkSamplerYcbcrConversion conversion;
25549     vkCreateSamplerYcbcrConversion(m_device->handle(), &ycbcr_create_info, nullptr, &conversion);
25550     VkSamplerYcbcrConversionInfo ycbcr_info = {};
25551     ycbcr_info.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO;
25552     ycbcr_info.conversion = conversion;
25553 
25554     // Create a sampler using conversion
25555     VkSamplerCreateInfo sci = SafeSaneSamplerCreateInfo();
25556     sci.pNext = &ycbcr_info;
25557 
25558     VkSampler sampler;
25559     VkResult err = vkCreateSampler(m_device->device(), &sci, NULL, &sampler);
25560     ASSERT_VK_SUCCESS(err);
25561 
25562     // Create an image without a Ycbcr conversion
25563     VkImageObj mpimage(m_device);
25564     mpimage.init(&ci);
25565 
25566     VkImageView view;
25567     VkImageViewCreateInfo ivci = {};
25568     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
25569     ivci.image = mpimage.handle();
25570     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
25571     ivci.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR;
25572     ivci.subresourceRange.layerCount = 1;
25573     ivci.subresourceRange.baseMipLevel = 0;
25574     ivci.subresourceRange.levelCount = 1;
25575     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
25576     vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
25577 
25578     // Use the image and sampler together in a descriptor set
25579     OneOffDescriptorSet ds(m_device, {
25580                                          {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, &sampler},
25581                                      });
25582 
25583     VkDescriptorImageInfo image_info{};
25584     image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
25585     image_info.imageView = view;
25586     image_info.sampler = sampler;
25587 
25588     // Update the descriptor set expecting to get an error
25589     VkWriteDescriptorSet descriptor_write = {};
25590     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
25591     descriptor_write.dstSet = ds.set_;
25592     descriptor_write.dstBinding = 0;
25593     descriptor_write.descriptorCount = 1;
25594     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
25595     descriptor_write.pImageInfo = &image_info;
25596     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkWriteDescriptorSet-descriptorType-01948");
25597     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
25598     m_errorMonitor->VerifyFound();
25599     vkDestroySamplerYcbcrConversion(m_device->device(), conversion, nullptr);
25600     vkDestroyImageView(m_device->device(), view, NULL);
25601     vkDestroySampler(m_device->device(), sampler, nullptr);
25602 }
25603 
TEST_F(VkLayerTest,CopyImageMultiplaneAspectBits)25604 TEST_F(VkLayerTest, CopyImageMultiplaneAspectBits) {
25605     // Image copy tests on multiplane images with aspect errors
25606 
25607     // Enable KHR multiplane req'd extensions
25608     bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
25609                                                     VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
25610     if (mp_extensions) {
25611         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
25612     }
25613     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
25614     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
25615     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
25616     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
25617     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
25618     if (mp_extensions) {
25619         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
25620         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
25621         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
25622         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
25623     } else {
25624         printf("%s test requires KHR multiplane extensions, not available.  Skipping.\n", kSkipPrefix);
25625         return;
25626     }
25627     ASSERT_NO_FATAL_FAILURE(InitState());
25628 
25629     // Select multi-plane formats and verify support
25630     VkFormat mp3_format = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR;
25631     VkFormat mp2_format = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR;
25632 
25633     VkImageCreateInfo ci = {};
25634     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
25635     ci.pNext = NULL;
25636     ci.flags = 0;
25637     ci.imageType = VK_IMAGE_TYPE_2D;
25638     ci.format = mp2_format;
25639     ci.extent = {256, 256, 1};
25640     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
25641     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
25642     ci.mipLevels = 1;
25643     ci.arrayLayers = 1;
25644     ci.samples = VK_SAMPLE_COUNT_1_BIT;
25645     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
25646     ci.queueFamilyIndexCount = 0;
25647     ci.pQueueFamilyIndices = NULL;
25648     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
25649 
25650     // Verify formats
25651     VkFormatFeatureFlags features = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
25652     bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
25653     ci.format = mp3_format;
25654     supported = supported && ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
25655     if (!supported) {
25656         printf("%s Multiplane image formats not supported.  Skipping test.\n", kSkipPrefix);
25657         return;  // Assume there's low ROI on searching for different mp formats
25658     }
25659 
25660     // Create images
25661     VkImageObj mp3_image(m_device);
25662     mp3_image.init(&ci);
25663     ASSERT_TRUE(mp3_image.initialized());
25664 
25665     ci.format = mp2_format;
25666     VkImageObj mp2_image(m_device);
25667     mp2_image.init(&ci);
25668     ASSERT_TRUE(mp2_image.initialized());
25669 
25670     ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
25671     VkImageObj sp_image(m_device);
25672     sp_image.init(&ci);
25673     ASSERT_TRUE(sp_image.initialized());
25674 
25675     m_commandBuffer->begin();
25676 
25677     VkImageCopy copy_region;
25678     copy_region.extent = {128, 128, 1};
25679     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
25680     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
25681     copy_region.srcSubresource.mipLevel = 0;
25682     copy_region.dstSubresource.mipLevel = 0;
25683     copy_region.srcSubresource.baseArrayLayer = 0;
25684     copy_region.dstSubresource.baseArrayLayer = 0;
25685     copy_region.srcSubresource.layerCount = 1;
25686     copy_region.dstSubresource.layerCount = 1;
25687     copy_region.srcOffset = {0, 0, 0};
25688     copy_region.dstOffset = {0, 0, 0};
25689 
25690     m_errorMonitor->SetUnexpectedError("VUID-vkCmdCopyImage-srcImage-00135");
25691     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-01552");
25692     m_commandBuffer->CopyImage(mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25693                                &copy_region);
25694     m_errorMonitor->VerifyFound();
25695 
25696     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
25697     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT_KHR;
25698     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-01553");
25699     m_commandBuffer->CopyImage(mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25700                                &copy_region);
25701     m_errorMonitor->VerifyFound();
25702 
25703     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT_KHR;
25704     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
25705     m_errorMonitor->SetUnexpectedError("VUID-vkCmdCopyImage-srcImage-00135");
25706     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstImage-01554");
25707     m_commandBuffer->CopyImage(mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25708                                &copy_region);
25709     m_errorMonitor->VerifyFound();
25710 
25711     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
25712     m_errorMonitor->SetUnexpectedError("VUID-vkCmdCopyImage-srcImage-00135");
25713     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstImage-01555");
25714     m_commandBuffer->CopyImage(mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25715                                &copy_region);
25716     m_errorMonitor->VerifyFound();
25717 
25718     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
25719     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-01556");
25720     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "dest image depth/stencil formats");  // also
25721     m_commandBuffer->CopyImage(mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, sp_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25722                                &copy_region);
25723     m_errorMonitor->VerifyFound();
25724 
25725     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
25726     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
25727     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstImage-01557");
25728     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "dest image depth/stencil formats");  // also
25729     m_commandBuffer->CopyImage(sp_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25730                                &copy_region);
25731     m_errorMonitor->VerifyFound();
25732 
25733     m_commandBuffer->end();
25734 }
25735 
TEST_F(VkLayerTest,CopyImageSrcSizeExceeded)25736 TEST_F(VkLayerTest, CopyImageSrcSizeExceeded) {
25737     // Image copy with source region specified greater than src image size
25738     ASSERT_NO_FATAL_FAILURE(Init());
25739 
25740     // Create images with full mip chain
25741     VkImageCreateInfo ci;
25742     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
25743     ci.pNext = NULL;
25744     ci.flags = 0;
25745     ci.imageType = VK_IMAGE_TYPE_3D;
25746     ci.format = VK_FORMAT_R8G8B8A8_UNORM;
25747     ci.extent = {32, 32, 8};
25748     ci.mipLevels = 6;
25749     ci.arrayLayers = 1;
25750     ci.samples = VK_SAMPLE_COUNT_1_BIT;
25751     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
25752     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
25753     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
25754     ci.queueFamilyIndexCount = 0;
25755     ci.pQueueFamilyIndices = NULL;
25756     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
25757 
25758     VkImageObj src_image(m_device);
25759     src_image.init(&ci);
25760     ASSERT_TRUE(src_image.initialized());
25761 
25762     // Dest image with one more mip level
25763     ci.extent = {64, 64, 16};
25764     ci.mipLevels = 7;
25765     ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
25766     VkImageObj dst_image(m_device);
25767     dst_image.init(&ci);
25768     ASSERT_TRUE(dst_image.initialized());
25769 
25770     m_commandBuffer->begin();
25771 
25772     VkImageCopy copy_region;
25773     copy_region.extent = {32, 32, 8};
25774     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
25775     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
25776     copy_region.srcSubresource.mipLevel = 0;
25777     copy_region.dstSubresource.mipLevel = 0;
25778     copy_region.srcSubresource.baseArrayLayer = 0;
25779     copy_region.dstSubresource.baseArrayLayer = 0;
25780     copy_region.srcSubresource.layerCount = 1;
25781     copy_region.dstSubresource.layerCount = 1;
25782     copy_region.srcOffset = {0, 0, 0};
25783     copy_region.dstOffset = {0, 0, 0};
25784 
25785     m_errorMonitor->ExpectSuccess();
25786     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25787                                &copy_region);
25788     m_errorMonitor->VerifyNotFound();
25789 
25790     // Source exceeded in x-dim, VU 01202
25791     copy_region.srcOffset.x = 4;
25792     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
25793                                          "VUID-vkCmdCopyImage-pRegions-00122");  // General "contained within" VU
25794     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcOffset-00144");
25795     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25796                                &copy_region);
25797     m_errorMonitor->VerifyFound();
25798 
25799     // Source exceeded in y-dim, VU 01203
25800     copy_region.srcOffset.x = 0;
25801     copy_region.extent.height = 48;
25802     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-pRegions-00122");
25803     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcOffset-00145");
25804     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25805                                &copy_region);
25806     m_errorMonitor->VerifyFound();
25807 
25808     // Source exceeded in z-dim, VU 01204
25809     copy_region.extent = {4, 4, 4};
25810     copy_region.srcSubresource.mipLevel = 2;
25811     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-pRegions-00122");
25812     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcOffset-00147");
25813     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25814                                &copy_region);
25815     m_errorMonitor->VerifyFound();
25816 
25817     m_commandBuffer->end();
25818 }
25819 
TEST_F(VkLayerTest,CopyImageDstSizeExceeded)25820 TEST_F(VkLayerTest, CopyImageDstSizeExceeded) {
25821     // Image copy with dest region specified greater than dest image size
25822     ASSERT_NO_FATAL_FAILURE(Init());
25823 
25824     // Create images with full mip chain
25825     VkImageCreateInfo ci;
25826     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
25827     ci.pNext = NULL;
25828     ci.flags = 0;
25829     ci.imageType = VK_IMAGE_TYPE_3D;
25830     ci.format = VK_FORMAT_R8G8B8A8_UNORM;
25831     ci.extent = {32, 32, 8};
25832     ci.mipLevels = 6;
25833     ci.arrayLayers = 1;
25834     ci.samples = VK_SAMPLE_COUNT_1_BIT;
25835     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
25836     ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
25837     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
25838     ci.queueFamilyIndexCount = 0;
25839     ci.pQueueFamilyIndices = NULL;
25840     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
25841 
25842     VkImageObj dst_image(m_device);
25843     dst_image.init(&ci);
25844     ASSERT_TRUE(dst_image.initialized());
25845 
25846     // Src image with one more mip level
25847     ci.extent = {64, 64, 16};
25848     ci.mipLevels = 7;
25849     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
25850     VkImageObj src_image(m_device);
25851     src_image.init(&ci);
25852     ASSERT_TRUE(src_image.initialized());
25853 
25854     m_commandBuffer->begin();
25855 
25856     VkImageCopy copy_region;
25857     copy_region.extent = {32, 32, 8};
25858     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
25859     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
25860     copy_region.srcSubresource.mipLevel = 0;
25861     copy_region.dstSubresource.mipLevel = 0;
25862     copy_region.srcSubresource.baseArrayLayer = 0;
25863     copy_region.dstSubresource.baseArrayLayer = 0;
25864     copy_region.srcSubresource.layerCount = 1;
25865     copy_region.dstSubresource.layerCount = 1;
25866     copy_region.srcOffset = {0, 0, 0};
25867     copy_region.dstOffset = {0, 0, 0};
25868 
25869     m_errorMonitor->ExpectSuccess();
25870     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25871                                &copy_region);
25872     m_errorMonitor->VerifyNotFound();
25873 
25874     // Dest exceeded in x-dim, VU 01205
25875     copy_region.dstOffset.x = 4;
25876     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
25877                                          "VUID-vkCmdCopyImage-pRegions-00123");  // General "contained within" VU
25878     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstOffset-00150");
25879     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25880                                &copy_region);
25881     m_errorMonitor->VerifyFound();
25882 
25883     // Dest exceeded in y-dim, VU 01206
25884     copy_region.dstOffset.x = 0;
25885     copy_region.extent.height = 48;
25886     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-pRegions-00123");
25887     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstOffset-00151");
25888     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25889                                &copy_region);
25890     m_errorMonitor->VerifyFound();
25891 
25892     // Dest exceeded in z-dim, VU 01207
25893     copy_region.extent = {4, 4, 4};
25894     copy_region.dstSubresource.mipLevel = 2;
25895     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-pRegions-00123");
25896     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstOffset-00153");
25897     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
25898                                &copy_region);
25899     m_errorMonitor->VerifyFound();
25900 
25901     m_commandBuffer->end();
25902 }
25903 
TEST_F(VkLayerTest,CopyImageFormatSizeMismatch)25904 TEST_F(VkLayerTest, CopyImageFormatSizeMismatch) {
25905     VkResult err;
25906     bool pass;
25907 
25908     // Create color images with different format sizes and try to copy between them
25909     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-srcImage-00135");
25910 
25911     SetTargetApiVersion(VK_API_VERSION_1_1);
25912     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
25913 
25914     // Create two images of different types and try to copy between them
25915     VkImage srcImage;
25916     VkImage dstImage;
25917     VkDeviceMemory srcMem;
25918     VkDeviceMemory destMem;
25919     VkMemoryRequirements memReqs;
25920 
25921     VkImageCreateInfo image_create_info = {};
25922     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
25923     image_create_info.pNext = NULL;
25924     image_create_info.imageType = VK_IMAGE_TYPE_2D;
25925     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
25926     image_create_info.extent.width = 32;
25927     image_create_info.extent.height = 32;
25928     image_create_info.extent.depth = 1;
25929     image_create_info.mipLevels = 1;
25930     image_create_info.arrayLayers = 1;
25931     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
25932     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
25933     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
25934     image_create_info.flags = 0;
25935 
25936     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
25937     ASSERT_VK_SUCCESS(err);
25938 
25939     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
25940     // Introduce failure by creating second image with a different-sized format.
25941     image_create_info.format = VK_FORMAT_R5G5B5A1_UNORM_PACK16;
25942     VkFormatProperties properties;
25943     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), image_create_info.format, &properties);
25944     if (properties.optimalTilingFeatures == 0) {
25945         vkDestroyImage(m_device->device(), srcImage, NULL);
25946         printf("%s Image format not supported; skipped.\n", kSkipPrefix);
25947         return;
25948     }
25949 
25950     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
25951     ASSERT_VK_SUCCESS(err);
25952 
25953     // Allocate memory
25954     VkMemoryAllocateInfo memAlloc = {};
25955     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
25956     memAlloc.pNext = NULL;
25957     memAlloc.allocationSize = 0;
25958     memAlloc.memoryTypeIndex = 0;
25959 
25960     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
25961     memAlloc.allocationSize = memReqs.size;
25962     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
25963     ASSERT_TRUE(pass);
25964     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
25965     ASSERT_VK_SUCCESS(err);
25966 
25967     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
25968     memAlloc.allocationSize = memReqs.size;
25969     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
25970     ASSERT_TRUE(pass);
25971     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
25972     ASSERT_VK_SUCCESS(err);
25973 
25974     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
25975     ASSERT_VK_SUCCESS(err);
25976     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
25977     ASSERT_VK_SUCCESS(err);
25978 
25979     m_commandBuffer->begin();
25980     VkImageCopy copyRegion;
25981     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
25982     copyRegion.srcSubresource.mipLevel = 0;
25983     copyRegion.srcSubresource.baseArrayLayer = 0;
25984     copyRegion.srcSubresource.layerCount = 1;
25985     copyRegion.srcOffset.x = 0;
25986     copyRegion.srcOffset.y = 0;
25987     copyRegion.srcOffset.z = 0;
25988     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
25989     copyRegion.dstSubresource.mipLevel = 0;
25990     copyRegion.dstSubresource.baseArrayLayer = 0;
25991     copyRegion.dstSubresource.layerCount = 1;
25992     copyRegion.dstOffset.x = 0;
25993     copyRegion.dstOffset.y = 0;
25994     copyRegion.dstOffset.z = 0;
25995     copyRegion.extent.width = 1;
25996     copyRegion.extent.height = 1;
25997     copyRegion.extent.depth = 1;
25998     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
25999     m_commandBuffer->end();
26000 
26001     m_errorMonitor->VerifyFound();
26002 
26003     vkDestroyImage(m_device->device(), dstImage, NULL);
26004     vkFreeMemory(m_device->device(), destMem, NULL);
26005 
26006     // Copy to multiplane image with mismatched sizes
26007     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-srcImage-00135");
26008 
26009     VkImageCreateInfo ci;
26010     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
26011     ci.pNext = NULL;
26012     ci.flags = 0;
26013     ci.imageType = VK_IMAGE_TYPE_2D;
26014     ci.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
26015     ci.extent = {32, 32, 1};
26016     ci.mipLevels = 1;
26017     ci.arrayLayers = 1;
26018     ci.samples = VK_SAMPLE_COUNT_1_BIT;
26019     ci.tiling = VK_IMAGE_TILING_LINEAR;
26020     ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
26021     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
26022     ci.queueFamilyIndexCount = 0;
26023     ci.pQueueFamilyIndices = NULL;
26024     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
26025 
26026     VkFormatFeatureFlags features = VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
26027     bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
26028     bool ycbcr = (DeviceExtensionEnabled(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME) ||
26029                   (DeviceValidationVersion() >= VK_API_VERSION_1_1));
26030     if (!supported || !ycbcr) {
26031         printf("%s Image format not supported; skipped multiplanar copy test.\n", kSkipPrefix);
26032         vkDestroyImage(m_device->device(), srcImage, NULL);
26033         vkFreeMemory(m_device->device(), srcMem, NULL);
26034         return;
26035     }
26036 
26037     VkImageObj mpImage(m_device);
26038     mpImage.init(&ci);
26039     ASSERT_TRUE(mpImage.initialized());
26040     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
26041     vkResetCommandBuffer(m_commandBuffer->handle(), 0);
26042     m_commandBuffer->begin();
26043     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, mpImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
26044     m_commandBuffer->end();
26045 
26046     m_errorMonitor->VerifyFound();
26047 
26048     vkDestroyImage(m_device->device(), srcImage, NULL);
26049     vkFreeMemory(m_device->device(), srcMem, NULL);
26050 }
26051 
TEST_F(VkLayerTest,CopyImageDepthStencilFormatMismatch)26052 TEST_F(VkLayerTest, CopyImageDepthStencilFormatMismatch) {
26053     ASSERT_NO_FATAL_FAILURE(Init());
26054     auto depth_format = FindSupportedDepthStencilFormat(gpu());
26055     if (!depth_format) {
26056         printf("%s Couldn't depth stencil image format.\n", kSkipPrefix);
26057         return;
26058     }
26059 
26060     VkFormatProperties properties;
26061     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D32_SFLOAT, &properties);
26062     if (properties.optimalTilingFeatures == 0) {
26063         printf("%s Image format not supported; skipped.\n", kSkipPrefix);
26064         return;
26065     }
26066 
26067     VkImageObj srcImage(m_device);
26068     srcImage.Init(32, 32, 1, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL);
26069     ASSERT_TRUE(srcImage.initialized());
26070     VkImageObj dstImage(m_device);
26071     dstImage.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
26072     ASSERT_TRUE(dstImage.initialized());
26073 
26074     // Create two images of different types and try to copy between them
26075 
26076     m_commandBuffer->begin();
26077     VkImageCopy copyRegion;
26078     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
26079     copyRegion.srcSubresource.mipLevel = 0;
26080     copyRegion.srcSubresource.baseArrayLayer = 0;
26081     copyRegion.srcSubresource.layerCount = 1;
26082     copyRegion.srcOffset.x = 0;
26083     copyRegion.srcOffset.y = 0;
26084     copyRegion.srcOffset.z = 0;
26085     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
26086     copyRegion.dstSubresource.mipLevel = 0;
26087     copyRegion.dstSubresource.baseArrayLayer = 0;
26088     copyRegion.dstSubresource.layerCount = 1;
26089     copyRegion.dstOffset.x = 0;
26090     copyRegion.dstOffset.y = 0;
26091     copyRegion.dstOffset.z = 0;
26092     copyRegion.extent.width = 1;
26093     copyRegion.extent.height = 1;
26094     copyRegion.extent.depth = 1;
26095 
26096     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
26097                                          "vkCmdCopyImage called with unmatched source and dest image depth");
26098     m_commandBuffer->CopyImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
26099                                &copyRegion);
26100     m_commandBuffer->end();
26101 
26102     m_errorMonitor->VerifyFound();
26103 }
26104 
TEST_F(VkLayerTest,CopyImageSampleCountMismatch)26105 TEST_F(VkLayerTest, CopyImageSampleCountMismatch) {
26106     TEST_DESCRIPTION("Image copies with sample count mis-matches");
26107 
26108     ASSERT_NO_FATAL_FAILURE(Init());
26109 
26110     VkImageFormatProperties image_format_properties;
26111     vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
26112                                              VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
26113                                              &image_format_properties);
26114 
26115     if ((0 == (VK_SAMPLE_COUNT_2_BIT & image_format_properties.sampleCounts)) ||
26116         (0 == (VK_SAMPLE_COUNT_4_BIT & image_format_properties.sampleCounts))) {
26117         printf("%s Image multi-sample support not found; skipped.\n", kSkipPrefix);
26118         return;
26119     }
26120 
26121     VkImageCreateInfo ci;
26122     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
26123     ci.pNext = NULL;
26124     ci.flags = 0;
26125     ci.imageType = VK_IMAGE_TYPE_2D;
26126     ci.format = VK_FORMAT_R8G8B8A8_UNORM;
26127     ci.extent = {128, 128, 1};
26128     ci.mipLevels = 1;
26129     ci.arrayLayers = 1;
26130     ci.samples = VK_SAMPLE_COUNT_1_BIT;
26131     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
26132     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
26133     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
26134     ci.queueFamilyIndexCount = 0;
26135     ci.pQueueFamilyIndices = NULL;
26136     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
26137 
26138     VkImageObj image1(m_device);
26139     image1.init(&ci);
26140     ASSERT_TRUE(image1.initialized());
26141 
26142     ci.samples = VK_SAMPLE_COUNT_2_BIT;
26143     VkImageObj image2(m_device);
26144     image2.init(&ci);
26145     ASSERT_TRUE(image2.initialized());
26146 
26147     ci.samples = VK_SAMPLE_COUNT_4_BIT;
26148     VkImageObj image4(m_device);
26149     image4.init(&ci);
26150     ASSERT_TRUE(image4.initialized());
26151 
26152     m_commandBuffer->begin();
26153 
26154     VkImageCopy copyRegion;
26155     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26156     copyRegion.srcSubresource.mipLevel = 0;
26157     copyRegion.srcSubresource.baseArrayLayer = 0;
26158     copyRegion.srcSubresource.layerCount = 1;
26159     copyRegion.srcOffset = {0, 0, 0};
26160     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26161     copyRegion.dstSubresource.mipLevel = 0;
26162     copyRegion.dstSubresource.baseArrayLayer = 0;
26163     copyRegion.dstSubresource.layerCount = 1;
26164     copyRegion.dstOffset = {0, 0, 0};
26165     copyRegion.extent = {128, 128, 1};
26166 
26167     // Copy a single sample image to/from a multi-sample image
26168     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-srcImage-00136");
26169     vkCmdCopyImage(m_commandBuffer->handle(), image1.handle(), VK_IMAGE_LAYOUT_GENERAL, image4.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
26170                    &copyRegion);
26171     m_errorMonitor->VerifyFound();
26172 
26173     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-srcImage-00136");
26174     vkCmdCopyImage(m_commandBuffer->handle(), image2.handle(), VK_IMAGE_LAYOUT_GENERAL, image1.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
26175                    &copyRegion);
26176     m_errorMonitor->VerifyFound();
26177 
26178     // Copy between multi-sample images with different sample counts
26179     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-srcImage-00136");
26180     vkCmdCopyImage(m_commandBuffer->handle(), image2.handle(), VK_IMAGE_LAYOUT_GENERAL, image4.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
26181                    &copyRegion);
26182     m_errorMonitor->VerifyFound();
26183 
26184     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-srcImage-00136");
26185     vkCmdCopyImage(m_commandBuffer->handle(), image4.handle(), VK_IMAGE_LAYOUT_GENERAL, image2.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
26186                    &copyRegion);
26187     m_errorMonitor->VerifyFound();
26188 
26189     m_commandBuffer->end();
26190 }
26191 
TEST_F(VkLayerTest,CopyImageAspectMismatch)26192 TEST_F(VkLayerTest, CopyImageAspectMismatch) {
26193     TEST_DESCRIPTION("Image copies with aspect mask errors");
26194     SetTargetApiVersion(VK_API_VERSION_1_1);
26195     ASSERT_NO_FATAL_FAILURE(Init());
26196     auto ds_format = FindSupportedDepthStencilFormat(gpu());
26197     if (!ds_format) {
26198         printf("%s Couldn't find depth stencil format.\n", kSkipPrefix);
26199         return;
26200     }
26201 
26202     VkFormatProperties properties;
26203     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D32_SFLOAT, &properties);
26204     if (properties.optimalTilingFeatures == 0) {
26205         printf("%s Image format VK_FORMAT_D32_SFLOAT not supported; skipped.\n", kSkipPrefix);
26206         return;
26207     }
26208     VkImageObj color_image(m_device), ds_image(m_device), depth_image(m_device);
26209     color_image.Init(128, 128, 1, VK_FORMAT_R32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
26210     depth_image.Init(128, 128, 1, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
26211                      VK_IMAGE_TILING_OPTIMAL, 0);
26212     ds_image.Init(128, 128, 1, ds_format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
26213                   VK_IMAGE_TILING_OPTIMAL, 0);
26214     ASSERT_TRUE(color_image.initialized());
26215     ASSERT_TRUE(depth_image.initialized());
26216     ASSERT_TRUE(ds_image.initialized());
26217 
26218     VkImageCopy copyRegion;
26219     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
26220     copyRegion.srcSubresource.mipLevel = 0;
26221     copyRegion.srcSubresource.baseArrayLayer = 0;
26222     copyRegion.srcSubresource.layerCount = 1;
26223     copyRegion.srcOffset = {0, 0, 0};
26224     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
26225     copyRegion.dstSubresource.mipLevel = 0;
26226     copyRegion.dstSubresource.baseArrayLayer = 0;
26227     copyRegion.dstSubresource.layerCount = 1;
26228     copyRegion.dstOffset = {64, 0, 0};
26229     copyRegion.extent = {64, 128, 1};
26230 
26231     // Submitting command before command buffer is in recording state
26232     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
26233                                          "You must call vkBeginCommandBuffer");  // "VUID-vkCmdCopyImage-commandBuffer-recording");
26234     vkCmdCopyImage(m_commandBuffer->handle(), depth_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(),
26235                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
26236     m_errorMonitor->VerifyFound();
26237 
26238     m_commandBuffer->begin();
26239 
26240     // Src and dest aspect masks don't match
26241     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
26242     bool ycbcr = (DeviceExtensionEnabled(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME) ||
26243                   (DeviceValidationVersion() >= VK_API_VERSION_1_1));
26244     std::string vuid = (ycbcr ? "VUID-VkImageCopy-srcImage-01551" : "VUID-VkImageCopy-aspectMask-00137");
26245     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
26246     vkCmdCopyImage(m_commandBuffer->handle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, ds_image.handle(),
26247                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
26248     m_errorMonitor->VerifyFound();
26249     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
26250 
26251     // Illegal combinations of aspect bits
26252     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;  // color must be alone
26253     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26254     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageSubresourceLayers-aspectMask-00167");
26255     // These aspect/format mismatches are redundant but unavoidable here
26256     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-aspectMask-00142");
26257     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
26258     vkCmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
26259                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
26260     m_errorMonitor->VerifyFound();
26261     // same test for dstSubresource
26262     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26263     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;  // color must be alone
26264     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageSubresourceLayers-aspectMask-00167");
26265     // These aspect/format mismatches are redundant but unavoidable here
26266     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-aspectMask-00143");
26267     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
26268     vkCmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
26269                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
26270     m_errorMonitor->VerifyFound();
26271 
26272     // Metadata aspect is illegal
26273     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
26274     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26275     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageSubresourceLayers-aspectMask-00168");
26276     // These aspect/format mismatches are redundant but unavoidable here
26277     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
26278     vkCmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
26279                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
26280     m_errorMonitor->VerifyFound();
26281     // same test for dstSubresource
26282     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26283     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
26284     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageSubresourceLayers-aspectMask-00168");
26285     // These aspect/format mismatches are redundant but unavoidable here
26286     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
26287     vkCmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
26288                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
26289     m_errorMonitor->VerifyFound();
26290 
26291     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
26292     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
26293 
26294     // Aspect mask doesn't match source image format
26295     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-aspectMask-00142");
26296     // Again redundant but unavoidable
26297     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "unmatched source and dest image depth/stencil formats");
26298     vkCmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(),
26299                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
26300     m_errorMonitor->VerifyFound();
26301 
26302     // Aspect mask doesn't match dest image format
26303     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26304     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26305     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-aspectMask-00143");
26306     // Again redundant but unavoidable
26307     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "unmatched source and dest image depth/stencil formats");
26308     vkCmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(),
26309                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
26310     m_errorMonitor->VerifyFound();
26311 
26312     m_commandBuffer->end();
26313 }
26314 
TEST_F(VkLayerTest,ResolveImageLowSampleCount)26315 TEST_F(VkLayerTest, ResolveImageLowSampleCount) {
26316     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
26317                                          "vkCmdResolveImage called with source sample count less than 2.");
26318 
26319     ASSERT_NO_FATAL_FAILURE(Init());
26320 
26321     // Create two images of sample count 1 and try to Resolve between them
26322 
26323     VkImageCreateInfo image_create_info = {};
26324     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
26325     image_create_info.pNext = NULL;
26326     image_create_info.imageType = VK_IMAGE_TYPE_2D;
26327     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
26328     image_create_info.extent.width = 32;
26329     image_create_info.extent.height = 1;
26330     image_create_info.extent.depth = 1;
26331     image_create_info.mipLevels = 1;
26332     image_create_info.arrayLayers = 1;
26333     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
26334     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
26335     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
26336     image_create_info.flags = 0;
26337 
26338     VkImageObj srcImage(m_device);
26339     srcImage.init(&image_create_info);
26340     ASSERT_TRUE(srcImage.initialized());
26341 
26342     VkImageObj dstImage(m_device);
26343     dstImage.init(&image_create_info);
26344     ASSERT_TRUE(dstImage.initialized());
26345 
26346     m_commandBuffer->begin();
26347     VkImageResolve resolveRegion;
26348     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26349     resolveRegion.srcSubresource.mipLevel = 0;
26350     resolveRegion.srcSubresource.baseArrayLayer = 0;
26351     resolveRegion.srcSubresource.layerCount = 1;
26352     resolveRegion.srcOffset.x = 0;
26353     resolveRegion.srcOffset.y = 0;
26354     resolveRegion.srcOffset.z = 0;
26355     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26356     resolveRegion.dstSubresource.mipLevel = 0;
26357     resolveRegion.dstSubresource.baseArrayLayer = 0;
26358     resolveRegion.dstSubresource.layerCount = 1;
26359     resolveRegion.dstOffset.x = 0;
26360     resolveRegion.dstOffset.y = 0;
26361     resolveRegion.dstOffset.z = 0;
26362     resolveRegion.extent.width = 1;
26363     resolveRegion.extent.height = 1;
26364     resolveRegion.extent.depth = 1;
26365     m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
26366                                   &resolveRegion);
26367     m_commandBuffer->end();
26368 
26369     m_errorMonitor->VerifyFound();
26370 }
26371 
TEST_F(VkLayerTest,ResolveImageHighSampleCount)26372 TEST_F(VkLayerTest, ResolveImageHighSampleCount) {
26373     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
26374                                          "vkCmdResolveImage called with dest sample count greater than 1.");
26375 
26376     ASSERT_NO_FATAL_FAILURE(Init());
26377 
26378     // Create two images of sample count 4 and try to Resolve between them
26379 
26380     VkImageCreateInfo image_create_info = {};
26381     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
26382     image_create_info.pNext = NULL;
26383     image_create_info.imageType = VK_IMAGE_TYPE_2D;
26384     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
26385     image_create_info.extent.width = 32;
26386     image_create_info.extent.height = 1;
26387     image_create_info.extent.depth = 1;
26388     image_create_info.mipLevels = 1;
26389     image_create_info.arrayLayers = 1;
26390     image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
26391     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
26392     // Note: Some implementations expect color attachment usage for any
26393     // multisample surface
26394     image_create_info.usage =
26395         VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
26396     image_create_info.flags = 0;
26397 
26398     VkImageObj srcImage(m_device);
26399     srcImage.init(&image_create_info);
26400     ASSERT_TRUE(srcImage.initialized());
26401 
26402     VkImageObj dstImage(m_device);
26403     dstImage.init(&image_create_info);
26404     ASSERT_TRUE(dstImage.initialized());
26405 
26406     m_commandBuffer->begin();
26407     // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
26408     // VK_IMAGE_LAYOUT_UNDEFINED = 0,
26409     // VK_IMAGE_LAYOUT_GENERAL = 1,
26410     VkImageResolve resolveRegion;
26411     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26412     resolveRegion.srcSubresource.mipLevel = 0;
26413     resolveRegion.srcSubresource.baseArrayLayer = 0;
26414     resolveRegion.srcSubresource.layerCount = 1;
26415     resolveRegion.srcOffset.x = 0;
26416     resolveRegion.srcOffset.y = 0;
26417     resolveRegion.srcOffset.z = 0;
26418     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26419     resolveRegion.dstSubresource.mipLevel = 0;
26420     resolveRegion.dstSubresource.baseArrayLayer = 0;
26421     resolveRegion.dstSubresource.layerCount = 1;
26422     resolveRegion.dstOffset.x = 0;
26423     resolveRegion.dstOffset.y = 0;
26424     resolveRegion.dstOffset.z = 0;
26425     resolveRegion.extent.width = 1;
26426     resolveRegion.extent.height = 1;
26427     resolveRegion.extent.depth = 1;
26428     m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
26429                                   &resolveRegion);
26430     m_commandBuffer->end();
26431 
26432     m_errorMonitor->VerifyFound();
26433 }
26434 
TEST_F(VkLayerTest,ResolveImageFormatMismatch)26435 TEST_F(VkLayerTest, ResolveImageFormatMismatch) {
26436     VkResult err;
26437     bool pass;
26438 
26439     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
26440                                          "vkCmdResolveImage called with unmatched source and dest formats.");
26441 
26442     ASSERT_NO_FATAL_FAILURE(Init());
26443 
26444     // Create two images of different types and try to copy between them
26445     VkImage srcImage;
26446     VkImage dstImage;
26447     VkDeviceMemory srcMem;
26448     VkDeviceMemory destMem;
26449     VkMemoryRequirements memReqs;
26450 
26451     VkImageCreateInfo image_create_info = {};
26452     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
26453     image_create_info.pNext = NULL;
26454     image_create_info.imageType = VK_IMAGE_TYPE_2D;
26455     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
26456     image_create_info.extent.width = 32;
26457     image_create_info.extent.height = 1;
26458     image_create_info.extent.depth = 1;
26459     image_create_info.mipLevels = 1;
26460     image_create_info.arrayLayers = 1;
26461     image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
26462     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
26463     // Note: Some implementations expect color attachment usage for any
26464     // multisample surface
26465     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
26466     image_create_info.flags = 0;
26467 
26468     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
26469     ASSERT_VK_SUCCESS(err);
26470 
26471     // Set format to something other than source image
26472     image_create_info.format = VK_FORMAT_R32_SFLOAT;
26473     // Note: Some implementations expect color attachment usage for any
26474     // multisample surface
26475     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
26476     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
26477 
26478     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
26479     ASSERT_VK_SUCCESS(err);
26480 
26481     // Allocate memory
26482     VkMemoryAllocateInfo memAlloc = {};
26483     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
26484     memAlloc.pNext = NULL;
26485     memAlloc.allocationSize = 0;
26486     memAlloc.memoryTypeIndex = 0;
26487 
26488     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
26489     memAlloc.allocationSize = memReqs.size;
26490     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
26491     ASSERT_TRUE(pass);
26492     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
26493     ASSERT_VK_SUCCESS(err);
26494 
26495     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
26496     memAlloc.allocationSize = memReqs.size;
26497     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
26498     ASSERT_TRUE(pass);
26499     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
26500     ASSERT_VK_SUCCESS(err);
26501 
26502     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
26503     ASSERT_VK_SUCCESS(err);
26504     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
26505     ASSERT_VK_SUCCESS(err);
26506 
26507     m_commandBuffer->begin();
26508     // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
26509     // VK_IMAGE_LAYOUT_UNDEFINED = 0,
26510     // VK_IMAGE_LAYOUT_GENERAL = 1,
26511     VkImageResolve resolveRegion;
26512     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26513     resolveRegion.srcSubresource.mipLevel = 0;
26514     resolveRegion.srcSubresource.baseArrayLayer = 0;
26515     resolveRegion.srcSubresource.layerCount = 1;
26516     resolveRegion.srcOffset.x = 0;
26517     resolveRegion.srcOffset.y = 0;
26518     resolveRegion.srcOffset.z = 0;
26519     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26520     resolveRegion.dstSubresource.mipLevel = 0;
26521     resolveRegion.dstSubresource.baseArrayLayer = 0;
26522     resolveRegion.dstSubresource.layerCount = 1;
26523     resolveRegion.dstOffset.x = 0;
26524     resolveRegion.dstOffset.y = 0;
26525     resolveRegion.dstOffset.z = 0;
26526     resolveRegion.extent.width = 1;
26527     resolveRegion.extent.height = 1;
26528     resolveRegion.extent.depth = 1;
26529     m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
26530     m_commandBuffer->end();
26531 
26532     m_errorMonitor->VerifyFound();
26533 
26534     vkDestroyImage(m_device->device(), srcImage, NULL);
26535     vkDestroyImage(m_device->device(), dstImage, NULL);
26536     vkFreeMemory(m_device->device(), srcMem, NULL);
26537     vkFreeMemory(m_device->device(), destMem, NULL);
26538 }
26539 
TEST_F(VkLayerTest,ResolveImageTypeMismatch)26540 TEST_F(VkLayerTest, ResolveImageTypeMismatch) {
26541     VkResult err;
26542     bool pass;
26543 
26544     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
26545                                          "vkCmdResolveImage called with unmatched source and dest image types.");
26546 
26547     ASSERT_NO_FATAL_FAILURE(Init());
26548 
26549     // Create two images of different types and try to copy between them
26550     VkImage srcImage;
26551     VkImage dstImage;
26552     VkDeviceMemory srcMem;
26553     VkDeviceMemory destMem;
26554     VkMemoryRequirements memReqs;
26555 
26556     VkImageCreateInfo image_create_info = {};
26557     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
26558     image_create_info.pNext = NULL;
26559     image_create_info.imageType = VK_IMAGE_TYPE_2D;
26560     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
26561     image_create_info.extent.width = 32;
26562     image_create_info.extent.height = 1;
26563     image_create_info.extent.depth = 1;
26564     image_create_info.mipLevels = 1;
26565     image_create_info.arrayLayers = 1;
26566     image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
26567     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
26568     // Note: Some implementations expect color attachment usage for any
26569     // multisample surface
26570     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
26571     image_create_info.flags = 0;
26572 
26573     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
26574     ASSERT_VK_SUCCESS(err);
26575 
26576     image_create_info.imageType = VK_IMAGE_TYPE_1D;
26577     // Note: Some implementations expect color attachment usage for any
26578     // multisample surface
26579     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
26580     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
26581 
26582     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
26583     ASSERT_VK_SUCCESS(err);
26584 
26585     // Allocate memory
26586     VkMemoryAllocateInfo memAlloc = {};
26587     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
26588     memAlloc.pNext = NULL;
26589     memAlloc.allocationSize = 0;
26590     memAlloc.memoryTypeIndex = 0;
26591 
26592     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
26593     memAlloc.allocationSize = memReqs.size;
26594     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
26595     ASSERT_TRUE(pass);
26596     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
26597     ASSERT_VK_SUCCESS(err);
26598 
26599     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
26600     memAlloc.allocationSize = memReqs.size;
26601     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
26602     ASSERT_TRUE(pass);
26603     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
26604     ASSERT_VK_SUCCESS(err);
26605 
26606     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
26607     ASSERT_VK_SUCCESS(err);
26608     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
26609     ASSERT_VK_SUCCESS(err);
26610 
26611     m_commandBuffer->begin();
26612     // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
26613     // VK_IMAGE_LAYOUT_UNDEFINED = 0,
26614     // VK_IMAGE_LAYOUT_GENERAL = 1,
26615     VkImageResolve resolveRegion;
26616     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26617     resolveRegion.srcSubresource.mipLevel = 0;
26618     resolveRegion.srcSubresource.baseArrayLayer = 0;
26619     resolveRegion.srcSubresource.layerCount = 1;
26620     resolveRegion.srcOffset.x = 0;
26621     resolveRegion.srcOffset.y = 0;
26622     resolveRegion.srcOffset.z = 0;
26623     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26624     resolveRegion.dstSubresource.mipLevel = 0;
26625     resolveRegion.dstSubresource.baseArrayLayer = 0;
26626     resolveRegion.dstSubresource.layerCount = 1;
26627     resolveRegion.dstOffset.x = 0;
26628     resolveRegion.dstOffset.y = 0;
26629     resolveRegion.dstOffset.z = 0;
26630     resolveRegion.extent.width = 1;
26631     resolveRegion.extent.height = 1;
26632     resolveRegion.extent.depth = 1;
26633     m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
26634     m_commandBuffer->end();
26635 
26636     m_errorMonitor->VerifyFound();
26637 
26638     vkDestroyImage(m_device->device(), srcImage, NULL);
26639     vkDestroyImage(m_device->device(), dstImage, NULL);
26640     vkFreeMemory(m_device->device(), srcMem, NULL);
26641     vkFreeMemory(m_device->device(), destMem, NULL);
26642 }
26643 
TEST_F(VkLayerTest,ResolveImageLayoutMismatch)26644 TEST_F(VkLayerTest, ResolveImageLayoutMismatch) {
26645     ASSERT_NO_FATAL_FAILURE(Init());
26646 
26647     // Create two images of different types and try to copy between them
26648     VkImageObj srcImage(m_device);
26649     VkImageObj dstImage(m_device);
26650 
26651     VkImageCreateInfo image_create_info = {};
26652     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
26653     image_create_info.pNext = NULL;
26654     image_create_info.imageType = VK_IMAGE_TYPE_2D;
26655     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
26656     image_create_info.extent.width = 32;
26657     image_create_info.extent.height = 32;
26658     image_create_info.extent.depth = 1;
26659     image_create_info.mipLevels = 1;
26660     image_create_info.arrayLayers = 1;
26661     image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
26662     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
26663     image_create_info.usage =
26664         VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
26665     // Note: Some implementations expect color attachment usage for any
26666     // multisample surface
26667     image_create_info.flags = 0;
26668     srcImage.init(&image_create_info);
26669     ASSERT_TRUE(srcImage.initialized());
26670 
26671     // Note: Some implementations expect color attachment usage for any
26672     // multisample surface
26673     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
26674     dstImage.init(&image_create_info);
26675     ASSERT_TRUE(dstImage.initialized());
26676 
26677     m_commandBuffer->begin();
26678     // source image must have valid contents before resolve
26679     VkClearColorValue clear_color = {{0, 0, 0, 0}};
26680     VkImageSubresourceRange subresource = {};
26681     subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26682     subresource.layerCount = 1;
26683     subresource.levelCount = 1;
26684     srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
26685     m_commandBuffer->ClearColorImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource);
26686     srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
26687     dstImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
26688 
26689     VkImageResolve resolveRegion;
26690     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26691     resolveRegion.srcSubresource.mipLevel = 0;
26692     resolveRegion.srcSubresource.baseArrayLayer = 0;
26693     resolveRegion.srcSubresource.layerCount = 1;
26694     resolveRegion.srcOffset.x = 0;
26695     resolveRegion.srcOffset.y = 0;
26696     resolveRegion.srcOffset.z = 0;
26697     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26698     resolveRegion.dstSubresource.mipLevel = 0;
26699     resolveRegion.dstSubresource.baseArrayLayer = 0;
26700     resolveRegion.dstSubresource.layerCount = 1;
26701     resolveRegion.dstOffset.x = 0;
26702     resolveRegion.dstOffset.y = 0;
26703     resolveRegion.dstOffset.z = 0;
26704     resolveRegion.extent.width = 1;
26705     resolveRegion.extent.height = 1;
26706     resolveRegion.extent.depth = 1;
26707     // source image layout mismatch
26708     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResolveImage-srcImageLayout-00260");
26709     m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_GENERAL, dstImage.image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
26710                                   1, &resolveRegion);
26711     m_errorMonitor->VerifyFound();
26712     // dst image layout mismatch
26713     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResolveImage-dstImageLayout-00262");
26714     m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(), VK_IMAGE_LAYOUT_GENERAL,
26715                                   1, &resolveRegion);
26716     m_errorMonitor->VerifyFound();
26717     m_commandBuffer->end();
26718 }
26719 
TEST_F(VkLayerTest,ResolveInvalidSubresource)26720 TEST_F(VkLayerTest, ResolveInvalidSubresource) {
26721     ASSERT_NO_FATAL_FAILURE(Init());
26722 
26723     // Create two images of different types and try to copy between them
26724     VkImageObj srcImage(m_device);
26725     VkImageObj dstImage(m_device);
26726 
26727     VkImageCreateInfo image_create_info = {};
26728     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
26729     image_create_info.pNext = NULL;
26730     image_create_info.imageType = VK_IMAGE_TYPE_2D;
26731     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
26732     image_create_info.extent.width = 32;
26733     image_create_info.extent.height = 32;
26734     image_create_info.extent.depth = 1;
26735     image_create_info.mipLevels = 1;
26736     image_create_info.arrayLayers = 1;
26737     image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
26738     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
26739     image_create_info.usage =
26740         VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
26741     // Note: Some implementations expect color attachment usage for any
26742     // multisample surface
26743     image_create_info.flags = 0;
26744     srcImage.init(&image_create_info);
26745     ASSERT_TRUE(srcImage.initialized());
26746 
26747     // Note: Some implementations expect color attachment usage for any
26748     // multisample surface
26749     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
26750     dstImage.init(&image_create_info);
26751     ASSERT_TRUE(dstImage.initialized());
26752 
26753     m_commandBuffer->begin();
26754     // source image must have valid contents before resolve
26755     VkClearColorValue clear_color = {{0, 0, 0, 0}};
26756     VkImageSubresourceRange subresource = {};
26757     subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26758     subresource.layerCount = 1;
26759     subresource.levelCount = 1;
26760     srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
26761     m_commandBuffer->ClearColorImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource);
26762     srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
26763     dstImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
26764 
26765     VkImageResolve resolveRegion;
26766     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26767     resolveRegion.srcSubresource.mipLevel = 0;
26768     resolveRegion.srcSubresource.baseArrayLayer = 0;
26769     resolveRegion.srcSubresource.layerCount = 1;
26770     resolveRegion.srcOffset.x = 0;
26771     resolveRegion.srcOffset.y = 0;
26772     resolveRegion.srcOffset.z = 0;
26773     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
26774     resolveRegion.dstSubresource.mipLevel = 0;
26775     resolveRegion.dstSubresource.baseArrayLayer = 0;
26776     resolveRegion.dstSubresource.layerCount = 1;
26777     resolveRegion.dstOffset.x = 0;
26778     resolveRegion.dstOffset.y = 0;
26779     resolveRegion.dstOffset.z = 0;
26780     resolveRegion.extent.width = 1;
26781     resolveRegion.extent.height = 1;
26782     resolveRegion.extent.depth = 1;
26783     // invalid source mip level
26784     resolveRegion.srcSubresource.mipLevel = image_create_info.mipLevels;
26785     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResolveImage-srcSubresource-01709");
26786     m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
26787                                   VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
26788     m_errorMonitor->VerifyFound();
26789     resolveRegion.srcSubresource.mipLevel = 0;
26790     // invalid dest mip level
26791     resolveRegion.dstSubresource.mipLevel = image_create_info.mipLevels;
26792     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResolveImage-dstSubresource-01710");
26793     m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
26794                                   VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
26795     m_errorMonitor->VerifyFound();
26796     resolveRegion.dstSubresource.mipLevel = 0;
26797     // invalid source array layer range
26798     resolveRegion.srcSubresource.baseArrayLayer = image_create_info.arrayLayers;
26799     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResolveImage-srcSubresource-01711");
26800     m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
26801                                   VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
26802     m_errorMonitor->VerifyFound();
26803     resolveRegion.srcSubresource.baseArrayLayer = 0;
26804     // invalid dest array layer range
26805     resolveRegion.dstSubresource.baseArrayLayer = image_create_info.arrayLayers;
26806     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResolveImage-dstSubresource-01712");
26807     m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
26808                                   VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
26809     m_errorMonitor->VerifyFound();
26810     resolveRegion.dstSubresource.baseArrayLayer = 0;
26811 
26812     m_commandBuffer->end();
26813 }
26814 
TEST_F(VkLayerTest,DepthStencilImageViewWithColorAspectBitError)26815 TEST_F(VkLayerTest, DepthStencilImageViewWithColorAspectBitError) {
26816     // Create a single Image descriptor and cause it to first hit an error due
26817     //  to using a DS format, then cause it to hit error due to COLOR_BIT not
26818     //  set in aspect
26819     // The image format check comes 2nd in validation so we trigger it first,
26820     //  then when we cause aspect fail next, bad format check will be preempted
26821     VkResult err;
26822 
26823     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
26824                                          "Combination depth/stencil image formats can have only the ");
26825 
26826     ASSERT_NO_FATAL_FAILURE(Init());
26827     auto depth_format = FindSupportedDepthStencilFormat(gpu());
26828     if (!depth_format) {
26829         printf("%s Couldn't find depth stencil format.\n", kSkipPrefix);
26830         return;
26831     }
26832 
26833     VkDescriptorPoolSize ds_type_count = {};
26834     ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
26835     ds_type_count.descriptorCount = 1;
26836 
26837     VkDescriptorPoolCreateInfo ds_pool_ci = {};
26838     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
26839     ds_pool_ci.pNext = NULL;
26840     ds_pool_ci.maxSets = 1;
26841     ds_pool_ci.poolSizeCount = 1;
26842     ds_pool_ci.pPoolSizes = &ds_type_count;
26843 
26844     VkDescriptorPool ds_pool;
26845     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
26846     ASSERT_VK_SUCCESS(err);
26847 
26848     VkDescriptorSetLayoutBinding dsl_binding = {};
26849     dsl_binding.binding = 0;
26850     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
26851     dsl_binding.descriptorCount = 1;
26852     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
26853     dsl_binding.pImmutableSamplers = NULL;
26854 
26855     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
26856 
26857     VkDescriptorSet descriptorSet;
26858     VkDescriptorSetAllocateInfo alloc_info = {};
26859     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
26860     alloc_info.descriptorSetCount = 1;
26861     alloc_info.descriptorPool = ds_pool;
26862     alloc_info.pSetLayouts = &ds_layout.handle();
26863     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
26864     ASSERT_VK_SUCCESS(err);
26865 
26866     VkImage image_bad;
26867     VkImage image_good;
26868     // One bad format and one good format for Color attachment
26869     const VkFormat tex_format_bad = depth_format;
26870     const VkFormat tex_format_good = VK_FORMAT_B8G8R8A8_UNORM;
26871     const int32_t tex_width = 32;
26872     const int32_t tex_height = 32;
26873 
26874     VkImageCreateInfo image_create_info = {};
26875     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
26876     image_create_info.pNext = NULL;
26877     image_create_info.imageType = VK_IMAGE_TYPE_2D;
26878     image_create_info.format = tex_format_bad;
26879     image_create_info.extent.width = tex_width;
26880     image_create_info.extent.height = tex_height;
26881     image_create_info.extent.depth = 1;
26882     image_create_info.mipLevels = 1;
26883     image_create_info.arrayLayers = 1;
26884     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
26885     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
26886     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
26887     image_create_info.flags = 0;
26888 
26889     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image_bad);
26890     ASSERT_VK_SUCCESS(err);
26891     image_create_info.format = tex_format_good;
26892     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
26893     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image_good);
26894     ASSERT_VK_SUCCESS(err);
26895 
26896     // ---Bind image memory---
26897     VkMemoryRequirements img_mem_reqs;
26898     vkGetImageMemoryRequirements(m_device->device(), image_bad, &img_mem_reqs);
26899     VkMemoryAllocateInfo image_alloc_info = {};
26900     image_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
26901     image_alloc_info.pNext = NULL;
26902     image_alloc_info.memoryTypeIndex = 0;
26903     image_alloc_info.allocationSize = img_mem_reqs.size;
26904     bool pass =
26905         m_device->phy().set_memory_type(img_mem_reqs.memoryTypeBits, &image_alloc_info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
26906     ASSERT_TRUE(pass);
26907     VkDeviceMemory mem;
26908     err = vkAllocateMemory(m_device->device(), &image_alloc_info, NULL, &mem);
26909     ASSERT_VK_SUCCESS(err);
26910     err = vkBindImageMemory(m_device->device(), image_bad, mem, 0);
26911     ASSERT_VK_SUCCESS(err);
26912     // -----------------------
26913 
26914     VkImageViewCreateInfo image_view_create_info = {};
26915     image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
26916     image_view_create_info.image = image_bad;
26917     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
26918     image_view_create_info.format = tex_format_bad;
26919     image_view_create_info.subresourceRange.baseArrayLayer = 0;
26920     image_view_create_info.subresourceRange.baseMipLevel = 0;
26921     image_view_create_info.subresourceRange.layerCount = 1;
26922     image_view_create_info.subresourceRange.levelCount = 1;
26923     image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
26924 
26925     VkImageView view;
26926     err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
26927 
26928     m_errorMonitor->VerifyFound();
26929 
26930     vkDestroyImage(m_device->device(), image_bad, NULL);
26931     vkDestroyImage(m_device->device(), image_good, NULL);
26932     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
26933 
26934     vkFreeMemory(m_device->device(), mem, NULL);
26935 }
26936 
TEST_F(VkLayerTest,ClearImageErrors)26937 TEST_F(VkLayerTest, ClearImageErrors) {
26938     TEST_DESCRIPTION("Call ClearColorImage w/ a depth|stencil image and ClearDepthStencilImage with a color image.");
26939 
26940     ASSERT_NO_FATAL_FAILURE(Init());
26941     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
26942 
26943     m_commandBuffer->begin();
26944 
26945     // Color image
26946     VkClearColorValue clear_color;
26947     memset(clear_color.uint32, 0, sizeof(uint32_t) * 4);
26948     const VkFormat color_format = VK_FORMAT_B8G8R8A8_UNORM;
26949     const int32_t img_width = 32;
26950     const int32_t img_height = 32;
26951     VkImageCreateInfo image_create_info = {};
26952     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
26953     image_create_info.pNext = NULL;
26954     image_create_info.imageType = VK_IMAGE_TYPE_2D;
26955     image_create_info.format = color_format;
26956     image_create_info.extent.width = img_width;
26957     image_create_info.extent.height = img_height;
26958     image_create_info.extent.depth = 1;
26959     image_create_info.mipLevels = 1;
26960     image_create_info.arrayLayers = 1;
26961     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
26962     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
26963 
26964     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
26965     vk_testing::Image color_image_no_transfer;
26966     color_image_no_transfer.init(*m_device, image_create_info);
26967 
26968     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
26969     vk_testing::Image color_image;
26970     color_image.init(*m_device, image_create_info);
26971 
26972     const VkImageSubresourceRange color_range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT);
26973 
26974     // Depth/Stencil image
26975     VkClearDepthStencilValue clear_value = {0};
26976     VkImageCreateInfo ds_image_create_info = vk_testing::Image::create_info();
26977     ds_image_create_info.imageType = VK_IMAGE_TYPE_2D;
26978     ds_image_create_info.format = VK_FORMAT_D16_UNORM;
26979     ds_image_create_info.extent.width = 64;
26980     ds_image_create_info.extent.height = 64;
26981     ds_image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
26982     ds_image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
26983 
26984     vk_testing::Image ds_image;
26985     ds_image.init(*m_device, ds_image_create_info);
26986 
26987     const VkImageSubresourceRange ds_range = vk_testing::Image::subresource_range(ds_image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT);
26988 
26989     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearColorImage called with depth/stencil image.");
26990 
26991     vkCmdClearColorImage(m_commandBuffer->handle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &color_range);
26992 
26993     m_errorMonitor->VerifyFound();
26994 
26995     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
26996                                          "vkCmdClearColorImage called with image created without VK_IMAGE_USAGE_TRANSFER_DST_BIT");
26997 
26998     vkCmdClearColorImage(m_commandBuffer->handle(), color_image_no_transfer.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
26999                          &color_range);
27000 
27001     m_errorMonitor->VerifyFound();
27002 
27003     // Call CmdClearDepthStencilImage with color image
27004     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
27005                                          "vkCmdClearDepthStencilImage called without a depth/stencil image.");
27006 
27007     vkCmdClearDepthStencilImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_value,
27008                                 1, &ds_range);
27009 
27010     m_errorMonitor->VerifyFound();
27011 }
27012 
TEST_F(VkLayerTest,CommandQueueFlags)27013 TEST_F(VkLayerTest, CommandQueueFlags) {
27014     TEST_DESCRIPTION(
27015         "Allocate a command buffer on a queue that does not support graphics and try to issue a graphics-only command");
27016 
27017     ASSERT_NO_FATAL_FAILURE(Init());
27018 
27019     uint32_t queueFamilyIndex = m_device->QueueFamilyWithoutCapabilities(VK_QUEUE_GRAPHICS_BIT);
27020     if (queueFamilyIndex == UINT32_MAX) {
27021         printf("%s Non-graphics queue family not found; skipped.\n", kSkipPrefix);
27022         return;
27023     } else {
27024         // Create command pool on a non-graphics queue
27025         VkCommandPoolObj command_pool(m_device, queueFamilyIndex);
27026 
27027         // Setup command buffer on pool
27028         VkCommandBufferObj command_buffer(m_device, &command_pool);
27029         command_buffer.begin();
27030 
27031         // Issue a graphics only command
27032         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-commandBuffer-cmdpool");
27033         VkViewport viewport = {0, 0, 16, 16, 0, 1};
27034         command_buffer.SetViewport(0, 1, &viewport);
27035         m_errorMonitor->VerifyFound();
27036     }
27037 }
27038 
TEST_F(VkLayerTest,ExecuteUnrecordedSecondaryCB)27039 TEST_F(VkLayerTest, ExecuteUnrecordedSecondaryCB) {
27040     TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a CB in the initial state");
27041     ASSERT_NO_FATAL_FAILURE(Init());
27042     VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
27043     // never record secondary
27044 
27045     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdExecuteCommands-pCommandBuffers-00089");
27046     m_commandBuffer->begin();
27047     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
27048     m_errorMonitor->VerifyFound();
27049     m_commandBuffer->end();
27050 }
27051 
TEST_F(VkLayerTest,ExecuteUnrecordedPrimaryCB)27052 TEST_F(VkLayerTest, ExecuteUnrecordedPrimaryCB) {
27053     TEST_DESCRIPTION("Attempt vkQueueSubmit with a CB in the initial state");
27054     ASSERT_NO_FATAL_FAILURE(Init());
27055     // never record m_commandBuffer
27056 
27057     VkSubmitInfo si = {};
27058     si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
27059     si.commandBufferCount = 1;
27060     si.pCommandBuffers = &m_commandBuffer->handle();
27061 
27062     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkQueueSubmit-pCommandBuffers-00072");
27063     vkQueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE);
27064     m_errorMonitor->VerifyFound();
27065 }
TEST_F(VkLayerTest,ExecuteSecondaryCBWithLayoutMismatch)27066 TEST_F(VkLayerTest, ExecuteSecondaryCBWithLayoutMismatch) {
27067     TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a CB with incorrect initial layout.");
27068 
27069     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
27070     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
27071 
27072     VkImageCreateInfo image_create_info = {};
27073     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
27074     image_create_info.pNext = NULL;
27075     image_create_info.imageType = VK_IMAGE_TYPE_2D;
27076     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
27077     image_create_info.extent.width = 32;
27078     image_create_info.extent.height = 1;
27079     image_create_info.extent.depth = 1;
27080     image_create_info.mipLevels = 1;
27081     image_create_info.arrayLayers = 1;
27082     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
27083     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
27084     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
27085     image_create_info.flags = 0;
27086 
27087     VkImageSubresource image_sub = VkImageObj::subresource(VK_IMAGE_ASPECT_COLOR_BIT, 0, 0);
27088     VkImageSubresourceRange image_sub_range = VkImageObj::subresource_range(image_sub);
27089 
27090     VkImageObj image(m_device);
27091     image.init(&image_create_info);
27092     ASSERT_TRUE(image.initialized());
27093     VkImageMemoryBarrier image_barrier =
27094         image.image_memory_barrier(0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, image_sub_range);
27095 
27096     auto pipeline = [&image_barrier](const VkCommandBufferObj &cb, VkImageLayout old_layout, VkImageLayout new_layout) {
27097         image_barrier.oldLayout = old_layout;
27098         image_barrier.newLayout = new_layout;
27099         vkCmdPipelineBarrier(cb.handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0,
27100                              nullptr, 1, &image_barrier);
27101     };
27102 
27103     // Validate that mismatched use of image layout in secondary command buffer is caught at record time
27104     VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
27105     secondary.begin();
27106     pipeline(secondary, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
27107     secondary.end();
27108 
27109     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "UNASSIGNED-vkCmdExecuteCommands-commandBuffer-00001");
27110     m_commandBuffer->begin();
27111     pipeline(*m_commandBuffer, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
27112     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
27113     m_errorMonitor->VerifyFound();
27114 
27115     // Validate that we've tracked the changes from the secondary CB correctly
27116     m_errorMonitor->ExpectSuccess();
27117     pipeline(*m_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL);
27118     m_errorMonitor->VerifyNotFound();
27119     m_commandBuffer->end();
27120 
27121     m_commandBuffer->reset();
27122     secondary.reset();
27123 
27124     // Validate that UNDEFINED doesn't false positive on us
27125     secondary.begin();
27126     pipeline(secondary, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
27127     secondary.end();
27128     m_commandBuffer->begin();
27129     pipeline(*m_commandBuffer, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
27130     m_errorMonitor->ExpectSuccess();
27131     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
27132     m_errorMonitor->VerifyNotFound();
27133     m_commandBuffer->end();
27134 }
27135 
TEST_F(VkLayerTest,ExtensionNotEnabled)27136 TEST_F(VkLayerTest, ExtensionNotEnabled) {
27137     TEST_DESCRIPTION("Validate that using an API from an unenabled extension returns an error");
27138 
27139     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
27140         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
27141     } else {
27142         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
27143                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
27144         return;
27145     }
27146     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
27147 
27148     // Required extensions except VK_KHR_GET_MEMORY_REQUIREMENTS_2 -- to create the needed error
27149     std::vector<const char *> required_device_extensions = {VK_KHR_MAINTENANCE1_EXTENSION_NAME, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME,
27150                                                             VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME};
27151     for (auto dev_ext : required_device_extensions) {
27152         if (DeviceExtensionSupported(gpu(), nullptr, dev_ext)) {
27153             m_device_extension_names.push_back(dev_ext);
27154         } else {
27155             printf("%s Did not find required device extension %s; skipped.\n", kSkipPrefix, dev_ext);
27156             break;
27157         }
27158     }
27159 
27160     // Need to ignore this error to get to the one we're testing
27161     m_errorMonitor->SetUnexpectedError("VUID-vkCreateDevice-ppEnabledExtensionNames-01387");
27162     ASSERT_NO_FATAL_FAILURE(InitState());
27163 
27164     // Find address of extension API
27165     auto vkCreateSamplerYcbcrConversionKHR =
27166         (PFN_vkCreateSamplerYcbcrConversionKHR)vkGetDeviceProcAddr(m_device->handle(), "vkCreateSamplerYcbcrConversionKHR");
27167     if (vkCreateSamplerYcbcrConversionKHR == nullptr) {
27168         printf("%s VK_KHR_sampler_ycbcr_conversion not supported by device; skipped.\n", kSkipPrefix);
27169         return;
27170     }
27171     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "UNASSIGNED-GeneralParameterError-ExtensionNotEnabled");
27172     VkSamplerYcbcrConversionCreateInfo ycbcr_info = {VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
27173                                                      NULL,
27174                                                      VK_FORMAT_UNDEFINED,
27175                                                      VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY,
27176                                                      VK_SAMPLER_YCBCR_RANGE_ITU_FULL,
27177                                                      {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
27178                                                       VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY},
27179                                                      VK_CHROMA_LOCATION_COSITED_EVEN,
27180                                                      VK_CHROMA_LOCATION_COSITED_EVEN,
27181                                                      VK_FILTER_NEAREST,
27182                                                      false};
27183     VkSamplerYcbcrConversion conversion;
27184     vkCreateSamplerYcbcrConversionKHR(m_device->handle(), &ycbcr_info, nullptr, &conversion);
27185     m_errorMonitor->VerifyFound();
27186 }
27187 
TEST_F(VkLayerTest,Maintenance1AndNegativeViewport)27188 TEST_F(VkLayerTest, Maintenance1AndNegativeViewport) {
27189     TEST_DESCRIPTION("Attempt to enable AMD_negative_viewport_height and Maintenance1_KHR extension simultaneously");
27190 
27191     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
27192     if (!((DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) &&
27193           (DeviceExtensionSupported(gpu(), nullptr, VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME)))) {
27194         printf("%s Maintenance1 and AMD_negative viewport height extensions not supported, skipping test\n", kSkipPrefix);
27195         return;
27196     }
27197     ASSERT_NO_FATAL_FAILURE(InitState());
27198 
27199     vk_testing::QueueCreateInfoArray queue_info(m_device->queue_props);
27200     const char *extension_names[2] = {"VK_KHR_maintenance1", "VK_AMD_negative_viewport_height"};
27201     VkDevice testDevice;
27202     VkDeviceCreateInfo device_create_info = {};
27203     auto features = m_device->phy().features();
27204     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
27205     device_create_info.pNext = NULL;
27206     device_create_info.queueCreateInfoCount = queue_info.size();
27207     device_create_info.pQueueCreateInfos = queue_info.data();
27208     device_create_info.enabledLayerCount = 0;
27209     device_create_info.ppEnabledLayerNames = NULL;
27210     device_create_info.enabledExtensionCount = 2;
27211     device_create_info.ppEnabledExtensionNames = (const char *const *)extension_names;
27212     device_create_info.pEnabledFeatures = &features;
27213 
27214     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-00374");
27215     // The following unexpected error is coming from the LunarG loader. Do not make it a desired message because platforms that do
27216     // not use the LunarG loader (e.g. Android) will not see the message and the test will fail.
27217     m_errorMonitor->SetUnexpectedError("Failed to create device chain.");
27218     vkCreateDevice(gpu(), &device_create_info, NULL, &testDevice);
27219     m_errorMonitor->VerifyFound();
27220 }
27221 
TEST_F(VkLayerTest,InvalidCreateDescriptorPool)27222 TEST_F(VkLayerTest, InvalidCreateDescriptorPool) {
27223     TEST_DESCRIPTION("Attempt to create descriptor pool with invalid parameters");
27224 
27225     ASSERT_NO_FATAL_FAILURE(Init());
27226 
27227     const uint32_t default_descriptor_count = 1;
27228     const VkDescriptorPoolSize dp_size_template{VK_DESCRIPTOR_TYPE_SAMPLER, default_descriptor_count};
27229 
27230     const VkDescriptorPoolCreateInfo dp_ci_template{VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
27231                                                     nullptr,  // pNext
27232                                                     0,        // flags
27233                                                     1,        // maxSets
27234                                                     1,        // poolSizeCount
27235                                                     &dp_size_template};
27236 
27237     // try maxSets = 0
27238     {
27239         VkDescriptorPoolCreateInfo invalid_dp_ci = dp_ci_template;
27240         invalid_dp_ci.maxSets = 0;  // invalid maxSets value
27241 
27242         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkDescriptorPoolCreateInfo-maxSets-00301");
27243         {
27244             VkDescriptorPool pool;
27245             vkCreateDescriptorPool(m_device->device(), &invalid_dp_ci, nullptr, &pool);
27246         }
27247         m_errorMonitor->VerifyFound();
27248     }
27249 
27250     // try descriptorCount = 0
27251     {
27252         VkDescriptorPoolSize invalid_dp_size = dp_size_template;
27253         invalid_dp_size.descriptorCount = 0;  // invalid descriptorCount value
27254 
27255         VkDescriptorPoolCreateInfo dp_ci = dp_ci_template;
27256         dp_ci.pPoolSizes = &invalid_dp_size;
27257 
27258         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkDescriptorPoolSize-descriptorCount-00302");
27259         {
27260             VkDescriptorPool pool;
27261             vkCreateDescriptorPool(m_device->device(), &dp_ci, nullptr, &pool);
27262         }
27263         m_errorMonitor->VerifyFound();
27264     }
27265 }
27266 
TEST_F(VkLayerTest,InvalidCreateBufferSize)27267 TEST_F(VkLayerTest, InvalidCreateBufferSize) {
27268     TEST_DESCRIPTION("Attempt to create VkBuffer with size of zero");
27269 
27270     ASSERT_NO_FATAL_FAILURE(Init());
27271 
27272     VkBufferCreateInfo info = {};
27273     info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
27274     info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
27275 
27276     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferCreateInfo-size-00912");
27277     info.size = 0;
27278     VkBuffer buffer;
27279     vkCreateBuffer(m_device->device(), &info, nullptr, &buffer);
27280     m_errorMonitor->VerifyFound();
27281 }
27282 
TEST_F(VkLayerTest,SetDynViewportParamTests)27283 TEST_F(VkLayerTest, SetDynViewportParamTests) {
27284     TEST_DESCRIPTION("Test parameters of vkCmdSetViewport without multiViewport feature");
27285 
27286     SetTargetApiVersion(VK_API_VERSION_1_1);
27287     VkPhysicalDeviceFeatures features{};
27288     ASSERT_NO_FATAL_FAILURE(Init(&features));
27289 
27290     const VkViewport vp = {0.0, 0.0, 64.0, 64.0, 0.0, 1.0};
27291     const VkViewport viewports[] = {vp, vp};
27292 
27293     m_commandBuffer->begin();
27294 
27295     // array tests
27296     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-firstViewport-01224");
27297     vkCmdSetViewport(m_commandBuffer->handle(), 1, 1, viewports);
27298     m_errorMonitor->VerifyFound();
27299 
27300     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-viewportCount-arraylength");
27301     vkCmdSetViewport(m_commandBuffer->handle(), 0, 0, nullptr);
27302     m_errorMonitor->VerifyFound();
27303 
27304     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-viewportCount-01225");
27305     vkCmdSetViewport(m_commandBuffer->handle(), 0, 2, viewports);
27306     m_errorMonitor->VerifyFound();
27307 
27308     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-firstViewport-01224");
27309     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-viewportCount-arraylength");
27310     vkCmdSetViewport(m_commandBuffer->handle(), 1, 0, viewports);
27311     m_errorMonitor->VerifyFound();
27312 
27313     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-firstViewport-01224");
27314     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-viewportCount-01225");
27315     vkCmdSetViewport(m_commandBuffer->handle(), 1, 2, viewports);
27316     m_errorMonitor->VerifyFound();
27317 
27318     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-pViewports-parameter");
27319     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, nullptr);
27320     m_errorMonitor->VerifyFound();
27321 
27322     // core viewport tests
27323     using std::vector;
27324     struct TestCase {
27325         VkViewport vp;
27326         std::string veid;
27327     };
27328 
27329     // not necessarily boundary values (unspecified cast rounding), but guaranteed to be over limit
27330     const auto one_past_max_w = NearestGreater(static_cast<float>(m_device->props.limits.maxViewportDimensions[0]));
27331     const auto one_past_max_h = NearestGreater(static_cast<float>(m_device->props.limits.maxViewportDimensions[1]));
27332 
27333     const auto min_bound = m_device->props.limits.viewportBoundsRange[0];
27334     const auto max_bound = m_device->props.limits.viewportBoundsRange[1];
27335     const auto one_before_min_bounds = NearestSmaller(min_bound);
27336     const auto one_past_max_bounds = NearestGreater(max_bound);
27337 
27338     const auto below_zero = NearestSmaller(0.0f);
27339     const auto past_one = NearestGreater(1.0f);
27340 
27341     vector<TestCase> test_cases = {
27342         {{0.0, 0.0, 0.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-width-01770"},
27343         {{0.0, 0.0, one_past_max_w, 64.0, 0.0, 1.0}, "VUID-VkViewport-width-01771"},
27344         {{0.0, 0.0, NAN, 64.0, 0.0, 1.0}, "VUID-VkViewport-width-01770"},
27345         {{0.0, 0.0, 64.0, one_past_max_h, 0.0, 1.0}, "VUID-VkViewport-height-01773"},
27346         {{one_before_min_bounds, 0.0, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01774"},
27347         {{one_past_max_bounds, 0.0, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01232"},
27348         {{NAN, 0.0, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01774"},
27349         {{0.0, one_before_min_bounds, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-y-01775"},
27350         {{0.0, NAN, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-y-01775"},
27351         {{max_bound, 0.0, 1.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01232"},
27352         {{0.0, max_bound, 64.0, 1.0, 0.0, 1.0}, "VUID-VkViewport-y-01233"},
27353         {{0.0, 0.0, 64.0, 64.0, below_zero, 1.0}, "VUID-VkViewport-minDepth-01234"},
27354         {{0.0, 0.0, 64.0, 64.0, past_one, 1.0}, "VUID-VkViewport-minDepth-01234"},
27355         {{0.0, 0.0, 64.0, 64.0, NAN, 1.0}, "VUID-VkViewport-minDepth-01234"},
27356         {{0.0, 0.0, 64.0, 64.0, 0.0, below_zero}, "VUID-VkViewport-maxDepth-01235"},
27357         {{0.0, 0.0, 64.0, 64.0, 0.0, past_one}, "VUID-VkViewport-maxDepth-01235"},
27358         {{0.0, 0.0, 64.0, 64.0, 0.0, NAN}, "VUID-VkViewport-maxDepth-01235"},
27359     };
27360 
27361     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
27362         test_cases.push_back({{0.0, 0.0, 64.0, 0.0, 0.0, 1.0}, "VUID-VkViewport-height-01772"});
27363         test_cases.push_back({{0.0, 0.0, 64.0, NAN, 0.0, 1.0}, "VUID-VkViewport-height-01772"});
27364     } else {
27365         test_cases.push_back({{0.0, 0.0, 64.0, NAN, 0.0, 1.0}, "VUID-VkViewport-height-01773"});
27366     }
27367 
27368     for (const auto &test_case : test_cases) {
27369         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.veid);
27370         vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &test_case.vp);
27371         m_errorMonitor->VerifyFound();
27372     }
27373 }
27374 
NegHeightViewportTests(VkDeviceObj * m_device,VkCommandBufferObj * m_commandBuffer,ErrorMonitor * m_errorMonitor)27375 void NegHeightViewportTests(VkDeviceObj *m_device, VkCommandBufferObj *m_commandBuffer, ErrorMonitor *m_errorMonitor) {
27376     const auto &limits = m_device->props.limits;
27377 
27378     m_commandBuffer->begin();
27379 
27380     using std::vector;
27381     struct TestCase {
27382         VkViewport vp;
27383         vector<std::string> vuids;
27384     };
27385 
27386     // not necessarily boundary values (unspecified cast rounding), but guaranteed to be over limit
27387     const auto one_before_min_h = NearestSmaller(-static_cast<float>(limits.maxViewportDimensions[1]));
27388     const auto one_past_max_h = NearestGreater(static_cast<float>(limits.maxViewportDimensions[1]));
27389 
27390     const auto min_bound = limits.viewportBoundsRange[0];
27391     const auto max_bound = limits.viewportBoundsRange[1];
27392     const auto one_before_min_bound = NearestSmaller(min_bound);
27393     const auto one_past_max_bound = NearestGreater(max_bound);
27394 
27395     const vector<TestCase> test_cases = {{{0.0, 0.0, 64.0, one_before_min_h, 0.0, 1.0}, {"VUID-VkViewport-height-01773"}},
27396                                          {{0.0, 0.0, 64.0, one_past_max_h, 0.0, 1.0}, {"VUID-VkViewport-height-01773"}},
27397                                          {{0.0, 0.0, 64.0, NAN, 0.0, 1.0}, {"VUID-VkViewport-height-01773"}},
27398                                          {{0.0, one_before_min_bound, 64.0, 1.0, 0.0, 1.0}, {"VUID-VkViewport-y-01775"}},
27399                                          {{0.0, one_past_max_bound, 64.0, -1.0, 0.0, 1.0}, {"VUID-VkViewport-y-01776"}},
27400                                          {{0.0, min_bound, 64.0, -1.0, 0.0, 1.0}, {"VUID-VkViewport-y-01777"}},
27401                                          {{0.0, max_bound, 64.0, 1.0, 0.0, 1.0}, {"VUID-VkViewport-y-01233"}}};
27402 
27403     for (const auto &test_case : test_cases) {
27404         for (const auto vuid : test_case.vuids) {
27405             if (vuid == "VUID-Undefined")
27406                 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
27407                                                      "is less than VkPhysicalDeviceLimits::viewportBoundsRange[0]");
27408             else
27409                 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
27410         }
27411         vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &test_case.vp);
27412         m_errorMonitor->VerifyFound();
27413     }
27414 }
27415 
TEST_F(VkLayerTest,SetDynViewportParamMaintenance1Tests)27416 TEST_F(VkLayerTest, SetDynViewportParamMaintenance1Tests) {
27417     TEST_DESCRIPTION("Verify errors are detected on misuse of SetViewport with a negative viewport extension enabled.");
27418 
27419     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
27420 
27421     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
27422         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
27423     } else {
27424         printf("%s VK_KHR_maintenance1 extension not supported -- skipping test\n", kSkipPrefix);
27425         return;
27426     }
27427     ASSERT_NO_FATAL_FAILURE(InitState());
27428 
27429     NegHeightViewportTests(m_device, m_commandBuffer, m_errorMonitor);
27430 }
27431 
TEST_F(VkLayerTest,SetDynViewportParamMultiviewportTests)27432 TEST_F(VkLayerTest, SetDynViewportParamMultiviewportTests) {
27433     TEST_DESCRIPTION("Test parameters of vkCmdSetViewport with multiViewport feature enabled");
27434 
27435     ASSERT_NO_FATAL_FAILURE(Init());
27436 
27437     if (!m_device->phy().features().multiViewport) {
27438         printf("%s VkPhysicalDeviceFeatures::multiViewport is not supported -- skipping test.\n", kSkipPrefix);
27439         return;
27440     }
27441 
27442     const auto max_viewports = m_device->props.limits.maxViewports;
27443     const uint32_t too_many_viewports = 65536 + 1;  // let's say this is too much to allocate pViewports for
27444 
27445     m_commandBuffer->begin();
27446 
27447     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-viewportCount-arraylength");
27448     vkCmdSetViewport(m_commandBuffer->handle(), 0, 0, nullptr);
27449     m_errorMonitor->VerifyFound();
27450 
27451     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-pViewports-parameter");
27452     vkCmdSetViewport(m_commandBuffer->handle(), 0, max_viewports, nullptr);
27453     m_errorMonitor->VerifyFound();
27454 
27455     if (max_viewports >= too_many_viewports) {
27456         printf(
27457             "%s VkPhysicalDeviceLimits::maxViewports is too large to practically test against -- skipping "
27458             "part of "
27459             "test.\n",
27460             kSkipPrefix);
27461         return;
27462     }
27463 
27464     const VkViewport vp = {0.0, 0.0, 64.0, 64.0, 0.0, 1.0};
27465     const std::vector<VkViewport> viewports(max_viewports + 1, vp);
27466 
27467     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-firstViewport-01223");
27468     vkCmdSetViewport(m_commandBuffer->handle(), 0, max_viewports + 1, viewports.data());
27469     m_errorMonitor->VerifyFound();
27470 
27471     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-firstViewport-01223");
27472     vkCmdSetViewport(m_commandBuffer->handle(), max_viewports, 1, viewports.data());
27473     m_errorMonitor->VerifyFound();
27474 
27475     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-firstViewport-01223");
27476     vkCmdSetViewport(m_commandBuffer->handle(), 1, max_viewports, viewports.data());
27477     m_errorMonitor->VerifyFound();
27478 
27479     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-viewportCount-arraylength");
27480     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-firstViewport-01223");
27481     vkCmdSetViewport(m_commandBuffer->handle(), max_viewports + 1, 0, viewports.data());
27482     m_errorMonitor->VerifyFound();
27483 }
27484 
27485 //
27486 // POSITIVE VALIDATION TESTS
27487 //
27488 // These tests do not expect to encounter ANY validation errors pass only if this is true
27489 
TEST_F(VkPositiveLayerTest,PointSizeWriteInFunction)27490 TEST_F(VkPositiveLayerTest, PointSizeWriteInFunction) {
27491     TEST_DESCRIPTION("Create a pipeline using TOPOLOGY_POINT_LIST and write PointSize in vertex shader function.");
27492 
27493     ASSERT_NO_FATAL_FAILURE(Init());
27494     m_errorMonitor->ExpectSuccess();
27495 
27496     ASSERT_NO_FATAL_FAILURE(InitViewport());
27497 
27498     // Create VS declaring PointSize and write to it in a function call.
27499     static const char PointSizeWriteVertShaderFcn[] =
27500         "#version 450\n"
27501         "vec2 vertices[3];\n"
27502         "out gl_PerVertex\n"
27503         "{\n"
27504         "    vec4 gl_Position;\n"
27505         "    float gl_PointSize;\n"
27506         "};\n"
27507         "void OutPointSize() {\n"
27508         "   gl_PointSize = 7.0;\n"
27509         "}\n"
27510         "void main() {\n"
27511         "    vertices[0] = vec2(-1.0, -1.0);\n"
27512         "    vertices[1] = vec2( 1.0, -1.0);\n"
27513         "    vertices[2] = vec2( 0.0,  1.0);\n"
27514         "    gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0);\n"
27515         "    OutPointSize();\n"
27516         "}\n";
27517 
27518     VkShaderObj vs(m_device, PointSizeWriteVertShaderFcn, VK_SHADER_STAGE_VERTEX_BIT, this);
27519     VkShaderObj ps(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
27520 
27521     {
27522         VkPipelineObj pipelineobj(m_device);
27523         pipelineobj.AddDefaultColorAttachment();
27524         pipelineobj.AddShader(&vs);
27525         pipelineobj.AddShader(&ps);
27526 
27527         // Set Input Assembly to TOPOLOGY POINT LIST
27528         VkPipelineInputAssemblyStateCreateInfo ia_state = {};
27529         ia_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
27530         ia_state.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
27531         pipelineobj.SetInputAssembly(&ia_state);
27532 
27533         ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
27534         m_commandBuffer->begin();
27535         m_commandBuffer->ClearAllBuffers(m_renderTargets, m_clear_color, m_depthStencil, m_depth_clear_color,
27536                                          m_stencil_clear_color);
27537         m_commandBuffer->PrepareAttachments(m_renderTargets, m_depthStencil);
27538         VkDescriptorSetObj descriptorSet(m_device);
27539         descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
27540         pipelineobj.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
27541     }
27542     m_errorMonitor->VerifyNotFound();
27543 }
27544 
TEST_F(VkPositiveLayerTest,PointSizeGeomShaderSuccess)27545 TEST_F(VkPositiveLayerTest, PointSizeGeomShaderSuccess) {
27546     TEST_DESCRIPTION(
27547         "Create a pipeline using TOPOLOGY_POINT_LIST, set PointSize vertex shader, and write in the final geometry stage.");
27548 
27549     ASSERT_NO_FATAL_FAILURE(Init());
27550     m_errorMonitor->ExpectSuccess();
27551 
27552     if ((!m_device->phy().features().geometryShader) || (!m_device->phy().features().shaderTessellationAndGeometryPointSize)) {
27553         printf("%s Device does not support the required geometry shader features; skipped.\n", kSkipPrefix);
27554         return;
27555     }
27556 
27557     ASSERT_NO_FATAL_FAILURE(InitViewport());
27558 
27559     // Create VS declaring PointSize and writing to it
27560     static const char PointSizeVertShader[] =
27561         "#version 450\n"
27562         "vec2 vertices[3];\n"
27563         "out gl_PerVertex\n"
27564         "{\n"
27565         "    vec4 gl_Position;\n"
27566         "    float gl_PointSize;\n"
27567         "};\n"
27568         "void main() {\n"
27569         "    vertices[0] = vec2(-1.0, -1.0);\n"
27570         "    vertices[1] = vec2( 1.0, -1.0);\n"
27571         "    vertices[2] = vec2( 0.0,  1.0);\n"
27572         "    gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0);\n"
27573         "    gl_PointSize = 5.0;\n"
27574         "}\n";
27575     static char const *gsSource =
27576         "#version 450\n"
27577         "layout (points) in;\n"
27578         "layout (points) out;\n"
27579         "layout (max_vertices = 1) out;\n"
27580         "void main() {\n"
27581         "   gl_Position = vec4(1.0, 0.5, 0.5, 0.0);\n"
27582         "   gl_PointSize = 3.3;\n"
27583         "   EmitVertex();\n"
27584         "}\n";
27585 
27586     VkShaderObj vs(m_device, PointSizeVertShader, VK_SHADER_STAGE_VERTEX_BIT, this);
27587     VkShaderObj gs(m_device, gsSource, VK_SHADER_STAGE_GEOMETRY_BIT, this);
27588     VkShaderObj ps(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
27589 
27590     VkPipelineObj pipelineobj(m_device);
27591     pipelineobj.AddDefaultColorAttachment();
27592     pipelineobj.AddShader(&vs);
27593     pipelineobj.AddShader(&gs);
27594     pipelineobj.AddShader(&ps);
27595 
27596     // Set Input Assembly to TOPOLOGY POINT LIST
27597     VkPipelineInputAssemblyStateCreateInfo ia_state = {};
27598     ia_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
27599     ia_state.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
27600     pipelineobj.SetInputAssembly(&ia_state);
27601 
27602     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
27603     m_commandBuffer->begin();
27604     m_commandBuffer->ClearAllBuffers(m_renderTargets, m_clear_color, m_depthStencil, m_depth_clear_color, m_stencil_clear_color);
27605     m_commandBuffer->PrepareAttachments(m_renderTargets, m_depthStencil);
27606     VkDescriptorSetObj descriptorSet(m_device);
27607     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
27608     pipelineobj.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
27609     m_errorMonitor->VerifyNotFound();
27610 }
27611 
TEST_F(VkPositiveLayerTest,LoosePointSizeWrite)27612 TEST_F(VkPositiveLayerTest, LoosePointSizeWrite) {
27613     TEST_DESCRIPTION("Create a pipeline using TOPOLOGY_POINT_LIST and write PointSize outside of a structure.");
27614 
27615     ASSERT_NO_FATAL_FAILURE(Init());
27616     m_errorMonitor->ExpectSuccess();
27617 
27618     ASSERT_NO_FATAL_FAILURE(InitViewport());
27619 
27620     const std::string LoosePointSizeWrite = R"(
27621                                        OpCapability Shader
27622                                   %1 = OpExtInstImport "GLSL.std.450"
27623                                        OpMemoryModel Logical GLSL450
27624                                        OpEntryPoint Vertex %main "main" %glposition %glpointsize %gl_VertexIndex
27625                                        OpSource GLSL 450
27626                                        OpName %main "main"
27627                                        OpName %vertices "vertices"
27628                                        OpName %glposition "glposition"
27629                                        OpName %glpointsize "glpointsize"
27630                                        OpName %gl_VertexIndex "gl_VertexIndex"
27631                                        OpDecorate %glposition BuiltIn Position
27632                                        OpDecorate %glpointsize BuiltIn PointSize
27633                                        OpDecorate %gl_VertexIndex BuiltIn VertexIndex
27634                                %void = OpTypeVoid
27635                                   %3 = OpTypeFunction %void
27636                               %float = OpTypeFloat 32
27637                             %v2float = OpTypeVector %float 2
27638                                %uint = OpTypeInt 32 0
27639                              %uint_3 = OpConstant %uint 3
27640                 %_arr_v2float_uint_3 = OpTypeArray %v2float %uint_3
27641    %_ptr_Private__arr_v2float_uint_3 = OpTypePointer Private %_arr_v2float_uint_3
27642                            %vertices = OpVariable %_ptr_Private__arr_v2float_uint_3 Private
27643                                 %int = OpTypeInt 32 1
27644                               %int_0 = OpConstant %int 0
27645                            %float_n1 = OpConstant %float -1
27646                                  %16 = OpConstantComposite %v2float %float_n1 %float_n1
27647                %_ptr_Private_v2float = OpTypePointer Private %v2float
27648                               %int_1 = OpConstant %int 1
27649                             %float_1 = OpConstant %float 1
27650                                  %21 = OpConstantComposite %v2float %float_1 %float_n1
27651                               %int_2 = OpConstant %int 2
27652                             %float_0 = OpConstant %float 0
27653                                  %25 = OpConstantComposite %v2float %float_0 %float_1
27654                             %v4float = OpTypeVector %float 4
27655             %_ptr_Output_gl_Position = OpTypePointer Output %v4float
27656                          %glposition = OpVariable %_ptr_Output_gl_Position Output
27657            %_ptr_Output_gl_PointSize = OpTypePointer Output %float
27658                         %glpointsize = OpVariable %_ptr_Output_gl_PointSize Output
27659                      %_ptr_Input_int = OpTypePointer Input %int
27660                      %gl_VertexIndex = OpVariable %_ptr_Input_int Input
27661                               %int_3 = OpConstant %int 3
27662                 %_ptr_Output_v4float = OpTypePointer Output %v4float
27663                   %_ptr_Output_float = OpTypePointer Output %float
27664                                %main = OpFunction %void None %3
27665                                   %5 = OpLabel
27666                                  %18 = OpAccessChain %_ptr_Private_v2float %vertices %int_0
27667                                        OpStore %18 %16
27668                                  %22 = OpAccessChain %_ptr_Private_v2float %vertices %int_1
27669                                        OpStore %22 %21
27670                                  %26 = OpAccessChain %_ptr_Private_v2float %vertices %int_2
27671                                        OpStore %26 %25
27672                                  %33 = OpLoad %int %gl_VertexIndex
27673                                  %35 = OpSMod %int %33 %int_3
27674                                  %36 = OpAccessChain %_ptr_Private_v2float %vertices %35
27675                                  %37 = OpLoad %v2float %36
27676                                  %38 = OpCompositeExtract %float %37 0
27677                                  %39 = OpCompositeExtract %float %37 1
27678                                  %40 = OpCompositeConstruct %v4float %38 %39 %float_0 %float_1
27679                                  %42 = OpAccessChain %_ptr_Output_v4float %glposition
27680                                        OpStore %42 %40
27681                                        OpStore %glpointsize %float_1
27682                                        OpReturn
27683                                        OpFunctionEnd
27684         )";
27685 
27686     // Create VS declaring PointSize and write to it in a function call.
27687     VkShaderObj vs(m_device, LoosePointSizeWrite, VK_SHADER_STAGE_VERTEX_BIT, this);
27688     VkShaderObj ps(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
27689 
27690     {
27691         VkPipelineObj pipelineobj(m_device);
27692         pipelineobj.AddDefaultColorAttachment();
27693         pipelineobj.AddShader(&vs);
27694         pipelineobj.AddShader(&ps);
27695 
27696         // Set Input Assembly to TOPOLOGY POINT LIST
27697         VkPipelineInputAssemblyStateCreateInfo ia_state = {};
27698         ia_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
27699         ia_state.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
27700         pipelineobj.SetInputAssembly(&ia_state);
27701 
27702         ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
27703         m_commandBuffer->begin();
27704         m_commandBuffer->ClearAllBuffers(m_renderTargets, m_clear_color, m_depthStencil, m_depth_clear_color,
27705                                          m_stencil_clear_color);
27706         m_commandBuffer->PrepareAttachments(m_renderTargets, m_depthStencil);
27707         VkDescriptorSetObj descriptorSet(m_device);
27708         descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
27709         pipelineobj.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
27710     }
27711     m_errorMonitor->VerifyNotFound();
27712 }
27713 
TEST_F(VkPositiveLayerTest,UncompressedToCompressedImageCopy)27714 TEST_F(VkPositiveLayerTest, UncompressedToCompressedImageCopy) {
27715     TEST_DESCRIPTION("Image copies between compressed and uncompressed images");
27716     ASSERT_NO_FATAL_FAILURE(Init());
27717 
27718     // Verify format support
27719     // Size-compatible (64-bit) formats. Uncompressed is 64 bits per texel, compressed is 64 bits per 4x4 block (or 4bpt).
27720     if (!ImageFormatAndFeaturesSupported(gpu(), VK_FORMAT_R16G16B16A16_UINT, VK_IMAGE_TILING_OPTIMAL,
27721                                          VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR | VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR) ||
27722         !ImageFormatAndFeaturesSupported(gpu(), VK_FORMAT_BC1_RGBA_SRGB_BLOCK, VK_IMAGE_TILING_OPTIMAL,
27723                                          VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR | VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR)) {
27724         printf("%s Required formats/features not supported - UncompressedToCompressedImageCopy skipped.\n", kSkipPrefix);
27725         return;
27726     }
27727 
27728     VkImageObj uncomp_10x10t_image(m_device);       // Size = 10 * 10 * 64 = 6400
27729     VkImageObj comp_10x10b_40x40t_image(m_device);  // Size = 40 * 40 * 4  = 6400
27730 
27731     uncomp_10x10t_image.Init(10, 10, 1, VK_FORMAT_R16G16B16A16_UINT,
27732                              VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
27733     comp_10x10b_40x40t_image.Init(40, 40, 1, VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
27734                                   VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
27735 
27736     if (!uncomp_10x10t_image.initialized() || !comp_10x10b_40x40t_image.initialized()) {
27737         printf("%s Unable to initialize surfaces - UncompressedToCompressedImageCopy skipped.\n", kSkipPrefix);
27738         return;
27739     }
27740 
27741     // Both copies represent the same number of bytes. Bytes Per Texel = 1 for bc6, 16 for uncompressed
27742     // Copy compressed to uncompressed
27743     VkImageCopy copy_region = {};
27744     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
27745     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
27746     copy_region.srcSubresource.mipLevel = 0;
27747     copy_region.dstSubresource.mipLevel = 0;
27748     copy_region.srcSubresource.baseArrayLayer = 0;
27749     copy_region.dstSubresource.baseArrayLayer = 0;
27750     copy_region.srcSubresource.layerCount = 1;
27751     copy_region.dstSubresource.layerCount = 1;
27752     copy_region.srcOffset = {0, 0, 0};
27753     copy_region.dstOffset = {0, 0, 0};
27754 
27755     m_errorMonitor->ExpectSuccess();
27756     m_commandBuffer->begin();
27757 
27758     // Copy from uncompressed to compressed
27759     copy_region.extent = {10, 10, 1};  // Dimensions in (uncompressed) texels
27760     vkCmdCopyImage(m_commandBuffer->handle(), uncomp_10x10t_image.handle(), VK_IMAGE_LAYOUT_GENERAL,
27761                    comp_10x10b_40x40t_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
27762 
27763     // And from compressed to uncompressed
27764     copy_region.extent = {40, 40, 1};  // Dimensions in (compressed) texels
27765     vkCmdCopyImage(m_commandBuffer->handle(), comp_10x10b_40x40t_image.handle(), VK_IMAGE_LAYOUT_GENERAL,
27766                    uncomp_10x10t_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
27767 
27768     m_errorMonitor->VerifyNotFound();
27769     m_commandBuffer->end();
27770 }
27771 
TEST_F(VkPositiveLayerTest,DeleteDescriptorSetLayoutsBeforeDescriptorSets)27772 TEST_F(VkPositiveLayerTest, DeleteDescriptorSetLayoutsBeforeDescriptorSets) {
27773     TEST_DESCRIPTION("Create DSLayouts and DescriptorSets and then delete the DSLayouts before the DescriptorSets.");
27774     ASSERT_NO_FATAL_FAILURE(Init());
27775     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
27776     VkResult err;
27777 
27778     m_errorMonitor->ExpectSuccess();
27779 
27780     VkDescriptorPoolSize ds_type_count = {};
27781     ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
27782     ds_type_count.descriptorCount = 1;
27783 
27784     VkDescriptorPoolCreateInfo ds_pool_ci = {};
27785     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
27786     ds_pool_ci.pNext = NULL;
27787     ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
27788     ds_pool_ci.maxSets = 1;
27789     ds_pool_ci.poolSizeCount = 1;
27790     ds_pool_ci.pPoolSizes = &ds_type_count;
27791 
27792     VkDescriptorPool ds_pool_one;
27793     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool_one);
27794     ASSERT_VK_SUCCESS(err);
27795 
27796     VkDescriptorSetLayoutBinding dsl_binding = {};
27797     dsl_binding.binding = 0;
27798     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
27799     dsl_binding.descriptorCount = 1;
27800     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
27801     dsl_binding.pImmutableSamplers = NULL;
27802 
27803     VkDescriptorSet descriptorSet;
27804     {
27805         const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
27806 
27807         VkDescriptorSetAllocateInfo alloc_info = {};
27808         alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
27809         alloc_info.descriptorSetCount = 1;
27810         alloc_info.descriptorPool = ds_pool_one;
27811         alloc_info.pSetLayouts = &ds_layout.handle();
27812         err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
27813         ASSERT_VK_SUCCESS(err);
27814     }  // ds_layout destroyed
27815     err = vkFreeDescriptorSets(m_device->device(), ds_pool_one, 1, &descriptorSet);
27816 
27817     vkDestroyDescriptorPool(m_device->device(), ds_pool_one, NULL);
27818     m_errorMonitor->VerifyNotFound();
27819 }
27820 
TEST_F(VkPositiveLayerTest,CommandPoolDeleteWithReferences)27821 TEST_F(VkPositiveLayerTest, CommandPoolDeleteWithReferences) {
27822     TEST_DESCRIPTION("Ensure the validation layers bookkeeping tracks the implicit command buffer frees.");
27823     ASSERT_NO_FATAL_FAILURE(Init());
27824 
27825     VkCommandPoolCreateInfo cmd_pool_info = {};
27826     cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
27827     cmd_pool_info.pNext = NULL;
27828     cmd_pool_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
27829     cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
27830     cmd_pool_info.flags = 0;
27831 
27832     VkCommandPool secondary_cmd_pool;
27833     VkResult res = vkCreateCommandPool(m_device->handle(), &cmd_pool_info, NULL, &secondary_cmd_pool);
27834     ASSERT_VK_SUCCESS(res);
27835 
27836     VkCommandBufferAllocateInfo cmdalloc = vk_testing::CommandBuffer::create_info(secondary_cmd_pool);
27837     cmdalloc.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
27838 
27839     VkCommandBuffer secondary_cmds;
27840     res = vkAllocateCommandBuffers(m_device->handle(), &cmdalloc, &secondary_cmds);
27841 
27842     VkCommandBufferInheritanceInfo cmd_buf_inheritance_info = {};
27843     cmd_buf_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
27844     cmd_buf_inheritance_info.pNext = NULL;
27845     cmd_buf_inheritance_info.renderPass = VK_NULL_HANDLE;
27846     cmd_buf_inheritance_info.subpass = 0;
27847     cmd_buf_inheritance_info.framebuffer = VK_NULL_HANDLE;
27848     cmd_buf_inheritance_info.occlusionQueryEnable = VK_FALSE;
27849     cmd_buf_inheritance_info.queryFlags = 0;
27850     cmd_buf_inheritance_info.pipelineStatistics = 0;
27851 
27852     VkCommandBufferBeginInfo secondary_begin = {};
27853     secondary_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
27854     secondary_begin.pNext = NULL;
27855     secondary_begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
27856     secondary_begin.pInheritanceInfo = &cmd_buf_inheritance_info;
27857 
27858     res = vkBeginCommandBuffer(secondary_cmds, &secondary_begin);
27859     ASSERT_VK_SUCCESS(res);
27860     vkEndCommandBuffer(secondary_cmds);
27861 
27862     m_commandBuffer->begin();
27863     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_cmds);
27864     m_commandBuffer->end();
27865 
27866     // DestroyCommandPool *implicitly* frees the command buffers allocated from it
27867     vkDestroyCommandPool(m_device->handle(), secondary_cmd_pool, NULL);
27868     // If bookkeeping has been lax, validating the reset will attempt to touch deleted data
27869     res = vkResetCommandPool(m_device->handle(), m_commandPool->handle(), 0);
27870     ASSERT_VK_SUCCESS(res);
27871 }
27872 
TEST_F(VkLayerTest,SecondaryCommandBufferClearColorAttachmentsRenderArea)27873 TEST_F(VkLayerTest, SecondaryCommandBufferClearColorAttachmentsRenderArea) {
27874     TEST_DESCRIPTION(
27875         "Create a secondary command buffer with CmdClearAttachments call that has a rect outside of renderPass renderArea");
27876     ASSERT_NO_FATAL_FAILURE(Init());
27877     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
27878 
27879     VkCommandBufferAllocateInfo command_buffer_allocate_info = {};
27880     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
27881     command_buffer_allocate_info.commandPool = m_commandPool->handle();
27882     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
27883     command_buffer_allocate_info.commandBufferCount = 1;
27884 
27885     VkCommandBuffer secondary_command_buffer;
27886     ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer));
27887     VkCommandBufferBeginInfo command_buffer_begin_info = {};
27888     VkCommandBufferInheritanceInfo command_buffer_inheritance_info = {};
27889     command_buffer_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
27890     command_buffer_inheritance_info.renderPass = m_renderPass;
27891     command_buffer_inheritance_info.framebuffer = m_framebuffer;
27892 
27893     command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
27894     command_buffer_begin_info.flags =
27895         VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
27896     command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info;
27897 
27898     vkBeginCommandBuffer(secondary_command_buffer, &command_buffer_begin_info);
27899     VkClearAttachment color_attachment;
27900     color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
27901     color_attachment.clearValue.color.float32[0] = 0;
27902     color_attachment.clearValue.color.float32[1] = 0;
27903     color_attachment.clearValue.color.float32[2] = 0;
27904     color_attachment.clearValue.color.float32[3] = 0;
27905     color_attachment.colorAttachment = 0;
27906     // x extent of 257 exceeds render area of 256
27907     VkClearRect clear_rect = {{{0, 0}, {257, 32}}};
27908     vkCmdClearAttachments(secondary_command_buffer, 1, &color_attachment, 1, &clear_rect);
27909     vkEndCommandBuffer(secondary_command_buffer);
27910     m_commandBuffer->begin();
27911     vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
27912 
27913     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearAttachments-pRects-00016");
27914     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
27915     m_errorMonitor->VerifyFound();
27916 
27917     vkCmdEndRenderPass(m_commandBuffer->handle());
27918     m_commandBuffer->end();
27919 }
27920 
TEST_F(VkPositiveLayerTest,SecondaryCommandBufferClearColorAttachments)27921 TEST_F(VkPositiveLayerTest, SecondaryCommandBufferClearColorAttachments) {
27922     TEST_DESCRIPTION("Create a secondary command buffer and record a CmdClearAttachments call into it");
27923     m_errorMonitor->ExpectSuccess();
27924     ASSERT_NO_FATAL_FAILURE(Init());
27925     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
27926 
27927     VkCommandBufferAllocateInfo command_buffer_allocate_info = {};
27928     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
27929     command_buffer_allocate_info.commandPool = m_commandPool->handle();
27930     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
27931     command_buffer_allocate_info.commandBufferCount = 1;
27932 
27933     VkCommandBuffer secondary_command_buffer;
27934     ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer));
27935     VkCommandBufferBeginInfo command_buffer_begin_info = {};
27936     VkCommandBufferInheritanceInfo command_buffer_inheritance_info = {};
27937     command_buffer_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
27938     command_buffer_inheritance_info.renderPass = m_renderPass;
27939     command_buffer_inheritance_info.framebuffer = m_framebuffer;
27940 
27941     command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
27942     command_buffer_begin_info.flags =
27943         VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
27944     command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info;
27945 
27946     vkBeginCommandBuffer(secondary_command_buffer, &command_buffer_begin_info);
27947     VkClearAttachment color_attachment;
27948     color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
27949     color_attachment.clearValue.color.float32[0] = 0;
27950     color_attachment.clearValue.color.float32[1] = 0;
27951     color_attachment.clearValue.color.float32[2] = 0;
27952     color_attachment.clearValue.color.float32[3] = 0;
27953     color_attachment.colorAttachment = 0;
27954     VkClearRect clear_rect = {{{0, 0}, {32, 32}}};
27955     vkCmdClearAttachments(secondary_command_buffer, 1, &color_attachment, 1, &clear_rect);
27956     vkEndCommandBuffer(secondary_command_buffer);
27957     m_commandBuffer->begin();
27958     vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
27959     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
27960     vkCmdEndRenderPass(m_commandBuffer->handle());
27961     m_commandBuffer->end();
27962     m_errorMonitor->VerifyNotFound();
27963 }
27964 
TEST_F(VkPositiveLayerTest,SecondaryCommandBufferImageLayoutTransitions)27965 TEST_F(VkPositiveLayerTest, SecondaryCommandBufferImageLayoutTransitions) {
27966     TEST_DESCRIPTION("Perform an image layout transition in a secondary command buffer followed by a transition in the primary.");
27967     VkResult err;
27968     m_errorMonitor->ExpectSuccess();
27969     ASSERT_NO_FATAL_FAILURE(Init());
27970     auto depth_format = FindSupportedDepthStencilFormat(gpu());
27971     if (!depth_format) {
27972         printf("%s Couldn't find depth stencil format.\n", kSkipPrefix);
27973         return;
27974     }
27975     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
27976     // Allocate a secondary and primary cmd buffer
27977     VkCommandBufferAllocateInfo command_buffer_allocate_info = {};
27978     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
27979     command_buffer_allocate_info.commandPool = m_commandPool->handle();
27980     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
27981     command_buffer_allocate_info.commandBufferCount = 1;
27982 
27983     VkCommandBuffer secondary_command_buffer;
27984     ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer));
27985     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
27986     VkCommandBuffer primary_command_buffer;
27987     ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &primary_command_buffer));
27988     VkCommandBufferBeginInfo command_buffer_begin_info = {};
27989     VkCommandBufferInheritanceInfo command_buffer_inheritance_info = {};
27990     command_buffer_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
27991     command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
27992     command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
27993     command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info;
27994 
27995     err = vkBeginCommandBuffer(secondary_command_buffer, &command_buffer_begin_info);
27996     ASSERT_VK_SUCCESS(err);
27997     VkImageObj image(m_device);
27998     image.Init(128, 128, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
27999     ASSERT_TRUE(image.initialized());
28000     VkImageMemoryBarrier img_barrier = {};
28001     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
28002     img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
28003     img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
28004     img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
28005     img_barrier.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
28006     img_barrier.image = image.handle();
28007     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
28008     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
28009     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
28010     img_barrier.subresourceRange.baseArrayLayer = 0;
28011     img_barrier.subresourceRange.baseMipLevel = 0;
28012     img_barrier.subresourceRange.layerCount = 1;
28013     img_barrier.subresourceRange.levelCount = 1;
28014     vkCmdPipelineBarrier(secondary_command_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr,
28015                          0, nullptr, 1, &img_barrier);
28016     err = vkEndCommandBuffer(secondary_command_buffer);
28017     ASSERT_VK_SUCCESS(err);
28018 
28019     // Now update primary cmd buffer to execute secondary and transitions image
28020     command_buffer_begin_info.pInheritanceInfo = nullptr;
28021     err = vkBeginCommandBuffer(primary_command_buffer, &command_buffer_begin_info);
28022     ASSERT_VK_SUCCESS(err);
28023     vkCmdExecuteCommands(primary_command_buffer, 1, &secondary_command_buffer);
28024     VkImageMemoryBarrier img_barrier2 = {};
28025     img_barrier2.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
28026     img_barrier2.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
28027     img_barrier2.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
28028     img_barrier2.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
28029     img_barrier2.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
28030     img_barrier2.image = image.handle();
28031     img_barrier2.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
28032     img_barrier2.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
28033     img_barrier2.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
28034     img_barrier2.subresourceRange.baseArrayLayer = 0;
28035     img_barrier2.subresourceRange.baseMipLevel = 0;
28036     img_barrier2.subresourceRange.layerCount = 1;
28037     img_barrier2.subresourceRange.levelCount = 1;
28038     vkCmdPipelineBarrier(primary_command_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 0,
28039                          nullptr, 1, &img_barrier2);
28040     err = vkEndCommandBuffer(primary_command_buffer);
28041     ASSERT_VK_SUCCESS(err);
28042     VkSubmitInfo submit_info = {};
28043     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
28044     submit_info.commandBufferCount = 1;
28045     submit_info.pCommandBuffers = &primary_command_buffer;
28046     err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
28047     ASSERT_VK_SUCCESS(err);
28048     m_errorMonitor->VerifyNotFound();
28049     err = vkDeviceWaitIdle(m_device->device());
28050     ASSERT_VK_SUCCESS(err);
28051     vkFreeCommandBuffers(m_device->device(), m_commandPool->handle(), 1, &secondary_command_buffer);
28052     vkFreeCommandBuffers(m_device->device(), m_commandPool->handle(), 1, &primary_command_buffer);
28053 }
28054 
28055 // This is a positive test. No failures are expected.
TEST_F(VkPositiveLayerTest,IgnoreUnrelatedDescriptor)28056 TEST_F(VkPositiveLayerTest, IgnoreUnrelatedDescriptor) {
28057     TEST_DESCRIPTION(
28058         "Ensure that the vkUpdateDescriptorSets validation code is ignoring VkWriteDescriptorSet members that are not related to "
28059         "the descriptor type specified by VkWriteDescriptorSet::descriptorType.  Correct validation behavior will result in the "
28060         "test running to completion without validation errors.");
28061 
28062     const uintptr_t invalid_ptr = 0xcdcdcdcd;
28063 
28064     ASSERT_NO_FATAL_FAILURE(Init());
28065 
28066     // Verify VK_FORMAT_R8_UNORM supports VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT
28067     const VkFormat format_texel_case = VK_FORMAT_R8_UNORM;
28068     const char *format_texel_case_string = "VK_FORMAT_R8_UNORM";
28069     VkFormatProperties format_properties;
28070     vkGetPhysicalDeviceFormatProperties(gpu(), format_texel_case, &format_properties);
28071     if (!(format_properties.bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT)) {
28072         printf("%s Test requires %s to support VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT\n", kSkipPrefix, format_texel_case_string);
28073         return;
28074     }
28075 
28076     // Image Case
28077     {
28078         m_errorMonitor->ExpectSuccess();
28079 
28080         VkImageObj image(m_device);
28081         image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
28082 
28083         VkImageView view = image.targetView(VK_FORMAT_B8G8R8A8_UNORM);
28084 
28085         OneOffDescriptorSet ds(m_device, {
28086                                              {0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr},
28087                                          });
28088 
28089         VkDescriptorImageInfo image_info = {};
28090         image_info.imageView = view;
28091         image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
28092 
28093         VkWriteDescriptorSet descriptor_write;
28094         memset(&descriptor_write, 0, sizeof(descriptor_write));
28095         descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
28096         descriptor_write.dstSet = ds.set_;
28097         descriptor_write.dstBinding = 0;
28098         descriptor_write.descriptorCount = 1;
28099         descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
28100         descriptor_write.pImageInfo = &image_info;
28101 
28102         // Set pBufferInfo and pTexelBufferView to invalid values, which should
28103         // be
28104         //  ignored for descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE.
28105         // This will most likely produce a crash if the parameter_validation
28106         // layer
28107         // does not correctly ignore pBufferInfo.
28108         descriptor_write.pBufferInfo = reinterpret_cast<const VkDescriptorBufferInfo *>(invalid_ptr);
28109         descriptor_write.pTexelBufferView = reinterpret_cast<const VkBufferView *>(invalid_ptr);
28110 
28111         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
28112 
28113         m_errorMonitor->VerifyNotFound();
28114     }
28115 
28116     // Buffer Case
28117     {
28118         m_errorMonitor->ExpectSuccess();
28119 
28120         VkBuffer buffer;
28121         uint32_t queue_family_index = 0;
28122         VkBufferCreateInfo buffer_create_info = {};
28123         buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
28124         buffer_create_info.size = 1024;
28125         buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
28126         buffer_create_info.queueFamilyIndexCount = 1;
28127         buffer_create_info.pQueueFamilyIndices = &queue_family_index;
28128 
28129         VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
28130         ASSERT_VK_SUCCESS(err);
28131 
28132         VkMemoryRequirements memory_reqs;
28133         VkDeviceMemory buffer_memory;
28134         bool pass;
28135         VkMemoryAllocateInfo memory_info = {};
28136         memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
28137         memory_info.pNext = NULL;
28138         memory_info.allocationSize = 0;
28139         memory_info.memoryTypeIndex = 0;
28140 
28141         vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
28142         memory_info.allocationSize = memory_reqs.size;
28143         pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
28144         ASSERT_TRUE(pass);
28145 
28146         err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
28147         ASSERT_VK_SUCCESS(err);
28148         err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
28149         ASSERT_VK_SUCCESS(err);
28150 
28151         OneOffDescriptorSet ds(m_device, {
28152                                              {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
28153                                          });
28154 
28155         VkDescriptorBufferInfo buffer_info = {};
28156         buffer_info.buffer = buffer;
28157         buffer_info.offset = 0;
28158         buffer_info.range = 1024;
28159 
28160         VkWriteDescriptorSet descriptor_write;
28161         memset(&descriptor_write, 0, sizeof(descriptor_write));
28162         descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
28163         descriptor_write.dstSet = ds.set_;
28164         descriptor_write.dstBinding = 0;
28165         descriptor_write.descriptorCount = 1;
28166         descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
28167         descriptor_write.pBufferInfo = &buffer_info;
28168 
28169         // Set pImageInfo and pTexelBufferView to invalid values, which should
28170         // be
28171         //  ignored for descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER.
28172         // This will most likely produce a crash if the parameter_validation
28173         // layer
28174         // does not correctly ignore pImageInfo.
28175         descriptor_write.pImageInfo = reinterpret_cast<const VkDescriptorImageInfo *>(invalid_ptr);
28176         descriptor_write.pTexelBufferView = reinterpret_cast<const VkBufferView *>(invalid_ptr);
28177 
28178         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
28179 
28180         m_errorMonitor->VerifyNotFound();
28181 
28182         vkDestroyBuffer(m_device->device(), buffer, NULL);
28183         vkFreeMemory(m_device->device(), buffer_memory, NULL);
28184     }
28185 
28186     // Texel Buffer Case
28187     {
28188         m_errorMonitor->ExpectSuccess();
28189 
28190         VkBuffer buffer;
28191         uint32_t queue_family_index = 0;
28192         VkBufferCreateInfo buffer_create_info = {};
28193         buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
28194         buffer_create_info.size = 1024;
28195         buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
28196         buffer_create_info.queueFamilyIndexCount = 1;
28197         buffer_create_info.pQueueFamilyIndices = &queue_family_index;
28198 
28199         VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
28200         ASSERT_VK_SUCCESS(err);
28201 
28202         VkMemoryRequirements memory_reqs;
28203         VkDeviceMemory buffer_memory;
28204         bool pass;
28205         VkMemoryAllocateInfo memory_info = {};
28206         memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
28207         memory_info.pNext = NULL;
28208         memory_info.allocationSize = 0;
28209         memory_info.memoryTypeIndex = 0;
28210 
28211         vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
28212         memory_info.allocationSize = memory_reqs.size;
28213         pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
28214         ASSERT_TRUE(pass);
28215 
28216         err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
28217         ASSERT_VK_SUCCESS(err);
28218         err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
28219         ASSERT_VK_SUCCESS(err);
28220 
28221         VkBufferViewCreateInfo buff_view_ci = {};
28222         buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
28223         buff_view_ci.buffer = buffer;
28224         buff_view_ci.format = format_texel_case;
28225         buff_view_ci.range = VK_WHOLE_SIZE;
28226         VkBufferView buffer_view;
28227         err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buffer_view);
28228 
28229         OneOffDescriptorSet ds(m_device, {
28230                                              {0, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
28231                                          });
28232 
28233         VkWriteDescriptorSet descriptor_write;
28234         memset(&descriptor_write, 0, sizeof(descriptor_write));
28235         descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
28236         descriptor_write.dstSet = ds.set_;
28237         descriptor_write.dstBinding = 0;
28238         descriptor_write.descriptorCount = 1;
28239         descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
28240         descriptor_write.pTexelBufferView = &buffer_view;
28241 
28242         // Set pImageInfo and pBufferInfo to invalid values, which should be
28243         //  ignored for descriptorType ==
28244         //  VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER.
28245         // This will most likely produce a crash if the parameter_validation
28246         // layer
28247         // does not correctly ignore pImageInfo and pBufferInfo.
28248         descriptor_write.pImageInfo = reinterpret_cast<const VkDescriptorImageInfo *>(invalid_ptr);
28249         descriptor_write.pBufferInfo = reinterpret_cast<const VkDescriptorBufferInfo *>(invalid_ptr);
28250 
28251         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
28252 
28253         m_errorMonitor->VerifyNotFound();
28254 
28255         vkDestroyBufferView(m_device->device(), buffer_view, NULL);
28256         vkDestroyBuffer(m_device->device(), buffer, NULL);
28257         vkFreeMemory(m_device->device(), buffer_memory, NULL);
28258     }
28259 }
28260 
TEST_F(VkPositiveLayerTest,ImmutableSamplerOnlyDescriptor)28261 TEST_F(VkPositiveLayerTest, ImmutableSamplerOnlyDescriptor) {
28262     TEST_DESCRIPTION("Bind a DescriptorSet with only an immutable sampler and make sure that we don't warn for no update.");
28263 
28264     ASSERT_NO_FATAL_FAILURE(Init());
28265     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
28266 
28267     OneOffDescriptorSet ds(m_device, {
28268                                          {0, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
28269                                      });
28270 
28271     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
28272     VkSampler sampler;
28273     VkResult err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
28274     ASSERT_VK_SUCCESS(err);
28275 
28276     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
28277 
28278     m_errorMonitor->ExpectSuccess();
28279     m_commandBuffer->begin();
28280     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
28281 
28282     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &ds.set_, 0,
28283                             nullptr);
28284     m_errorMonitor->VerifyNotFound();
28285 
28286     vkDestroySampler(m_device->device(), sampler, NULL);
28287 
28288     m_commandBuffer->EndRenderPass();
28289     m_commandBuffer->end();
28290 }
28291 
TEST_F(VkLayerTest,DuplicateDescriptorBinding)28292 TEST_F(VkLayerTest, DuplicateDescriptorBinding) {
28293     TEST_DESCRIPTION("Create a descriptor set layout with a duplicate binding number.");
28294 
28295     ASSERT_NO_FATAL_FAILURE(Init());
28296     // Create layout where two binding #s are "1"
28297     static const uint32_t NUM_BINDINGS = 3;
28298     VkDescriptorSetLayoutBinding dsl_binding[NUM_BINDINGS] = {};
28299     dsl_binding[0].binding = 1;
28300     dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
28301     dsl_binding[0].descriptorCount = 1;
28302     dsl_binding[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
28303     dsl_binding[0].pImmutableSamplers = NULL;
28304     dsl_binding[1].binding = 0;
28305     dsl_binding[1].descriptorCount = 1;
28306     dsl_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
28307     dsl_binding[1].descriptorCount = 1;
28308     dsl_binding[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
28309     dsl_binding[1].pImmutableSamplers = NULL;
28310     dsl_binding[2].binding = 1;  // Duplicate binding should cause error
28311     dsl_binding[2].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
28312     dsl_binding[2].descriptorCount = 1;
28313     dsl_binding[2].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
28314     dsl_binding[2].pImmutableSamplers = NULL;
28315 
28316     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
28317     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
28318     ds_layout_ci.pNext = NULL;
28319     ds_layout_ci.bindingCount = NUM_BINDINGS;
28320     ds_layout_ci.pBindings = dsl_binding;
28321     VkDescriptorSetLayout ds_layout;
28322     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkDescriptorSetLayoutCreateInfo-binding-00279");
28323     vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
28324     m_errorMonitor->VerifyFound();
28325 }
28326 
TEST_F(VkLayerTest,InvalidPushDescriptorSetLayout)28327 TEST_F(VkLayerTest, InvalidPushDescriptorSetLayout) {
28328     TEST_DESCRIPTION("Create a push descriptor set layout with invalid bindings.");
28329 
28330     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
28331         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
28332     } else {
28333         printf("%s Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n", kSkipPrefix);
28334         return;
28335     }
28336 
28337     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
28338     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
28339         m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
28340     } else {
28341         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
28342         return;
28343     }
28344 
28345     ASSERT_NO_FATAL_FAILURE(InitState());
28346 
28347     // Get the push descriptor limits
28348     auto push_descriptor_prop = GetPushDescriptorProperties(instance(), gpu());
28349     if (push_descriptor_prop.maxPushDescriptors < 1) {
28350         // Some implementations report an invalid maxPushDescriptors of 0
28351         printf("%s maxPushDescriptors is zero, skipping tests\n", kSkipPrefix);
28352         return;
28353     }
28354 
28355     VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
28356 
28357     auto ds_layout_ci = lvl_init_struct<VkDescriptorSetLayoutCreateInfo>();
28358     ds_layout_ci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
28359     ds_layout_ci.bindingCount = 1;
28360     ds_layout_ci.pBindings = &binding;
28361 
28362     // Note that as binding is referenced in ds_layout_ci, it is effectively in the closure by reference as well.
28363     auto test_create_ds_layout = [&ds_layout_ci, this](std::string error) {
28364         VkDescriptorSetLayout ds_layout = VK_NULL_HANDLE;
28365         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error);
28366         vkCreateDescriptorSetLayout(m_device->handle(), &ds_layout_ci, nullptr, &ds_layout);
28367         m_errorMonitor->VerifyFound();
28368         vkDestroyDescriptorSetLayout(m_device->handle(), ds_layout, nullptr);
28369     };
28370 
28371     // Starting with the initial VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC type set above..
28372     test_create_ds_layout("VUID-VkDescriptorSetLayoutCreateInfo-flags-00280");
28373 
28374     binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
28375     test_create_ds_layout(
28376         "VUID-VkDescriptorSetLayoutCreateInfo-flags-00280");  // This is the same VUID as above, just a second error condition.
28377 
28378     if (!(push_descriptor_prop.maxPushDescriptors == std::numeric_limits<uint32_t>::max())) {
28379         binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
28380         binding.descriptorCount = push_descriptor_prop.maxPushDescriptors + 1;
28381         test_create_ds_layout("VUID-VkDescriptorSetLayoutCreateInfo-flags-00281");
28382     } else {
28383         printf("%s maxPushDescriptors is set to maximum unit32_t value, skipping 'out of range test'.\n", kSkipPrefix);
28384     }
28385 }
28386 
TEST_F(VkLayerTest,PushDescriptorSetLayoutWithoutExtension)28387 TEST_F(VkLayerTest, PushDescriptorSetLayoutWithoutExtension) {
28388     TEST_DESCRIPTION("Create a push descriptor set layout without loading the needed extension.");
28389     ASSERT_NO_FATAL_FAILURE(Init());
28390 
28391     VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
28392 
28393     auto ds_layout_ci = lvl_init_struct<VkDescriptorSetLayoutCreateInfo>();
28394     ds_layout_ci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
28395     ds_layout_ci.bindingCount = 1;
28396     ds_layout_ci.pBindings = &binding;
28397 
28398     std::string error = "Attempted to use VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR in ";
28399     error = error + "VkDescriptorSetLayoutCreateInfo::flags but its required extension ";
28400     error = error + VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME;
28401     error = error + " has not been enabled.";
28402 
28403     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error.c_str());
28404     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkDescriptorSetLayoutCreateInfo-flags-00281");
28405     VkDescriptorSetLayout ds_layout = VK_NULL_HANDLE;
28406     vkCreateDescriptorSetLayout(m_device->handle(), &ds_layout_ci, nullptr, &ds_layout);
28407     m_errorMonitor->VerifyFound();
28408     vkDestroyDescriptorSetLayout(m_device->handle(), ds_layout, nullptr);
28409 }
28410 
TEST_F(VkLayerTest,DescriptorIndexingSetLayoutWithoutExtension)28411 TEST_F(VkLayerTest, DescriptorIndexingSetLayoutWithoutExtension) {
28412     TEST_DESCRIPTION("Create an update_after_bind set layout without loading the needed extension.");
28413     ASSERT_NO_FATAL_FAILURE(Init());
28414 
28415     auto ds_layout_ci = lvl_init_struct<VkDescriptorSetLayoutCreateInfo>();
28416     ds_layout_ci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT;
28417 
28418     std::string error = "Attemped to use VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT in ";
28419     error = error + "VkDescriptorSetLayoutCreateInfo::flags but its required extension ";
28420     error = error + VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME;
28421     error = error + " has not been enabled.";
28422 
28423     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error.c_str());
28424     VkDescriptorSetLayout ds_layout = VK_NULL_HANDLE;
28425     vkCreateDescriptorSetLayout(m_device->handle(), &ds_layout_ci, nullptr, &ds_layout);
28426     m_errorMonitor->VerifyFound();
28427     vkDestroyDescriptorSetLayout(m_device->handle(), ds_layout, nullptr);
28428 }
28429 
TEST_F(VkLayerTest,DescriptorIndexingSetLayout)28430 TEST_F(VkLayerTest, DescriptorIndexingSetLayout) {
28431     TEST_DESCRIPTION("Exercise various create/allocate-time errors related to VK_EXT_descriptor_indexing.");
28432 
28433     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
28434         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
28435     } else {
28436         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
28437                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
28438         return;
28439     }
28440     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
28441     std::array<const char *, 2> required_device_extensions = {
28442         {VK_KHR_MAINTENANCE3_EXTENSION_NAME, VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME}};
28443     for (auto device_extension : required_device_extensions) {
28444         if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
28445             m_device_extension_names.push_back(device_extension);
28446         } else {
28447             printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
28448             return;
28449         }
28450     }
28451 
28452     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
28453         (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
28454     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
28455 
28456     // Create a device that enables all supported indexing features except descriptorBindingUniformBufferUpdateAfterBind
28457     auto indexing_features = lvl_init_struct<VkPhysicalDeviceDescriptorIndexingFeaturesEXT>();
28458     auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&indexing_features);
28459     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
28460 
28461     indexing_features.descriptorBindingUniformBufferUpdateAfterBind = VK_FALSE;
28462 
28463     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
28464 
28465     std::array<VkDescriptorBindingFlagsEXT, 2> flags = {VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT,
28466                                                         VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT};
28467     auto flags_create_info = lvl_init_struct<VkDescriptorSetLayoutBindingFlagsCreateInfoEXT>();
28468     flags_create_info.bindingCount = (uint32_t)flags.size();
28469     flags_create_info.pBindingFlags = flags.data();
28470 
28471     VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
28472     auto ds_layout_ci = lvl_init_struct<VkDescriptorSetLayoutCreateInfo>(&flags_create_info);
28473     ds_layout_ci.bindingCount = 1;
28474     ds_layout_ci.pBindings = &binding;
28475     VkDescriptorSetLayout ds_layout = VK_NULL_HANDLE;
28476 
28477     // VU for VkDescriptorSetLayoutBindingFlagsCreateInfoEXT::bindingCount
28478     flags_create_info.bindingCount = 2;
28479     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
28480                                          "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfoEXT-bindingCount-03002");
28481     VkResult err = vkCreateDescriptorSetLayout(m_device->handle(), &ds_layout_ci, nullptr, &ds_layout);
28482     m_errorMonitor->VerifyFound();
28483     vkDestroyDescriptorSetLayout(m_device->handle(), ds_layout, nullptr);
28484 
28485     flags_create_info.bindingCount = 1;
28486 
28487     // set is missing UPDATE_AFTER_BIND_POOL flag.
28488     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkDescriptorSetLayoutCreateInfo-flags-03000");
28489     // binding uses a feature we disabled
28490     m_errorMonitor->SetDesiredFailureMsg(
28491         VK_DEBUG_REPORT_ERROR_BIT_EXT,
28492         "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfoEXT-descriptorBindingUniformBufferUpdateAfterBind-03005");
28493     err = vkCreateDescriptorSetLayout(m_device->handle(), &ds_layout_ci, nullptr, &ds_layout);
28494     m_errorMonitor->VerifyFound();
28495     vkDestroyDescriptorSetLayout(m_device->handle(), ds_layout, nullptr);
28496 
28497     ds_layout_ci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT;
28498     ds_layout_ci.bindingCount = 0;
28499     flags_create_info.bindingCount = 0;
28500     err = vkCreateDescriptorSetLayout(m_device->handle(), &ds_layout_ci, nullptr, &ds_layout);
28501     ASSERT_VK_SUCCESS(err);
28502 
28503     VkDescriptorPoolSize pool_size = {binding.descriptorType, binding.descriptorCount};
28504     auto dspci = lvl_init_struct<VkDescriptorPoolCreateInfo>();
28505     dspci.poolSizeCount = 1;
28506     dspci.pPoolSizes = &pool_size;
28507     dspci.maxSets = 1;
28508     VkDescriptorPool pool;
28509     err = vkCreateDescriptorPool(m_device->handle(), &dspci, nullptr, &pool);
28510     ASSERT_VK_SUCCESS(err);
28511 
28512     auto ds_alloc_info = lvl_init_struct<VkDescriptorSetAllocateInfo>();
28513     ds_alloc_info.descriptorPool = pool;
28514     ds_alloc_info.descriptorSetCount = 1;
28515     ds_alloc_info.pSetLayouts = &ds_layout;
28516 
28517     VkDescriptorSet ds = VK_NULL_HANDLE;
28518     // mismatch between descriptor set and pool
28519     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkDescriptorSetAllocateInfo-pSetLayouts-03044");
28520     vkAllocateDescriptorSets(m_device->handle(), &ds_alloc_info, &ds);
28521     m_errorMonitor->VerifyFound();
28522 
28523     vkDestroyDescriptorSetLayout(m_device->handle(), ds_layout, nullptr);
28524     vkDestroyDescriptorPool(m_device->handle(), pool, nullptr);
28525 
28526     if (indexing_features.descriptorBindingVariableDescriptorCount) {
28527         ds_layout_ci.flags = 0;
28528         ds_layout_ci.bindingCount = 1;
28529         flags_create_info.bindingCount = 1;
28530         flags[0] = VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT;
28531         err = vkCreateDescriptorSetLayout(m_device->handle(), &ds_layout_ci, nullptr, &ds_layout);
28532         ASSERT_VK_SUCCESS(err);
28533 
28534         pool_size = {binding.descriptorType, binding.descriptorCount};
28535         dspci = lvl_init_struct<VkDescriptorPoolCreateInfo>();
28536         dspci.poolSizeCount = 1;
28537         dspci.pPoolSizes = &pool_size;
28538         dspci.maxSets = 1;
28539         err = vkCreateDescriptorPool(m_device->handle(), &dspci, nullptr, &pool);
28540         ASSERT_VK_SUCCESS(err);
28541 
28542         auto count_alloc_info = lvl_init_struct<VkDescriptorSetVariableDescriptorCountAllocateInfoEXT>();
28543         count_alloc_info.descriptorSetCount = 1;
28544         // Set variable count larger than what was in the descriptor binding
28545         uint32_t variable_count = 2;
28546         count_alloc_info.pDescriptorCounts = &variable_count;
28547 
28548         ds_alloc_info = lvl_init_struct<VkDescriptorSetAllocateInfo>(&count_alloc_info);
28549         ds_alloc_info.descriptorPool = pool;
28550         ds_alloc_info.descriptorSetCount = 1;
28551         ds_alloc_info.pSetLayouts = &ds_layout;
28552 
28553         ds = VK_NULL_HANDLE;
28554         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
28555                                              "VUID-VkDescriptorSetVariableDescriptorCountAllocateInfoEXT-pSetLayouts-03046");
28556         vkAllocateDescriptorSets(m_device->handle(), &ds_alloc_info, &ds);
28557         m_errorMonitor->VerifyFound();
28558 
28559         vkDestroyDescriptorSetLayout(m_device->handle(), ds_layout, nullptr);
28560         vkDestroyDescriptorPool(m_device->handle(), pool, nullptr);
28561     }
28562 }
28563 
TEST_F(VkLayerTest,DescriptorIndexingUpdateAfterBind)28564 TEST_F(VkLayerTest, DescriptorIndexingUpdateAfterBind) {
28565     TEST_DESCRIPTION("Exercise errors for updating a descriptor set after it is bound.");
28566 
28567     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
28568         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
28569     } else {
28570         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
28571                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
28572         return;
28573     }
28574 
28575     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
28576     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME) &&
28577         DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE3_EXTENSION_NAME)) {
28578         m_device_extension_names.push_back(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
28579         m_device_extension_names.push_back(VK_KHR_MAINTENANCE3_EXTENSION_NAME);
28580     } else {
28581         printf("%s Descriptor Indexing or Maintenance3 Extension not supported, skipping tests\n", kSkipPrefix);
28582         return;
28583     }
28584 
28585     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
28586         (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
28587     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
28588 
28589     // Create a device that enables all supported indexing features except descriptorBindingUniformBufferUpdateAfterBind
28590     auto indexing_features = lvl_init_struct<VkPhysicalDeviceDescriptorIndexingFeaturesEXT>();
28591     auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&indexing_features);
28592     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
28593 
28594     indexing_features.descriptorBindingUniformBufferUpdateAfterBind = VK_FALSE;
28595 
28596     if (VK_FALSE == indexing_features.descriptorBindingStorageBufferUpdateAfterBind) {
28597         printf("%s Test requires (unsupported) descriptorBindingStorageBufferUpdateAfterBind, skipping\n", kSkipPrefix);
28598         return;
28599     }
28600     if (VK_FALSE == features2.features.fragmentStoresAndAtomics) {
28601         printf("%s Test requires (unsupported) fragmentStoresAndAtomics, skipping\n", kSkipPrefix);
28602         return;
28603     }
28604 
28605     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
28606     ASSERT_NO_FATAL_FAILURE(InitViewport());
28607     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
28608 
28609     VkDescriptorBindingFlagsEXT flags[2] = {0, VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT};
28610     auto flags_create_info = lvl_init_struct<VkDescriptorSetLayoutBindingFlagsCreateInfoEXT>();
28611     flags_create_info.bindingCount = 2;
28612     flags_create_info.pBindingFlags = &flags[0];
28613 
28614     // Descriptor set has two bindings - only the second is update_after_bind
28615     VkDescriptorSetLayoutBinding binding[2] = {
28616         {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
28617         {1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
28618     };
28619     auto ds_layout_ci = lvl_init_struct<VkDescriptorSetLayoutCreateInfo>(&flags_create_info);
28620     ds_layout_ci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT;
28621     ds_layout_ci.bindingCount = 2;
28622     ds_layout_ci.pBindings = &binding[0];
28623     VkDescriptorSetLayout ds_layout = VK_NULL_HANDLE;
28624 
28625     VkResult err = vkCreateDescriptorSetLayout(m_device->handle(), &ds_layout_ci, nullptr, &ds_layout);
28626 
28627     VkDescriptorPoolSize pool_sizes[2] = {
28628         {binding[0].descriptorType, binding[0].descriptorCount},
28629         {binding[1].descriptorType, binding[1].descriptorCount},
28630     };
28631     auto dspci = lvl_init_struct<VkDescriptorPoolCreateInfo>();
28632     dspci.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT;
28633     dspci.poolSizeCount = 2;
28634     dspci.pPoolSizes = &pool_sizes[0];
28635     dspci.maxSets = 1;
28636     VkDescriptorPool pool;
28637     err = vkCreateDescriptorPool(m_device->handle(), &dspci, nullptr, &pool);
28638     ASSERT_VK_SUCCESS(err);
28639 
28640     auto ds_alloc_info = lvl_init_struct<VkDescriptorSetAllocateInfo>();
28641     ds_alloc_info.descriptorPool = pool;
28642     ds_alloc_info.descriptorSetCount = 1;
28643     ds_alloc_info.pSetLayouts = &ds_layout;
28644 
28645     VkDescriptorSet ds = VK_NULL_HANDLE;
28646     vkAllocateDescriptorSets(m_device->handle(), &ds_alloc_info, &ds);
28647     ASSERT_VK_SUCCESS(err);
28648 
28649     VkBufferCreateInfo buffCI = {};
28650     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
28651     buffCI.size = 1024;
28652     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
28653 
28654     VkBuffer dyub;
28655     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
28656     ASSERT_VK_SUCCESS(err);
28657 
28658     VkDeviceMemory mem;
28659     VkMemoryRequirements mem_reqs;
28660     vkGetBufferMemoryRequirements(m_device->device(), dyub, &mem_reqs);
28661 
28662     VkMemoryAllocateInfo mem_alloc_info = {};
28663     mem_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
28664     mem_alloc_info.allocationSize = mem_reqs.size;
28665     m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
28666     err = vkAllocateMemory(m_device->device(), &mem_alloc_info, NULL, &mem);
28667     ASSERT_VK_SUCCESS(err);
28668 
28669     err = vkBindBufferMemory(m_device->device(), dyub, mem, 0);
28670     ASSERT_VK_SUCCESS(err);
28671 
28672     VkDescriptorBufferInfo buffInfo[2] = {};
28673     buffInfo[0].buffer = dyub;
28674     buffInfo[0].offset = 0;
28675     buffInfo[0].range = 1024;
28676 
28677     VkWriteDescriptorSet descriptor_write[2] = {};
28678     descriptor_write[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
28679     descriptor_write[0].dstSet = ds;
28680     descriptor_write[0].dstBinding = 0;
28681     descriptor_write[0].descriptorCount = 1;
28682     descriptor_write[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
28683     descriptor_write[0].pBufferInfo = buffInfo;
28684     descriptor_write[1] = descriptor_write[0];
28685     descriptor_write[1].dstBinding = 1;
28686     descriptor_write[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
28687 
28688     VkPipelineLayout pipeline_layout;
28689     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
28690     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
28691     pipeline_layout_ci.setLayoutCount = 1;
28692     pipeline_layout_ci.pSetLayouts = &ds_layout;
28693 
28694     vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
28695 
28696     // Create a dummy pipeline, since VL inspects which bindings are actually used at draw time
28697     char const *vsSource =
28698         "#version 450\n"
28699         "void main(){\n"
28700         "   gl_Position = vec4(0);\n"
28701         "}\n";
28702     char const *fsSource =
28703         "#version 450\n"
28704         "\n"
28705         "layout(location=0) out vec4 color;\n"
28706         "layout(set=0, binding=0) uniform foo0 { float x0; } bar0;\n"
28707         "layout(set=0, binding=1) buffer  foo1 { float x1; } bar1;\n"
28708         "void main(){\n"
28709         "   color = vec4(bar0.x0 + bar1.x1);\n"
28710         "}\n";
28711 
28712     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
28713     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
28714 
28715     VkPipelineObj pipe(m_device);
28716     pipe.SetViewport(m_viewports);
28717     pipe.SetScissor(m_scissors);
28718     pipe.AddDefaultColorAttachment();
28719     pipe.AddShader(&vs);
28720     pipe.AddShader(&fs);
28721     pipe.CreateVKPipeline(pipeline_layout, m_renderPass);
28722 
28723     // Make both bindings valid before binding to the command buffer
28724     vkUpdateDescriptorSets(m_device->device(), 2, &descriptor_write[0], 0, NULL);
28725     m_errorMonitor->VerifyNotFound();
28726 
28727     // Two subtests. First only updates the update_after_bind binding and expects
28728     // no error. Second updates the other binding and expects an error when the
28729     // command buffer is ended.
28730     for (uint32_t i = 0; i < 2; ++i) {
28731         m_commandBuffer->begin();
28732 
28733         vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &ds, 0, NULL);
28734 
28735         m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
28736         vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
28737         vkCmdDraw(m_commandBuffer->handle(), 0, 0, 0, 0);
28738         vkCmdEndRenderPass(m_commandBuffer->handle());
28739 
28740         m_errorMonitor->VerifyNotFound();
28741         // Valid to update binding 1 after being bound
28742         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write[1], 0, NULL);
28743         m_errorMonitor->VerifyNotFound();
28744 
28745         if (i == 0) {
28746             // expect no errors
28747             m_commandBuffer->end();
28748             m_errorMonitor->VerifyNotFound();
28749         } else {
28750             // Invalid to update binding 0 after being bound. But the error is actually
28751             // generated during vkEndCommandBuffer
28752             vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write[0], 0, NULL);
28753             m_errorMonitor->VerifyNotFound();
28754 
28755             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is invalid because bound DescriptorSet");
28756 
28757             vkEndCommandBuffer(m_commandBuffer->handle());
28758             m_errorMonitor->VerifyFound();
28759         }
28760     }
28761 
28762     vkDestroyDescriptorSetLayout(m_device->handle(), ds_layout, nullptr);
28763     vkDestroyDescriptorPool(m_device->handle(), pool, nullptr);
28764     vkDestroyBuffer(m_device->handle(), dyub, NULL);
28765     vkFreeMemory(m_device->handle(), mem, NULL);
28766     vkDestroyPipelineLayout(m_device->handle(), pipeline_layout, NULL);
28767 }
28768 
TEST_F(VkLayerTest,AllocatePushDescriptorSet)28769 TEST_F(VkLayerTest, AllocatePushDescriptorSet) {
28770     TEST_DESCRIPTION("Attempt to allocate a push descriptor set.");
28771     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
28772         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
28773     } else {
28774         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
28775                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
28776         return;
28777     }
28778 
28779     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
28780     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
28781         m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
28782     } else {
28783         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
28784         return;
28785     }
28786     ASSERT_NO_FATAL_FAILURE(InitState());
28787 
28788     auto push_descriptor_prop = GetPushDescriptorProperties(instance(), gpu());
28789     if (push_descriptor_prop.maxPushDescriptors < 1) {
28790         // Some implementations report an invalid maxPushDescriptors of 0
28791         printf("%s maxPushDescriptors is zero, skipping tests\n", kSkipPrefix);
28792         return;
28793     }
28794 
28795     VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
28796     auto ds_layout_ci = lvl_init_struct<VkDescriptorSetLayoutCreateInfo>();
28797     ds_layout_ci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
28798     ds_layout_ci.bindingCount = 1;
28799     ds_layout_ci.pBindings = &binding;
28800     VkDescriptorSetLayout ds_layout = VK_NULL_HANDLE;
28801     VkResult err = vkCreateDescriptorSetLayout(m_device->handle(), &ds_layout_ci, nullptr, &ds_layout);
28802     ASSERT_VK_SUCCESS(err);
28803 
28804     VkDescriptorPoolSize pool_size = {binding.descriptorType, binding.descriptorCount};
28805     auto dspci = lvl_init_struct<VkDescriptorPoolCreateInfo>();
28806     dspci.poolSizeCount = 1;
28807     dspci.pPoolSizes = &pool_size;
28808     dspci.maxSets = 1;
28809     VkDescriptorPool pool;
28810     err = vkCreateDescriptorPool(m_device->handle(), &dspci, nullptr, &pool);
28811     ASSERT_VK_SUCCESS(err);
28812 
28813     auto ds_alloc_info = lvl_init_struct<VkDescriptorSetAllocateInfo>();
28814     ds_alloc_info.descriptorPool = pool;
28815     ds_alloc_info.descriptorSetCount = 1;
28816     ds_alloc_info.pSetLayouts = &ds_layout;
28817 
28818     VkDescriptorSet ds = VK_NULL_HANDLE;
28819     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkDescriptorSetAllocateInfo-pSetLayouts-00308");
28820     vkAllocateDescriptorSets(m_device->handle(), &ds_alloc_info, &ds);
28821     m_errorMonitor->VerifyFound();
28822 
28823     vkDestroyDescriptorPool(m_device->handle(), pool, nullptr);
28824     vkDestroyDescriptorSetLayout(m_device->handle(), ds_layout, nullptr);
28825 }
28826 
TEST_F(VkLayerTest,PushDescriptorSetCmdPushBadArgs)28827 TEST_F(VkLayerTest, PushDescriptorSetCmdPushBadArgs) {
28828     TEST_DESCRIPTION("Attempt to push a push descriptor set with incorrect arguments.");
28829     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
28830         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
28831     } else {
28832         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
28833                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
28834         return;
28835     }
28836 
28837     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
28838     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
28839         m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
28840     } else {
28841         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
28842         return;
28843     }
28844     ASSERT_NO_FATAL_FAILURE(InitState());
28845 
28846     auto push_descriptor_prop = GetPushDescriptorProperties(instance(), gpu());
28847     if (push_descriptor_prop.maxPushDescriptors < 1) {
28848         // Some implementations report an invalid maxPushDescriptors of 0
28849         printf("%s maxPushDescriptors is zero, skipping tests\n", kSkipPrefix);
28850         return;
28851     }
28852 
28853     // Create ordinary and push descriptor set layout
28854     VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
28855     const VkDescriptorSetLayoutObj ds_layout(m_device, {binding});
28856     ASSERT_TRUE(ds_layout.initialized());
28857     const VkDescriptorSetLayoutObj push_ds_layout(m_device, {binding}, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
28858     ASSERT_TRUE(push_ds_layout.initialized());
28859 
28860     // Now use the descriptor set layouts to create a pipeline layout
28861     const VkPipelineLayoutObj pipeline_layout(m_device, {&push_ds_layout, &ds_layout});
28862     ASSERT_TRUE(pipeline_layout.initialized());
28863 
28864     // Create a descriptor to push
28865     const uint32_t buffer_data[4] = {4, 5, 6, 7};
28866     VkConstantBufferObj buffer_obj(m_device, sizeof(buffer_data), &buffer_data);
28867     ASSERT_TRUE(buffer_obj.initialized());
28868 
28869     // Create a "write" struct, noting that the buffer_info cannot be a temporary arg (the return from write_descriptor_set
28870     // references its data), and the DescriptorSet() can be temporary, because the value is ignored
28871     VkDescriptorBufferInfo buffer_info = {buffer_obj.handle(), 0, VK_WHOLE_SIZE};
28872 
28873     VkWriteDescriptorSet descriptor_write = vk_testing::Device::write_descriptor_set(
28874         vk_testing::DescriptorSet(), 0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &buffer_info);
28875 
28876     // Find address of extension call and make the call
28877     PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR =
28878         (PFN_vkCmdPushDescriptorSetKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR");
28879     ASSERT_TRUE(vkCmdPushDescriptorSetKHR != nullptr);
28880 
28881     // Section 1: Queue family matching/capabilities.
28882     // Create command pool on a non-graphics queue
28883     const uint32_t no_gfx_qfi = m_device->QueueFamilyMatching(VK_QUEUE_COMPUTE_BIT, VK_QUEUE_GRAPHICS_BIT);
28884     const uint32_t transfer_only_qfi =
28885         m_device->QueueFamilyMatching(VK_QUEUE_TRANSFER_BIT, (VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT));
28886     if ((UINT32_MAX == transfer_only_qfi) && (UINT32_MAX == no_gfx_qfi)) {
28887         printf("%s No compute or transfer only queue family, skipping bindpoint and queue tests.", kSkipPrefix);
28888     } else {
28889         const uint32_t err_qfi = (UINT32_MAX == no_gfx_qfi) ? transfer_only_qfi : no_gfx_qfi;
28890 
28891         VkCommandPoolObj command_pool(m_device, err_qfi);
28892         ASSERT_TRUE(command_pool.initialized());
28893         VkCommandBufferObj command_buffer(m_device, &command_pool);
28894         ASSERT_TRUE(command_buffer.initialized());
28895         command_buffer.begin();
28896 
28897         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
28898                                              "VUID-vkCmdPushDescriptorSetKHR-pipelineBindPoint-00363");
28899         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkWriteDescriptorSet-descriptorType-00330");
28900         if (err_qfi == transfer_only_qfi) {
28901             // This as this queue neither supports the gfx or compute bindpoints, we'll get two errors
28902             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
28903                                                  "VUID-vkCmdPushDescriptorSetKHR-commandBuffer-cmdpool");
28904         }
28905         vkCmdPushDescriptorSetKHR(command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
28906                                   &descriptor_write);
28907         m_errorMonitor->VerifyFound();
28908         command_buffer.end();
28909 
28910         // If we succeed in testing only one condition above, we need to test the other below.
28911         if ((UINT32_MAX != transfer_only_qfi) && (err_qfi != transfer_only_qfi)) {
28912             // Need to test the neither compute/gfx supported case separately.
28913             VkCommandPoolObj tran_command_pool(m_device, transfer_only_qfi);
28914             ASSERT_TRUE(tran_command_pool.initialized());
28915             VkCommandBufferObj tran_command_buffer(m_device, &tran_command_pool);
28916             ASSERT_TRUE(tran_command_buffer.initialized());
28917             tran_command_buffer.begin();
28918 
28919             // We can't avoid getting *both* errors in this case
28920             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
28921                                                  "VUID-vkCmdPushDescriptorSetKHR-pipelineBindPoint-00363");
28922             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkWriteDescriptorSet-descriptorType-00330");
28923             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
28924                                                  "VUID-vkCmdPushDescriptorSetKHR-commandBuffer-cmdpool");
28925             vkCmdPushDescriptorSetKHR(tran_command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
28926                                       &descriptor_write);
28927             m_errorMonitor->VerifyFound();
28928             tran_command_buffer.end();
28929         }
28930     }
28931 
28932     // Push to the non-push binding
28933     m_commandBuffer->begin();
28934     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPushDescriptorSetKHR-set-00365");
28935     vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 1, 1,
28936                               &descriptor_write);
28937     m_errorMonitor->VerifyFound();
28938 
28939     // Specify set out of bounds
28940     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPushDescriptorSetKHR-set-00364");
28941     vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 2, 1,
28942                               &descriptor_write);
28943     m_errorMonitor->VerifyFound();
28944     m_commandBuffer->end();
28945 
28946     // This is a test for VUID-vkCmdPushDescriptorSetKHR-commandBuffer-recording
28947     // TODO: Add VALIDATION_ERROR_ code support to core_validation::ValidateCmd
28948     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
28949                                          "You must call vkBeginCommandBuffer() before this call to vkCmdPushDescriptorSetKHR()");
28950     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkWriteDescriptorSet-descriptorType-00330");
28951     vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
28952                               &descriptor_write);
28953     m_errorMonitor->VerifyFound();
28954 }
28955 
TEST_F(VkLayerTest,SetDynScissorParamTests)28956 TEST_F(VkLayerTest, SetDynScissorParamTests) {
28957     TEST_DESCRIPTION("Test parameters of vkCmdSetScissor without multiViewport feature");
28958 
28959     VkPhysicalDeviceFeatures features{};
28960     ASSERT_NO_FATAL_FAILURE(Init(&features));
28961 
28962     const VkRect2D scissor = {{0, 0}, {16, 16}};
28963     const VkRect2D scissors[] = {scissor, scissor};
28964 
28965     m_commandBuffer->begin();
28966 
28967     // array tests
28968     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-firstScissor-00593");
28969     vkCmdSetScissor(m_commandBuffer->handle(), 1, 1, scissors);
28970     m_errorMonitor->VerifyFound();
28971 
28972     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-scissorCount-arraylength");
28973     vkCmdSetScissor(m_commandBuffer->handle(), 0, 0, nullptr);
28974     m_errorMonitor->VerifyFound();
28975 
28976     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-scissorCount-00594");
28977     vkCmdSetScissor(m_commandBuffer->handle(), 0, 2, scissors);
28978     m_errorMonitor->VerifyFound();
28979 
28980     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-firstScissor-00593");
28981     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-scissorCount-arraylength");
28982     vkCmdSetScissor(m_commandBuffer->handle(), 1, 0, scissors);
28983     m_errorMonitor->VerifyFound();
28984 
28985     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-firstScissor-00593");
28986     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-scissorCount-00594");
28987     vkCmdSetScissor(m_commandBuffer->handle(), 1, 2, scissors);
28988     m_errorMonitor->VerifyFound();
28989 
28990     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-pScissors-parameter");
28991     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, nullptr);
28992     m_errorMonitor->VerifyFound();
28993 
28994     struct TestCase {
28995         VkRect2D scissor;
28996         std::string vuid;
28997     };
28998 
28999     std::vector<TestCase> test_cases = {{{{-1, 0}, {16, 16}}, "VUID-vkCmdSetScissor-x-00595"},
29000                                         {{{0, -1}, {16, 16}}, "VUID-vkCmdSetScissor-x-00595"},
29001                                         {{{1, 0}, {INT32_MAX, 16}}, "VUID-vkCmdSetScissor-offset-00596"},
29002                                         {{{INT32_MAX, 0}, {1, 16}}, "VUID-vkCmdSetScissor-offset-00596"},
29003                                         {{{0, 0}, {uint32_t{INT32_MAX} + 1, 16}}, "VUID-vkCmdSetScissor-offset-00596"},
29004                                         {{{0, 1}, {16, INT32_MAX}}, "VUID-vkCmdSetScissor-offset-00597"},
29005                                         {{{0, INT32_MAX}, {16, 1}}, "VUID-vkCmdSetScissor-offset-00597"},
29006                                         {{{0, 0}, {16, uint32_t{INT32_MAX} + 1}}, "VUID-vkCmdSetScissor-offset-00597"}};
29007 
29008     for (const auto &test_case : test_cases) {
29009         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuid);
29010         vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &test_case.scissor);
29011         m_errorMonitor->VerifyFound();
29012     }
29013 
29014     m_commandBuffer->end();
29015 }
29016 
TEST_F(VkLayerTest,SetDynScissorParamMultiviewportTests)29017 TEST_F(VkLayerTest, SetDynScissorParamMultiviewportTests) {
29018     TEST_DESCRIPTION("Test parameters of vkCmdSetScissor with multiViewport feature enabled");
29019 
29020     ASSERT_NO_FATAL_FAILURE(Init());
29021 
29022     if (!m_device->phy().features().multiViewport) {
29023         printf("%s VkPhysicalDeviceFeatures::multiViewport is not supported -- skipping test.\n", kSkipPrefix);
29024         return;
29025     }
29026 
29027     const auto max_scissors = m_device->props.limits.maxViewports;
29028     const uint32_t too_many_scissors = 65536 + 1;  // let's say this is too much to allocate pScissors for
29029 
29030     m_commandBuffer->begin();
29031 
29032     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-scissorCount-arraylength");
29033     vkCmdSetScissor(m_commandBuffer->handle(), 0, 0, nullptr);
29034     m_errorMonitor->VerifyFound();
29035 
29036     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-pScissors-parameter");
29037     vkCmdSetScissor(m_commandBuffer->handle(), 0, max_scissors, nullptr);
29038     m_errorMonitor->VerifyFound();
29039 
29040     if (max_scissors >= too_many_scissors) {
29041         printf(
29042             "%s VkPhysicalDeviceLimits::maxViewports is too large to practically test against -- skipping "
29043             "part of "
29044             "test.\n",
29045             kSkipPrefix);
29046         return;
29047     }
29048 
29049     const VkRect2D scissor = {{0, 0}, {16, 16}};
29050     const std::vector<VkRect2D> scissors(max_scissors + 1, scissor);
29051 
29052     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-firstScissor-00592");
29053     vkCmdSetScissor(m_commandBuffer->handle(), 0, max_scissors + 1, scissors.data());
29054     m_errorMonitor->VerifyFound();
29055 
29056     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-firstScissor-00592");
29057     vkCmdSetScissor(m_commandBuffer->handle(), max_scissors, 1, scissors.data());
29058     m_errorMonitor->VerifyFound();
29059 
29060     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-firstScissor-00592");
29061     vkCmdSetScissor(m_commandBuffer->handle(), 1, max_scissors, scissors.data());
29062     m_errorMonitor->VerifyFound();
29063 
29064     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-scissorCount-arraylength");
29065     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-firstScissor-00592");
29066     vkCmdSetScissor(m_commandBuffer->handle(), max_scissors + 1, 0, scissors.data());
29067     m_errorMonitor->VerifyFound();
29068 }
29069 
29070 // This is a positive test. No failures are expected.
TEST_F(VkPositiveLayerTest,EmptyDescriptorUpdateTest)29071 TEST_F(VkPositiveLayerTest, EmptyDescriptorUpdateTest) {
29072     TEST_DESCRIPTION("Update last descriptor in a set that includes an empty binding");
29073     VkResult err;
29074 
29075     ASSERT_NO_FATAL_FAILURE(Init());
29076     m_errorMonitor->ExpectSuccess();
29077 
29078     // Create layout with two uniform buffer descriptors w/ empty binding between them
29079     OneOffDescriptorSet ds(m_device, {
29080                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
29081                                          {1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0 /*!*/, 0, nullptr},
29082                                          {2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
29083                                      });
29084 
29085     // Create a buffer to be used for update
29086     VkBufferCreateInfo buff_ci = {};
29087     buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
29088     buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
29089     buff_ci.size = 256;
29090     buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
29091     VkBuffer buffer;
29092     err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
29093     ASSERT_VK_SUCCESS(err);
29094     // Have to bind memory to buffer before descriptor update
29095     VkMemoryAllocateInfo mem_alloc = {};
29096     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
29097     mem_alloc.pNext = NULL;
29098     mem_alloc.allocationSize = 512;  // one allocation for both buffers
29099     mem_alloc.memoryTypeIndex = 0;
29100 
29101     VkMemoryRequirements mem_reqs;
29102     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
29103     bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
29104     if (!pass) {
29105         printf("%s Failed to allocate memory.\n", kSkipPrefix);
29106         vkDestroyBuffer(m_device->device(), buffer, NULL);
29107         return;
29108     }
29109     // Make sure allocation is sufficiently large to accommodate buffer requirements
29110     if (mem_reqs.size > mem_alloc.allocationSize) {
29111         mem_alloc.allocationSize = mem_reqs.size;
29112     }
29113 
29114     VkDeviceMemory mem;
29115     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
29116     ASSERT_VK_SUCCESS(err);
29117     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
29118     ASSERT_VK_SUCCESS(err);
29119 
29120     // Only update the descriptor at binding 2
29121     VkDescriptorBufferInfo buff_info = {};
29122     buff_info.buffer = buffer;
29123     buff_info.offset = 0;
29124     buff_info.range = VK_WHOLE_SIZE;
29125     VkWriteDescriptorSet descriptor_write = {};
29126     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
29127     descriptor_write.dstBinding = 2;
29128     descriptor_write.descriptorCount = 1;
29129     descriptor_write.pTexelBufferView = nullptr;
29130     descriptor_write.pBufferInfo = &buff_info;
29131     descriptor_write.pImageInfo = nullptr;
29132     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
29133     descriptor_write.dstSet = ds.set_;
29134 
29135     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
29136 
29137     m_errorMonitor->VerifyNotFound();
29138     // Cleanup
29139     vkFreeMemory(m_device->device(), mem, NULL);
29140     vkDestroyBuffer(m_device->device(), buffer, NULL);
29141 }
29142 
TEST_F(VkLayerTest,MultiplePushDescriptorSets)29143 TEST_F(VkLayerTest, MultiplePushDescriptorSets) {
29144     TEST_DESCRIPTION("Verify an error message for multiple push descriptor sets.");
29145 
29146     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
29147         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
29148     } else {
29149         printf("%s Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n", kSkipPrefix);
29150         return;
29151     }
29152     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
29153     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
29154         m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
29155     } else {
29156         printf("%s Push Descriptors Extension not supported, skipping tests\n", kSkipPrefix);
29157         return;
29158     }
29159     ASSERT_NO_FATAL_FAILURE(InitState());
29160 
29161     auto push_descriptor_prop = GetPushDescriptorProperties(instance(), gpu());
29162     if (push_descriptor_prop.maxPushDescriptors < 1) {
29163         // Some implementations report an invalid maxPushDescriptors of 0
29164         printf("%s maxPushDescriptors is zero, skipping tests\n", kSkipPrefix);
29165         return;
29166     }
29167 
29168     VkDescriptorSetLayoutBinding dsl_binding = {};
29169     dsl_binding.binding = 0;
29170     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
29171     dsl_binding.descriptorCount = 1;
29172     dsl_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
29173     dsl_binding.pImmutableSamplers = NULL;
29174 
29175     const unsigned int descriptor_set_layout_count = 2;
29176     std::vector<VkDescriptorSetLayoutObj> ds_layouts;
29177     for (uint32_t i = 0; i < descriptor_set_layout_count; ++i) {
29178         dsl_binding.binding = i;
29179         ds_layouts.emplace_back(m_device, std::vector<VkDescriptorSetLayoutBinding>(1, dsl_binding),
29180                                 VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
29181     }
29182     const auto &ds_vk_layouts = MakeVkHandles<VkDescriptorSetLayout>(ds_layouts);
29183 
29184     VkPipelineLayout pipeline_layout;
29185     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
29186     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
29187     pipeline_layout_ci.pNext = NULL;
29188     pipeline_layout_ci.pushConstantRangeCount = 0;
29189     pipeline_layout_ci.pPushConstantRanges = NULL;
29190     pipeline_layout_ci.setLayoutCount = ds_vk_layouts.size();
29191     pipeline_layout_ci.pSetLayouts = ds_vk_layouts.data();
29192 
29193     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00293");
29194     vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
29195     m_errorMonitor->VerifyFound();
29196 }
29197 
TEST_F(VkLayerTest,CreateDescriptorUpdateTemplate)29198 TEST_F(VkLayerTest, CreateDescriptorUpdateTemplate) {
29199     TEST_DESCRIPTION("Verify error messages for invalid vkCreateDescriptorUpdateTemplate calls.");
29200 
29201     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
29202         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
29203     } else {
29204         printf("%s Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n", kSkipPrefix);
29205         return;
29206     }
29207     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
29208     // Note: Includes workaround for some implementations which incorrectly return 0 maxPushDescriptors
29209     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME) &&
29210         DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME) &&
29211         (GetPushDescriptorProperties(instance(), gpu()).maxPushDescriptors > 0)) {
29212         m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
29213         m_device_extension_names.push_back(VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME);
29214     } else {
29215         printf("%s Push Descriptors and Descriptor Update Template Extensions not supported, skipping tests\n", kSkipPrefix);
29216         return;
29217     }
29218     ASSERT_NO_FATAL_FAILURE(InitState());
29219 
29220     VkDescriptorSetLayoutBinding dsl_binding = {};
29221     dsl_binding.binding = 0;
29222     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
29223     dsl_binding.descriptorCount = 1;
29224     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
29225     dsl_binding.pImmutableSamplers = NULL;
29226 
29227     const VkDescriptorSetLayoutObj ds_layout_ub(m_device, {dsl_binding});
29228     const VkDescriptorSetLayoutObj ds_layout_ub1(m_device, {dsl_binding});
29229     const VkDescriptorSetLayoutObj ds_layout_ub_push(m_device, {dsl_binding},
29230                                                      VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
29231     const VkPipelineLayoutObj pipeline_layout(m_device, {{&ds_layout_ub, &ds_layout_ub1, &ds_layout_ub_push}});
29232     PFN_vkCreateDescriptorUpdateTemplateKHR vkCreateDescriptorUpdateTemplateKHR =
29233         (PFN_vkCreateDescriptorUpdateTemplateKHR)vkGetDeviceProcAddr(m_device->device(), "vkCreateDescriptorUpdateTemplateKHR");
29234     ASSERT_NE(vkCreateDescriptorUpdateTemplateKHR, nullptr);
29235     PFN_vkDestroyDescriptorUpdateTemplateKHR vkDestroyDescriptorUpdateTemplateKHR =
29236         (PFN_vkDestroyDescriptorUpdateTemplateKHR)vkGetDeviceProcAddr(m_device->device(), "vkDestroyDescriptorUpdateTemplateKHR");
29237     ASSERT_NE(vkDestroyDescriptorUpdateTemplateKHR, nullptr);
29238 
29239     VkDescriptorUpdateTemplateEntry entries = {0, 0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, sizeof(VkBuffer)};
29240     VkDescriptorUpdateTemplateCreateInfo create_info = {};
29241     create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO;
29242     create_info.pNext = nullptr;
29243     create_info.flags = 0;
29244     create_info.descriptorUpdateEntryCount = 1;
29245     create_info.pDescriptorUpdateEntries = &entries;
29246 
29247     auto do_test = [&](std::string err) {
29248         VkDescriptorUpdateTemplateKHR dut = VK_NULL_HANDLE;
29249         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, err);
29250         if (VK_SUCCESS == vkCreateDescriptorUpdateTemplateKHR(m_device->handle(), &create_info, nullptr, &dut)) {
29251             vkDestroyDescriptorUpdateTemplateKHR(m_device->handle(), dut, nullptr);
29252         }
29253         m_errorMonitor->VerifyFound();
29254     };
29255 
29256     // Descriptor set type template
29257     create_info.templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET;
29258     // descriptorSetLayout is NULL
29259     do_test("VUID-VkDescriptorUpdateTemplateCreateInfo-templateType-00350");
29260 
29261     // Push descriptor type template
29262     create_info.templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR;
29263     create_info.pipelineBindPoint = VK_PIPELINE_BIND_POINT_COMPUTE;
29264     create_info.pipelineLayout = pipeline_layout.handle();
29265     create_info.set = 2;
29266 
29267     // Bad bindpoint -- force fuzz the bind point
29268     memset(&create_info.pipelineBindPoint, 0xFE, sizeof(create_info.pipelineBindPoint));
29269     do_test("VUID-VkDescriptorUpdateTemplateCreateInfo-templateType-00351");
29270     create_info.pipelineBindPoint = VK_PIPELINE_BIND_POINT_COMPUTE;
29271 
29272     // Bad pipeline layout
29273     create_info.pipelineLayout = VK_NULL_HANDLE;
29274     do_test("VUID-VkDescriptorUpdateTemplateCreateInfo-templateType-00352");
29275     create_info.pipelineLayout = pipeline_layout.handle();
29276 
29277     // Wrong set #
29278     create_info.set = 0;
29279     do_test("VUID-VkDescriptorUpdateTemplateCreateInfo-templateType-00353");
29280 
29281     // Invalid set #
29282     create_info.set = 42;
29283     do_test("VUID-VkDescriptorUpdateTemplateCreateInfo-templateType-00353");
29284 }
29285 
29286 // This is a positive test. No failures are expected.
TEST_F(VkPositiveLayerTest,PushDescriptorNullDstSetTest)29287 TEST_F(VkPositiveLayerTest, PushDescriptorNullDstSetTest) {
29288     TEST_DESCRIPTION("Use null dstSet in CmdPushDescriptorSetKHR");
29289 
29290     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
29291         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
29292     } else {
29293         printf("%s Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n", kSkipPrefix);
29294         return;
29295     }
29296     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
29297     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
29298         m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
29299     } else {
29300         printf("%s Push Descriptors Extension not supported, skipping tests\n", kSkipPrefix);
29301         return;
29302     }
29303     ASSERT_NO_FATAL_FAILURE(InitState());
29304     m_errorMonitor->ExpectSuccess();
29305 
29306     auto push_descriptor_prop = GetPushDescriptorProperties(instance(), gpu());
29307     if (push_descriptor_prop.maxPushDescriptors < 1) {
29308         // Some implementations report an invalid maxPushDescriptors of 0
29309         printf("%s maxPushDescriptors is zero, skipping tests\n", kSkipPrefix);
29310         return;
29311     }
29312 
29313     VkDescriptorSetLayoutBinding dsl_binding = {};
29314     dsl_binding.binding = 2;
29315     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
29316     dsl_binding.descriptorCount = 1;
29317     dsl_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
29318     dsl_binding.pImmutableSamplers = NULL;
29319 
29320     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding}, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
29321 
29322     // Now use the descriptor layout to create a pipeline layout
29323     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout});
29324 
29325     static const float vbo_data[3] = {1.f, 0.f, 1.f};
29326     VkConstantBufferObj vbo(m_device, sizeof(vbo_data), (const void *)&vbo_data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
29327 
29328     VkDescriptorBufferInfo buff_info;
29329     buff_info.buffer = vbo.handle();
29330     buff_info.offset = 0;
29331     buff_info.range = sizeof(vbo_data);
29332     VkWriteDescriptorSet descriptor_write = {};
29333     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
29334     descriptor_write.dstBinding = 2;
29335     descriptor_write.descriptorCount = 1;
29336     descriptor_write.pTexelBufferView = nullptr;
29337     descriptor_write.pBufferInfo = &buff_info;
29338     descriptor_write.pImageInfo = nullptr;
29339     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
29340     descriptor_write.dstSet = 0;  // Should not cause a validation error
29341 
29342     // Find address of extension call and make the call
29343     PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR =
29344         (PFN_vkCmdPushDescriptorSetKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR");
29345     assert(vkCmdPushDescriptorSetKHR != nullptr);
29346     m_commandBuffer->begin();
29347     vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
29348                               &descriptor_write);
29349 
29350     m_errorMonitor->VerifyNotFound();
29351 }
29352 
29353 // This is a positive test. No failures are expected.
TEST_F(VkPositiveLayerTest,PushDescriptorUnboundSetTest)29354 TEST_F(VkPositiveLayerTest, PushDescriptorUnboundSetTest) {
29355     TEST_DESCRIPTION("Ensure that no validation errors are produced for not bound push descriptor sets");
29356     VkResult err;
29357     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
29358         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
29359     } else {
29360         printf("%s Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n", kSkipPrefix);
29361         return;
29362     }
29363     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
29364     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
29365         m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
29366     } else {
29367         printf("%s Push Descriptors Extension not supported, skipping tests\n", kSkipPrefix);
29368         return;
29369     }
29370     ASSERT_NO_FATAL_FAILURE(InitState());
29371 
29372     auto push_descriptor_prop = GetPushDescriptorProperties(instance(), gpu());
29373     if (push_descriptor_prop.maxPushDescriptors < 1) {
29374         // Some implementations report an invalid maxPushDescriptors of 0
29375         printf("%s maxPushDescriptors is zero, skipping tests\n", kSkipPrefix);
29376         return;
29377     }
29378 
29379     ASSERT_NO_FATAL_FAILURE(InitViewport());
29380     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
29381     m_errorMonitor->ExpectSuccess();
29382 
29383     VkDescriptorPoolSize ds_type_count = {};
29384     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
29385     ds_type_count.descriptorCount = 1;
29386 
29387     VkDescriptorPoolCreateInfo ds_pool_ci = {};
29388     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
29389     ds_pool_ci.pNext = NULL;
29390     ds_pool_ci.maxSets = 1;
29391     ds_pool_ci.poolSizeCount = 1;
29392     ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
29393     ds_pool_ci.pPoolSizes = &ds_type_count;
29394 
29395     VkDescriptorPool ds_pool;
29396     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
29397     ASSERT_VK_SUCCESS(err);
29398 
29399     // Create descriptor set layout
29400     VkDescriptorSetLayoutBinding dsl_binding = {};
29401     dsl_binding.binding = 2;
29402     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
29403     dsl_binding.descriptorCount = 1;
29404     dsl_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
29405     dsl_binding.pImmutableSamplers = NULL;
29406 
29407     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
29408 
29409     // Create push descriptor set layout
29410     const VkDescriptorSetLayoutObj push_ds_layout(m_device, {dsl_binding}, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
29411 
29412     // Allocate descriptor set
29413     VkDescriptorSetAllocateInfo alloc_info = {};
29414     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
29415     alloc_info.pNext = NULL;
29416     alloc_info.descriptorPool = ds_pool;
29417     alloc_info.descriptorSetCount = 1;
29418     alloc_info.pSetLayouts = &ds_layout.handle();
29419     VkDescriptorSet descriptor_set;
29420     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
29421     ASSERT_VK_SUCCESS(err);
29422 
29423     // Now use the descriptor layouts to create a pipeline layout
29424     const VkPipelineLayoutObj pipeline_layout(m_device, {&push_ds_layout, &ds_layout});
29425 
29426     // Create PSO
29427     char const *vsSource =
29428         "#version 450\n"
29429         "\n"
29430         "void main(){\n"
29431         "   gl_Position = vec4(1);\n"
29432         "}\n";
29433     char const *fsSource =
29434         "#version 450\n"
29435         "\n"
29436         "layout(location=0) out vec4 x;\n"
29437         "layout(set=0) layout(binding=2) uniform foo1 { float x; } bar1;\n"
29438         "layout(set=1) layout(binding=2) uniform foo2 { float y; } bar2;\n"
29439         "void main(){\n"
29440         "   x = vec4(bar1.x) + vec4(bar2.y);\n"
29441         "}\n";
29442     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
29443     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
29444     VkPipelineObj pipe(m_device);
29445     pipe.SetViewport(m_viewports);
29446     pipe.SetScissor(m_scissors);
29447     pipe.AddShader(&vs);
29448     pipe.AddShader(&fs);
29449     pipe.AddDefaultColorAttachment();
29450     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
29451 
29452     static const float bo_data[1] = {1.f};
29453     VkConstantBufferObj buffer(m_device, sizeof(bo_data), (const void *)&bo_data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
29454 
29455     // Update descriptor set
29456     VkDescriptorBufferInfo buff_info;
29457     buff_info.buffer = buffer.handle();
29458     buff_info.offset = 0;
29459     buff_info.range = sizeof(bo_data);
29460     VkWriteDescriptorSet descriptor_write = {};
29461     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
29462     descriptor_write.dstBinding = 2;
29463     descriptor_write.descriptorCount = 1;
29464     descriptor_write.pTexelBufferView = nullptr;
29465     descriptor_write.pBufferInfo = &buff_info;
29466     descriptor_write.pImageInfo = nullptr;
29467     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
29468     descriptor_write.dstSet = descriptor_set;
29469     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
29470 
29471     PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR =
29472         (PFN_vkCmdPushDescriptorSetKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR");
29473     assert(vkCmdPushDescriptorSetKHR != nullptr);
29474 
29475     m_commandBuffer->begin();
29476     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
29477     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
29478 
29479     // Push descriptors and bind descriptor set
29480     vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
29481                               &descriptor_write);
29482     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 1, 1,
29483                             &descriptor_set, 0, NULL);
29484 
29485     // No errors should be generated.
29486     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
29487 
29488     m_errorMonitor->VerifyNotFound();
29489 
29490     m_commandBuffer->EndRenderPass();
29491     m_commandBuffer->end();
29492 
29493     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
29494 }
29495 
29496 // This is a positive test. No failures are expected.
TEST_F(VkPositiveLayerTest,TestAliasedMemoryTracking)29497 TEST_F(VkPositiveLayerTest, TestAliasedMemoryTracking) {
29498     VkResult err;
29499     bool pass;
29500 
29501     TEST_DESCRIPTION(
29502         "Create a buffer, allocate memory, bind memory, destroy the buffer, create an image, and bind the same memory to it");
29503 
29504     m_errorMonitor->ExpectSuccess();
29505 
29506     ASSERT_NO_FATAL_FAILURE(Init());
29507 
29508     VkBuffer buffer;
29509     VkImage image;
29510     VkDeviceMemory mem;
29511     VkMemoryRequirements mem_reqs;
29512 
29513     VkBufferCreateInfo buf_info = {};
29514     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
29515     buf_info.pNext = NULL;
29516     buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
29517     buf_info.size = 256;
29518     buf_info.queueFamilyIndexCount = 0;
29519     buf_info.pQueueFamilyIndices = NULL;
29520     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
29521     buf_info.flags = 0;
29522     err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
29523     ASSERT_VK_SUCCESS(err);
29524 
29525     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
29526 
29527     VkMemoryAllocateInfo alloc_info = {};
29528     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
29529     alloc_info.pNext = NULL;
29530     alloc_info.memoryTypeIndex = 0;
29531 
29532     // Ensure memory is big enough for both bindings
29533     alloc_info.allocationSize = 0x10000;
29534 
29535     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
29536     if (!pass) {
29537         printf("%s Failed to allocate memory.\n", kSkipPrefix);
29538         vkDestroyBuffer(m_device->device(), buffer, NULL);
29539         return;
29540     }
29541 
29542     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
29543     ASSERT_VK_SUCCESS(err);
29544 
29545     uint8_t *pData;
29546     err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData);
29547     ASSERT_VK_SUCCESS(err);
29548 
29549     memset(pData, 0xCADECADE, static_cast<size_t>(mem_reqs.size));
29550 
29551     vkUnmapMemory(m_device->device(), mem);
29552 
29553     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
29554     ASSERT_VK_SUCCESS(err);
29555 
29556     // NOW, destroy the buffer. Obviously, the resource no longer occupies this
29557     // memory. In fact, it was never used by the GPU.
29558     // Just be sure, wait for idle.
29559     vkDestroyBuffer(m_device->device(), buffer, NULL);
29560     vkDeviceWaitIdle(m_device->device());
29561 
29562     // Use optimal as some platforms report linear support but then fail image creation
29563     VkImageTiling image_tiling = VK_IMAGE_TILING_OPTIMAL;
29564     VkImageFormatProperties image_format_properties;
29565     vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, image_tiling,
29566                                              VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0, &image_format_properties);
29567     if (image_format_properties.maxExtent.width == 0) {
29568         printf("%s Image format not supported; skipped.\n", kSkipPrefix);
29569         vkFreeMemory(m_device->device(), mem, NULL);
29570         return;
29571     }
29572     VkImageCreateInfo image_create_info = {};
29573     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
29574     image_create_info.pNext = NULL;
29575     image_create_info.imageType = VK_IMAGE_TYPE_2D;
29576     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
29577     image_create_info.extent.width = 64;
29578     image_create_info.extent.height = 64;
29579     image_create_info.extent.depth = 1;
29580     image_create_info.mipLevels = 1;
29581     image_create_info.arrayLayers = 1;
29582     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
29583     image_create_info.tiling = image_tiling;
29584     image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
29585     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
29586     image_create_info.queueFamilyIndexCount = 0;
29587     image_create_info.pQueueFamilyIndices = NULL;
29588     image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
29589     image_create_info.flags = 0;
29590 
29591     /* Create a mappable image.  It will be the texture if linear images are OK
29592      * to be textures or it will be the staging image if they are not.
29593      */
29594     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
29595     ASSERT_VK_SUCCESS(err);
29596 
29597     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
29598 
29599     VkMemoryAllocateInfo mem_alloc = {};
29600     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
29601     mem_alloc.pNext = NULL;
29602     mem_alloc.allocationSize = 0;
29603     mem_alloc.memoryTypeIndex = 0;
29604     mem_alloc.allocationSize = mem_reqs.size;
29605 
29606     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
29607     if (!pass) {
29608         printf("%s Failed to allocate memory.\n", kSkipPrefix);
29609         vkFreeMemory(m_device->device(), mem, NULL);
29610         vkDestroyImage(m_device->device(), image, NULL);
29611         return;
29612     }
29613 
29614     // VALIDATION FAILURE:
29615     err = vkBindImageMemory(m_device->device(), image, mem, 0);
29616     ASSERT_VK_SUCCESS(err);
29617 
29618     m_errorMonitor->VerifyNotFound();
29619 
29620     vkFreeMemory(m_device->device(), mem, NULL);
29621     vkDestroyImage(m_device->device(), image, NULL);
29622 }
29623 
29624 // This is a positive test. No failures are expected.
TEST_F(VkPositiveLayerTest,TestDestroyFreeNullHandles)29625 TEST_F(VkPositiveLayerTest, TestDestroyFreeNullHandles) {
29626     VkResult err;
29627 
29628     TEST_DESCRIPTION("Call all applicable destroy and free routines with NULL handles, expecting no validation errors");
29629 
29630     m_errorMonitor->ExpectSuccess();
29631 
29632     ASSERT_NO_FATAL_FAILURE(Init());
29633     vkDestroyBuffer(m_device->device(), VK_NULL_HANDLE, NULL);
29634     vkDestroyBufferView(m_device->device(), VK_NULL_HANDLE, NULL);
29635     vkDestroyCommandPool(m_device->device(), VK_NULL_HANDLE, NULL);
29636     vkDestroyDescriptorPool(m_device->device(), VK_NULL_HANDLE, NULL);
29637     vkDestroyDescriptorSetLayout(m_device->device(), VK_NULL_HANDLE, NULL);
29638     vkDestroyDevice(VK_NULL_HANDLE, NULL);
29639     vkDestroyEvent(m_device->device(), VK_NULL_HANDLE, NULL);
29640     vkDestroyFence(m_device->device(), VK_NULL_HANDLE, NULL);
29641     vkDestroyFramebuffer(m_device->device(), VK_NULL_HANDLE, NULL);
29642     vkDestroyImage(m_device->device(), VK_NULL_HANDLE, NULL);
29643     vkDestroyImageView(m_device->device(), VK_NULL_HANDLE, NULL);
29644     vkDestroyInstance(VK_NULL_HANDLE, NULL);
29645     vkDestroyPipeline(m_device->device(), VK_NULL_HANDLE, NULL);
29646     vkDestroyPipelineCache(m_device->device(), VK_NULL_HANDLE, NULL);
29647     vkDestroyPipelineLayout(m_device->device(), VK_NULL_HANDLE, NULL);
29648     vkDestroyQueryPool(m_device->device(), VK_NULL_HANDLE, NULL);
29649     vkDestroyRenderPass(m_device->device(), VK_NULL_HANDLE, NULL);
29650     vkDestroySampler(m_device->device(), VK_NULL_HANDLE, NULL);
29651     vkDestroySemaphore(m_device->device(), VK_NULL_HANDLE, NULL);
29652     vkDestroyShaderModule(m_device->device(), VK_NULL_HANDLE, NULL);
29653 
29654     VkCommandPool command_pool;
29655     VkCommandPoolCreateInfo pool_create_info{};
29656     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
29657     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
29658     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
29659     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
29660     VkCommandBuffer command_buffers[3] = {};
29661     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
29662     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
29663     command_buffer_allocate_info.commandPool = command_pool;
29664     command_buffer_allocate_info.commandBufferCount = 1;
29665     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
29666     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffers[1]);
29667     vkFreeCommandBuffers(m_device->device(), command_pool, 3, command_buffers);
29668     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
29669 
29670     VkDescriptorPoolSize ds_type_count = {};
29671     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
29672     ds_type_count.descriptorCount = 1;
29673 
29674     VkDescriptorPoolCreateInfo ds_pool_ci = {};
29675     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
29676     ds_pool_ci.pNext = NULL;
29677     ds_pool_ci.maxSets = 1;
29678     ds_pool_ci.poolSizeCount = 1;
29679     ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
29680     ds_pool_ci.pPoolSizes = &ds_type_count;
29681 
29682     VkDescriptorPool ds_pool;
29683     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
29684     ASSERT_VK_SUCCESS(err);
29685 
29686     VkDescriptorSetLayoutBinding dsl_binding = {};
29687     dsl_binding.binding = 2;
29688     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
29689     dsl_binding.descriptorCount = 1;
29690     dsl_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
29691     dsl_binding.pImmutableSamplers = NULL;
29692 
29693     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
29694 
29695     VkDescriptorSet descriptor_sets[3] = {};
29696     VkDescriptorSetAllocateInfo alloc_info = {};
29697     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
29698     alloc_info.descriptorSetCount = 1;
29699     alloc_info.descriptorPool = ds_pool;
29700     alloc_info.pSetLayouts = &ds_layout.handle();
29701     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_sets[1]);
29702     ASSERT_VK_SUCCESS(err);
29703     vkFreeDescriptorSets(m_device->device(), ds_pool, 3, descriptor_sets);
29704     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
29705 
29706     vkFreeMemory(m_device->device(), VK_NULL_HANDLE, NULL);
29707 
29708     m_errorMonitor->VerifyNotFound();
29709 }
29710 
TEST_F(VkPositiveLayerTest,QueueSubmitSemaphoresAndLayoutTracking)29711 TEST_F(VkPositiveLayerTest, QueueSubmitSemaphoresAndLayoutTracking) {
29712     TEST_DESCRIPTION("Submit multiple command buffers with chained semaphore signals and layout transitions");
29713 
29714     m_errorMonitor->ExpectSuccess();
29715 
29716     ASSERT_NO_FATAL_FAILURE(Init());
29717     VkCommandBuffer cmd_bufs[4];
29718     VkCommandBufferAllocateInfo alloc_info;
29719     alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
29720     alloc_info.pNext = NULL;
29721     alloc_info.commandBufferCount = 4;
29722     alloc_info.commandPool = m_commandPool->handle();
29723     alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
29724     vkAllocateCommandBuffers(m_device->device(), &alloc_info, cmd_bufs);
29725     VkImageObj image(m_device);
29726     image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM,
29727                (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT),
29728                VK_IMAGE_TILING_OPTIMAL, 0);
29729     ASSERT_TRUE(image.initialized());
29730     VkCommandBufferBeginInfo cb_binfo;
29731     cb_binfo.pNext = NULL;
29732     cb_binfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
29733     cb_binfo.pInheritanceInfo = VK_NULL_HANDLE;
29734     cb_binfo.flags = 0;
29735     // Use 4 command buffers, each with an image layout transition, ColorAO->General->ColorAO->TransferSrc->TransferDst
29736     vkBeginCommandBuffer(cmd_bufs[0], &cb_binfo);
29737     VkImageMemoryBarrier img_barrier = {};
29738     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
29739     img_barrier.pNext = NULL;
29740     img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
29741     img_barrier.dstAccessMask = VK_ACCESS_HOST_WRITE_BIT;
29742     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
29743     img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
29744     img_barrier.image = image.handle();
29745     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
29746     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
29747     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
29748     img_barrier.subresourceRange.baseArrayLayer = 0;
29749     img_barrier.subresourceRange.baseMipLevel = 0;
29750     img_barrier.subresourceRange.layerCount = 1;
29751     img_barrier.subresourceRange.levelCount = 1;
29752     vkCmdPipelineBarrier(cmd_bufs[0], VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, nullptr, 0, nullptr, 1,
29753                          &img_barrier);
29754     vkEndCommandBuffer(cmd_bufs[0]);
29755     vkBeginCommandBuffer(cmd_bufs[1], &cb_binfo);
29756     img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
29757     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
29758     vkCmdPipelineBarrier(cmd_bufs[1], VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, nullptr, 0, nullptr, 1,
29759                          &img_barrier);
29760     vkEndCommandBuffer(cmd_bufs[1]);
29761     vkBeginCommandBuffer(cmd_bufs[2], &cb_binfo);
29762     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
29763     img_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
29764     vkCmdPipelineBarrier(cmd_bufs[2], VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, nullptr, 0, nullptr, 1,
29765                          &img_barrier);
29766     vkEndCommandBuffer(cmd_bufs[2]);
29767     vkBeginCommandBuffer(cmd_bufs[3], &cb_binfo);
29768     img_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
29769     img_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
29770     vkCmdPipelineBarrier(cmd_bufs[3], VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, nullptr, 0, nullptr, 1,
29771                          &img_barrier);
29772     vkEndCommandBuffer(cmd_bufs[3]);
29773 
29774     // Submit 4 command buffers in 3 submits, with submits 2 and 3 waiting for semaphores from submits 1 and 2
29775     VkSemaphore semaphore1, semaphore2;
29776     VkSemaphoreCreateInfo semaphore_create_info{};
29777     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
29778     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore1);
29779     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore2);
29780     VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
29781     VkSubmitInfo submit_info[3];
29782     submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
29783     submit_info[0].pNext = nullptr;
29784     submit_info[0].commandBufferCount = 1;
29785     submit_info[0].pCommandBuffers = &cmd_bufs[0];
29786     submit_info[0].signalSemaphoreCount = 1;
29787     submit_info[0].pSignalSemaphores = &semaphore1;
29788     submit_info[0].waitSemaphoreCount = 0;
29789     submit_info[0].pWaitDstStageMask = nullptr;
29790     submit_info[0].pWaitDstStageMask = flags;
29791     submit_info[1].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
29792     submit_info[1].pNext = nullptr;
29793     submit_info[1].commandBufferCount = 1;
29794     submit_info[1].pCommandBuffers = &cmd_bufs[1];
29795     submit_info[1].waitSemaphoreCount = 1;
29796     submit_info[1].pWaitSemaphores = &semaphore1;
29797     submit_info[1].signalSemaphoreCount = 1;
29798     submit_info[1].pSignalSemaphores = &semaphore2;
29799     submit_info[1].pWaitDstStageMask = flags;
29800     submit_info[2].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
29801     submit_info[2].pNext = nullptr;
29802     submit_info[2].commandBufferCount = 2;
29803     submit_info[2].pCommandBuffers = &cmd_bufs[2];
29804     submit_info[2].waitSemaphoreCount = 1;
29805     submit_info[2].pWaitSemaphores = &semaphore2;
29806     submit_info[2].signalSemaphoreCount = 0;
29807     submit_info[2].pSignalSemaphores = nullptr;
29808     submit_info[2].pWaitDstStageMask = flags;
29809     vkQueueSubmit(m_device->m_queue, 3, submit_info, VK_NULL_HANDLE);
29810     vkQueueWaitIdle(m_device->m_queue);
29811 
29812     vkDestroySemaphore(m_device->device(), semaphore1, NULL);
29813     vkDestroySemaphore(m_device->device(), semaphore2, NULL);
29814     m_errorMonitor->VerifyNotFound();
29815 }
29816 
TEST_F(VkPositiveLayerTest,DynamicOffsetWithInactiveBinding)29817 TEST_F(VkPositiveLayerTest, DynamicOffsetWithInactiveBinding) {
29818     // Create a descriptorSet w/ dynamic descriptors where 1 binding is inactive
29819     // We previously had a bug where dynamic offset of inactive bindings was still being used
29820     VkResult err;
29821     m_errorMonitor->ExpectSuccess();
29822 
29823     ASSERT_NO_FATAL_FAILURE(Init());
29824     ASSERT_NO_FATAL_FAILURE(InitViewport());
29825     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
29826 
29827     OneOffDescriptorSet ds(m_device, {
29828                                          {2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
29829                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
29830                                          {1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
29831                                      });
29832 
29833     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
29834 
29835     // Create two buffers to update the descriptors with
29836     // The first will be 2k and used for bindings 0 & 1, the second is 1k for binding 2
29837     uint32_t qfi = 0;
29838     VkBufferCreateInfo buffCI = {};
29839     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
29840     buffCI.size = 2048;
29841     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
29842     buffCI.queueFamilyIndexCount = 1;
29843     buffCI.pQueueFamilyIndices = &qfi;
29844 
29845     VkBuffer dyub1;
29846     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub1);
29847     ASSERT_VK_SUCCESS(err);
29848     // buffer2
29849     buffCI.size = 1024;
29850     VkBuffer dyub2;
29851     err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub2);
29852     ASSERT_VK_SUCCESS(err);
29853     // Allocate memory and bind to buffers
29854     VkMemoryAllocateInfo mem_alloc[2] = {};
29855     mem_alloc[0].sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
29856     mem_alloc[0].pNext = NULL;
29857     mem_alloc[0].memoryTypeIndex = 0;
29858     mem_alloc[1].sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
29859     mem_alloc[1].pNext = NULL;
29860     mem_alloc[1].memoryTypeIndex = 0;
29861 
29862     VkMemoryRequirements mem_reqs1;
29863     vkGetBufferMemoryRequirements(m_device->device(), dyub1, &mem_reqs1);
29864     VkMemoryRequirements mem_reqs2;
29865     vkGetBufferMemoryRequirements(m_device->device(), dyub2, &mem_reqs2);
29866     mem_alloc[0].allocationSize = mem_reqs1.size;
29867     bool pass = m_device->phy().set_memory_type(mem_reqs1.memoryTypeBits, &mem_alloc[0], 0);
29868     mem_alloc[1].allocationSize = mem_reqs2.size;
29869     pass &= m_device->phy().set_memory_type(mem_reqs2.memoryTypeBits, &mem_alloc[1], 0);
29870     if (!pass) {
29871         printf("%s Failed to allocate memory.\n", kSkipPrefix);
29872         vkDestroyBuffer(m_device->device(), dyub1, NULL);
29873         vkDestroyBuffer(m_device->device(), dyub2, NULL);
29874         return;
29875     }
29876 
29877     VkDeviceMemory mem1;
29878     err = vkAllocateMemory(m_device->device(), &mem_alloc[0], NULL, &mem1);
29879     ASSERT_VK_SUCCESS(err);
29880     err = vkBindBufferMemory(m_device->device(), dyub1, mem1, 0);
29881     ASSERT_VK_SUCCESS(err);
29882     VkDeviceMemory mem2;
29883     err = vkAllocateMemory(m_device->device(), &mem_alloc[1], NULL, &mem2);
29884     ASSERT_VK_SUCCESS(err);
29885     err = vkBindBufferMemory(m_device->device(), dyub2, mem2, 0);
29886     ASSERT_VK_SUCCESS(err);
29887     // Update descriptors
29888     const uint32_t BINDING_COUNT = 3;
29889     VkDescriptorBufferInfo buff_info[BINDING_COUNT] = {};
29890     buff_info[0].buffer = dyub1;
29891     buff_info[0].offset = 0;
29892     buff_info[0].range = 256;
29893     buff_info[1].buffer = dyub1;
29894     buff_info[1].offset = 256;
29895     buff_info[1].range = 512;
29896     buff_info[2].buffer = dyub2;
29897     buff_info[2].offset = 0;
29898     buff_info[2].range = 512;
29899 
29900     VkWriteDescriptorSet descriptor_write;
29901     memset(&descriptor_write, 0, sizeof(descriptor_write));
29902     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
29903     descriptor_write.dstSet = ds.set_;
29904     descriptor_write.dstBinding = 0;
29905     descriptor_write.descriptorCount = BINDING_COUNT;
29906     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
29907     descriptor_write.pBufferInfo = buff_info;
29908 
29909     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
29910 
29911     m_commandBuffer->begin();
29912     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
29913 
29914     // Create PSO to be used for draw-time errors below
29915     char const *vsSource =
29916         "#version 450\n"
29917         "\n"
29918         "void main(){\n"
29919         "   gl_Position = vec4(1);\n"
29920         "}\n";
29921     char const *fsSource =
29922         "#version 450\n"
29923         "\n"
29924         "layout(location=0) out vec4 x;\n"
29925         "layout(set=0) layout(binding=0) uniform foo1 { int x; int y; } bar1;\n"
29926         "layout(set=0) layout(binding=2) uniform foo2 { int x; int y; } bar2;\n"
29927         "void main(){\n"
29928         "   x = vec4(bar1.y) + vec4(bar2.y);\n"
29929         "}\n";
29930     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
29931     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
29932     VkPipelineObj pipe(m_device);
29933     pipe.SetViewport(m_viewports);
29934     pipe.SetScissor(m_scissors);
29935     pipe.AddShader(&vs);
29936     pipe.AddShader(&fs);
29937     pipe.AddDefaultColorAttachment();
29938     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
29939 
29940     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
29941     // This update should succeed, but offset of inactive binding 1 oversteps binding 2 buffer size
29942     //   we used to have a bug in this case.
29943     uint32_t dyn_off[BINDING_COUNT] = {0, 1024, 256};
29944     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &ds.set_,
29945                             BINDING_COUNT, dyn_off);
29946     m_commandBuffer->Draw(1, 0, 0, 0);
29947     m_errorMonitor->VerifyNotFound();
29948 
29949     m_commandBuffer->EndRenderPass();
29950     m_commandBuffer->end();
29951 
29952     vkDestroyBuffer(m_device->device(), dyub1, NULL);
29953     vkDestroyBuffer(m_device->device(), dyub2, NULL);
29954     vkFreeMemory(m_device->device(), mem1, NULL);
29955     vkFreeMemory(m_device->device(), mem2, NULL);
29956 }
29957 
TEST_F(VkPositiveLayerTest,NonCoherentMemoryMapping)29958 TEST_F(VkPositiveLayerTest, NonCoherentMemoryMapping) {
29959     TEST_DESCRIPTION(
29960         "Ensure that validations handling of non-coherent memory mapping while using VK_WHOLE_SIZE does not cause access "
29961         "violations");
29962     VkResult err;
29963     uint8_t *pData;
29964     ASSERT_NO_FATAL_FAILURE(Init());
29965 
29966     VkDeviceMemory mem;
29967     VkMemoryRequirements mem_reqs;
29968     mem_reqs.memoryTypeBits = 0xFFFFFFFF;
29969     const VkDeviceSize atom_size = m_device->props.limits.nonCoherentAtomSize;
29970     VkMemoryAllocateInfo alloc_info = {};
29971     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
29972     alloc_info.pNext = NULL;
29973     alloc_info.memoryTypeIndex = 0;
29974 
29975     static const VkDeviceSize allocation_size = 32 * atom_size;
29976     alloc_info.allocationSize = allocation_size;
29977 
29978     // Find a memory configurations WITHOUT a COHERENT bit, otherwise exit
29979     bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
29980                                                 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
29981     if (!pass) {
29982         pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info,
29983                                                VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
29984                                                VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
29985         if (!pass) {
29986             pass = m_device->phy().set_memory_type(
29987                 mem_reqs.memoryTypeBits, &alloc_info,
29988                 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
29989                 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
29990             if (!pass) {
29991                 printf("%s Couldn't find a memory type wihtout a COHERENT bit.\n", kSkipPrefix);
29992                 return;
29993             }
29994         }
29995     }
29996 
29997     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
29998     ASSERT_VK_SUCCESS(err);
29999 
30000     // Map/Flush/Invalidate using WHOLE_SIZE and zero offsets and entire mapped range
30001     m_errorMonitor->ExpectSuccess();
30002     err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, (void **)&pData);
30003     ASSERT_VK_SUCCESS(err);
30004     VkMappedMemoryRange mmr = {};
30005     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
30006     mmr.memory = mem;
30007     mmr.offset = 0;
30008     mmr.size = VK_WHOLE_SIZE;
30009     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
30010     ASSERT_VK_SUCCESS(err);
30011     err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr);
30012     ASSERT_VK_SUCCESS(err);
30013     m_errorMonitor->VerifyNotFound();
30014     vkUnmapMemory(m_device->device(), mem);
30015 
30016     // Map/Flush/Invalidate using WHOLE_SIZE and an offset and entire mapped range
30017     m_errorMonitor->ExpectSuccess();
30018     err = vkMapMemory(m_device->device(), mem, 5 * atom_size, VK_WHOLE_SIZE, 0, (void **)&pData);
30019     ASSERT_VK_SUCCESS(err);
30020     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
30021     mmr.memory = mem;
30022     mmr.offset = 6 * atom_size;
30023     mmr.size = VK_WHOLE_SIZE;
30024     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
30025     ASSERT_VK_SUCCESS(err);
30026     err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr);
30027     ASSERT_VK_SUCCESS(err);
30028     m_errorMonitor->VerifyNotFound();
30029     vkUnmapMemory(m_device->device(), mem);
30030 
30031     // Map with offset and size
30032     // Flush/Invalidate subrange of mapped area with offset and size
30033     m_errorMonitor->ExpectSuccess();
30034     err = vkMapMemory(m_device->device(), mem, 3 * atom_size, 9 * atom_size, 0, (void **)&pData);
30035     ASSERT_VK_SUCCESS(err);
30036     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
30037     mmr.memory = mem;
30038     mmr.offset = 4 * atom_size;
30039     mmr.size = 2 * atom_size;
30040     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
30041     ASSERT_VK_SUCCESS(err);
30042     err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr);
30043     ASSERT_VK_SUCCESS(err);
30044     m_errorMonitor->VerifyNotFound();
30045     vkUnmapMemory(m_device->device(), mem);
30046 
30047     // Map without offset and flush WHOLE_SIZE with two separate offsets
30048     m_errorMonitor->ExpectSuccess();
30049     err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, (void **)&pData);
30050     ASSERT_VK_SUCCESS(err);
30051     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
30052     mmr.memory = mem;
30053     mmr.offset = allocation_size - (4 * atom_size);
30054     mmr.size = VK_WHOLE_SIZE;
30055     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
30056     ASSERT_VK_SUCCESS(err);
30057     mmr.offset = allocation_size - (6 * atom_size);
30058     mmr.size = VK_WHOLE_SIZE;
30059     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
30060     ASSERT_VK_SUCCESS(err);
30061     m_errorMonitor->VerifyNotFound();
30062     vkUnmapMemory(m_device->device(), mem);
30063 
30064     vkFreeMemory(m_device->device(), mem, NULL);
30065 }
30066 
30067 // This is a positive test. We used to expect error in this case but spec now allows it
TEST_F(VkPositiveLayerTest,ResetUnsignaledFence)30068 TEST_F(VkPositiveLayerTest, ResetUnsignaledFence) {
30069     m_errorMonitor->ExpectSuccess();
30070     vk_testing::Fence testFence;
30071     VkFenceCreateInfo fenceInfo = {};
30072     fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
30073     fenceInfo.pNext = NULL;
30074 
30075     ASSERT_NO_FATAL_FAILURE(Init());
30076     testFence.init(*m_device, fenceInfo);
30077     VkFence fences[1] = {testFence.handle()};
30078     VkResult result = vkResetFences(m_device->device(), 1, fences);
30079     ASSERT_VK_SUCCESS(result);
30080 
30081     m_errorMonitor->VerifyNotFound();
30082 }
30083 
TEST_F(VkPositiveLayerTest,CommandBufferSimultaneousUseSync)30084 TEST_F(VkPositiveLayerTest, CommandBufferSimultaneousUseSync) {
30085     m_errorMonitor->ExpectSuccess();
30086 
30087     ASSERT_NO_FATAL_FAILURE(Init());
30088     VkResult err;
30089 
30090     // Record (empty!) command buffer that can be submitted multiple times
30091     // simultaneously.
30092     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
30093                                      VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, nullptr};
30094     m_commandBuffer->begin(&cbbi);
30095     m_commandBuffer->end();
30096 
30097     VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
30098     VkFence fence;
30099     err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
30100     ASSERT_VK_SUCCESS(err);
30101 
30102     VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
30103     VkSemaphore s1, s2;
30104     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s1);
30105     ASSERT_VK_SUCCESS(err);
30106     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s2);
30107     ASSERT_VK_SUCCESS(err);
30108 
30109     // Submit CB once signaling s1, with fence so we can roll forward to its retirement.
30110     VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &m_commandBuffer->handle(), 1, &s1};
30111     err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
30112     ASSERT_VK_SUCCESS(err);
30113 
30114     // Submit CB again, signaling s2.
30115     si.pSignalSemaphores = &s2;
30116     err = vkQueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE);
30117     ASSERT_VK_SUCCESS(err);
30118 
30119     // Wait for fence.
30120     err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
30121     ASSERT_VK_SUCCESS(err);
30122 
30123     // CB is still in flight from second submission, but semaphore s1 is no
30124     // longer in flight. delete it.
30125     vkDestroySemaphore(m_device->device(), s1, nullptr);
30126 
30127     m_errorMonitor->VerifyNotFound();
30128 
30129     // Force device idle and clean up remaining objects
30130     vkDeviceWaitIdle(m_device->device());
30131     vkDestroySemaphore(m_device->device(), s2, nullptr);
30132     vkDestroyFence(m_device->device(), fence, nullptr);
30133 }
30134 
TEST_F(VkPositiveLayerTest,FenceCreateSignaledWaitHandling)30135 TEST_F(VkPositiveLayerTest, FenceCreateSignaledWaitHandling) {
30136     m_errorMonitor->ExpectSuccess();
30137 
30138     ASSERT_NO_FATAL_FAILURE(Init());
30139     VkResult err;
30140 
30141     // A fence created signaled
30142     VkFenceCreateInfo fci1 = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, VK_FENCE_CREATE_SIGNALED_BIT};
30143     VkFence f1;
30144     err = vkCreateFence(m_device->device(), &fci1, nullptr, &f1);
30145     ASSERT_VK_SUCCESS(err);
30146 
30147     // A fence created not
30148     VkFenceCreateInfo fci2 = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
30149     VkFence f2;
30150     err = vkCreateFence(m_device->device(), &fci2, nullptr, &f2);
30151     ASSERT_VK_SUCCESS(err);
30152 
30153     // Submit the unsignaled fence
30154     VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 0, nullptr, 0, nullptr};
30155     err = vkQueueSubmit(m_device->m_queue, 1, &si, f2);
30156 
30157     // Wait on both fences, with signaled first.
30158     VkFence fences[] = {f1, f2};
30159     vkWaitForFences(m_device->device(), 2, fences, VK_TRUE, UINT64_MAX);
30160 
30161     // Should have both retired!
30162     vkDestroyFence(m_device->device(), f1, nullptr);
30163     vkDestroyFence(m_device->device(), f2, nullptr);
30164 
30165     m_errorMonitor->VerifyNotFound();
30166 }
30167 
TEST_F(VkPositiveLayerTest,CreateImageViewFollowsParameterCompatibilityRequirements)30168 TEST_F(VkPositiveLayerTest, CreateImageViewFollowsParameterCompatibilityRequirements) {
30169     TEST_DESCRIPTION("Verify that creating an ImageView with valid usage does not generate validation errors.");
30170 
30171     ASSERT_NO_FATAL_FAILURE(Init());
30172 
30173     m_errorMonitor->ExpectSuccess();
30174 
30175     VkImageCreateInfo imgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
30176                                  nullptr,
30177                                  VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
30178                                  VK_IMAGE_TYPE_2D,
30179                                  VK_FORMAT_R8G8B8A8_UNORM,
30180                                  {128, 128, 1},
30181                                  1,
30182                                  1,
30183                                  VK_SAMPLE_COUNT_1_BIT,
30184                                  VK_IMAGE_TILING_OPTIMAL,
30185                                  VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
30186                                  VK_SHARING_MODE_EXCLUSIVE,
30187                                  0,
30188                                  nullptr,
30189                                  VK_IMAGE_LAYOUT_UNDEFINED};
30190     VkImageObj image(m_device);
30191     image.init(&imgInfo);
30192     ASSERT_TRUE(image.initialized());
30193     VkImageView imageView;
30194     VkImageViewCreateInfo ivci = {};
30195     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
30196     ivci.image = image.handle();
30197     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
30198     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
30199     ivci.subresourceRange.layerCount = 1;
30200     ivci.subresourceRange.baseMipLevel = 0;
30201     ivci.subresourceRange.levelCount = 1;
30202     ivci.subresourceRange.baseArrayLayer = 0;
30203     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
30204 
30205     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
30206     m_errorMonitor->VerifyNotFound();
30207     vkDestroyImageView(m_device->device(), imageView, NULL);
30208 }
30209 
TEST_F(VkPositiveLayerTest,ValidUsage)30210 TEST_F(VkPositiveLayerTest, ValidUsage) {
30211     TEST_DESCRIPTION("Verify that creating an image view from an image with valid usage doesn't generate validation errors");
30212 
30213     ASSERT_NO_FATAL_FAILURE(Init());
30214 
30215     m_errorMonitor->ExpectSuccess();
30216     // Verify that we can create a view with usage INPUT_ATTACHMENT
30217     VkImageObj image(m_device);
30218     image.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
30219     ASSERT_TRUE(image.initialized());
30220     VkImageView imageView;
30221     VkImageViewCreateInfo ivci = {};
30222     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
30223     ivci.image = image.handle();
30224     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
30225     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
30226     ivci.subresourceRange.layerCount = 1;
30227     ivci.subresourceRange.baseMipLevel = 0;
30228     ivci.subresourceRange.levelCount = 1;
30229     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
30230 
30231     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
30232     m_errorMonitor->VerifyNotFound();
30233     vkDestroyImageView(m_device->device(), imageView, NULL);
30234 }
30235 
30236 // This is a positive test. No failures are expected.
TEST_F(VkPositiveLayerTest,BindSparse)30237 TEST_F(VkPositiveLayerTest, BindSparse) {
30238     TEST_DESCRIPTION("Bind 2 memory ranges to one image using vkQueueBindSparse, destroy the image and then free the memory");
30239 
30240     ASSERT_NO_FATAL_FAILURE(Init());
30241 
30242     auto index = m_device->graphics_queue_node_index_;
30243     if (!(m_device->queue_props[index].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT)) {
30244         printf("%s Graphics queue does not have sparse binding bit.\n", kSkipPrefix);
30245         return;
30246     }
30247     if (!m_device->phy().features().sparseBinding) {
30248         printf("%s Device does not support sparse bindings.\n", kSkipPrefix);
30249         return;
30250     }
30251 
30252     m_errorMonitor->ExpectSuccess(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT);
30253 
30254     VkImage image;
30255     VkImageCreateInfo image_create_info = {};
30256     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
30257     image_create_info.pNext = NULL;
30258     image_create_info.imageType = VK_IMAGE_TYPE_2D;
30259     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
30260     image_create_info.extent.width = 64;
30261     image_create_info.extent.height = 64;
30262     image_create_info.extent.depth = 1;
30263     image_create_info.mipLevels = 1;
30264     image_create_info.arrayLayers = 1;
30265     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
30266     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
30267     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
30268     image_create_info.flags = VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
30269     VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
30270     ASSERT_VK_SUCCESS(err);
30271 
30272     VkMemoryRequirements memory_reqs;
30273     VkDeviceMemory memory_one, memory_two;
30274     bool pass;
30275     VkMemoryAllocateInfo memory_info = {};
30276     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
30277     memory_info.pNext = NULL;
30278     memory_info.allocationSize = 0;
30279     memory_info.memoryTypeIndex = 0;
30280     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
30281     // Find an image big enough to allow sparse mapping of 2 memory regions
30282     // Increase the image size until it is at least twice the
30283     // size of the required alignment, to ensure we can bind both
30284     // allocated memory blocks to the image on aligned offsets.
30285     while (memory_reqs.size < (memory_reqs.alignment * 2)) {
30286         vkDestroyImage(m_device->device(), image, nullptr);
30287         image_create_info.extent.width *= 2;
30288         image_create_info.extent.height *= 2;
30289         err = vkCreateImage(m_device->device(), &image_create_info, nullptr, &image);
30290         ASSERT_VK_SUCCESS(err);
30291         vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
30292     }
30293     // Allocate 2 memory regions of minimum alignment size, bind one at 0, the other
30294     // at the end of the first
30295     memory_info.allocationSize = memory_reqs.alignment;
30296     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
30297     ASSERT_TRUE(pass);
30298     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &memory_one);
30299     ASSERT_VK_SUCCESS(err);
30300     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &memory_two);
30301     ASSERT_VK_SUCCESS(err);
30302     VkSparseMemoryBind binds[2];
30303     binds[0].flags = 0;
30304     binds[0].memory = memory_one;
30305     binds[0].memoryOffset = 0;
30306     binds[0].resourceOffset = 0;
30307     binds[0].size = memory_info.allocationSize;
30308     binds[1].flags = 0;
30309     binds[1].memory = memory_two;
30310     binds[1].memoryOffset = 0;
30311     binds[1].resourceOffset = memory_info.allocationSize;
30312     binds[1].size = memory_info.allocationSize;
30313 
30314     VkSparseImageOpaqueMemoryBindInfo opaqueBindInfo;
30315     opaqueBindInfo.image = image;
30316     opaqueBindInfo.bindCount = 2;
30317     opaqueBindInfo.pBinds = binds;
30318 
30319     VkFence fence = VK_NULL_HANDLE;
30320     VkBindSparseInfo bindSparseInfo = {};
30321     bindSparseInfo.sType = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO;
30322     bindSparseInfo.imageOpaqueBindCount = 1;
30323     bindSparseInfo.pImageOpaqueBinds = &opaqueBindInfo;
30324 
30325     vkQueueBindSparse(m_device->m_queue, 1, &bindSparseInfo, fence);
30326     vkQueueWaitIdle(m_device->m_queue);
30327     vkDestroyImage(m_device->device(), image, NULL);
30328     vkFreeMemory(m_device->device(), memory_one, NULL);
30329     vkFreeMemory(m_device->device(), memory_two, NULL);
30330     m_errorMonitor->VerifyNotFound();
30331 }
30332 
TEST_F(VkPositiveLayerTest,BindSparseMetadata)30333 TEST_F(VkPositiveLayerTest, BindSparseMetadata) {
30334     TEST_DESCRIPTION("Bind memory for the metadata aspect of a sparse image");
30335 
30336     ASSERT_NO_FATAL_FAILURE(Init());
30337 
30338     auto index = m_device->graphics_queue_node_index_;
30339     if (!(m_device->queue_props[index].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT)) {
30340         printf("%s Graphics queue does not have sparse binding bit.\n", kSkipPrefix);
30341         return;
30342     }
30343     if (!m_device->phy().features().sparseResidencyImage2D) {
30344         printf("%s Device does not support sparse residency for images.\n", kSkipPrefix);
30345         return;
30346     }
30347 
30348     m_errorMonitor->ExpectSuccess(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT);
30349 
30350     // Create a sparse image
30351     VkImage image;
30352     VkImageCreateInfo image_create_info = {};
30353     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
30354     image_create_info.pNext = NULL;
30355     image_create_info.imageType = VK_IMAGE_TYPE_2D;
30356     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
30357     image_create_info.extent.width = 64;
30358     image_create_info.extent.height = 64;
30359     image_create_info.extent.depth = 1;
30360     image_create_info.mipLevels = 1;
30361     image_create_info.arrayLayers = 1;
30362     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
30363     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
30364     image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
30365     image_create_info.flags = VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT;
30366     VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
30367     ASSERT_VK_SUCCESS(err);
30368 
30369     // Query image memory requirements
30370     VkMemoryRequirements memory_reqs;
30371     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
30372 
30373     // Query sparse memory requirements
30374     uint32_t sparse_reqs_count = 0;
30375     vkGetImageSparseMemoryRequirements(m_device->device(), image, &sparse_reqs_count, nullptr);
30376     std::vector<VkSparseImageMemoryRequirements> sparse_reqs(sparse_reqs_count);
30377     vkGetImageSparseMemoryRequirements(m_device->device(), image, &sparse_reqs_count, sparse_reqs.data());
30378 
30379     // Find requirements for metadata aspect
30380     const VkSparseImageMemoryRequirements *metadata_reqs = nullptr;
30381     for (auto const &aspect_sparse_reqs : sparse_reqs) {
30382         if (aspect_sparse_reqs.formatProperties.aspectMask == VK_IMAGE_ASPECT_METADATA_BIT) {
30383             metadata_reqs = &aspect_sparse_reqs;
30384         }
30385     }
30386 
30387     if (!metadata_reqs) {
30388         printf("%s Sparse image does not require memory for metadata.\n", kSkipPrefix);
30389     } else {
30390         // Allocate memory for the metadata
30391         VkDeviceMemory metadata_memory = VK_NULL_HANDLE;
30392         VkMemoryAllocateInfo metadata_memory_info = {};
30393         metadata_memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
30394         metadata_memory_info.allocationSize = metadata_reqs->imageMipTailSize;
30395         m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &metadata_memory_info, 0);
30396         err = vkAllocateMemory(m_device->device(), &metadata_memory_info, NULL, &metadata_memory);
30397         ASSERT_VK_SUCCESS(err);
30398 
30399         // Bind metadata
30400         VkSparseMemoryBind sparse_bind = {};
30401         sparse_bind.resourceOffset = metadata_reqs->imageMipTailOffset;
30402         sparse_bind.size = metadata_reqs->imageMipTailSize;
30403         sparse_bind.memory = metadata_memory;
30404         sparse_bind.memoryOffset = 0;
30405         sparse_bind.flags = VK_SPARSE_MEMORY_BIND_METADATA_BIT;
30406 
30407         VkSparseImageOpaqueMemoryBindInfo opaque_bind_info = {};
30408         opaque_bind_info.image = image;
30409         opaque_bind_info.bindCount = 1;
30410         opaque_bind_info.pBinds = &sparse_bind;
30411 
30412         VkBindSparseInfo bind_info = {};
30413         bind_info.sType = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO;
30414         bind_info.imageOpaqueBindCount = 1;
30415         bind_info.pImageOpaqueBinds = &opaque_bind_info;
30416 
30417         vkQueueBindSparse(m_device->m_queue, 1, &bind_info, VK_NULL_HANDLE);
30418         m_errorMonitor->VerifyNotFound();
30419 
30420         // Cleanup
30421         vkQueueWaitIdle(m_device->m_queue);
30422         vkFreeMemory(m_device->device(), metadata_memory, NULL);
30423     }
30424 
30425     vkDestroyImage(m_device->device(), image, NULL);
30426 }
30427 
TEST_F(VkPositiveLayerTest,FramebufferBindingDestroyCommandPool)30428 TEST_F(VkPositiveLayerTest, FramebufferBindingDestroyCommandPool) {
30429     TEST_DESCRIPTION(
30430         "This test should pass. Create a Framebuffer and command buffer, bind them together, then destroy command pool and "
30431         "framebuffer and verify there are no errors.");
30432 
30433     m_errorMonitor->ExpectSuccess();
30434 
30435     ASSERT_NO_FATAL_FAILURE(Init());
30436 
30437     // A renderpass with one color attachment.
30438     VkAttachmentDescription attachment = {0,
30439                                           VK_FORMAT_R8G8B8A8_UNORM,
30440                                           VK_SAMPLE_COUNT_1_BIT,
30441                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
30442                                           VK_ATTACHMENT_STORE_OP_STORE,
30443                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
30444                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
30445                                           VK_IMAGE_LAYOUT_UNDEFINED,
30446                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
30447 
30448     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
30449 
30450     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
30451 
30452     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
30453 
30454     VkRenderPass rp;
30455     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
30456     ASSERT_VK_SUCCESS(err);
30457 
30458     // A compatible framebuffer.
30459     VkImageObj image(m_device);
30460     image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
30461     ASSERT_TRUE(image.initialized());
30462 
30463     VkImageView view = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
30464 
30465     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
30466     VkFramebuffer fb;
30467     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
30468     ASSERT_VK_SUCCESS(err);
30469 
30470     // Explicitly create a command buffer to bind the FB to so that we can then
30471     //  destroy the command pool in order to implicitly free command buffer
30472     VkCommandPool command_pool;
30473     VkCommandPoolCreateInfo pool_create_info{};
30474     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
30475     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
30476     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
30477     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
30478 
30479     VkCommandBuffer command_buffer;
30480     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
30481     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
30482     command_buffer_allocate_info.commandPool = command_pool;
30483     command_buffer_allocate_info.commandBufferCount = 1;
30484     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
30485     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
30486 
30487     // Begin our cmd buffer with renderpass using our framebuffer
30488     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
30489     VkCommandBufferBeginInfo begin_info{};
30490     begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
30491     vkBeginCommandBuffer(command_buffer, &begin_info);
30492 
30493     vkCmdBeginRenderPass(command_buffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
30494     vkCmdEndRenderPass(command_buffer);
30495     vkEndCommandBuffer(command_buffer);
30496     // Destroy command pool to implicitly free command buffer
30497     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
30498     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
30499     vkDestroyRenderPass(m_device->device(), rp, nullptr);
30500     m_errorMonitor->VerifyNotFound();
30501 }
30502 
TEST_F(VkPositiveLayerTest,FramebufferCreateDepthStencilLayoutTransitionForDepthOnlyImageView)30503 TEST_F(VkPositiveLayerTest, FramebufferCreateDepthStencilLayoutTransitionForDepthOnlyImageView) {
30504     TEST_DESCRIPTION(
30505         "Validate that when an imageView of a depth/stencil image is used as a depth/stencil framebuffer attachment, the "
30506         "aspectMask is ignored and both depth and stencil image subresources are used.");
30507 
30508     ASSERT_NO_FATAL_FAILURE(Init());
30509     VkFormatProperties format_properties;
30510     vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_D32_SFLOAT_S8_UINT, &format_properties);
30511     if (!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
30512         printf("%s Image format does not support sampling.\n", kSkipPrefix);
30513         return;
30514     }
30515 
30516     m_errorMonitor->ExpectSuccess();
30517 
30518     VkAttachmentDescription attachment = {0,
30519                                           VK_FORMAT_D32_SFLOAT_S8_UINT,
30520                                           VK_SAMPLE_COUNT_1_BIT,
30521                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
30522                                           VK_ATTACHMENT_STORE_OP_STORE,
30523                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
30524                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
30525                                           VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
30526                                           VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
30527 
30528     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
30529 
30530     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &att_ref, 0, nullptr};
30531 
30532     VkSubpassDependency dep = {0,
30533                                0,
30534                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
30535                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
30536                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
30537                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
30538                                VK_DEPENDENCY_BY_REGION_BIT};
30539 
30540     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep};
30541 
30542     VkResult err;
30543     VkRenderPass rp;
30544     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
30545     ASSERT_VK_SUCCESS(err);
30546 
30547     VkImageObj image(m_device);
30548     image.InitNoLayout(32, 32, 1, VK_FORMAT_D32_SFLOAT_S8_UINT,
30549                        0x26,  // usage
30550                        VK_IMAGE_TILING_OPTIMAL, 0);
30551     ASSERT_TRUE(image.initialized());
30552     image.SetLayout(0x6, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
30553 
30554     VkImageViewCreateInfo ivci = {
30555         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
30556         nullptr,
30557         0,
30558         image.handle(),
30559         VK_IMAGE_VIEW_TYPE_2D,
30560         VK_FORMAT_D32_SFLOAT_S8_UINT,
30561         {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
30562         {0x2, 0, 1, 0, 1},
30563     };
30564     VkImageView view;
30565     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
30566     ASSERT_VK_SUCCESS(err);
30567 
30568     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
30569     VkFramebuffer fb;
30570     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
30571     ASSERT_VK_SUCCESS(err);
30572 
30573     m_commandBuffer->begin();
30574 
30575     VkImageMemoryBarrier imb = {};
30576     imb.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
30577     imb.pNext = nullptr;
30578     imb.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
30579     imb.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
30580     imb.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
30581     imb.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
30582     imb.srcQueueFamilyIndex = 0;
30583     imb.dstQueueFamilyIndex = 0;
30584     imb.image = image.handle();
30585     imb.subresourceRange.aspectMask = 0x6;
30586     imb.subresourceRange.baseMipLevel = 0;
30587     imb.subresourceRange.levelCount = 0x1;
30588     imb.subresourceRange.baseArrayLayer = 0;
30589     imb.subresourceRange.layerCount = 0x1;
30590 
30591     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
30592                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &imb);
30593 
30594     m_commandBuffer->end();
30595     m_commandBuffer->QueueCommandBuffer(false);
30596     m_errorMonitor->VerifyNotFound();
30597 
30598     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
30599     vkDestroyRenderPass(m_device->device(), rp, nullptr);
30600     vkDestroyImageView(m_device->device(), view, nullptr);
30601 }
30602 
30603 // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,BarrierLayoutToImageUsage)30604 TEST_F(VkPositiveLayerTest, BarrierLayoutToImageUsage) {
30605     TEST_DESCRIPTION("Ensure barriers' new and old VkImageLayout are compatible with their images' VkImageUsageFlags");
30606 
30607     m_errorMonitor->ExpectSuccess();
30608 
30609     ASSERT_NO_FATAL_FAILURE(Init());
30610     auto depth_format = FindSupportedDepthStencilFormat(gpu());
30611     if (!depth_format) {
30612         printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
30613         return;
30614     }
30615     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
30616 
30617     VkImageMemoryBarrier img_barrier = {};
30618     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
30619     img_barrier.pNext = NULL;
30620     img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
30621     img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
30622     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
30623     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
30624     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
30625     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
30626     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
30627     img_barrier.subresourceRange.baseArrayLayer = 0;
30628     img_barrier.subresourceRange.baseMipLevel = 0;
30629     img_barrier.subresourceRange.layerCount = 1;
30630     img_barrier.subresourceRange.levelCount = 1;
30631 
30632     {
30633         VkImageObj img_color(m_device);
30634         img_color.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
30635         ASSERT_TRUE(img_color.initialized());
30636 
30637         VkImageObj img_ds1(m_device);
30638         img_ds1.Init(128, 128, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
30639         ASSERT_TRUE(img_ds1.initialized());
30640 
30641         VkImageObj img_ds2(m_device);
30642         img_ds2.Init(128, 128, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
30643         ASSERT_TRUE(img_ds2.initialized());
30644 
30645         VkImageObj img_xfer_src(m_device);
30646         img_xfer_src.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL);
30647         ASSERT_TRUE(img_xfer_src.initialized());
30648 
30649         VkImageObj img_xfer_dst(m_device);
30650         img_xfer_dst.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
30651         ASSERT_TRUE(img_xfer_dst.initialized());
30652 
30653         VkImageObj img_sampled(m_device);
30654         img_sampled.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL);
30655         ASSERT_TRUE(img_sampled.initialized());
30656 
30657         VkImageObj img_input(m_device);
30658         img_input.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
30659         ASSERT_TRUE(img_input.initialized());
30660 
30661         const struct {
30662             VkImageObj &image_obj;
30663             VkImageLayout old_layout;
30664             VkImageLayout new_layout;
30665         } buffer_layouts[] = {
30666             // clang-format off
30667             {img_color,    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,         VK_IMAGE_LAYOUT_GENERAL},
30668             {img_ds1,      VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL},
30669             {img_ds2,      VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,  VK_IMAGE_LAYOUT_GENERAL},
30670             {img_sampled,  VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,         VK_IMAGE_LAYOUT_GENERAL},
30671             {img_input,    VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,         VK_IMAGE_LAYOUT_GENERAL},
30672             {img_xfer_src, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,             VK_IMAGE_LAYOUT_GENERAL},
30673             {img_xfer_dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,             VK_IMAGE_LAYOUT_GENERAL},
30674             // clang-format on
30675         };
30676         const uint32_t layout_count = sizeof(buffer_layouts) / sizeof(buffer_layouts[0]);
30677 
30678         m_commandBuffer->begin();
30679         for (uint32_t i = 0; i < layout_count; ++i) {
30680             img_barrier.image = buffer_layouts[i].image_obj.handle();
30681             const VkImageUsageFlags usage = buffer_layouts[i].image_obj.usage();
30682             img_barrier.subresourceRange.aspectMask = (usage == VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
30683                                                           ? (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)
30684                                                           : VK_IMAGE_ASPECT_COLOR_BIT;
30685 
30686             img_barrier.oldLayout = buffer_layouts[i].old_layout;
30687             img_barrier.newLayout = buffer_layouts[i].new_layout;
30688             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
30689                                  nullptr, 0, nullptr, 1, &img_barrier);
30690 
30691             img_barrier.oldLayout = buffer_layouts[i].new_layout;
30692             img_barrier.newLayout = buffer_layouts[i].old_layout;
30693             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
30694                                  nullptr, 0, nullptr, 1, &img_barrier);
30695         }
30696         m_commandBuffer->end();
30697 
30698         img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
30699         img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
30700     }
30701     m_errorMonitor->VerifyNotFound();
30702 }
30703 
30704 // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,WaitEventThenSet)30705 TEST_F(VkPositiveLayerTest, WaitEventThenSet) {
30706     TEST_DESCRIPTION("Wait on a event then set it after the wait has been submitted.");
30707 
30708     m_errorMonitor->ExpectSuccess();
30709     ASSERT_NO_FATAL_FAILURE(Init());
30710 
30711     VkEvent event;
30712     VkEventCreateInfo event_create_info{};
30713     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
30714     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
30715 
30716     VkCommandPool command_pool;
30717     VkCommandPoolCreateInfo pool_create_info{};
30718     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
30719     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
30720     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
30721     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
30722 
30723     VkCommandBuffer command_buffer;
30724     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
30725     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
30726     command_buffer_allocate_info.commandPool = command_pool;
30727     command_buffer_allocate_info.commandBufferCount = 1;
30728     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
30729     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
30730 
30731     VkQueue queue = VK_NULL_HANDLE;
30732     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
30733 
30734     {
30735         VkCommandBufferBeginInfo begin_info{};
30736         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
30737         vkBeginCommandBuffer(command_buffer, &begin_info);
30738 
30739         vkCmdWaitEvents(command_buffer, 1, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0,
30740                         nullptr, 0, nullptr);
30741         vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
30742         vkEndCommandBuffer(command_buffer);
30743     }
30744     {
30745         VkSubmitInfo submit_info{};
30746         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
30747         submit_info.commandBufferCount = 1;
30748         submit_info.pCommandBuffers = &command_buffer;
30749         submit_info.signalSemaphoreCount = 0;
30750         submit_info.pSignalSemaphores = nullptr;
30751         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
30752     }
30753     { vkSetEvent(m_device->device(), event); }
30754 
30755     vkQueueWaitIdle(queue);
30756 
30757     vkDestroyEvent(m_device->device(), event, nullptr);
30758     vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
30759     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
30760 
30761     m_errorMonitor->VerifyNotFound();
30762 }
30763 // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,QueryAndCopySecondaryCommandBuffers)30764 TEST_F(VkPositiveLayerTest, QueryAndCopySecondaryCommandBuffers) {
30765     TEST_DESCRIPTION("Issue a query on a secondary command buffer and copy it on a primary.");
30766 
30767     ASSERT_NO_FATAL_FAILURE(Init());
30768     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
30769         printf("%s Queue family needs to have multiple queues to run this test.\n", kSkipPrefix);
30770         return;
30771     }
30772 
30773     m_errorMonitor->ExpectSuccess();
30774 
30775     VkQueryPool query_pool;
30776     VkQueryPoolCreateInfo query_pool_create_info{};
30777     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
30778     query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
30779     query_pool_create_info.queryCount = 1;
30780     vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
30781 
30782     VkCommandPoolObj command_pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
30783     VkCommandBufferObj primary_buffer(m_device, &command_pool);
30784     VkCommandBufferObj secondary_buffer(m_device, &command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
30785 
30786     VkQueue queue = VK_NULL_HANDLE;
30787     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
30788 
30789     uint32_t qfi = 0;
30790     VkBufferCreateInfo buff_create_info = {};
30791     buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
30792     buff_create_info.size = 1024;
30793     buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
30794     buff_create_info.queueFamilyIndexCount = 1;
30795     buff_create_info.pQueueFamilyIndices = &qfi;
30796 
30797     VkResult err;
30798     VkBuffer buffer;
30799     err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer);
30800     ASSERT_VK_SUCCESS(err);
30801 
30802     VkMemoryRequirements memReqs;
30803     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
30804     VkMemoryAllocateInfo mem_alloc = {};
30805     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
30806     mem_alloc.pNext = NULL;
30807     mem_alloc.allocationSize = memReqs.size;
30808     mem_alloc.memoryTypeIndex = 0;
30809     bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
30810     if (!pass) {
30811         printf("%s Failed to allocate memory.\n", kSkipPrefix);
30812         vkDestroyBuffer(m_device->device(), buffer, NULL);
30813         return;
30814     }
30815 
30816     VkDeviceMemory mem;
30817     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
30818     ASSERT_VK_SUCCESS(err);
30819     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
30820     ASSERT_VK_SUCCESS(err);
30821 
30822     VkCommandBufferInheritanceInfo hinfo = {};
30823     hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
30824     hinfo.renderPass = VK_NULL_HANDLE;
30825     hinfo.subpass = 0;
30826     hinfo.framebuffer = VK_NULL_HANDLE;
30827     hinfo.occlusionQueryEnable = VK_FALSE;
30828     hinfo.queryFlags = 0;
30829     hinfo.pipelineStatistics = 0;
30830 
30831     {
30832         VkCommandBufferBeginInfo begin_info{};
30833         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
30834         begin_info.pInheritanceInfo = &hinfo;
30835         secondary_buffer.begin(&begin_info);
30836         vkCmdResetQueryPool(secondary_buffer.handle(), query_pool, 0, 1);
30837         vkCmdWriteTimestamp(secondary_buffer.handle(), VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
30838         secondary_buffer.end();
30839 
30840         primary_buffer.begin();
30841         vkCmdExecuteCommands(primary_buffer.handle(), 1, &secondary_buffer.handle());
30842         vkCmdCopyQueryPoolResults(primary_buffer.handle(), query_pool, 0, 1, buffer, 0, 0, 0);
30843         primary_buffer.end();
30844     }
30845 
30846     primary_buffer.QueueCommandBuffer();
30847     vkQueueWaitIdle(queue);
30848 
30849     vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
30850     vkDestroyBuffer(m_device->device(), buffer, NULL);
30851     vkFreeMemory(m_device->device(), mem, NULL);
30852 
30853     m_errorMonitor->VerifyNotFound();
30854 }
30855 
30856 // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,QueryAndCopyMultipleCommandBuffers)30857 TEST_F(VkPositiveLayerTest, QueryAndCopyMultipleCommandBuffers) {
30858     TEST_DESCRIPTION("Issue a query and copy from it on a second command buffer.");
30859 
30860     ASSERT_NO_FATAL_FAILURE(Init());
30861     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
30862         printf("%s Queue family needs to have multiple queues to run this test.\n", kSkipPrefix);
30863         return;
30864     }
30865 
30866     m_errorMonitor->ExpectSuccess();
30867 
30868     VkQueryPool query_pool;
30869     VkQueryPoolCreateInfo query_pool_create_info{};
30870     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
30871     query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
30872     query_pool_create_info.queryCount = 1;
30873     vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
30874 
30875     VkCommandPool command_pool;
30876     VkCommandPoolCreateInfo pool_create_info{};
30877     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
30878     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
30879     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
30880     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
30881 
30882     VkCommandBuffer command_buffer[2];
30883     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
30884     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
30885     command_buffer_allocate_info.commandPool = command_pool;
30886     command_buffer_allocate_info.commandBufferCount = 2;
30887     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
30888     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
30889 
30890     VkQueue queue = VK_NULL_HANDLE;
30891     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
30892 
30893     uint32_t qfi = 0;
30894     VkBufferCreateInfo buff_create_info = {};
30895     buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
30896     buff_create_info.size = 1024;
30897     buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
30898     buff_create_info.queueFamilyIndexCount = 1;
30899     buff_create_info.pQueueFamilyIndices = &qfi;
30900 
30901     VkResult err;
30902     VkBuffer buffer;
30903     err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer);
30904     ASSERT_VK_SUCCESS(err);
30905 
30906     VkMemoryRequirements memReqs;
30907     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
30908     VkMemoryAllocateInfo mem_alloc = {};
30909     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
30910     mem_alloc.pNext = NULL;
30911     mem_alloc.allocationSize = memReqs.size;
30912     mem_alloc.memoryTypeIndex = 0;
30913     bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
30914     if (!pass) {
30915         vkDestroyBuffer(m_device->device(), buffer, NULL);
30916         return;
30917     }
30918 
30919     VkDeviceMemory mem;
30920     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
30921     ASSERT_VK_SUCCESS(err);
30922     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
30923     ASSERT_VK_SUCCESS(err);
30924 
30925     {
30926         VkCommandBufferBeginInfo begin_info{};
30927         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
30928         vkBeginCommandBuffer(command_buffer[0], &begin_info);
30929 
30930         vkCmdResetQueryPool(command_buffer[0], query_pool, 0, 1);
30931         vkCmdWriteTimestamp(command_buffer[0], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
30932 
30933         vkEndCommandBuffer(command_buffer[0]);
30934 
30935         vkBeginCommandBuffer(command_buffer[1], &begin_info);
30936 
30937         vkCmdCopyQueryPoolResults(command_buffer[1], query_pool, 0, 1, buffer, 0, 0, 0);
30938 
30939         vkEndCommandBuffer(command_buffer[1]);
30940     }
30941     {
30942         VkSubmitInfo submit_info{};
30943         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
30944         submit_info.commandBufferCount = 2;
30945         submit_info.pCommandBuffers = command_buffer;
30946         submit_info.signalSemaphoreCount = 0;
30947         submit_info.pSignalSemaphores = nullptr;
30948         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
30949     }
30950 
30951     vkQueueWaitIdle(queue);
30952 
30953     vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
30954     vkFreeCommandBuffers(m_device->device(), command_pool, 2, command_buffer);
30955     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
30956     vkDestroyBuffer(m_device->device(), buffer, NULL);
30957     vkFreeMemory(m_device->device(), mem, NULL);
30958 
30959     m_errorMonitor->VerifyNotFound();
30960 }
30961 
TEST_F(VkLayerTest,ResetEventThenSet)30962 TEST_F(VkLayerTest, ResetEventThenSet) {
30963     TEST_DESCRIPTION("Reset an event then set it after the reset has been submitted.");
30964 
30965     ASSERT_NO_FATAL_FAILURE(Init());
30966     VkEvent event;
30967     VkEventCreateInfo event_create_info{};
30968     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
30969     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
30970 
30971     VkCommandPool command_pool;
30972     VkCommandPoolCreateInfo pool_create_info{};
30973     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
30974     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
30975     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
30976     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
30977 
30978     VkCommandBuffer command_buffer;
30979     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
30980     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
30981     command_buffer_allocate_info.commandPool = command_pool;
30982     command_buffer_allocate_info.commandBufferCount = 1;
30983     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
30984     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
30985 
30986     VkQueue queue = VK_NULL_HANDLE;
30987     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
30988 
30989     {
30990         VkCommandBufferBeginInfo begin_info{};
30991         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
30992         vkBeginCommandBuffer(command_buffer, &begin_info);
30993 
30994         vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
30995         vkEndCommandBuffer(command_buffer);
30996     }
30997     {
30998         VkSubmitInfo submit_info{};
30999         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
31000         submit_info.commandBufferCount = 1;
31001         submit_info.pCommandBuffers = &command_buffer;
31002         submit_info.signalSemaphoreCount = 0;
31003         submit_info.pSignalSemaphores = nullptr;
31004         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
31005     }
31006     {
31007         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is already in use by a command buffer.");
31008         vkSetEvent(m_device->device(), event);
31009         m_errorMonitor->VerifyFound();
31010     }
31011 
31012     vkQueueWaitIdle(queue);
31013 
31014     vkDestroyEvent(m_device->device(), event, nullptr);
31015     vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
31016     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
31017 }
31018 
31019 // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,TwoFencesThreeFrames)31020 TEST_F(VkPositiveLayerTest, TwoFencesThreeFrames) {
31021     TEST_DESCRIPTION(
31022         "Two command buffers with two separate fences are each run through a Submit & WaitForFences cycle 3 times. This previously "
31023         "revealed a bug so running this positive test to prevent a regression.");
31024     m_errorMonitor->ExpectSuccess();
31025 
31026     ASSERT_NO_FATAL_FAILURE(Init());
31027     VkQueue queue = VK_NULL_HANDLE;
31028     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
31029 
31030     static const uint32_t NUM_OBJECTS = 2;
31031     static const uint32_t NUM_FRAMES = 3;
31032     VkCommandBuffer cmd_buffers[NUM_OBJECTS] = {};
31033     VkFence fences[NUM_OBJECTS] = {};
31034 
31035     VkCommandPool cmd_pool;
31036     VkCommandPoolCreateInfo cmd_pool_ci = {};
31037     cmd_pool_ci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
31038     cmd_pool_ci.queueFamilyIndex = m_device->graphics_queue_node_index_;
31039     cmd_pool_ci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
31040     VkResult err = vkCreateCommandPool(m_device->device(), &cmd_pool_ci, nullptr, &cmd_pool);
31041     ASSERT_VK_SUCCESS(err);
31042 
31043     VkCommandBufferAllocateInfo cmd_buf_info = {};
31044     cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
31045     cmd_buf_info.commandPool = cmd_pool;
31046     cmd_buf_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
31047     cmd_buf_info.commandBufferCount = 1;
31048 
31049     VkFenceCreateInfo fence_ci = {};
31050     fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
31051     fence_ci.pNext = nullptr;
31052     fence_ci.flags = 0;
31053 
31054     for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
31055         err = vkAllocateCommandBuffers(m_device->device(), &cmd_buf_info, &cmd_buffers[i]);
31056         ASSERT_VK_SUCCESS(err);
31057         err = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fences[i]);
31058         ASSERT_VK_SUCCESS(err);
31059     }
31060 
31061     for (uint32_t frame = 0; frame < NUM_FRAMES; ++frame) {
31062         for (uint32_t obj = 0; obj < NUM_OBJECTS; ++obj) {
31063             // Create empty cmd buffer
31064             VkCommandBufferBeginInfo cmdBufBeginDesc = {};
31065             cmdBufBeginDesc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
31066 
31067             err = vkBeginCommandBuffer(cmd_buffers[obj], &cmdBufBeginDesc);
31068             ASSERT_VK_SUCCESS(err);
31069             err = vkEndCommandBuffer(cmd_buffers[obj]);
31070             ASSERT_VK_SUCCESS(err);
31071 
31072             VkSubmitInfo submit_info = {};
31073             submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
31074             submit_info.commandBufferCount = 1;
31075             submit_info.pCommandBuffers = &cmd_buffers[obj];
31076             // Submit cmd buffer and wait for fence
31077             err = vkQueueSubmit(queue, 1, &submit_info, fences[obj]);
31078             ASSERT_VK_SUCCESS(err);
31079             err = vkWaitForFences(m_device->device(), 1, &fences[obj], VK_TRUE, UINT64_MAX);
31080             ASSERT_VK_SUCCESS(err);
31081             err = vkResetFences(m_device->device(), 1, &fences[obj]);
31082             ASSERT_VK_SUCCESS(err);
31083         }
31084     }
31085     m_errorMonitor->VerifyNotFound();
31086     vkDestroyCommandPool(m_device->device(), cmd_pool, NULL);
31087     for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
31088         vkDestroyFence(m_device->device(), fences[i], nullptr);
31089     }
31090 }
31091 // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWI)31092 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWI) {
31093     TEST_DESCRIPTION(
31094         "Two command buffers, each in a separate QueueSubmit call submitted on separate queues followed by a QueueWaitIdle.");
31095 
31096     ASSERT_NO_FATAL_FAILURE(Init());
31097     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
31098         printf("%s Queue family needs to have multiple queues to run this test.\n", kSkipPrefix);
31099         return;
31100     }
31101 
31102     m_errorMonitor->ExpectSuccess();
31103 
31104     VkSemaphore semaphore;
31105     VkSemaphoreCreateInfo semaphore_create_info{};
31106     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
31107     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
31108 
31109     VkCommandPool command_pool;
31110     VkCommandPoolCreateInfo pool_create_info{};
31111     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
31112     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
31113     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
31114     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
31115 
31116     VkCommandBuffer command_buffer[2];
31117     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
31118     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
31119     command_buffer_allocate_info.commandPool = command_pool;
31120     command_buffer_allocate_info.commandBufferCount = 2;
31121     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
31122     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
31123 
31124     VkQueue queue = VK_NULL_HANDLE;
31125     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
31126 
31127     {
31128         VkCommandBufferBeginInfo begin_info{};
31129         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
31130         vkBeginCommandBuffer(command_buffer[0], &begin_info);
31131 
31132         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
31133                              nullptr, 0, nullptr, 0, nullptr);
31134 
31135         VkViewport viewport{};
31136         viewport.maxDepth = 1.0f;
31137         viewport.minDepth = 0.0f;
31138         viewport.width = 512;
31139         viewport.height = 512;
31140         viewport.x = 0;
31141         viewport.y = 0;
31142         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
31143         vkEndCommandBuffer(command_buffer[0]);
31144     }
31145     {
31146         VkCommandBufferBeginInfo begin_info{};
31147         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
31148         vkBeginCommandBuffer(command_buffer[1], &begin_info);
31149 
31150         VkViewport viewport{};
31151         viewport.maxDepth = 1.0f;
31152         viewport.minDepth = 0.0f;
31153         viewport.width = 512;
31154         viewport.height = 512;
31155         viewport.x = 0;
31156         viewport.y = 0;
31157         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
31158         vkEndCommandBuffer(command_buffer[1]);
31159     }
31160     {
31161         VkSubmitInfo submit_info{};
31162         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
31163         submit_info.commandBufferCount = 1;
31164         submit_info.pCommandBuffers = &command_buffer[0];
31165         submit_info.signalSemaphoreCount = 1;
31166         submit_info.pSignalSemaphores = &semaphore;
31167         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
31168     }
31169     {
31170         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
31171         VkSubmitInfo submit_info{};
31172         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
31173         submit_info.commandBufferCount = 1;
31174         submit_info.pCommandBuffers = &command_buffer[1];
31175         submit_info.waitSemaphoreCount = 1;
31176         submit_info.pWaitSemaphores = &semaphore;
31177         submit_info.pWaitDstStageMask = flags;
31178         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
31179     }
31180 
31181     vkQueueWaitIdle(m_device->m_queue);
31182 
31183     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
31184     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
31185     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
31186 
31187     m_errorMonitor->VerifyNotFound();
31188 }
31189 
31190 // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWIFence)31191 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWIFence) {
31192     TEST_DESCRIPTION(
31193         "Two command buffers, each in a separate QueueSubmit call submitted on separate queues, the second having a fence followed "
31194         "by a QueueWaitIdle.");
31195 
31196     ASSERT_NO_FATAL_FAILURE(Init());
31197     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
31198         printf("%s Queue family needs to have multiple queues to run this test.\n", kSkipPrefix);
31199         return;
31200     }
31201 
31202     m_errorMonitor->ExpectSuccess();
31203 
31204     VkFence fence;
31205     VkFenceCreateInfo fence_create_info{};
31206     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
31207     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
31208 
31209     VkSemaphore semaphore;
31210     VkSemaphoreCreateInfo semaphore_create_info{};
31211     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
31212     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
31213 
31214     VkCommandPool command_pool;
31215     VkCommandPoolCreateInfo pool_create_info{};
31216     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
31217     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
31218     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
31219     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
31220 
31221     VkCommandBuffer command_buffer[2];
31222     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
31223     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
31224     command_buffer_allocate_info.commandPool = command_pool;
31225     command_buffer_allocate_info.commandBufferCount = 2;
31226     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
31227     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
31228 
31229     VkQueue queue = VK_NULL_HANDLE;
31230     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
31231 
31232     {
31233         VkCommandBufferBeginInfo begin_info{};
31234         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
31235         vkBeginCommandBuffer(command_buffer[0], &begin_info);
31236 
31237         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
31238                              nullptr, 0, nullptr, 0, nullptr);
31239 
31240         VkViewport viewport{};
31241         viewport.maxDepth = 1.0f;
31242         viewport.minDepth = 0.0f;
31243         viewport.width = 512;
31244         viewport.height = 512;
31245         viewport.x = 0;
31246         viewport.y = 0;
31247         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
31248         vkEndCommandBuffer(command_buffer[0]);
31249     }
31250     {
31251         VkCommandBufferBeginInfo begin_info{};
31252         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
31253         vkBeginCommandBuffer(command_buffer[1], &begin_info);
31254 
31255         VkViewport viewport{};
31256         viewport.maxDepth = 1.0f;
31257         viewport.minDepth = 0.0f;
31258         viewport.width = 512;
31259         viewport.height = 512;
31260         viewport.x = 0;
31261         viewport.y = 0;
31262         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
31263         vkEndCommandBuffer(command_buffer[1]);
31264     }
31265     {
31266         VkSubmitInfo submit_info{};
31267         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
31268         submit_info.commandBufferCount = 1;
31269         submit_info.pCommandBuffers = &command_buffer[0];
31270         submit_info.signalSemaphoreCount = 1;
31271         submit_info.pSignalSemaphores = &semaphore;
31272         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
31273     }
31274     {
31275         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
31276         VkSubmitInfo submit_info{};
31277         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
31278         submit_info.commandBufferCount = 1;
31279         submit_info.pCommandBuffers = &command_buffer[1];
31280         submit_info.waitSemaphoreCount = 1;
31281         submit_info.pWaitSemaphores = &semaphore;
31282         submit_info.pWaitDstStageMask = flags;
31283         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
31284     }
31285 
31286     vkQueueWaitIdle(m_device->m_queue);
31287 
31288     vkDestroyFence(m_device->device(), fence, nullptr);
31289     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
31290     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
31291     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
31292 
31293     m_errorMonitor->VerifyNotFound();
31294 }
31295 
31296 // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceTwoWFF)31297 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceTwoWFF) {
31298     TEST_DESCRIPTION(
31299         "Two command buffers, each in a separate QueueSubmit call submitted on separate queues, the second having a fence followed "
31300         "by two consecutive WaitForFences calls on the same fence.");
31301 
31302     ASSERT_NO_FATAL_FAILURE(Init());
31303     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
31304         printf("%s Queue family needs to have multiple queues to run this test.\n", kSkipPrefix);
31305         return;
31306     }
31307 
31308     m_errorMonitor->ExpectSuccess();
31309 
31310     VkFence fence;
31311     VkFenceCreateInfo fence_create_info{};
31312     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
31313     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
31314 
31315     VkSemaphore semaphore;
31316     VkSemaphoreCreateInfo semaphore_create_info{};
31317     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
31318     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
31319 
31320     VkCommandPool command_pool;
31321     VkCommandPoolCreateInfo pool_create_info{};
31322     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
31323     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
31324     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
31325     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
31326 
31327     VkCommandBuffer command_buffer[2];
31328     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
31329     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
31330     command_buffer_allocate_info.commandPool = command_pool;
31331     command_buffer_allocate_info.commandBufferCount = 2;
31332     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
31333     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
31334 
31335     VkQueue queue = VK_NULL_HANDLE;
31336     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
31337 
31338     {
31339         VkCommandBufferBeginInfo begin_info{};
31340         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
31341         vkBeginCommandBuffer(command_buffer[0], &begin_info);
31342 
31343         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
31344                              nullptr, 0, nullptr, 0, nullptr);
31345 
31346         VkViewport viewport{};
31347         viewport.maxDepth = 1.0f;
31348         viewport.minDepth = 0.0f;
31349         viewport.width = 512;
31350         viewport.height = 512;
31351         viewport.x = 0;
31352         viewport.y = 0;
31353         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
31354         vkEndCommandBuffer(command_buffer[0]);
31355     }
31356     {
31357         VkCommandBufferBeginInfo begin_info{};
31358         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
31359         vkBeginCommandBuffer(command_buffer[1], &begin_info);
31360 
31361         VkViewport viewport{};
31362         viewport.maxDepth = 1.0f;
31363         viewport.minDepth = 0.0f;
31364         viewport.width = 512;
31365         viewport.height = 512;
31366         viewport.x = 0;
31367         viewport.y = 0;
31368         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
31369         vkEndCommandBuffer(command_buffer[1]);
31370     }
31371     {
31372         VkSubmitInfo submit_info{};
31373         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
31374         submit_info.commandBufferCount = 1;
31375         submit_info.pCommandBuffers = &command_buffer[0];
31376         submit_info.signalSemaphoreCount = 1;
31377         submit_info.pSignalSemaphores = &semaphore;
31378         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
31379     }
31380     {
31381         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
31382         VkSubmitInfo submit_info{};
31383         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
31384         submit_info.commandBufferCount = 1;
31385         submit_info.pCommandBuffers = &command_buffer[1];
31386         submit_info.waitSemaphoreCount = 1;
31387         submit_info.pWaitSemaphores = &semaphore;
31388         submit_info.pWaitDstStageMask = flags;
31389         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
31390     }
31391 
31392     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
31393     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
31394 
31395     vkDestroyFence(m_device->device(), fence, nullptr);
31396     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
31397     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
31398     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
31399 
31400     m_errorMonitor->VerifyNotFound();
31401 }
31402 
TEST_F(VkPositiveLayerTest,TwoQueuesEnsureCorrectRetirementWithWorkStolen)31403 TEST_F(VkPositiveLayerTest, TwoQueuesEnsureCorrectRetirementWithWorkStolen) {
31404     ASSERT_NO_FATAL_FAILURE(Init());
31405     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
31406         printf("%s Test requires two queues, skipping\n", kSkipPrefix);
31407         return;
31408     }
31409 
31410     VkResult err;
31411 
31412     m_errorMonitor->ExpectSuccess();
31413 
31414     VkQueue q0 = m_device->m_queue;
31415     VkQueue q1 = nullptr;
31416     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &q1);
31417     ASSERT_NE(q1, nullptr);
31418 
31419     // An (empty) command buffer. We must have work in the first submission --
31420     // the layer treats unfenced work differently from fenced work.
31421     VkCommandPoolCreateInfo cpci = {VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, nullptr, 0, 0};
31422     VkCommandPool pool;
31423     err = vkCreateCommandPool(m_device->device(), &cpci, nullptr, &pool);
31424     ASSERT_VK_SUCCESS(err);
31425     VkCommandBufferAllocateInfo cbai = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, nullptr, pool,
31426                                         VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1};
31427     VkCommandBuffer cb;
31428     err = vkAllocateCommandBuffers(m_device->device(), &cbai, &cb);
31429     ASSERT_VK_SUCCESS(err);
31430     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, nullptr};
31431     err = vkBeginCommandBuffer(cb, &cbbi);
31432     ASSERT_VK_SUCCESS(err);
31433     err = vkEndCommandBuffer(cb);
31434     ASSERT_VK_SUCCESS(err);
31435 
31436     // A semaphore
31437     VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
31438     VkSemaphore s;
31439     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s);
31440     ASSERT_VK_SUCCESS(err);
31441 
31442     // First submission, to q0
31443     VkSubmitInfo s0 = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &cb, 1, &s};
31444 
31445     err = vkQueueSubmit(q0, 1, &s0, VK_NULL_HANDLE);
31446     ASSERT_VK_SUCCESS(err);
31447 
31448     // Second submission, to q1, waiting on s
31449     VkFlags waitmask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;  // doesn't really matter what this value is.
31450     VkSubmitInfo s1 = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &s, &waitmask, 0, nullptr, 0, nullptr};
31451 
31452     err = vkQueueSubmit(q1, 1, &s1, VK_NULL_HANDLE);
31453     ASSERT_VK_SUCCESS(err);
31454 
31455     // Wait for q0 idle
31456     err = vkQueueWaitIdle(q0);
31457     ASSERT_VK_SUCCESS(err);
31458 
31459     // Command buffer should have been completed (it was on q0); reset the pool.
31460     vkFreeCommandBuffers(m_device->device(), pool, 1, &cb);
31461 
31462     m_errorMonitor->VerifyNotFound();
31463 
31464     // Force device completely idle and clean up resources
31465     vkDeviceWaitIdle(m_device->device());
31466     vkDestroyCommandPool(m_device->device(), pool, nullptr);
31467     vkDestroySemaphore(m_device->device(), s, nullptr);
31468 }
31469 
31470 // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFence)31471 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFence) {
31472     TEST_DESCRIPTION(
31473         "Two command buffers, each in a separate QueueSubmit call submitted on separate queues, the second having a fence, "
31474         "followed by a WaitForFences call.");
31475 
31476     ASSERT_NO_FATAL_FAILURE(Init());
31477     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
31478         printf("%s Queue family needs to have multiple queues to run this test.\n", kSkipPrefix);
31479         return;
31480     }
31481 
31482     m_errorMonitor->ExpectSuccess();
31483 
31484     VkFence fence;
31485     VkFenceCreateInfo fence_create_info{};
31486     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
31487     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
31488 
31489     VkSemaphore semaphore;
31490     VkSemaphoreCreateInfo semaphore_create_info{};
31491     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
31492     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
31493 
31494     VkCommandPool command_pool;
31495     VkCommandPoolCreateInfo pool_create_info{};
31496     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
31497     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
31498     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
31499     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
31500 
31501     VkCommandBuffer command_buffer[2];
31502     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
31503     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
31504     command_buffer_allocate_info.commandPool = command_pool;
31505     command_buffer_allocate_info.commandBufferCount = 2;
31506     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
31507     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
31508 
31509     VkQueue queue = VK_NULL_HANDLE;
31510     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
31511 
31512     {
31513         VkCommandBufferBeginInfo begin_info{};
31514         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
31515         vkBeginCommandBuffer(command_buffer[0], &begin_info);
31516 
31517         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
31518                              nullptr, 0, nullptr, 0, nullptr);
31519 
31520         VkViewport viewport{};
31521         viewport.maxDepth = 1.0f;
31522         viewport.minDepth = 0.0f;
31523         viewport.width = 512;
31524         viewport.height = 512;
31525         viewport.x = 0;
31526         viewport.y = 0;
31527         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
31528         vkEndCommandBuffer(command_buffer[0]);
31529     }
31530     {
31531         VkCommandBufferBeginInfo begin_info{};
31532         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
31533         vkBeginCommandBuffer(command_buffer[1], &begin_info);
31534 
31535         VkViewport viewport{};
31536         viewport.maxDepth = 1.0f;
31537         viewport.minDepth = 0.0f;
31538         viewport.width = 512;
31539         viewport.height = 512;
31540         viewport.x = 0;
31541         viewport.y = 0;
31542         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
31543         vkEndCommandBuffer(command_buffer[1]);
31544     }
31545     {
31546         VkSubmitInfo submit_info{};
31547         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
31548         submit_info.commandBufferCount = 1;
31549         submit_info.pCommandBuffers = &command_buffer[0];
31550         submit_info.signalSemaphoreCount = 1;
31551         submit_info.pSignalSemaphores = &semaphore;
31552         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
31553     }
31554     {
31555         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
31556         VkSubmitInfo submit_info{};
31557         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
31558         submit_info.commandBufferCount = 1;
31559         submit_info.pCommandBuffers = &command_buffer[1];
31560         submit_info.waitSemaphoreCount = 1;
31561         submit_info.pWaitSemaphores = &semaphore;
31562         submit_info.pWaitDstStageMask = flags;
31563         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
31564     }
31565 
31566     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
31567 
31568     vkDestroyFence(m_device->device(), fence, nullptr);
31569     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
31570     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
31571     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
31572 
31573     m_errorMonitor->VerifyNotFound();
31574 }
31575 
31576 // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,TwoQueueSubmitsOneQueueWithSemaphoreAndOneFence)31577 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsOneQueueWithSemaphoreAndOneFence) {
31578     TEST_DESCRIPTION(
31579         "Two command buffers, each in a separate QueueSubmit call on the same queue, sharing a signal/wait semaphore, the second "
31580         "having a fence, followed by a WaitForFences call.");
31581 
31582     m_errorMonitor->ExpectSuccess();
31583 
31584     ASSERT_NO_FATAL_FAILURE(Init());
31585     VkFence fence;
31586     VkFenceCreateInfo fence_create_info{};
31587     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
31588     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
31589 
31590     VkSemaphore semaphore;
31591     VkSemaphoreCreateInfo semaphore_create_info{};
31592     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
31593     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
31594 
31595     VkCommandPool command_pool;
31596     VkCommandPoolCreateInfo pool_create_info{};
31597     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
31598     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
31599     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
31600     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
31601 
31602     VkCommandBuffer command_buffer[2];
31603     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
31604     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
31605     command_buffer_allocate_info.commandPool = command_pool;
31606     command_buffer_allocate_info.commandBufferCount = 2;
31607     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
31608     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
31609 
31610     {
31611         VkCommandBufferBeginInfo begin_info{};
31612         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
31613         vkBeginCommandBuffer(command_buffer[0], &begin_info);
31614 
31615         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
31616                              nullptr, 0, nullptr, 0, nullptr);
31617 
31618         VkViewport viewport{};
31619         viewport.maxDepth = 1.0f;
31620         viewport.minDepth = 0.0f;
31621         viewport.width = 512;
31622         viewport.height = 512;
31623         viewport.x = 0;
31624         viewport.y = 0;
31625         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
31626         vkEndCommandBuffer(command_buffer[0]);
31627     }
31628     {
31629         VkCommandBufferBeginInfo begin_info{};
31630         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
31631         vkBeginCommandBuffer(command_buffer[1], &begin_info);
31632 
31633         VkViewport viewport{};
31634         viewport.maxDepth = 1.0f;
31635         viewport.minDepth = 0.0f;
31636         viewport.width = 512;
31637         viewport.height = 512;
31638         viewport.x = 0;
31639         viewport.y = 0;
31640         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
31641         vkEndCommandBuffer(command_buffer[1]);
31642     }
31643     {
31644         VkSubmitInfo submit_info{};
31645         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
31646         submit_info.commandBufferCount = 1;
31647         submit_info.pCommandBuffers = &command_buffer[0];
31648         submit_info.signalSemaphoreCount = 1;
31649         submit_info.pSignalSemaphores = &semaphore;
31650         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
31651     }
31652     {
31653         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
31654         VkSubmitInfo submit_info{};
31655         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
31656         submit_info.commandBufferCount = 1;
31657         submit_info.pCommandBuffers = &command_buffer[1];
31658         submit_info.waitSemaphoreCount = 1;
31659         submit_info.pWaitSemaphores = &semaphore;
31660         submit_info.pWaitDstStageMask = flags;
31661         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
31662     }
31663 
31664     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
31665 
31666     vkDestroyFence(m_device->device(), fence, nullptr);
31667     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
31668     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
31669     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
31670 
31671     m_errorMonitor->VerifyNotFound();
31672 }
31673 
31674 // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,TwoQueueSubmitsOneQueueNullQueueSubmitWithFence)31675 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsOneQueueNullQueueSubmitWithFence) {
31676     TEST_DESCRIPTION(
31677         "Two command buffers, each in a separate QueueSubmit call on the same queue, no fences, followed by a third QueueSubmit "
31678         "with NO SubmitInfos but with a fence, followed by a WaitForFences call.");
31679 
31680     m_errorMonitor->ExpectSuccess();
31681 
31682     ASSERT_NO_FATAL_FAILURE(Init());
31683     VkFence fence;
31684     VkFenceCreateInfo fence_create_info{};
31685     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
31686     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
31687 
31688     VkCommandPool command_pool;
31689     VkCommandPoolCreateInfo pool_create_info{};
31690     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
31691     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
31692     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
31693     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
31694 
31695     VkCommandBuffer command_buffer[2];
31696     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
31697     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
31698     command_buffer_allocate_info.commandPool = command_pool;
31699     command_buffer_allocate_info.commandBufferCount = 2;
31700     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
31701     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
31702 
31703     {
31704         VkCommandBufferBeginInfo begin_info{};
31705         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
31706         vkBeginCommandBuffer(command_buffer[0], &begin_info);
31707 
31708         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
31709                              nullptr, 0, nullptr, 0, nullptr);
31710 
31711         VkViewport viewport{};
31712         viewport.maxDepth = 1.0f;
31713         viewport.minDepth = 0.0f;
31714         viewport.width = 512;
31715         viewport.height = 512;
31716         viewport.x = 0;
31717         viewport.y = 0;
31718         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
31719         vkEndCommandBuffer(command_buffer[0]);
31720     }
31721     {
31722         VkCommandBufferBeginInfo begin_info{};
31723         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
31724         vkBeginCommandBuffer(command_buffer[1], &begin_info);
31725 
31726         VkViewport viewport{};
31727         viewport.maxDepth = 1.0f;
31728         viewport.minDepth = 0.0f;
31729         viewport.width = 512;
31730         viewport.height = 512;
31731         viewport.x = 0;
31732         viewport.y = 0;
31733         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
31734         vkEndCommandBuffer(command_buffer[1]);
31735     }
31736     {
31737         VkSubmitInfo submit_info{};
31738         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
31739         submit_info.commandBufferCount = 1;
31740         submit_info.pCommandBuffers = &command_buffer[0];
31741         submit_info.signalSemaphoreCount = 0;
31742         submit_info.pSignalSemaphores = VK_NULL_HANDLE;
31743         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
31744     }
31745     {
31746         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
31747         VkSubmitInfo submit_info{};
31748         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
31749         submit_info.commandBufferCount = 1;
31750         submit_info.pCommandBuffers = &command_buffer[1];
31751         submit_info.waitSemaphoreCount = 0;
31752         submit_info.pWaitSemaphores = VK_NULL_HANDLE;
31753         submit_info.pWaitDstStageMask = flags;
31754         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
31755     }
31756 
31757     vkQueueSubmit(m_device->m_queue, 0, NULL, fence);
31758 
31759     VkResult err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
31760     ASSERT_VK_SUCCESS(err);
31761 
31762     vkDestroyFence(m_device->device(), fence, nullptr);
31763     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
31764     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
31765 
31766     m_errorMonitor->VerifyNotFound();
31767 }
31768 
31769 // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,TwoQueueSubmitsOneQueueOneFence)31770 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsOneQueueOneFence) {
31771     TEST_DESCRIPTION(
31772         "Two command buffers, each in a separate QueueSubmit call on the same queue, the second having a fence, followed by a "
31773         "WaitForFences call.");
31774 
31775     m_errorMonitor->ExpectSuccess();
31776 
31777     ASSERT_NO_FATAL_FAILURE(Init());
31778     VkFence fence;
31779     VkFenceCreateInfo fence_create_info{};
31780     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
31781     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
31782 
31783     VkCommandPool command_pool;
31784     VkCommandPoolCreateInfo pool_create_info{};
31785     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
31786     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
31787     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
31788     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
31789 
31790     VkCommandBuffer command_buffer[2];
31791     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
31792     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
31793     command_buffer_allocate_info.commandPool = command_pool;
31794     command_buffer_allocate_info.commandBufferCount = 2;
31795     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
31796     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
31797 
31798     {
31799         VkCommandBufferBeginInfo begin_info{};
31800         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
31801         vkBeginCommandBuffer(command_buffer[0], &begin_info);
31802 
31803         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
31804                              nullptr, 0, nullptr, 0, nullptr);
31805 
31806         VkViewport viewport{};
31807         viewport.maxDepth = 1.0f;
31808         viewport.minDepth = 0.0f;
31809         viewport.width = 512;
31810         viewport.height = 512;
31811         viewport.x = 0;
31812         viewport.y = 0;
31813         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
31814         vkEndCommandBuffer(command_buffer[0]);
31815     }
31816     {
31817         VkCommandBufferBeginInfo begin_info{};
31818         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
31819         vkBeginCommandBuffer(command_buffer[1], &begin_info);
31820 
31821         VkViewport viewport{};
31822         viewport.maxDepth = 1.0f;
31823         viewport.minDepth = 0.0f;
31824         viewport.width = 512;
31825         viewport.height = 512;
31826         viewport.x = 0;
31827         viewport.y = 0;
31828         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
31829         vkEndCommandBuffer(command_buffer[1]);
31830     }
31831     {
31832         VkSubmitInfo submit_info{};
31833         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
31834         submit_info.commandBufferCount = 1;
31835         submit_info.pCommandBuffers = &command_buffer[0];
31836         submit_info.signalSemaphoreCount = 0;
31837         submit_info.pSignalSemaphores = VK_NULL_HANDLE;
31838         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
31839     }
31840     {
31841         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
31842         VkSubmitInfo submit_info{};
31843         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
31844         submit_info.commandBufferCount = 1;
31845         submit_info.pCommandBuffers = &command_buffer[1];
31846         submit_info.waitSemaphoreCount = 0;
31847         submit_info.pWaitSemaphores = VK_NULL_HANDLE;
31848         submit_info.pWaitDstStageMask = flags;
31849         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
31850     }
31851 
31852     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
31853 
31854     vkDestroyFence(m_device->device(), fence, nullptr);
31855     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
31856     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
31857 
31858     m_errorMonitor->VerifyNotFound();
31859 }
31860 
31861 // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,TwoSubmitInfosWithSemaphoreOneQueueSubmitsOneFence)31862 TEST_F(VkPositiveLayerTest, TwoSubmitInfosWithSemaphoreOneQueueSubmitsOneFence) {
31863     TEST_DESCRIPTION(
31864         "Two command buffers each in a separate SubmitInfo sent in a single QueueSubmit call followed by a WaitForFences call.");
31865     ASSERT_NO_FATAL_FAILURE(Init());
31866 
31867     m_errorMonitor->ExpectSuccess();
31868 
31869     VkFence fence;
31870     VkFenceCreateInfo fence_create_info{};
31871     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
31872     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
31873 
31874     VkSemaphore semaphore;
31875     VkSemaphoreCreateInfo semaphore_create_info{};
31876     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
31877     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
31878 
31879     VkCommandPool command_pool;
31880     VkCommandPoolCreateInfo pool_create_info{};
31881     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
31882     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
31883     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
31884     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
31885 
31886     VkCommandBuffer command_buffer[2];
31887     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
31888     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
31889     command_buffer_allocate_info.commandPool = command_pool;
31890     command_buffer_allocate_info.commandBufferCount = 2;
31891     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
31892     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
31893 
31894     {
31895         VkCommandBufferBeginInfo begin_info{};
31896         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
31897         vkBeginCommandBuffer(command_buffer[0], &begin_info);
31898 
31899         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
31900                              nullptr, 0, nullptr, 0, nullptr);
31901 
31902         VkViewport viewport{};
31903         viewport.maxDepth = 1.0f;
31904         viewport.minDepth = 0.0f;
31905         viewport.width = 512;
31906         viewport.height = 512;
31907         viewport.x = 0;
31908         viewport.y = 0;
31909         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
31910         vkEndCommandBuffer(command_buffer[0]);
31911     }
31912     {
31913         VkCommandBufferBeginInfo begin_info{};
31914         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
31915         vkBeginCommandBuffer(command_buffer[1], &begin_info);
31916 
31917         VkViewport viewport{};
31918         viewport.maxDepth = 1.0f;
31919         viewport.minDepth = 0.0f;
31920         viewport.width = 512;
31921         viewport.height = 512;
31922         viewport.x = 0;
31923         viewport.y = 0;
31924         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
31925         vkEndCommandBuffer(command_buffer[1]);
31926     }
31927     {
31928         VkSubmitInfo submit_info[2];
31929         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
31930 
31931         submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
31932         submit_info[0].pNext = NULL;
31933         submit_info[0].commandBufferCount = 1;
31934         submit_info[0].pCommandBuffers = &command_buffer[0];
31935         submit_info[0].signalSemaphoreCount = 1;
31936         submit_info[0].pSignalSemaphores = &semaphore;
31937         submit_info[0].waitSemaphoreCount = 0;
31938         submit_info[0].pWaitSemaphores = NULL;
31939         submit_info[0].pWaitDstStageMask = 0;
31940 
31941         submit_info[1].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
31942         submit_info[1].pNext = NULL;
31943         submit_info[1].commandBufferCount = 1;
31944         submit_info[1].pCommandBuffers = &command_buffer[1];
31945         submit_info[1].waitSemaphoreCount = 1;
31946         submit_info[1].pWaitSemaphores = &semaphore;
31947         submit_info[1].pWaitDstStageMask = flags;
31948         submit_info[1].signalSemaphoreCount = 0;
31949         submit_info[1].pSignalSemaphores = NULL;
31950         vkQueueSubmit(m_device->m_queue, 2, &submit_info[0], fence);
31951     }
31952 
31953     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
31954 
31955     vkDestroyFence(m_device->device(), fence, nullptr);
31956     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
31957     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
31958     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
31959 
31960     m_errorMonitor->VerifyNotFound();
31961 }
31962 
TEST_F(VkPositiveLayerTest,CreatePipelineAttribMatrixType)31963 TEST_F(VkPositiveLayerTest, CreatePipelineAttribMatrixType) {
31964     TEST_DESCRIPTION("Test that pipeline validation accepts matrices passed as vertex attributes");
31965     m_errorMonitor->ExpectSuccess();
31966 
31967     ASSERT_NO_FATAL_FAILURE(Init());
31968     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
31969 
31970     VkVertexInputBindingDescription input_binding;
31971     memset(&input_binding, 0, sizeof(input_binding));
31972 
31973     VkVertexInputAttributeDescription input_attribs[2];
31974     memset(input_attribs, 0, sizeof(input_attribs));
31975 
31976     for (int i = 0; i < 2; i++) {
31977         input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
31978         input_attribs[i].location = i;
31979     }
31980 
31981     char const *vsSource =
31982         "#version 450\n"
31983         "\n"
31984         "layout(location=0) in mat2x4 x;\n"
31985         "void main(){\n"
31986         "   gl_Position = x[0] + x[1];\n"
31987         "}\n";
31988     char const *fsSource =
31989         "#version 450\n"
31990         "\n"
31991         "layout(location=0) out vec4 color;\n"
31992         "void main(){\n"
31993         "   color = vec4(1);\n"
31994         "}\n";
31995 
31996     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
31997     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
31998 
31999     VkPipelineObj pipe(m_device);
32000     pipe.AddDefaultColorAttachment();
32001     pipe.AddShader(&vs);
32002     pipe.AddShader(&fs);
32003 
32004     pipe.AddVertexInputBindings(&input_binding, 1);
32005     pipe.AddVertexInputAttribs(input_attribs, 2);
32006 
32007     VkDescriptorSetObj descriptorSet(m_device);
32008     descriptorSet.AppendDummy();
32009     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
32010 
32011     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
32012 
32013     /* expect success */
32014     m_errorMonitor->VerifyNotFound();
32015 }
32016 
TEST_F(VkPositiveLayerTest,CreatePipelineAttribArrayType)32017 TEST_F(VkPositiveLayerTest, CreatePipelineAttribArrayType) {
32018     m_errorMonitor->ExpectSuccess();
32019 
32020     ASSERT_NO_FATAL_FAILURE(Init());
32021     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
32022 
32023     VkVertexInputBindingDescription input_binding;
32024     memset(&input_binding, 0, sizeof(input_binding));
32025 
32026     VkVertexInputAttributeDescription input_attribs[2];
32027     memset(input_attribs, 0, sizeof(input_attribs));
32028 
32029     for (int i = 0; i < 2; i++) {
32030         input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
32031         input_attribs[i].location = i;
32032     }
32033 
32034     char const *vsSource =
32035         "#version 450\n"
32036         "\n"
32037         "layout(location=0) in vec4 x[2];\n"
32038         "void main(){\n"
32039         "   gl_Position = x[0] + x[1];\n"
32040         "}\n";
32041     char const *fsSource =
32042         "#version 450\n"
32043         "\n"
32044         "layout(location=0) out vec4 color;\n"
32045         "void main(){\n"
32046         "   color = vec4(1);\n"
32047         "}\n";
32048 
32049     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
32050     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
32051 
32052     VkPipelineObj pipe(m_device);
32053     pipe.AddDefaultColorAttachment();
32054     pipe.AddShader(&vs);
32055     pipe.AddShader(&fs);
32056 
32057     pipe.AddVertexInputBindings(&input_binding, 1);
32058     pipe.AddVertexInputAttribs(input_attribs, 2);
32059 
32060     VkDescriptorSetObj descriptorSet(m_device);
32061     descriptorSet.AppendDummy();
32062     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
32063 
32064     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
32065 
32066     m_errorMonitor->VerifyNotFound();
32067 }
32068 
TEST_F(VkPositiveLayerTest,CreatePipelineAttribComponents)32069 TEST_F(VkPositiveLayerTest, CreatePipelineAttribComponents) {
32070     TEST_DESCRIPTION(
32071         "Test that pipeline validation accepts consuming a vertex attribute through multiple vertex shader inputs, each consuming "
32072         "a different subset of the components, and that fragment shader-attachment validation tolerates multiple duplicate "
32073         "location outputs");
32074     m_errorMonitor->ExpectSuccess(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT);
32075 
32076     ASSERT_NO_FATAL_FAILURE(Init());
32077     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
32078 
32079     VkVertexInputBindingDescription input_binding;
32080     memset(&input_binding, 0, sizeof(input_binding));
32081 
32082     VkVertexInputAttributeDescription input_attribs[3];
32083     memset(input_attribs, 0, sizeof(input_attribs));
32084 
32085     for (int i = 0; i < 3; i++) {
32086         input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
32087         input_attribs[i].location = i;
32088     }
32089 
32090     char const *vsSource =
32091         "#version 450\n"
32092         "\n"
32093         "layout(location=0) in vec4 x;\n"
32094         "layout(location=1) in vec3 y1;\n"
32095         "layout(location=1, component=3) in float y2;\n"
32096         "layout(location=2) in vec4 z;\n"
32097         "void main(){\n"
32098         "   gl_Position = x + vec4(y1, y2) + z;\n"
32099         "}\n";
32100     char const *fsSource =
32101         "#version 450\n"
32102         "\n"
32103         "layout(location=0, component=0) out float color0;\n"
32104         "layout(location=0, component=1) out float color1;\n"
32105         "layout(location=0, component=2) out float color2;\n"
32106         "layout(location=0, component=3) out float color3;\n"
32107         "layout(location=1, component=0) out vec2 second_color0;\n"
32108         "layout(location=1, component=2) out vec2 second_color1;\n"
32109         "void main(){\n"
32110         "   color0 = float(1);\n"
32111         "   second_color0 = vec2(1);\n"
32112         "}\n";
32113 
32114     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
32115     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
32116 
32117     VkPipelineObj pipe(m_device);
32118 
32119     VkDescriptorSetObj descriptorSet(m_device);
32120     descriptorSet.AppendDummy();
32121     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
32122 
32123     // Create a renderPass with two color attachments
32124     VkAttachmentReference attachments[2] = {};
32125     attachments[0].layout = VK_IMAGE_LAYOUT_GENERAL;
32126     attachments[1].attachment = 1;
32127     attachments[1].layout = VK_IMAGE_LAYOUT_GENERAL;
32128 
32129     VkSubpassDescription subpass = {};
32130     subpass.pColorAttachments = attachments;
32131     subpass.colorAttachmentCount = 2;
32132 
32133     VkRenderPassCreateInfo rpci = {};
32134     rpci.subpassCount = 1;
32135     rpci.pSubpasses = &subpass;
32136     rpci.attachmentCount = 2;
32137 
32138     VkAttachmentDescription attach_desc[2] = {};
32139     attach_desc[0].format = VK_FORMAT_B8G8R8A8_UNORM;
32140     attach_desc[0].samples = VK_SAMPLE_COUNT_1_BIT;
32141     attach_desc[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
32142     attach_desc[0].finalLayout = VK_IMAGE_LAYOUT_GENERAL;
32143     attach_desc[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
32144     attach_desc[1].format = VK_FORMAT_B8G8R8A8_UNORM;
32145     attach_desc[1].samples = VK_SAMPLE_COUNT_1_BIT;
32146     attach_desc[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
32147     attach_desc[1].finalLayout = VK_IMAGE_LAYOUT_GENERAL;
32148     attach_desc[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
32149 
32150     rpci.pAttachments = attach_desc;
32151     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
32152 
32153     VkRenderPass renderpass;
32154     vkCreateRenderPass(m_device->device(), &rpci, NULL, &renderpass);
32155     pipe.AddShader(&vs);
32156     pipe.AddShader(&fs);
32157 
32158     VkPipelineColorBlendAttachmentState att_state1 = {};
32159     att_state1.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
32160     att_state1.blendEnable = VK_FALSE;
32161 
32162     pipe.AddColorAttachment(0, att_state1);
32163     pipe.AddColorAttachment(1, att_state1);
32164     pipe.AddVertexInputBindings(&input_binding, 1);
32165     pipe.AddVertexInputAttribs(input_attribs, 3);
32166     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderpass);
32167     vkDestroyRenderPass(m_device->device(), renderpass, nullptr);
32168 
32169     m_errorMonitor->VerifyNotFound();
32170 }
32171 
TEST_F(VkPositiveLayerTest,CreatePipelineSimplePositive)32172 TEST_F(VkPositiveLayerTest, CreatePipelineSimplePositive) {
32173     m_errorMonitor->ExpectSuccess();
32174 
32175     ASSERT_NO_FATAL_FAILURE(Init());
32176     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
32177 
32178     char const *vsSource =
32179         "#version 450\n"
32180         "void main(){\n"
32181         "   gl_Position = vec4(0);\n"
32182         "}\n";
32183     char const *fsSource =
32184         "#version 450\n"
32185         "\n"
32186         "layout(location=0) out vec4 color;\n"
32187         "void main(){\n"
32188         "   color = vec4(1);\n"
32189         "}\n";
32190 
32191     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
32192     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
32193 
32194     VkPipelineObj pipe(m_device);
32195     pipe.AddDefaultColorAttachment();
32196     pipe.AddShader(&vs);
32197     pipe.AddShader(&fs);
32198 
32199     VkDescriptorSetObj descriptorSet(m_device);
32200     descriptorSet.AppendDummy();
32201     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
32202 
32203     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
32204 
32205     m_errorMonitor->VerifyNotFound();
32206 }
32207 
TEST_F(VkPositiveLayerTest,CreatePipelineRelaxedTypeMatch)32208 TEST_F(VkPositiveLayerTest, CreatePipelineRelaxedTypeMatch) {
32209     TEST_DESCRIPTION(
32210         "Test that pipeline validation accepts the relaxed type matching rules set out in 14.1.3: fundamental type must match, and "
32211         "producer side must have at least as many components");
32212     m_errorMonitor->ExpectSuccess();
32213 
32214     // VK 1.0.8 Specification, 14.1.3 "Additionally,..." block
32215 
32216     ASSERT_NO_FATAL_FAILURE(Init());
32217     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
32218 
32219     char const *vsSource =
32220         "#version 450\n"
32221         "layout(location=0) out vec3 x;\n"
32222         "layout(location=1) out ivec3 y;\n"
32223         "layout(location=2) out vec3 z;\n"
32224         "void main(){\n"
32225         "   gl_Position = vec4(0);\n"
32226         "   x = vec3(0); y = ivec3(0); z = vec3(0);\n"
32227         "}\n";
32228     char const *fsSource =
32229         "#version 450\n"
32230         "\n"
32231         "layout(location=0) out vec4 color;\n"
32232         "layout(location=0) in float x;\n"
32233         "layout(location=1) flat in int y;\n"
32234         "layout(location=2) in vec2 z;\n"
32235         "void main(){\n"
32236         "   color = vec4(1 + x + y + z.x);\n"
32237         "}\n";
32238 
32239     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
32240     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
32241 
32242     VkPipelineObj pipe(m_device);
32243     pipe.AddDefaultColorAttachment();
32244     pipe.AddShader(&vs);
32245     pipe.AddShader(&fs);
32246 
32247     VkDescriptorSetObj descriptorSet(m_device);
32248     descriptorSet.AppendDummy();
32249     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
32250 
32251     VkResult err = VK_SUCCESS;
32252     err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
32253     ASSERT_VK_SUCCESS(err);
32254 
32255     m_errorMonitor->VerifyNotFound();
32256 }
32257 
TEST_F(VkPositiveLayerTest,CreatePipelineTessPerVertex)32258 TEST_F(VkPositiveLayerTest, CreatePipelineTessPerVertex) {
32259     TEST_DESCRIPTION("Test that pipeline validation accepts per-vertex variables passed between the TCS and TES stages");
32260     m_errorMonitor->ExpectSuccess();
32261 
32262     ASSERT_NO_FATAL_FAILURE(Init());
32263     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
32264 
32265     if (!m_device->phy().features().tessellationShader) {
32266         printf("%s Device does not support tessellation shaders; skipped.\n", kSkipPrefix);
32267         return;
32268     }
32269 
32270     char const *vsSource =
32271         "#version 450\n"
32272         "void main(){}\n";
32273     char const *tcsSource =
32274         "#version 450\n"
32275         "layout(location=0) out int x[];\n"
32276         "layout(vertices=3) out;\n"
32277         "void main(){\n"
32278         "   gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
32279         "   gl_TessLevelInner[0] = 1;\n"
32280         "   x[gl_InvocationID] = gl_InvocationID;\n"
32281         "}\n";
32282     char const *tesSource =
32283         "#version 450\n"
32284         "layout(triangles, equal_spacing, cw) in;\n"
32285         "layout(location=0) in int x[];\n"
32286         "void main(){\n"
32287         "   gl_Position.xyz = gl_TessCoord;\n"
32288         "   gl_Position.w = x[0] + x[1] + x[2];\n"
32289         "}\n";
32290     char const *fsSource =
32291         "#version 450\n"
32292         "layout(location=0) out vec4 color;\n"
32293         "void main(){\n"
32294         "   color = vec4(1);\n"
32295         "}\n";
32296 
32297     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
32298     VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
32299     VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
32300     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
32301 
32302     VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
32303                                                  VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
32304 
32305     VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
32306 
32307     VkPipelineObj pipe(m_device);
32308     pipe.SetInputAssembly(&iasci);
32309     pipe.SetTessellation(&tsci);
32310     pipe.AddDefaultColorAttachment();
32311     pipe.AddShader(&vs);
32312     pipe.AddShader(&tcs);
32313     pipe.AddShader(&tes);
32314     pipe.AddShader(&fs);
32315 
32316     VkDescriptorSetObj descriptorSet(m_device);
32317     descriptorSet.AppendDummy();
32318     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
32319 
32320     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
32321 
32322     m_errorMonitor->VerifyNotFound();
32323 }
32324 
TEST_F(VkPositiveLayerTest,CreatePipelineGeometryInputBlockPositive)32325 TEST_F(VkPositiveLayerTest, CreatePipelineGeometryInputBlockPositive) {
32326     TEST_DESCRIPTION(
32327         "Test that pipeline validation accepts a user-defined interface block passed into the geometry shader. This is interesting "
32328         "because the 'extra' array level is not present on the member type, but on the block instance.");
32329     m_errorMonitor->ExpectSuccess();
32330 
32331     ASSERT_NO_FATAL_FAILURE(Init());
32332     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
32333 
32334     if (!m_device->phy().features().geometryShader) {
32335         printf("%s Device does not support geometry shaders; skipped.\n", kSkipPrefix);
32336         return;
32337     }
32338 
32339     char const *vsSource =
32340         "#version 450\n"
32341         "layout(location=0) out VertexData { vec4 x; } vs_out;\n"
32342         "void main(){\n"
32343         "   vs_out.x = vec4(1);\n"
32344         "}\n";
32345     char const *gsSource =
32346         "#version 450\n"
32347         "layout(triangles) in;\n"
32348         "layout(triangle_strip, max_vertices=3) out;\n"
32349         "layout(location=0) in VertexData { vec4 x; } gs_in[];\n"
32350         "void main() {\n"
32351         "   gl_Position = gs_in[0].x;\n"
32352         "   EmitVertex();\n"
32353         "}\n";
32354     char const *fsSource =
32355         "#version 450\n"
32356         "layout(location=0) out vec4 color;\n"
32357         "void main(){\n"
32358         "   color = vec4(1);\n"
32359         "}\n";
32360 
32361     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
32362     VkShaderObj gs(m_device, gsSource, VK_SHADER_STAGE_GEOMETRY_BIT, this);
32363     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
32364 
32365     VkPipelineObj pipe(m_device);
32366     pipe.AddDefaultColorAttachment();
32367     pipe.AddShader(&vs);
32368     pipe.AddShader(&gs);
32369     pipe.AddShader(&fs);
32370 
32371     VkDescriptorSetObj descriptorSet(m_device);
32372     descriptorSet.AppendDummy();
32373     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
32374 
32375     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
32376 
32377     m_errorMonitor->VerifyNotFound();
32378 }
32379 
TEST_F(VkPositiveLayerTest,CreatePipeline64BitAttributesPositive)32380 TEST_F(VkPositiveLayerTest, CreatePipeline64BitAttributesPositive) {
32381     TEST_DESCRIPTION(
32382         "Test that pipeline validation accepts basic use of 64bit vertex attributes. This is interesting because they consume "
32383         "multiple locations.");
32384     m_errorMonitor->ExpectSuccess();
32385 
32386     if (!EnableDeviceProfileLayer()) {
32387         printf("%s Failed to enable device profile layer.\n", kSkipPrefix);
32388         return;
32389     }
32390 
32391     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
32392     ASSERT_NO_FATAL_FAILURE(InitState());
32393     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
32394 
32395     if (!m_device->phy().features().shaderFloat64) {
32396         printf("%s Device does not support 64bit vertex attributes; skipped.\n", kSkipPrefix);
32397         return;
32398     }
32399     // Set 64bit format to support VTX Buffer feature
32400     PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr;
32401     PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr;
32402 
32403     // Load required functions
32404     if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) {
32405         return;
32406     }
32407     VkFormatProperties format_props;
32408     fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R64G64B64A64_SFLOAT, &format_props);
32409     format_props.bufferFeatures |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;
32410     fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R64G64B64A64_SFLOAT, format_props);
32411 
32412     VkVertexInputBindingDescription input_bindings[1];
32413     memset(input_bindings, 0, sizeof(input_bindings));
32414 
32415     VkVertexInputAttributeDescription input_attribs[4];
32416     memset(input_attribs, 0, sizeof(input_attribs));
32417     input_attribs[0].location = 0;
32418     input_attribs[0].offset = 0;
32419     input_attribs[0].format = VK_FORMAT_R64G64B64A64_SFLOAT;
32420     input_attribs[1].location = 2;
32421     input_attribs[1].offset = 32;
32422     input_attribs[1].format = VK_FORMAT_R64G64B64A64_SFLOAT;
32423     input_attribs[2].location = 4;
32424     input_attribs[2].offset = 64;
32425     input_attribs[2].format = VK_FORMAT_R64G64B64A64_SFLOAT;
32426     input_attribs[3].location = 6;
32427     input_attribs[3].offset = 96;
32428     input_attribs[3].format = VK_FORMAT_R64G64B64A64_SFLOAT;
32429 
32430     char const *vsSource =
32431         "#version 450\n"
32432         "\n"
32433         "layout(location=0) in dmat4 x;\n"
32434         "void main(){\n"
32435         "   gl_Position = vec4(x[0][0]);\n"
32436         "}\n";
32437     char const *fsSource =
32438         "#version 450\n"
32439         "\n"
32440         "layout(location=0) out vec4 color;\n"
32441         "void main(){\n"
32442         "   color = vec4(1);\n"
32443         "}\n";
32444 
32445     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
32446     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
32447 
32448     VkPipelineObj pipe(m_device);
32449     pipe.AddDefaultColorAttachment();
32450     pipe.AddShader(&vs);
32451     pipe.AddShader(&fs);
32452 
32453     pipe.AddVertexInputBindings(input_bindings, 1);
32454     pipe.AddVertexInputAttribs(input_attribs, 4);
32455 
32456     VkDescriptorSetObj descriptorSet(m_device);
32457     descriptorSet.AppendDummy();
32458     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
32459 
32460     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
32461 
32462     m_errorMonitor->VerifyNotFound();
32463 }
32464 
TEST_F(VkPositiveLayerTest,CreatePipelineInputAttachmentPositive)32465 TEST_F(VkPositiveLayerTest, CreatePipelineInputAttachmentPositive) {
32466     TEST_DESCRIPTION("Positive test for a correctly matched input attachment");
32467     m_errorMonitor->ExpectSuccess();
32468 
32469     ASSERT_NO_FATAL_FAILURE(Init());
32470 
32471     char const *vsSource =
32472         "#version 450\n"
32473         "\n"
32474         "void main(){\n"
32475         "    gl_Position = vec4(1);\n"
32476         "}\n";
32477     char const *fsSource =
32478         "#version 450\n"
32479         "\n"
32480         "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
32481         "layout(location=0) out vec4 color;\n"
32482         "void main() {\n"
32483         "   color = subpassLoad(x);\n"
32484         "}\n";
32485 
32486     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
32487     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
32488 
32489     VkPipelineObj pipe(m_device);
32490     pipe.AddShader(&vs);
32491     pipe.AddShader(&fs);
32492     pipe.AddDefaultColorAttachment();
32493     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
32494 
32495     VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
32496     const VkDescriptorSetLayoutObj dsl(m_device, {dslb});
32497     const VkPipelineLayoutObj pl(m_device, {&dsl});
32498 
32499     VkAttachmentDescription descs[2] = {
32500         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
32501          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
32502          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
32503         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
32504          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
32505     };
32506     VkAttachmentReference color = {
32507         0,
32508         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
32509     };
32510     VkAttachmentReference input = {
32511         1,
32512         VK_IMAGE_LAYOUT_GENERAL,
32513     };
32514 
32515     VkSubpassDescription sd = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr};
32516 
32517     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr};
32518     VkRenderPass rp;
32519     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
32520     ASSERT_VK_SUCCESS(err);
32521 
32522     // should be OK. would go wrong here if it's going to...
32523     pipe.CreateVKPipeline(pl.handle(), rp);
32524 
32525     m_errorMonitor->VerifyNotFound();
32526 
32527     vkDestroyRenderPass(m_device->device(), rp, nullptr);
32528 }
32529 
TEST_F(VkPositiveLayerTest,CreateComputePipelineMissingDescriptorUnusedPositive)32530 TEST_F(VkPositiveLayerTest, CreateComputePipelineMissingDescriptorUnusedPositive) {
32531     TEST_DESCRIPTION(
32532         "Test that pipeline validation accepts a compute pipeline which declares a descriptor-backed resource which is not "
32533         "provided, but the shader does not statically use it. This is interesting because it requires compute pipelines to have a "
32534         "proper descriptor use walk, which they didn't for some time.");
32535     m_errorMonitor->ExpectSuccess();
32536 
32537     ASSERT_NO_FATAL_FAILURE(Init());
32538 
32539     char const *csSource =
32540         "#version 450\n"
32541         "\n"
32542         "layout(local_size_x=1) in;\n"
32543         "layout(set=0, binding=0) buffer block { vec4 x; };\n"
32544         "void main(){\n"
32545         "   // x is not used.\n"
32546         "}\n";
32547 
32548     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
32549 
32550     VkDescriptorSetObj descriptorSet(m_device);
32551     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
32552 
32553     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
32554                                         nullptr,
32555                                         0,
32556                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
32557                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
32558                                         descriptorSet.GetPipelineLayout(),
32559                                         VK_NULL_HANDLE,
32560                                         -1};
32561 
32562     VkPipeline pipe;
32563     VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
32564 
32565     m_errorMonitor->VerifyNotFound();
32566 
32567     if (err == VK_SUCCESS) {
32568         vkDestroyPipeline(m_device->device(), pipe, nullptr);
32569     }
32570 }
32571 
TEST_F(VkPositiveLayerTest,CreateComputePipelineCombinedImageSamplerConsumedAsSampler)32572 TEST_F(VkPositiveLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsSampler) {
32573     TEST_DESCRIPTION(
32574         "Test that pipeline validation accepts a shader consuming only the sampler portion of a combined image + sampler");
32575     m_errorMonitor->ExpectSuccess();
32576 
32577     ASSERT_NO_FATAL_FAILURE(Init());
32578 
32579     std::vector<VkDescriptorSetLayoutBinding> bindings = {
32580         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
32581         {1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
32582         {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
32583     };
32584 
32585     const VkDescriptorSetLayoutObj dsl(m_device, bindings);
32586     const VkPipelineLayoutObj pl(m_device, {&dsl});
32587 
32588     char const *csSource =
32589         "#version 450\n"
32590         "\n"
32591         "layout(local_size_x=1) in;\n"
32592         "layout(set=0, binding=0) uniform sampler s;\n"
32593         "layout(set=0, binding=1) uniform texture2D t;\n"
32594         "layout(set=0, binding=2) buffer block { vec4 x; };\n"
32595         "void main() {\n"
32596         "   x = texture(sampler2D(t, s), vec2(0));\n"
32597         "}\n";
32598     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
32599 
32600     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
32601                                         nullptr,
32602                                         0,
32603                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
32604                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
32605                                         pl.handle(),
32606                                         VK_NULL_HANDLE,
32607                                         -1};
32608 
32609     VkPipeline pipe;
32610     VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
32611 
32612     m_errorMonitor->VerifyNotFound();
32613 
32614     if (err == VK_SUCCESS) {
32615         vkDestroyPipeline(m_device->device(), pipe, nullptr);
32616     }
32617 }
32618 
TEST_F(VkPositiveLayerTest,CreateComputePipelineCombinedImageSamplerConsumedAsImage)32619 TEST_F(VkPositiveLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsImage) {
32620     TEST_DESCRIPTION(
32621         "Test that pipeline validation accepts a shader consuming only the image portion of a combined image + sampler");
32622     m_errorMonitor->ExpectSuccess();
32623 
32624     ASSERT_NO_FATAL_FAILURE(Init());
32625 
32626     std::vector<VkDescriptorSetLayoutBinding> bindings = {
32627         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
32628         {1, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
32629         {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
32630     };
32631 
32632     const VkDescriptorSetLayoutObj dsl(m_device, bindings);
32633     const VkPipelineLayoutObj pl(m_device, {&dsl});
32634 
32635     char const *csSource =
32636         "#version 450\n"
32637         "\n"
32638         "layout(local_size_x=1) in;\n"
32639         "layout(set=0, binding=0) uniform texture2D t;\n"
32640         "layout(set=0, binding=1) uniform sampler s;\n"
32641         "layout(set=0, binding=2) buffer block { vec4 x; };\n"
32642         "void main() {\n"
32643         "   x = texture(sampler2D(t, s), vec2(0));\n"
32644         "}\n";
32645     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
32646 
32647     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
32648                                         nullptr,
32649                                         0,
32650                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
32651                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
32652                                         pl.handle(),
32653                                         VK_NULL_HANDLE,
32654                                         -1};
32655 
32656     VkPipeline pipe;
32657     VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
32658 
32659     m_errorMonitor->VerifyNotFound();
32660 
32661     if (err == VK_SUCCESS) {
32662         vkDestroyPipeline(m_device->device(), pipe, nullptr);
32663     }
32664 }
32665 
TEST_F(VkPositiveLayerTest,CreateComputePipelineCombinedImageSamplerConsumedAsBoth)32666 TEST_F(VkPositiveLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsBoth) {
32667     TEST_DESCRIPTION(
32668         "Test that pipeline validation accepts a shader consuming both the sampler and the image of a combined image+sampler but "
32669         "via separate variables");
32670     m_errorMonitor->ExpectSuccess();
32671 
32672     ASSERT_NO_FATAL_FAILURE(Init());
32673 
32674     std::vector<VkDescriptorSetLayoutBinding> bindings = {
32675         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
32676         {1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
32677     };
32678 
32679     const VkDescriptorSetLayoutObj dsl(m_device, bindings);
32680     const VkPipelineLayoutObj pl(m_device, {&dsl});
32681 
32682     char const *csSource =
32683         "#version 450\n"
32684         "\n"
32685         "layout(local_size_x=1) in;\n"
32686         "layout(set=0, binding=0) uniform texture2D t;\n"
32687         "layout(set=0, binding=0) uniform sampler s;  // both binding 0!\n"
32688         "layout(set=0, binding=1) buffer block { vec4 x; };\n"
32689         "void main() {\n"
32690         "   x = texture(sampler2D(t, s), vec2(0));\n"
32691         "}\n";
32692     VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
32693 
32694     VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
32695                                         nullptr,
32696                                         0,
32697                                         {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
32698                                          VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
32699                                         pl.handle(),
32700                                         VK_NULL_HANDLE,
32701                                         -1};
32702 
32703     VkPipeline pipe;
32704     VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
32705 
32706     m_errorMonitor->VerifyNotFound();
32707 
32708     if (err == VK_SUCCESS) {
32709         vkDestroyPipeline(m_device->device(), pipe, nullptr);
32710     }
32711 }
32712 
TEST_F(VkPositiveLayerTest,CreateDescriptorSetBindingWithIgnoredSamplers)32713 TEST_F(VkPositiveLayerTest, CreateDescriptorSetBindingWithIgnoredSamplers) {
32714     TEST_DESCRIPTION("Test that layers conditionally do ignore the pImmutableSamplers on vkCreateDescriptorSetLayout");
32715 
32716     bool prop2_found = false;
32717     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
32718         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
32719         prop2_found = true;
32720     } else {
32721         printf("%s %s Extension not supported, skipping push descriptor sub-tests\n", kSkipPrefix,
32722                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
32723     }
32724 
32725     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
32726     bool push_descriptor_found = false;
32727     if (prop2_found && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
32728         m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
32729 
32730         // In addition to the extension being supported we need to have at least one available
32731         // Some implementations report an invalid maxPushDescriptors of 0
32732         push_descriptor_found = GetPushDescriptorProperties(instance(), gpu()).maxPushDescriptors > 0;
32733     } else {
32734         printf("%s %s Extension not supported, skipping push descriptor sub-tests\n", kSkipPrefix,
32735                VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
32736     }
32737 
32738     ASSERT_NO_FATAL_FAILURE(InitState());
32739     const uint64_t fake_address_64 = 0xCDCDCDCDCDCDCDCD;
32740     const uint64_t fake_address_32 = 0xCDCDCDCD;
32741     const void *fake_pointer =
32742         sizeof(void *) == 8 ? reinterpret_cast<void *>(fake_address_64) : reinterpret_cast<void *>(fake_address_32);
32743     const VkSampler *hopefully_undereferencable_pointer = reinterpret_cast<const VkSampler *>(fake_pointer);
32744 
32745     // regular descriptors
32746     m_errorMonitor->ExpectSuccess();
32747     {
32748         const VkDescriptorSetLayoutBinding non_sampler_bindings[] = {
32749             {0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
32750             {1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
32751             {2, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
32752             {3, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
32753             {4, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
32754             {5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
32755             {6, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
32756             {7, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
32757             {8, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
32758         };
32759         const VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0,
32760                                                        static_cast<uint32_t>(size(non_sampler_bindings)), non_sampler_bindings};
32761         VkDescriptorSetLayout dsl;
32762         const VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
32763         ASSERT_VK_SUCCESS(err);
32764         vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
32765     }
32766     m_errorMonitor->VerifyNotFound();
32767 
32768     if (push_descriptor_found) {
32769         // push descriptors
32770         m_errorMonitor->ExpectSuccess();
32771         {
32772             const VkDescriptorSetLayoutBinding non_sampler_bindings[] = {
32773                 {0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
32774                 {1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
32775                 {2, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
32776                 {3, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
32777                 {4, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
32778                 {5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
32779                 {6, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
32780             };
32781             const VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr,
32782                                                            VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
32783                                                            static_cast<uint32_t>(size(non_sampler_bindings)), non_sampler_bindings};
32784             VkDescriptorSetLayout dsl;
32785             const VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
32786             ASSERT_VK_SUCCESS(err);
32787             vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
32788         }
32789         m_errorMonitor->VerifyNotFound();
32790     }
32791 }
32792 
TEST_F(VkPositiveLayerTest,Maintenance1Tests)32793 TEST_F(VkPositiveLayerTest, Maintenance1Tests) {
32794     TEST_DESCRIPTION("Validate various special cases for the Maintenance1_KHR extension");
32795 
32796     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
32797     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
32798         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
32799     } else {
32800         printf("%s Maintenance1 Extension not supported, skipping tests\n", kSkipPrefix);
32801         return;
32802     }
32803     ASSERT_NO_FATAL_FAILURE(InitState());
32804 
32805     m_errorMonitor->ExpectSuccess();
32806 
32807     VkCommandBufferObj cmd_buf(m_device, m_commandPool);
32808     cmd_buf.begin();
32809     // Set Negative height, should give error if Maintenance 1 is not enabled
32810     VkViewport viewport = {0, 0, 16, -16, 0, 1};
32811     vkCmdSetViewport(cmd_buf.handle(), 0, 1, &viewport);
32812     cmd_buf.end();
32813 
32814     m_errorMonitor->VerifyNotFound();
32815 }
32816 
TEST_F(VkLayerTest,DuplicateValidPNextStructures)32817 TEST_F(VkLayerTest, DuplicateValidPNextStructures) {
32818     TEST_DESCRIPTION("Create a pNext chain containing valid structures, but with a duplicate structure type");
32819 
32820     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
32821     if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME)) {
32822         m_device_extension_names.push_back(VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME);
32823     } else {
32824         printf("%s VK_NV_dedicated_allocation extension not supported, skipping test\n", kSkipPrefix);
32825         return;
32826     }
32827     ASSERT_NO_FATAL_FAILURE(InitState());
32828 
32829     // Create two pNext structures which by themselves would be valid
32830     VkDedicatedAllocationBufferCreateInfoNV dedicated_buffer_create_info = {};
32831     VkDedicatedAllocationBufferCreateInfoNV dedicated_buffer_create_info_2 = {};
32832     dedicated_buffer_create_info.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV;
32833     dedicated_buffer_create_info.pNext = &dedicated_buffer_create_info_2;
32834     dedicated_buffer_create_info.dedicatedAllocation = VK_TRUE;
32835 
32836     dedicated_buffer_create_info_2.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV;
32837     dedicated_buffer_create_info_2.pNext = nullptr;
32838     dedicated_buffer_create_info_2.dedicatedAllocation = VK_TRUE;
32839 
32840     uint32_t queue_family_index = 0;
32841     VkBufferCreateInfo buffer_create_info = {};
32842     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
32843     buffer_create_info.pNext = &dedicated_buffer_create_info;
32844     buffer_create_info.size = 1024;
32845     buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
32846     buffer_create_info.queueFamilyIndexCount = 1;
32847     buffer_create_info.pQueueFamilyIndices = &queue_family_index;
32848 
32849     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "chain contains duplicate structure types");
32850     VkBuffer buffer;
32851     vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
32852     m_errorMonitor->VerifyFound();
32853 }
32854 
TEST_F(VkLayerTest,DedicatedAllocation)32855 TEST_F(VkLayerTest, DedicatedAllocation) {
32856     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
32857     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME)) {
32858         m_device_extension_names.push_back(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
32859         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
32860     } else {
32861         printf("%s Dedicated allocation extension not supported, skipping test\n", kSkipPrefix);
32862         return;
32863     }
32864     ASSERT_NO_FATAL_FAILURE(InitState());
32865 
32866     VkMemoryPropertyFlags mem_flags = 0;
32867     const VkDeviceSize resource_size = 1024;
32868     auto buffer_info = VkBufferObj::create_info(resource_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
32869     VkBufferObj buffer;
32870     buffer.init_no_mem(*m_device, buffer_info);
32871     auto buffer_alloc_info = vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, buffer.memory_requirements(), mem_flags);
32872     auto buffer_dedicated_info = lvl_init_struct<VkMemoryDedicatedAllocateInfoKHR>();
32873     buffer_dedicated_info.buffer = buffer.handle();
32874     buffer_alloc_info.pNext = &buffer_dedicated_info;
32875     vk_testing::DeviceMemory dedicated_buffer_memory;
32876     dedicated_buffer_memory.init(*m_device, buffer_alloc_info);
32877 
32878     VkBufferObj wrong_buffer;
32879     wrong_buffer.init_no_mem(*m_device, buffer_info);
32880 
32881     // Bind with wrong buffer
32882     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkBindBufferMemory-memory-01508");
32883     vkBindBufferMemory(m_device->handle(), wrong_buffer.handle(), dedicated_buffer_memory.handle(), 0);
32884     m_errorMonitor->VerifyFound();
32885 
32886     // Bind with non-zero offset (same VUID)
32887     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
32888                                          "VUID-vkBindBufferMemory-memory-01508");  // offset must be zero
32889     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
32890                                          "VUID-vkBindBufferMemory-size-01037");  // offset pushes us past size
32891     auto offset = buffer.memory_requirements().alignment;
32892     vkBindBufferMemory(m_device->handle(), buffer.handle(), dedicated_buffer_memory.handle(), offset);
32893     m_errorMonitor->VerifyFound();
32894 
32895     // Bind correctly (depends on the "skip" above)
32896     m_errorMonitor->ExpectSuccess();
32897     vkBindBufferMemory(m_device->handle(), buffer.handle(), dedicated_buffer_memory.handle(), 0);
32898     m_errorMonitor->VerifyNotFound();
32899 
32900     // And for images...
32901     vk_testing::Image image;
32902     vk_testing::Image wrong_image;
32903     auto image_info = vk_testing::Image::create_info();
32904     image_info.extent.width = resource_size;
32905     image_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
32906     image_info.format = VK_FORMAT_R8G8B8A8_UNORM;
32907     image.init_no_mem(*m_device, image_info);
32908     wrong_image.init_no_mem(*m_device, image_info);
32909 
32910     auto image_dedicated_info = lvl_init_struct<VkMemoryDedicatedAllocateInfoKHR>();
32911     image_dedicated_info.image = image.handle();
32912     auto image_alloc_info = vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, image.memory_requirements(), mem_flags);
32913     image_alloc_info.pNext = &image_dedicated_info;
32914     vk_testing::DeviceMemory dedicated_image_memory;
32915     dedicated_image_memory.init(*m_device, image_alloc_info);
32916 
32917     // Bind with wrong image
32918     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkBindImageMemory-memory-01509");
32919     vkBindImageMemory(m_device->handle(), wrong_image.handle(), dedicated_image_memory.handle(), 0);
32920     m_errorMonitor->VerifyFound();
32921 
32922     // Bind with non-zero offset (same VUID)
32923     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
32924                                          "VUID-vkBindImageMemory-memory-01509");  // offset must be zero
32925     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
32926                                          "VUID-vkBindImageMemory-size-01049");  // offset pushes us past size
32927     auto image_offset = image.memory_requirements().alignment;
32928     vkBindImageMemory(m_device->handle(), image.handle(), dedicated_image_memory.handle(), image_offset);
32929     m_errorMonitor->VerifyFound();
32930 
32931     // Bind correctly (depends on the "skip" above)
32932     m_errorMonitor->ExpectSuccess();
32933     vkBindImageMemory(m_device->handle(), image.handle(), dedicated_image_memory.handle(), 0);
32934     m_errorMonitor->VerifyNotFound();
32935 }
32936 
TEST_F(VkPositiveLayerTest,ValidStructPNext)32937 TEST_F(VkPositiveLayerTest, ValidStructPNext) {
32938     TEST_DESCRIPTION("Verify that a valid pNext value is handled correctly");
32939 
32940     // Positive test to check parameter_validation and unique_objects support for NV_dedicated_allocation
32941     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
32942     if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME)) {
32943         m_device_extension_names.push_back(VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME);
32944     } else {
32945         printf("%s VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME Extension not supported, skipping test\n", kSkipPrefix);
32946         return;
32947     }
32948     ASSERT_NO_FATAL_FAILURE(InitState());
32949 
32950     m_errorMonitor->ExpectSuccess();
32951 
32952     VkDedicatedAllocationBufferCreateInfoNV dedicated_buffer_create_info = {};
32953     dedicated_buffer_create_info.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV;
32954     dedicated_buffer_create_info.pNext = nullptr;
32955     dedicated_buffer_create_info.dedicatedAllocation = VK_TRUE;
32956 
32957     uint32_t queue_family_index = 0;
32958     VkBufferCreateInfo buffer_create_info = {};
32959     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
32960     buffer_create_info.pNext = &dedicated_buffer_create_info;
32961     buffer_create_info.size = 1024;
32962     buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
32963     buffer_create_info.queueFamilyIndexCount = 1;
32964     buffer_create_info.pQueueFamilyIndices = &queue_family_index;
32965 
32966     VkBuffer buffer;
32967     VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
32968     ASSERT_VK_SUCCESS(err);
32969 
32970     VkMemoryRequirements memory_reqs;
32971     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
32972 
32973     VkDedicatedAllocationMemoryAllocateInfoNV dedicated_memory_info = {};
32974     dedicated_memory_info.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV;
32975     dedicated_memory_info.pNext = nullptr;
32976     dedicated_memory_info.buffer = buffer;
32977     dedicated_memory_info.image = VK_NULL_HANDLE;
32978 
32979     VkMemoryAllocateInfo memory_info = {};
32980     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
32981     memory_info.pNext = &dedicated_memory_info;
32982     memory_info.allocationSize = memory_reqs.size;
32983 
32984     bool pass;
32985     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
32986     ASSERT_TRUE(pass);
32987 
32988     VkDeviceMemory buffer_memory;
32989     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
32990     ASSERT_VK_SUCCESS(err);
32991 
32992     err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
32993     ASSERT_VK_SUCCESS(err);
32994 
32995     vkDestroyBuffer(m_device->device(), buffer, NULL);
32996     vkFreeMemory(m_device->device(), buffer_memory, NULL);
32997 
32998     m_errorMonitor->VerifyNotFound();
32999 }
33000 
TEST_F(VkPositiveLayerTest,PSOPolygonModeValid)33001 TEST_F(VkPositiveLayerTest, PSOPolygonModeValid) {
33002     TEST_DESCRIPTION("Verify that using a solid polygon fill mode works correctly.");
33003 
33004     ASSERT_NO_FATAL_FAILURE(Init());
33005     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
33006 
33007     std::vector<const char *> device_extension_names;
33008     auto features = m_device->phy().features();
33009     // Artificially disable support for non-solid fill modes
33010     features.fillModeNonSolid = false;
33011     // The sacrificial device object
33012     VkDeviceObj test_device(0, gpu(), device_extension_names, &features);
33013 
33014     VkRenderpassObj render_pass(&test_device);
33015 
33016     const VkPipelineLayoutObj pipeline_layout(&test_device);
33017 
33018     VkPipelineRasterizationStateCreateInfo rs_ci = {};
33019     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
33020     rs_ci.pNext = nullptr;
33021     rs_ci.lineWidth = 1.0f;
33022     rs_ci.rasterizerDiscardEnable = false;
33023 
33024     VkShaderObj vs(&test_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
33025     VkShaderObj fs(&test_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
33026 
33027     // Set polygonMode=FILL. No error is expected
33028     m_errorMonitor->ExpectSuccess();
33029     {
33030         VkPipelineObj pipe(&test_device);
33031         pipe.AddShader(&vs);
33032         pipe.AddShader(&fs);
33033         pipe.AddDefaultColorAttachment();
33034         // Set polygonMode to a good value
33035         rs_ci.polygonMode = VK_POLYGON_MODE_FILL;
33036         pipe.SetRasterization(&rs_ci);
33037         pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle());
33038     }
33039     m_errorMonitor->VerifyNotFound();
33040 }
33041 
TEST_F(VkPositiveLayerTest,LongSemaphoreChain)33042 TEST_F(VkPositiveLayerTest, LongSemaphoreChain) {
33043     m_errorMonitor->ExpectSuccess();
33044 
33045     ASSERT_NO_FATAL_FAILURE(Init());
33046     VkResult err;
33047 
33048     std::vector<VkSemaphore> semaphores;
33049 
33050     const int chainLength = 32768;
33051     VkPipelineStageFlags flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
33052 
33053     for (int i = 0; i < chainLength; i++) {
33054         VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
33055         VkSemaphore semaphore;
33056         err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &semaphore);
33057         ASSERT_VK_SUCCESS(err);
33058 
33059         semaphores.push_back(semaphore);
33060 
33061         VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO,
33062                            nullptr,
33063                            semaphores.size() > 1 ? 1u : 0u,
33064                            semaphores.size() > 1 ? &semaphores[semaphores.size() - 2] : nullptr,
33065                            &flags,
33066                            0,
33067                            nullptr,
33068                            1,
33069                            &semaphores[semaphores.size() - 1]};
33070         err = vkQueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE);
33071         ASSERT_VK_SUCCESS(err);
33072     }
33073 
33074     VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
33075     VkFence fence;
33076     err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
33077     ASSERT_VK_SUCCESS(err);
33078     VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &semaphores.back(), &flags, 0, nullptr, 0, nullptr};
33079     err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
33080     ASSERT_VK_SUCCESS(err);
33081 
33082     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
33083 
33084     for (auto semaphore : semaphores) vkDestroySemaphore(m_device->device(), semaphore, nullptr);
33085 
33086     vkDestroyFence(m_device->device(), fence, nullptr);
33087 
33088     m_errorMonitor->VerifyNotFound();
33089 }
33090 
TEST_F(VkPositiveLayerTest,ExternalSemaphore)33091 TEST_F(VkPositiveLayerTest, ExternalSemaphore) {
33092 #ifdef _WIN32
33093     const auto extension_name = VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME;
33094     const auto handle_type = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR;
33095 #else
33096     const auto extension_name = VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME;
33097     const auto handle_type = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
33098 #endif
33099     // Check for external semaphore instance extensions
33100     if (InstanceExtensionSupported(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME)) {
33101         m_instance_extension_names.push_back(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
33102         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
33103     } else {
33104         printf("%s External semaphore extension not supported, skipping test\n", kSkipPrefix);
33105         return;
33106     }
33107     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
33108 
33109     // Check for external semaphore device extensions
33110     if (DeviceExtensionSupported(gpu(), nullptr, extension_name)) {
33111         m_device_extension_names.push_back(extension_name);
33112         m_device_extension_names.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
33113     } else {
33114         printf("%s External semaphore extension not supported, skipping test\n", kSkipPrefix);
33115         return;
33116     }
33117     ASSERT_NO_FATAL_FAILURE(InitState());
33118 
33119     // Check for external semaphore import and export capability
33120     VkPhysicalDeviceExternalSemaphoreInfoKHR esi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR, nullptr,
33121                                                     handle_type};
33122     VkExternalSemaphorePropertiesKHR esp = {VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR, nullptr};
33123     auto vkGetPhysicalDeviceExternalSemaphorePropertiesKHR =
33124         (PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)vkGetInstanceProcAddr(
33125             instance(), "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR");
33126     vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(gpu(), &esi, &esp);
33127 
33128     if (!(esp.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR) ||
33129         !(esp.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR)) {
33130         printf("%s External semaphore does not support importing and exporting, skipping test\n", kSkipPrefix);
33131         return;
33132     }
33133 
33134     VkResult err;
33135     m_errorMonitor->ExpectSuccess();
33136 
33137     // Create a semaphore to export payload from
33138     VkExportSemaphoreCreateInfoKHR esci = {VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR, nullptr, handle_type};
33139     VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &esci, 0};
33140 
33141     VkSemaphore export_semaphore;
33142     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &export_semaphore);
33143     ASSERT_VK_SUCCESS(err);
33144 
33145     // Create a semaphore to import payload into
33146     sci.pNext = nullptr;
33147     VkSemaphore import_semaphore;
33148     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &import_semaphore);
33149     ASSERT_VK_SUCCESS(err);
33150 
33151 #ifdef _WIN32
33152     // Export semaphore payload to an opaque handle
33153     HANDLE handle = nullptr;
33154     VkSemaphoreGetWin32HandleInfoKHR ghi = {VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR, nullptr, export_semaphore,
33155                                             handle_type};
33156     auto vkGetSemaphoreWin32HandleKHR =
33157         (PFN_vkGetSemaphoreWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetSemaphoreWin32HandleKHR");
33158     err = vkGetSemaphoreWin32HandleKHR(m_device->device(), &ghi, &handle);
33159     ASSERT_VK_SUCCESS(err);
33160 
33161     // Import opaque handle exported above
33162     VkImportSemaphoreWin32HandleInfoKHR ihi = {
33163         VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR, nullptr, import_semaphore, 0, handle_type, handle, nullptr};
33164     auto vkImportSemaphoreWin32HandleKHR =
33165         (PFN_vkImportSemaphoreWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportSemaphoreWin32HandleKHR");
33166     err = vkImportSemaphoreWin32HandleKHR(m_device->device(), &ihi);
33167     ASSERT_VK_SUCCESS(err);
33168 #else
33169     // Export semaphore payload to an opaque handle
33170     int fd = 0;
33171     VkSemaphoreGetFdInfoKHR ghi = {VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR, nullptr, export_semaphore, handle_type};
33172     auto vkGetSemaphoreFdKHR = (PFN_vkGetSemaphoreFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetSemaphoreFdKHR");
33173     err = vkGetSemaphoreFdKHR(m_device->device(), &ghi, &fd);
33174     ASSERT_VK_SUCCESS(err);
33175 
33176     // Import opaque handle exported above
33177     VkImportSemaphoreFdInfoKHR ihi = {
33178         VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR, nullptr, import_semaphore, 0, handle_type, fd};
33179     auto vkImportSemaphoreFdKHR = (PFN_vkImportSemaphoreFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportSemaphoreFdKHR");
33180     err = vkImportSemaphoreFdKHR(m_device->device(), &ihi);
33181     ASSERT_VK_SUCCESS(err);
33182 #endif
33183 
33184     // Signal the exported semaphore and wait on the imported semaphore
33185     VkPipelineStageFlags flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
33186     VkSubmitInfo si[] = {
33187         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, &flags, 0, nullptr, 1, &export_semaphore},
33188         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &import_semaphore, &flags, 0, nullptr, 0, nullptr},
33189         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, &flags, 0, nullptr, 1, &export_semaphore},
33190         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &import_semaphore, &flags, 0, nullptr, 0, nullptr},
33191     };
33192     err = vkQueueSubmit(m_device->m_queue, 4, si, VK_NULL_HANDLE);
33193     ASSERT_VK_SUCCESS(err);
33194 
33195     if (m_device->phy().features().sparseBinding) {
33196         // Signal the imported semaphore and wait on the exported semaphore
33197         VkBindSparseInfo bi[] = {
33198             {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 1, &import_semaphore},
33199             {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 1, &export_semaphore, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr},
33200             {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 1, &import_semaphore},
33201             {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 1, &export_semaphore, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr},
33202         };
33203         err = vkQueueBindSparse(m_device->m_queue, 4, bi, VK_NULL_HANDLE);
33204         ASSERT_VK_SUCCESS(err);
33205     }
33206 
33207     // Cleanup
33208     err = vkQueueWaitIdle(m_device->m_queue);
33209     ASSERT_VK_SUCCESS(err);
33210     vkDestroySemaphore(m_device->device(), export_semaphore, nullptr);
33211     vkDestroySemaphore(m_device->device(), import_semaphore, nullptr);
33212 
33213     m_errorMonitor->VerifyNotFound();
33214 }
33215 
TEST_F(VkPositiveLayerTest,ExternalFence)33216 TEST_F(VkPositiveLayerTest, ExternalFence) {
33217 #ifdef _WIN32
33218     const auto extension_name = VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME;
33219     const auto handle_type = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
33220 #else
33221     const auto extension_name = VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME;
33222     const auto handle_type = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
33223 #endif
33224     // Check for external fence instance extensions
33225     if (InstanceExtensionSupported(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME)) {
33226         m_instance_extension_names.push_back(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME);
33227         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
33228     } else {
33229         printf("%s External fence extension not supported, skipping test\n", kSkipPrefix);
33230         return;
33231     }
33232     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
33233 
33234     // Check for external fence device extensions
33235     if (DeviceExtensionSupported(gpu(), nullptr, extension_name)) {
33236         m_device_extension_names.push_back(extension_name);
33237         m_device_extension_names.push_back(VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME);
33238     } else {
33239         printf("%s External fence extension not supported, skipping test\n", kSkipPrefix);
33240         return;
33241     }
33242     ASSERT_NO_FATAL_FAILURE(InitState());
33243 
33244     // Check for external fence import and export capability
33245     VkPhysicalDeviceExternalFenceInfoKHR efi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR, nullptr, handle_type};
33246     VkExternalFencePropertiesKHR efp = {VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR, nullptr};
33247     auto vkGetPhysicalDeviceExternalFencePropertiesKHR = (PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR)vkGetInstanceProcAddr(
33248         instance(), "vkGetPhysicalDeviceExternalFencePropertiesKHR");
33249     vkGetPhysicalDeviceExternalFencePropertiesKHR(gpu(), &efi, &efp);
33250 
33251     if (!(efp.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR) ||
33252         !(efp.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR)) {
33253         printf("%s External fence does not support importing and exporting, skipping test\n", kSkipPrefix);
33254         return;
33255     }
33256 
33257     VkResult err;
33258     m_errorMonitor->ExpectSuccess();
33259 
33260     // Create a fence to export payload from
33261     VkFence export_fence;
33262     {
33263         VkExportFenceCreateInfoKHR efci = {VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR, nullptr, handle_type};
33264         VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, &efci, 0};
33265         err = vkCreateFence(m_device->device(), &fci, nullptr, &export_fence);
33266         ASSERT_VK_SUCCESS(err);
33267     }
33268 
33269     // Create a fence to import payload into
33270     VkFence import_fence;
33271     {
33272         VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
33273         err = vkCreateFence(m_device->device(), &fci, nullptr, &import_fence);
33274         ASSERT_VK_SUCCESS(err);
33275     }
33276 
33277 #ifdef _WIN32
33278     // Export fence payload to an opaque handle
33279     HANDLE handle = nullptr;
33280     {
33281         VkFenceGetWin32HandleInfoKHR ghi = {VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR, nullptr, export_fence, handle_type};
33282         auto vkGetFenceWin32HandleKHR =
33283             (PFN_vkGetFenceWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetFenceWin32HandleKHR");
33284         err = vkGetFenceWin32HandleKHR(m_device->device(), &ghi, &handle);
33285         ASSERT_VK_SUCCESS(err);
33286     }
33287 
33288     // Import opaque handle exported above
33289     {
33290         VkImportFenceWin32HandleInfoKHR ifi = {
33291             VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR, nullptr, import_fence, 0, handle_type, handle, nullptr};
33292         auto vkImportFenceWin32HandleKHR =
33293             (PFN_vkImportFenceWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportFenceWin32HandleKHR");
33294         err = vkImportFenceWin32HandleKHR(m_device->device(), &ifi);
33295         ASSERT_VK_SUCCESS(err);
33296     }
33297 #else
33298     // Export fence payload to an opaque handle
33299     int fd = 0;
33300     {
33301         VkFenceGetFdInfoKHR gfi = {VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR, nullptr, export_fence, handle_type};
33302         auto vkGetFenceFdKHR = (PFN_vkGetFenceFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetFenceFdKHR");
33303         err = vkGetFenceFdKHR(m_device->device(), &gfi, &fd);
33304         ASSERT_VK_SUCCESS(err);
33305     }
33306 
33307     // Import opaque handle exported above
33308     {
33309         VkImportFenceFdInfoKHR ifi = {VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR, nullptr, import_fence, 0, handle_type, fd};
33310         auto vkImportFenceFdKHR = (PFN_vkImportFenceFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportFenceFdKHR");
33311         err = vkImportFenceFdKHR(m_device->device(), &ifi);
33312         ASSERT_VK_SUCCESS(err);
33313     }
33314 #endif
33315 
33316     // Signal the exported fence and wait on the imported fence
33317     vkQueueSubmit(m_device->m_queue, 0, nullptr, export_fence);
33318     vkWaitForFences(m_device->device(), 1, &import_fence, VK_TRUE, 1000000000);
33319     vkResetFences(m_device->device(), 1, &import_fence);
33320     vkQueueSubmit(m_device->m_queue, 0, nullptr, export_fence);
33321     vkWaitForFences(m_device->device(), 1, &import_fence, VK_TRUE, 1000000000);
33322     vkResetFences(m_device->device(), 1, &import_fence);
33323 
33324     // Signal the imported fence and wait on the exported fence
33325     vkQueueSubmit(m_device->m_queue, 0, nullptr, import_fence);
33326     vkWaitForFences(m_device->device(), 1, &export_fence, VK_TRUE, 1000000000);
33327     vkResetFences(m_device->device(), 1, &export_fence);
33328     vkQueueSubmit(m_device->m_queue, 0, nullptr, import_fence);
33329     vkWaitForFences(m_device->device(), 1, &export_fence, VK_TRUE, 1000000000);
33330     vkResetFences(m_device->device(), 1, &export_fence);
33331 
33332     // Cleanup
33333     err = vkQueueWaitIdle(m_device->m_queue);
33334     ASSERT_VK_SUCCESS(err);
33335     vkDestroyFence(m_device->device(), export_fence, nullptr);
33336     vkDestroyFence(m_device->device(), import_fence, nullptr);
33337 
33338     m_errorMonitor->VerifyNotFound();
33339 }
33340 
ReleaseNullFence(void * arg)33341 extern "C" void *ReleaseNullFence(void *arg) {
33342     struct thread_data_struct *data = (struct thread_data_struct *)arg;
33343 
33344     for (int i = 0; i < 40000; i++) {
33345         vkDestroyFence(data->device, VK_NULL_HANDLE, NULL);
33346         if (data->bailout) {
33347             break;
33348         }
33349     }
33350     return NULL;
33351 }
33352 
TEST_F(VkPositiveLayerTest,ThreadNullFenceCollision)33353 TEST_F(VkPositiveLayerTest, ThreadNullFenceCollision) {
33354     test_platform_thread thread;
33355 
33356     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "THREADING ERROR");
33357 
33358     ASSERT_NO_FATAL_FAILURE(Init());
33359 
33360     struct thread_data_struct data;
33361     data.device = m_device->device();
33362     data.bailout = false;
33363     m_errorMonitor->SetBailout(&data.bailout);
33364 
33365     // Call vkDestroyFence of VK_NULL_HANDLE repeatedly using multiple threads.
33366     // There should be no validation error from collision of that non-object.
33367     test_platform_thread_create(&thread, ReleaseNullFence, (void *)&data);
33368     for (int i = 0; i < 40000; i++) {
33369         vkDestroyFence(m_device->device(), VK_NULL_HANDLE, NULL);
33370     }
33371     test_platform_thread_join(thread, NULL);
33372 
33373     m_errorMonitor->SetBailout(NULL);
33374 
33375     m_errorMonitor->VerifyNotFound();
33376 }
33377 
TEST_F(VkPositiveLayerTest,ClearColorImageWithValidRange)33378 TEST_F(VkPositiveLayerTest, ClearColorImageWithValidRange) {
33379     TEST_DESCRIPTION("Record clear color with a valid VkImageSubresourceRange");
33380 
33381     ASSERT_NO_FATAL_FAILURE(Init());
33382     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
33383 
33384     VkImageObj image(m_device);
33385     image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
33386     ASSERT_TRUE(image.create_info().arrayLayers == 1);
33387     ASSERT_TRUE(image.initialized());
33388     image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
33389 
33390     const VkClearColorValue clear_color = {{0.0f, 0.0f, 0.0f, 1.0f}};
33391 
33392     m_commandBuffer->begin();
33393     const auto cb_handle = m_commandBuffer->handle();
33394 
33395     // Try good case
33396     {
33397         m_errorMonitor->ExpectSuccess();
33398         VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
33399         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
33400         m_errorMonitor->VerifyNotFound();
33401     }
33402 
33403     // Try good case with VK_REMAINING
33404     {
33405         m_errorMonitor->ExpectSuccess();
33406         VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS};
33407         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
33408         m_errorMonitor->VerifyNotFound();
33409     }
33410 }
33411 
TEST_F(VkPositiveLayerTest,ClearDepthStencilWithValidRange)33412 TEST_F(VkPositiveLayerTest, ClearDepthStencilWithValidRange) {
33413     TEST_DESCRIPTION("Record clear depth with a valid VkImageSubresourceRange");
33414 
33415     ASSERT_NO_FATAL_FAILURE(Init());
33416     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
33417 
33418     auto depth_format = FindSupportedDepthStencilFormat(gpu());
33419     if (!depth_format) {
33420         printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
33421         return;
33422     }
33423 
33424     VkImageObj image(m_device);
33425     image.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
33426     ASSERT_TRUE(image.create_info().arrayLayers == 1);
33427     ASSERT_TRUE(image.initialized());
33428     const VkImageAspectFlags ds_aspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
33429     image.SetLayout(ds_aspect, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
33430 
33431     const VkClearDepthStencilValue clear_value = {};
33432 
33433     m_commandBuffer->begin();
33434     const auto cb_handle = m_commandBuffer->handle();
33435 
33436     // Try good case
33437     {
33438         m_errorMonitor->ExpectSuccess();
33439         VkImageSubresourceRange range = {ds_aspect, 0, 1, 0, 1};
33440         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
33441         m_errorMonitor->VerifyNotFound();
33442     }
33443 
33444     // Try good case with VK_REMAINING
33445     {
33446         m_errorMonitor->ExpectSuccess();
33447         VkImageSubresourceRange range = {ds_aspect, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS};
33448         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
33449         m_errorMonitor->VerifyNotFound();
33450     }
33451 }
33452 
TEST_F(VkPositiveLayerTest,CreateGraphicsPipelineWithIgnoredPointers)33453 TEST_F(VkPositiveLayerTest, CreateGraphicsPipelineWithIgnoredPointers) {
33454     TEST_DESCRIPTION("Create Graphics Pipeline with pointers that must be ignored by layers");
33455 
33456     ASSERT_NO_FATAL_FAILURE(Init());
33457 
33458     m_depth_stencil_fmt = FindSupportedDepthStencilFormat(gpu());
33459     ASSERT_TRUE(m_depth_stencil_fmt != 0);
33460 
33461     m_depthStencil->Init(m_device, static_cast<int32_t>(m_width), static_cast<int32_t>(m_height), m_depth_stencil_fmt);
33462 
33463     ASSERT_NO_FATAL_FAILURE(InitRenderTarget(m_depthStencil->BindInfo()));
33464 
33465     const uint64_t fake_address_64 = 0xCDCDCDCDCDCDCDCD;
33466     const uint64_t fake_address_32 = 0xCDCDCDCD;
33467     void *hopefully_undereferencable_pointer =
33468         sizeof(void *) == 8 ? reinterpret_cast<void *>(fake_address_64) : reinterpret_cast<void *>(fake_address_32);
33469 
33470     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,
33471                    this);
33472 
33473     const VkPipelineVertexInputStateCreateInfo pipeline_vertex_input_state_create_info{
33474         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
33475         nullptr,  // pNext
33476         0,        // flags
33477         0,
33478         nullptr,  // bindings
33479         0,
33480         nullptr  // attributes
33481     };
33482 
33483     const VkPipelineInputAssemblyStateCreateInfo pipeline_input_assembly_state_create_info{
33484         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
33485         nullptr,  // pNext
33486         0,        // flags
33487         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
33488         VK_FALSE  // primitive restart
33489     };
33490 
33491     const VkPipelineRasterizationStateCreateInfo pipeline_rasterization_state_create_info_template{
33492         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
33493         nullptr,   // pNext
33494         0,         // flags
33495         VK_FALSE,  // depthClamp
33496         VK_FALSE,  // rasterizerDiscardEnable
33497         VK_POLYGON_MODE_FILL,
33498         VK_CULL_MODE_NONE,
33499         VK_FRONT_FACE_COUNTER_CLOCKWISE,
33500         VK_FALSE,  // depthBias
33501         0.0f,
33502         0.0f,
33503         0.0f,  // depthBias params
33504         1.0f   // lineWidth
33505     };
33506 
33507     VkPipelineLayout pipeline_layout;
33508     {
33509         VkPipelineLayoutCreateInfo pipeline_layout_create_info{
33510             VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
33511             nullptr,  // pNext
33512             0,        // flags
33513             0,
33514             nullptr,  // layouts
33515             0,
33516             nullptr  // push constants
33517         };
33518 
33519         VkResult err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_create_info, nullptr, &pipeline_layout);
33520         ASSERT_VK_SUCCESS(err);
33521     }
33522 
33523     // try disabled rasterizer and no tessellation
33524     {
33525         m_errorMonitor->ExpectSuccess();
33526 
33527         VkPipelineRasterizationStateCreateInfo pipeline_rasterization_state_create_info =
33528             pipeline_rasterization_state_create_info_template;
33529         pipeline_rasterization_state_create_info.rasterizerDiscardEnable = VK_TRUE;
33530 
33531         VkGraphicsPipelineCreateInfo graphics_pipeline_create_info{
33532             VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
33533             nullptr,  // pNext
33534             0,        // flags
33535             1,        // stageCount
33536             &vs.GetStageCreateInfo(),
33537             &pipeline_vertex_input_state_create_info,
33538             &pipeline_input_assembly_state_create_info,
33539             reinterpret_cast<const VkPipelineTessellationStateCreateInfo *>(hopefully_undereferencable_pointer),
33540             reinterpret_cast<const VkPipelineViewportStateCreateInfo *>(hopefully_undereferencable_pointer),
33541             &pipeline_rasterization_state_create_info,
33542             reinterpret_cast<const VkPipelineMultisampleStateCreateInfo *>(hopefully_undereferencable_pointer),
33543             reinterpret_cast<const VkPipelineDepthStencilStateCreateInfo *>(hopefully_undereferencable_pointer),
33544             reinterpret_cast<const VkPipelineColorBlendStateCreateInfo *>(hopefully_undereferencable_pointer),
33545             nullptr,  // dynamic states
33546             pipeline_layout,
33547             m_renderPass,
33548             0,  // subpass
33549             VK_NULL_HANDLE,
33550             0};
33551 
33552         VkPipeline pipeline;
33553         vkCreateGraphicsPipelines(m_device->handle(), VK_NULL_HANDLE, 1, &graphics_pipeline_create_info, nullptr, &pipeline);
33554 
33555         m_errorMonitor->VerifyNotFound();
33556 
33557         vkDestroyPipeline(m_device->handle(), pipeline, nullptr);
33558     }
33559 
33560     const VkPipelineMultisampleStateCreateInfo pipeline_multisample_state_create_info{
33561         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
33562         nullptr,  // pNext
33563         0,        // flags
33564         VK_SAMPLE_COUNT_1_BIT,
33565         VK_FALSE,  // sample shading
33566         0.0f,      // minSampleShading
33567         nullptr,   // pSampleMask
33568         VK_FALSE,  // alphaToCoverageEnable
33569         VK_FALSE   // alphaToOneEnable
33570     };
33571 
33572     // try enabled rasterizer but no subpass attachments
33573     {
33574         m_errorMonitor->ExpectSuccess();
33575 
33576         VkPipelineRasterizationStateCreateInfo pipeline_rasterization_state_create_info =
33577             pipeline_rasterization_state_create_info_template;
33578         pipeline_rasterization_state_create_info.rasterizerDiscardEnable = VK_FALSE;
33579 
33580         VkViewport viewport = {0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f};
33581         VkRect2D scissor = {{0, 0}, {static_cast<uint32_t>(m_width), static_cast<uint32_t>(m_height)}};
33582 
33583         const VkPipelineViewportStateCreateInfo pipeline_viewport_state_create_info{
33584             VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
33585             nullptr,  // pNext
33586             0,        // flags
33587             1,
33588             &viewport,
33589             1,
33590             &scissor};
33591 
33592         VkRenderPass render_pass;
33593         {
33594             VkSubpassDescription subpass_desc = {};
33595 
33596             VkRenderPassCreateInfo render_pass_create_info{
33597                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
33598                 nullptr,  // pNext
33599                 0,        // flags
33600                 0,
33601                 nullptr,  // attachments
33602                 1,
33603                 &subpass_desc,
33604                 0,
33605                 nullptr  // subpass dependencies
33606             };
33607 
33608             VkResult err = vkCreateRenderPass(m_device->handle(), &render_pass_create_info, nullptr, &render_pass);
33609             ASSERT_VK_SUCCESS(err);
33610         }
33611 
33612         VkGraphicsPipelineCreateInfo graphics_pipeline_create_info{
33613             VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
33614             nullptr,  // pNext
33615             0,        // flags
33616             1,        // stageCount
33617             &vs.GetStageCreateInfo(),
33618             &pipeline_vertex_input_state_create_info,
33619             &pipeline_input_assembly_state_create_info,
33620             nullptr,
33621             &pipeline_viewport_state_create_info,
33622             &pipeline_rasterization_state_create_info,
33623             &pipeline_multisample_state_create_info,
33624             reinterpret_cast<const VkPipelineDepthStencilStateCreateInfo *>(hopefully_undereferencable_pointer),
33625             reinterpret_cast<const VkPipelineColorBlendStateCreateInfo *>(hopefully_undereferencable_pointer),
33626             nullptr,  // dynamic states
33627             pipeline_layout,
33628             render_pass,
33629             0,  // subpass
33630             VK_NULL_HANDLE,
33631             0};
33632 
33633         VkPipeline pipeline;
33634         vkCreateGraphicsPipelines(m_device->handle(), VK_NULL_HANDLE, 1, &graphics_pipeline_create_info, nullptr, &pipeline);
33635 
33636         m_errorMonitor->VerifyNotFound();
33637 
33638         vkDestroyPipeline(m_device->handle(), pipeline, nullptr);
33639         vkDestroyRenderPass(m_device->handle(), render_pass, nullptr);
33640     }
33641 
33642     // try dynamic viewport and scissor
33643     {
33644         m_errorMonitor->ExpectSuccess();
33645 
33646         VkPipelineRasterizationStateCreateInfo pipeline_rasterization_state_create_info =
33647             pipeline_rasterization_state_create_info_template;
33648         pipeline_rasterization_state_create_info.rasterizerDiscardEnable = VK_FALSE;
33649 
33650         const VkPipelineViewportStateCreateInfo pipeline_viewport_state_create_info{
33651             VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
33652             nullptr,  // pNext
33653             0,        // flags
33654             1,
33655             reinterpret_cast<const VkViewport *>(hopefully_undereferencable_pointer),
33656             1,
33657             reinterpret_cast<const VkRect2D *>(hopefully_undereferencable_pointer)};
33658 
33659         const VkPipelineDepthStencilStateCreateInfo pipeline_depth_stencil_state_create_info{
33660             VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
33661             nullptr,  // pNext
33662             0,        // flags
33663         };
33664 
33665         const VkPipelineColorBlendAttachmentState pipeline_color_blend_attachment_state = {};
33666 
33667         const VkPipelineColorBlendStateCreateInfo pipeline_color_blend_state_create_info{
33668             VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
33669             nullptr,  // pNext
33670             0,        // flags
33671             VK_FALSE,
33672             VK_LOGIC_OP_CLEAR,
33673             1,
33674             &pipeline_color_blend_attachment_state,
33675             {0.0f, 0.0f, 0.0f, 0.0f}};
33676 
33677         const VkDynamicState dynamic_states[2] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
33678 
33679         const VkPipelineDynamicStateCreateInfo pipeline_dynamic_state_create_info{
33680             VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
33681             nullptr,  // pNext
33682             0,        // flags
33683             2, dynamic_states};
33684 
33685         VkGraphicsPipelineCreateInfo graphics_pipeline_create_info{VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
33686                                                                    nullptr,  // pNext
33687                                                                    0,        // flags
33688                                                                    1,        // stageCount
33689                                                                    &vs.GetStageCreateInfo(),
33690                                                                    &pipeline_vertex_input_state_create_info,
33691                                                                    &pipeline_input_assembly_state_create_info,
33692                                                                    nullptr,
33693                                                                    &pipeline_viewport_state_create_info,
33694                                                                    &pipeline_rasterization_state_create_info,
33695                                                                    &pipeline_multisample_state_create_info,
33696                                                                    &pipeline_depth_stencil_state_create_info,
33697                                                                    &pipeline_color_blend_state_create_info,
33698                                                                    &pipeline_dynamic_state_create_info,  // dynamic states
33699                                                                    pipeline_layout,
33700                                                                    m_renderPass,
33701                                                                    0,  // subpass
33702                                                                    VK_NULL_HANDLE,
33703                                                                    0};
33704 
33705         VkPipeline pipeline;
33706         vkCreateGraphicsPipelines(m_device->handle(), VK_NULL_HANDLE, 1, &graphics_pipeline_create_info, nullptr, &pipeline);
33707 
33708         m_errorMonitor->VerifyNotFound();
33709 
33710         vkDestroyPipeline(m_device->handle(), pipeline, nullptr);
33711     }
33712 
33713     vkDestroyPipelineLayout(m_device->handle(), pipeline_layout, nullptr);
33714 }
33715 
TEST_F(VkPositiveLayerTest,ExternalMemory)33716 TEST_F(VkPositiveLayerTest, ExternalMemory) {
33717     TEST_DESCRIPTION("Perform a copy through a pair of buffers linked by external memory");
33718 
33719 #ifdef _WIN32
33720     const auto ext_mem_extension_name = VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME;
33721     const auto handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
33722 #else
33723     const auto ext_mem_extension_name = VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME;
33724     const auto handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
33725 #endif
33726 
33727     // Check for external memory instance extensions
33728     std::vector<const char *> reqd_instance_extensions = {
33729         {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME}};
33730     for (auto extension_name : reqd_instance_extensions) {
33731         if (InstanceExtensionSupported(extension_name)) {
33732             m_instance_extension_names.push_back(extension_name);
33733         } else {
33734             printf("%s Required instance extension %s not supported, skipping test\n", kSkipPrefix, extension_name);
33735             return;
33736         }
33737     }
33738 
33739     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
33740 
33741     // Check for import/export capability
33742     VkPhysicalDeviceExternalBufferInfoKHR ebi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR, nullptr, 0,
33743                                                  VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, handle_type};
33744     VkExternalBufferPropertiesKHR ebp = {VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR, nullptr, {0, 0, 0}};
33745     auto vkGetPhysicalDeviceExternalBufferPropertiesKHR = (PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR)vkGetInstanceProcAddr(
33746         instance(), "vkGetPhysicalDeviceExternalBufferPropertiesKHR");
33747     ASSERT_TRUE(vkGetPhysicalDeviceExternalBufferPropertiesKHR != nullptr);
33748     vkGetPhysicalDeviceExternalBufferPropertiesKHR(gpu(), &ebi, &ebp);
33749     if (!(ebp.externalMemoryProperties.compatibleHandleTypes & handle_type) ||
33750         !(ebp.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR) ||
33751         !(ebp.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR)) {
33752         printf("%s External buffer does not support importing and exporting, skipping test\n", kSkipPrefix);
33753         return;
33754     }
33755 
33756     // Check if dedicated allocation is required
33757     bool dedicated_allocation =
33758         ebp.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR;
33759     if (dedicated_allocation) {
33760         if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME)) {
33761             m_device_extension_names.push_back(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
33762             m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
33763         } else {
33764             printf("%s Dedicated allocation extension not supported, skipping test\n", kSkipPrefix);
33765             return;
33766         }
33767     }
33768 
33769     // Check for external memory device extensions
33770     if (DeviceExtensionSupported(gpu(), nullptr, ext_mem_extension_name)) {
33771         m_device_extension_names.push_back(ext_mem_extension_name);
33772         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
33773     } else {
33774         printf("%s External memory extension not supported, skipping test\n", kSkipPrefix);
33775         return;
33776     }
33777     ASSERT_NO_FATAL_FAILURE(InitState());
33778 
33779     m_errorMonitor->ExpectSuccess(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT);
33780 
33781     VkMemoryPropertyFlags mem_flags = 0;
33782     const VkDeviceSize buffer_size = 1024;
33783 
33784     // Create export and import buffers
33785     const VkExternalMemoryBufferCreateInfoKHR external_buffer_info = {VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR,
33786                                                                       nullptr, handle_type};
33787     auto buffer_info = VkBufferObj::create_info(buffer_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
33788     buffer_info.pNext = &external_buffer_info;
33789     VkBufferObj buffer_export;
33790     buffer_export.init_no_mem(*m_device, buffer_info);
33791     VkBufferObj buffer_import;
33792     buffer_import.init_no_mem(*m_device, buffer_info);
33793 
33794     // Allocation info
33795     auto alloc_info = vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, buffer_export.memory_requirements(), mem_flags);
33796 
33797     // Add export allocation info to pNext chain
33798     VkExportMemoryAllocateInfoKHR export_info = {VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR, nullptr, handle_type};
33799     alloc_info.pNext = &export_info;
33800 
33801     // Add dedicated allocation info to pNext chain if required
33802     VkMemoryDedicatedAllocateInfoKHR dedicated_info = {VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR, nullptr,
33803                                                        VK_NULL_HANDLE, buffer_export.handle()};
33804     if (dedicated_allocation) {
33805         export_info.pNext = &dedicated_info;
33806     }
33807 
33808     // Allocate memory to be exported
33809     vk_testing::DeviceMemory memory_export;
33810     memory_export.init(*m_device, alloc_info);
33811 
33812     // Bind exported memory
33813     buffer_export.bind_memory(memory_export, 0);
33814 
33815 #ifdef _WIN32
33816     // Export memory to handle
33817     auto vkGetMemoryWin32HandleKHR = (PFN_vkGetMemoryWin32HandleKHR)vkGetInstanceProcAddr(instance(), "vkGetMemoryWin32HandleKHR");
33818     ASSERT_TRUE(vkGetMemoryWin32HandleKHR != nullptr);
33819     VkMemoryGetWin32HandleInfoKHR mghi = {VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR, nullptr, memory_export.handle(),
33820                                           handle_type};
33821     HANDLE handle;
33822     ASSERT_VK_SUCCESS(vkGetMemoryWin32HandleKHR(m_device->device(), &mghi, &handle));
33823 
33824     VkImportMemoryWin32HandleInfoKHR import_info = {VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR, nullptr, handle_type,
33825                                                     handle};
33826 #else
33827     // Export memory to fd
33828     auto vkGetMemoryFdKHR = (PFN_vkGetMemoryFdKHR)vkGetInstanceProcAddr(instance(), "vkGetMemoryFdKHR");
33829     ASSERT_TRUE(vkGetMemoryFdKHR != nullptr);
33830     VkMemoryGetFdInfoKHR mgfi = {VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR, nullptr, memory_export.handle(), handle_type};
33831     int fd;
33832     ASSERT_VK_SUCCESS(vkGetMemoryFdKHR(m_device->device(), &mgfi, &fd));
33833 
33834     VkImportMemoryFdInfoKHR import_info = {VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, nullptr, handle_type, fd};
33835 #endif
33836 
33837     // Import memory
33838     alloc_info = vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, buffer_import.memory_requirements(), mem_flags);
33839     alloc_info.pNext = &import_info;
33840     vk_testing::DeviceMemory memory_import;
33841     memory_import.init(*m_device, alloc_info);
33842 
33843     // Bind imported memory
33844     buffer_import.bind_memory(memory_import, 0);
33845 
33846     // Create test buffers and fill input buffer
33847     VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
33848     VkBufferObj buffer_input;
33849     buffer_input.init_as_src_and_dst(*m_device, buffer_size, mem_prop);
33850     auto input_mem = (uint8_t *)buffer_input.memory().map();
33851     for (uint32_t i = 0; i < buffer_size; i++) {
33852         input_mem[i] = (i & 0xFF);
33853     }
33854     buffer_input.memory().unmap();
33855     VkBufferObj buffer_output;
33856     buffer_output.init_as_src_and_dst(*m_device, buffer_size, mem_prop);
33857 
33858     // Copy from input buffer to output buffer through the exported/imported memory
33859     m_commandBuffer->begin();
33860     VkBufferCopy copy_info = {0, 0, buffer_size};
33861     vkCmdCopyBuffer(m_commandBuffer->handle(), buffer_input.handle(), buffer_export.handle(), 1, &copy_info);
33862     // Insert memory barrier to guarantee copy order
33863     VkMemoryBarrier mem_barrier = {VK_STRUCTURE_TYPE_MEMORY_BARRIER, nullptr, VK_ACCESS_TRANSFER_WRITE_BIT,
33864                                    VK_ACCESS_TRANSFER_READ_BIT};
33865     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
33866                          &mem_barrier, 0, nullptr, 0, nullptr);
33867     vkCmdCopyBuffer(m_commandBuffer->handle(), buffer_import.handle(), buffer_output.handle(), 1, &copy_info);
33868     m_commandBuffer->end();
33869     m_commandBuffer->QueueCommandBuffer();
33870 
33871     m_errorMonitor->VerifyNotFound();
33872 }
33873 
TEST_F(VkLayerTest,AMDMixedAttachmentSamplesValidateGraphicsPipeline)33874 TEST_F(VkLayerTest, AMDMixedAttachmentSamplesValidateGraphicsPipeline) {
33875     TEST_DESCRIPTION("Verify an error message for an incorrect graphics pipeline rasterization sample count.");
33876 
33877     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
33878     if (DeviceExtensionSupported(gpu(), nullptr, VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME)) {
33879         m_device_extension_names.push_back(VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME);
33880     } else {
33881         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME);
33882         return;
33883     }
33884     ASSERT_NO_FATAL_FAILURE(InitState());
33885 
33886     VkRenderpassObj render_pass(m_device);
33887 
33888     const VkPipelineLayoutObj pipeline_layout(m_device);
33889 
33890     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
33891     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
33892 
33893     // Set a mismatched sample count
33894 
33895     VkPipelineMultisampleStateCreateInfo ms_state_ci = {};
33896     ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
33897     ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
33898 
33899     VkPipelineObj pipe(m_device);
33900     pipe.AddShader(&vs);
33901     pipe.AddShader(&fs);
33902     pipe.AddDefaultColorAttachment();
33903     pipe.SetMSAA(&ms_state_ci);
33904 
33905     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGraphicsPipelineCreateInfo-subpass-01505");
33906 
33907     pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle());
33908 
33909     m_errorMonitor->VerifyFound();
33910 }
33911 
TEST_F(VkPositiveLayerTest,ParameterLayerFeatures2Capture)33912 TEST_F(VkPositiveLayerTest, ParameterLayerFeatures2Capture) {
33913     TEST_DESCRIPTION("Ensure parameter_validation_layer correctly captures physical device features");
33914     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
33915         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
33916     } else {
33917         printf("%s Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n", kSkipPrefix);
33918         return;
33919     }
33920 
33921     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
33922 
33923     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
33924         (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
33925     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
33926 
33927     VkResult err;
33928     m_errorMonitor->ExpectSuccess();
33929 
33930     VkPhysicalDeviceFeatures2KHR features2;
33931     features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
33932     features2.pNext = nullptr;
33933 
33934     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
33935 
33936     // We're not creating a valid m_device, but the phy wrapper is useful
33937     vk_testing::PhysicalDevice physical_device(gpu());
33938     vk_testing::QueueCreateInfoArray queue_info(physical_device.queue_properties());
33939     // Only request creation with queuefamilies that have at least one queue
33940     std::vector<VkDeviceQueueCreateInfo> create_queue_infos;
33941     auto qci = queue_info.data();
33942     for (uint32_t i = 0; i < queue_info.size(); ++i) {
33943         if (qci[i].queueCount) {
33944             create_queue_infos.push_back(qci[i]);
33945         }
33946     }
33947 
33948     VkDeviceCreateInfo dev_info = {};
33949     dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
33950     dev_info.pNext = &features2;
33951     dev_info.flags = 0;
33952     dev_info.queueCreateInfoCount = create_queue_infos.size();
33953     dev_info.pQueueCreateInfos = create_queue_infos.data();
33954     dev_info.enabledLayerCount = 0;
33955     dev_info.ppEnabledLayerNames = nullptr;
33956     dev_info.enabledExtensionCount = 0;
33957     dev_info.ppEnabledExtensionNames = nullptr;
33958     dev_info.pEnabledFeatures = nullptr;
33959 
33960     VkDevice device;
33961     err = vkCreateDevice(gpu(), &dev_info, nullptr, &device);
33962     ASSERT_VK_SUCCESS(err);
33963 
33964     if (features2.features.samplerAnisotropy) {
33965         // Test that the parameter layer is caching the features correctly using CreateSampler
33966         VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
33967         // If the features were not captured correctly, this should cause an error
33968         sampler_ci.anisotropyEnable = VK_TRUE;
33969         sampler_ci.maxAnisotropy = physical_device.properties().limits.maxSamplerAnisotropy;
33970 
33971         VkSampler sampler = VK_NULL_HANDLE;
33972         err = vkCreateSampler(device, &sampler_ci, nullptr, &sampler);
33973         ASSERT_VK_SUCCESS(err);
33974         vkDestroySampler(device, sampler, nullptr);
33975     } else {
33976         printf("%s Feature samplerAnisotropy not enabled;  parameter_layer check skipped.\n", kSkipPrefix);
33977     }
33978 
33979     // Verify the core validation layer has captured the physical device features by creating a a query pool.
33980     if (features2.features.pipelineStatisticsQuery) {
33981         VkQueryPool query_pool;
33982         VkQueryPoolCreateInfo qpci{};
33983         qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
33984         qpci.queryType = VK_QUERY_TYPE_PIPELINE_STATISTICS;
33985         qpci.queryCount = 1;
33986         err = vkCreateQueryPool(device, &qpci, nullptr, &query_pool);
33987         ASSERT_VK_SUCCESS(err);
33988 
33989         vkDestroyQueryPool(device, query_pool, nullptr);
33990     } else {
33991         printf("%s Feature pipelineStatisticsQuery not enabled;  core_validation_layer check skipped.\n", kSkipPrefix);
33992     }
33993 
33994     vkDestroyDevice(device, nullptr);
33995 
33996     m_errorMonitor->VerifyNotFound();
33997 }
33998 
TEST_F(VkPositiveLayerTest,GetMemoryRequirements2)33999 TEST_F(VkPositiveLayerTest, GetMemoryRequirements2) {
34000     TEST_DESCRIPTION(
34001         "Get memory requirements with VK_KHR_get_memory_requirements2 instead of core entry points and verify layers do not emit "
34002         "errors when objects are bound and used");
34003 
34004     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
34005 
34006     // Check for VK_KHR_get_memory_requirementes2 extensions
34007     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME)) {
34008         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
34009     } else {
34010         printf("%s %s not supported, skipping test\n", kSkipPrefix, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
34011         return;
34012     }
34013 
34014     ASSERT_NO_FATAL_FAILURE(InitState());
34015 
34016     m_errorMonitor->ExpectSuccess(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT);
34017 
34018     // Create a test buffer
34019     VkBufferObj buffer;
34020     buffer.init_no_mem(*m_device,
34021                        VkBufferObj::create_info(1024, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT));
34022 
34023     // Use extension to get buffer memory requirements
34024     auto vkGetBufferMemoryRequirements2KHR = reinterpret_cast<PFN_vkGetBufferMemoryRequirements2KHR>(
34025         vkGetDeviceProcAddr(m_device->device(), "vkGetBufferMemoryRequirements2KHR"));
34026     ASSERT_TRUE(vkGetBufferMemoryRequirements2KHR != nullptr);
34027     VkBufferMemoryRequirementsInfo2KHR buffer_info = {VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR, nullptr,
34028                                                       buffer.handle()};
34029     VkMemoryRequirements2KHR buffer_reqs = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR};
34030     vkGetBufferMemoryRequirements2KHR(m_device->device(), &buffer_info, &buffer_reqs);
34031 
34032     // Allocate and bind buffer memory
34033     vk_testing::DeviceMemory buffer_memory;
34034     buffer_memory.init(*m_device, vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, buffer_reqs.memoryRequirements, 0));
34035     vkBindBufferMemory(m_device->device(), buffer.handle(), buffer_memory.handle(), 0);
34036 
34037     // Create a test image
34038     auto image_ci = vk_testing::Image::create_info();
34039     image_ci.imageType = VK_IMAGE_TYPE_2D;
34040     image_ci.extent.width = 32;
34041     image_ci.extent.height = 32;
34042     image_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
34043     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
34044     image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
34045     vk_testing::Image image;
34046     image.init_no_mem(*m_device, image_ci);
34047 
34048     // Use extension to get image memory requirements
34049     auto vkGetImageMemoryRequirements2KHR = reinterpret_cast<PFN_vkGetImageMemoryRequirements2KHR>(
34050         vkGetDeviceProcAddr(m_device->device(), "vkGetImageMemoryRequirements2KHR"));
34051     ASSERT_TRUE(vkGetImageMemoryRequirements2KHR != nullptr);
34052     VkImageMemoryRequirementsInfo2KHR image_info = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR, nullptr,
34053                                                     image.handle()};
34054     VkMemoryRequirements2KHR image_reqs = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR};
34055     vkGetImageMemoryRequirements2KHR(m_device->device(), &image_info, &image_reqs);
34056 
34057     // Allocate and bind image memory
34058     vk_testing::DeviceMemory image_memory;
34059     image_memory.init(*m_device, vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, image_reqs.memoryRequirements, 0));
34060     vkBindImageMemory(m_device->device(), image.handle(), image_memory.handle(), 0);
34061 
34062     // Now execute arbitrary commands that use the test buffer and image
34063     m_commandBuffer->begin();
34064 
34065     // Fill buffer with 0
34066     vkCmdFillBuffer(m_commandBuffer->handle(), buffer.handle(), 0, VK_WHOLE_SIZE, 0);
34067 
34068     // Transition and clear image
34069     const auto subresource_range = image.subresource_range(VK_IMAGE_ASPECT_COLOR_BIT);
34070     const auto barrier = image.image_memory_barrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
34071                                                     VK_IMAGE_LAYOUT_GENERAL, subresource_range);
34072     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
34073                          nullptr, 0, nullptr, 1, &barrier);
34074     const VkClearColorValue color = {};
34075     vkCmdClearColorImage(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, &color, 1, &subresource_range);
34076 
34077     // Submit and verify no validation errors
34078     m_commandBuffer->end();
34079     m_commandBuffer->QueueCommandBuffer();
34080     m_errorMonitor->VerifyNotFound();
34081 }
34082 
TEST_F(VkPositiveLayerTest,BindMemory2)34083 TEST_F(VkPositiveLayerTest, BindMemory2) {
34084     TEST_DESCRIPTION(
34085         "Bind memory with VK_KHR_bind_memory2 instead of core entry points and verify layers do not emit errors when objects are "
34086         "used");
34087 
34088     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
34089 
34090     // Check for VK_KHR_get_memory_requirementes2 extensions
34091     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME)) {
34092         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
34093     } else {
34094         printf("%s %s not supported, skipping test\n", kSkipPrefix, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
34095         return;
34096     }
34097 
34098     ASSERT_NO_FATAL_FAILURE(InitState());
34099 
34100     m_errorMonitor->ExpectSuccess(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT);
34101 
34102     // Create a test buffer
34103     VkBufferObj buffer;
34104     buffer.init_no_mem(*m_device, VkBufferObj::create_info(1024, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
34105 
34106     // Allocate buffer memory
34107     vk_testing::DeviceMemory buffer_memory;
34108     buffer_memory.init(*m_device, vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, buffer.memory_requirements(), 0));
34109 
34110     // Bind buffer memory with extension
34111     auto vkBindBufferMemory2KHR =
34112         reinterpret_cast<PFN_vkBindBufferMemory2KHR>(vkGetDeviceProcAddr(m_device->device(), "vkBindBufferMemory2KHR"));
34113     ASSERT_TRUE(vkBindBufferMemory2KHR != nullptr);
34114     VkBindBufferMemoryInfoKHR buffer_bind_info = {VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR, nullptr, buffer.handle(),
34115                                                   buffer_memory.handle(), 0};
34116     vkBindBufferMemory2KHR(m_device->device(), 1, &buffer_bind_info);
34117 
34118     // Create a test image
34119     auto image_ci = vk_testing::Image::create_info();
34120     image_ci.imageType = VK_IMAGE_TYPE_2D;
34121     image_ci.extent.width = 32;
34122     image_ci.extent.height = 32;
34123     image_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
34124     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
34125     image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
34126     vk_testing::Image image;
34127     image.init_no_mem(*m_device, image_ci);
34128 
34129     // Allocate image memory
34130     vk_testing::DeviceMemory image_memory;
34131     image_memory.init(*m_device, vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, image.memory_requirements(), 0));
34132 
34133     // Bind image memory with extension
34134     auto vkBindImageMemory2KHR =
34135         reinterpret_cast<PFN_vkBindImageMemory2KHR>(vkGetDeviceProcAddr(m_device->device(), "vkBindImageMemory2KHR"));
34136     ASSERT_TRUE(vkBindImageMemory2KHR != nullptr);
34137     VkBindImageMemoryInfoKHR image_bind_info = {VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR, nullptr, image.handle(),
34138                                                 image_memory.handle(), 0};
34139     vkBindImageMemory2KHR(m_device->device(), 1, &image_bind_info);
34140 
34141     // Now execute arbitrary commands that use the test buffer and image
34142     m_commandBuffer->begin();
34143 
34144     // Fill buffer with 0
34145     vkCmdFillBuffer(m_commandBuffer->handle(), buffer.handle(), 0, VK_WHOLE_SIZE, 0);
34146 
34147     // Transition and clear image
34148     const auto subresource_range = image.subresource_range(VK_IMAGE_ASPECT_COLOR_BIT);
34149     const auto barrier = image.image_memory_barrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
34150                                                     VK_IMAGE_LAYOUT_GENERAL, subresource_range);
34151     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
34152                          nullptr, 0, nullptr, 1, &barrier);
34153     const VkClearColorValue color = {};
34154     vkCmdClearColorImage(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, &color, 1, &subresource_range);
34155 
34156     // Submit and verify no validation errors
34157     m_commandBuffer->end();
34158     m_commandBuffer->QueueCommandBuffer();
34159     m_errorMonitor->VerifyNotFound();
34160 }
34161 
TEST_F(VkPositiveLayerTest,MultiplaneImageTests)34162 TEST_F(VkPositiveLayerTest, MultiplaneImageTests) {
34163     TEST_DESCRIPTION("Positive test of multiplane image operations");
34164 
34165     // Enable KHR multiplane req'd extensions
34166     bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
34167                                                     VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION);
34168     if (mp_extensions) {
34169         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
34170     }
34171     SetTargetApiVersion(VK_API_VERSION_1_1);
34172     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
34173     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
34174     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
34175     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
34176     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
34177     if (mp_extensions) {
34178         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
34179         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
34180         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
34181         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
34182     } else {
34183         printf("%s test requires KHR multiplane extensions, not available.  Skipping.\n", kSkipPrefix);
34184         return;
34185     }
34186     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
34187     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
34188 
34189     VkImageCreateInfo ci = {};
34190     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
34191     ci.pNext = NULL;
34192     ci.flags = 0;
34193     ci.imageType = VK_IMAGE_TYPE_2D;
34194     ci.format = VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR;  // All planes of equal extent
34195     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
34196     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
34197     ci.extent = {128, 128, 1};
34198     ci.mipLevels = 1;
34199     ci.arrayLayers = 1;
34200     ci.samples = VK_SAMPLE_COUNT_1_BIT;
34201     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
34202     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
34203 
34204     // Verify format
34205     VkFormatFeatureFlags features = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
34206     bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
34207     if (!supported) {
34208         printf("%s Multiplane image format not supported.  Skipping test.\n", kSkipPrefix);
34209         return;  // Assume there's low ROI on searching for different mp formats
34210     }
34211 
34212     VkImage image;
34213     ASSERT_VK_SUCCESS(vkCreateImage(device(), &ci, NULL, &image));
34214 
34215     // Allocate & bind memory
34216     VkPhysicalDeviceMemoryProperties phys_mem_props;
34217     vkGetPhysicalDeviceMemoryProperties(gpu(), &phys_mem_props);
34218     VkMemoryRequirements mem_reqs;
34219     vkGetImageMemoryRequirements(device(), image, &mem_reqs);
34220     VkDeviceMemory mem_obj = VK_NULL_HANDLE;
34221     VkMemoryPropertyFlagBits mem_props = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
34222     for (uint32_t type = 0; type < phys_mem_props.memoryTypeCount; type++) {
34223         if ((mem_reqs.memoryTypeBits & (1 << type)) &&
34224             ((phys_mem_props.memoryTypes[type].propertyFlags & mem_props) == mem_props)) {
34225             VkMemoryAllocateInfo alloc_info = {};
34226             alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
34227             alloc_info.allocationSize = mem_reqs.size;
34228             alloc_info.memoryTypeIndex = type;
34229             ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &alloc_info, NULL, &mem_obj));
34230             break;
34231         }
34232     }
34233 
34234     if (VK_NULL_HANDLE == mem_obj) {
34235         printf("%s Unable to allocate image memory. Skipping test.\n", kSkipPrefix);
34236         vkDestroyImage(device(), image, NULL);
34237         return;
34238     }
34239     ASSERT_VK_SUCCESS(vkBindImageMemory(device(), image, mem_obj, 0));
34240 
34241     // Copy plane 0 to plane 2
34242     VkImageCopy copyRegion = {};
34243     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT_KHR;
34244     copyRegion.srcSubresource.mipLevel = 0;
34245     copyRegion.srcSubresource.baseArrayLayer = 0;
34246     copyRegion.srcSubresource.layerCount = 1;
34247     copyRegion.srcOffset = {0, 0, 0};
34248     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
34249     copyRegion.dstSubresource.mipLevel = 0;
34250     copyRegion.dstSubresource.baseArrayLayer = 0;
34251     copyRegion.dstSubresource.layerCount = 1;
34252     copyRegion.dstOffset = {0, 0, 0};
34253     copyRegion.extent.width = 128;
34254     copyRegion.extent.height = 128;
34255     copyRegion.extent.depth = 1;
34256 
34257     m_errorMonitor->ExpectSuccess();
34258     m_commandBuffer->begin();
34259     m_commandBuffer->CopyImage(image, VK_IMAGE_LAYOUT_GENERAL, image, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
34260     m_commandBuffer->end();
34261     m_errorMonitor->VerifyNotFound();
34262 
34263     vkFreeMemory(device(), mem_obj, NULL);
34264     vkDestroyImage(device(), image, NULL);
34265 
34266     // Repeat bind test on a DISJOINT multi-planar image, with per-plane memory objects, using API2 variants
34267     //
34268     features |= VK_FORMAT_FEATURE_DISJOINT_BIT;
34269     ci.flags = VK_IMAGE_CREATE_DISJOINT_BIT;
34270     if (ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features)) {
34271         ASSERT_VK_SUCCESS(vkCreateImage(device(), &ci, NULL, &image));
34272 
34273         // Allocate & bind memory
34274         VkPhysicalDeviceMemoryProperties2 phys_mem_props2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2};
34275         vkGetPhysicalDeviceMemoryProperties2(gpu(), &phys_mem_props2);
34276         VkImagePlaneMemoryRequirementsInfo image_plane_req = {VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO};
34277         VkImageMemoryRequirementsInfo2 mem_req_info2 = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2};
34278         mem_req_info2.pNext = &image_plane_req;
34279         mem_req_info2.image = image;
34280         VkMemoryRequirements2 mem_reqs2 = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2};
34281 
34282         VkDeviceMemory p0_mem, p1_mem, p2_mem;
34283         mem_props = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
34284         VkMemoryAllocateInfo alloc_info = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
34285 
34286         // Plane 0
34287         image_plane_req.planeAspect = VK_IMAGE_ASPECT_PLANE_0_BIT;
34288         vkGetImageMemoryRequirements2(device(), &mem_req_info2, &mem_reqs2);
34289         uint32_t mem_type = 0;
34290         for (mem_type = 0; mem_type < phys_mem_props2.memoryProperties.memoryTypeCount; mem_type++) {
34291             if ((mem_reqs2.memoryRequirements.memoryTypeBits & (1 << mem_type)) &&
34292                 ((phys_mem_props2.memoryProperties.memoryTypes[mem_type].propertyFlags & mem_props) == mem_props)) {
34293                 alloc_info.memoryTypeIndex = mem_type;
34294                 break;
34295             }
34296         }
34297         alloc_info.allocationSize = mem_reqs2.memoryRequirements.size;
34298         ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &alloc_info, NULL, &p0_mem));
34299 
34300         // Plane 1 & 2 use same memory type
34301         image_plane_req.planeAspect = VK_IMAGE_ASPECT_PLANE_1_BIT;
34302         vkGetImageMemoryRequirements2(device(), &mem_req_info2, &mem_reqs2);
34303         alloc_info.allocationSize = mem_reqs2.memoryRequirements.size;
34304         ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &alloc_info, NULL, &p1_mem));
34305 
34306         image_plane_req.planeAspect = VK_IMAGE_ASPECT_PLANE_2_BIT;
34307         vkGetImageMemoryRequirements2(device(), &mem_req_info2, &mem_reqs2);
34308         alloc_info.allocationSize = mem_reqs2.memoryRequirements.size;
34309         ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &alloc_info, NULL, &p2_mem));
34310 
34311         // Set up 3-plane binding
34312         VkBindImageMemoryInfo bind_info[3];
34313         for (int plane = 0; plane < 3; plane++) {
34314             bind_info[plane].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
34315             bind_info[plane].pNext = nullptr;
34316             bind_info[plane].image = image;
34317             bind_info[plane].memoryOffset = 0;
34318         }
34319         bind_info[0].memory = p0_mem;
34320         bind_info[1].memory = p1_mem;
34321         bind_info[2].memory = p2_mem;
34322 
34323         m_errorMonitor->ExpectSuccess();
34324         vkBindImageMemory2(device(), 3, bind_info);
34325         m_errorMonitor->VerifyNotFound();
34326 
34327         vkFreeMemory(device(), p0_mem, NULL);
34328         vkFreeMemory(device(), p1_mem, NULL);
34329         vkFreeMemory(device(), p2_mem, NULL);
34330         vkDestroyImage(device(), image, NULL);
34331     }
34332 
34333     // Test that changing the layout of ASPECT_COLOR also changes the layout of the individual planes
34334     VkBufferObj buffer;
34335     VkMemoryPropertyFlags reqs = 0;
34336     buffer.init_as_src(*m_device, (VkDeviceSize)128 * 128 * 3, reqs);
34337     VkImageObj mpimage(m_device);
34338     mpimage.Init(256, 256, 1, VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
34339                  VK_IMAGE_TILING_OPTIMAL, 0);
34340     VkBufferImageCopy copy_region = {};
34341     copy_region.bufferRowLength = 128;
34342     copy_region.bufferImageHeight = 128;
34343     copy_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT_KHR;
34344     copy_region.imageSubresource.layerCount = 1;
34345     copy_region.imageExtent.height = 64;
34346     copy_region.imageExtent.width = 64;
34347     copy_region.imageExtent.depth = 1;
34348 
34349     vkResetCommandBuffer(m_commandBuffer->handle(), 0);
34350     m_commandBuffer->begin();
34351     mpimage.ImageMemoryBarrier(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
34352     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), mpimage.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
34353                            &copy_region);
34354     m_commandBuffer->end();
34355     m_commandBuffer->QueueCommandBuffer(false);
34356     m_errorMonitor->VerifyNotFound();
34357 
34358     // Test to verify that views of multiplanar images have layouts tracked correctly
34359     // by changing the image's layout then using a view of that image
34360     VkImageView view;
34361     VkImageViewCreateInfo ivci = {};
34362     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
34363     ivci.image = mpimage.handle();
34364     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
34365     ivci.format = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR;
34366     ivci.subresourceRange.layerCount = 1;
34367     ivci.subresourceRange.baseMipLevel = 0;
34368     ivci.subresourceRange.levelCount = 1;
34369     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
34370     vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
34371 
34372     OneOffDescriptorSet ds(m_device, {
34373                                          {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
34374                                      });
34375 
34376     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
34377     VkSampler sampler;
34378 
34379     VkResult err;
34380     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
34381     ASSERT_VK_SUCCESS(err);
34382 
34383     const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_});
34384 
34385     VkDescriptorImageInfo image_info{};
34386     image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
34387     image_info.imageView = view;
34388     image_info.sampler = sampler;
34389 
34390     VkWriteDescriptorSet descriptor_write = {};
34391     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
34392     descriptor_write.dstSet = ds.set_;
34393     descriptor_write.dstBinding = 0;
34394     descriptor_write.descriptorCount = 1;
34395     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
34396     descriptor_write.pImageInfo = &image_info;
34397 
34398     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
34399 
34400     char const *vsSource =
34401         "#version 450\n"
34402         "\n"
34403         "void main(){\n"
34404         "   gl_Position = vec4(1);\n"
34405         "}\n";
34406     char const *fsSource =
34407         "#version 450\n"
34408         "\n"
34409         "layout(set=0, binding=0) uniform sampler2D s;\n"
34410         "layout(location=0) out vec4 x;\n"
34411         "void main(){\n"
34412         "   x = texture(s, vec2(1));\n"
34413         "}\n";
34414 
34415     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
34416     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
34417     VkPipelineObj pipe(m_device);
34418     pipe.AddShader(&vs);
34419     pipe.AddShader(&fs);
34420     pipe.AddDefaultColorAttachment();
34421     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
34422 
34423     m_errorMonitor->ExpectSuccess();
34424     m_commandBuffer->begin();
34425     VkImageMemoryBarrier img_barrier = {};
34426     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
34427     img_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
34428     img_barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
34429     img_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
34430     img_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
34431     img_barrier.image = mpimage.handle();
34432     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
34433     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
34434     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
34435     img_barrier.subresourceRange.baseArrayLayer = 0;
34436     img_barrier.subresourceRange.baseMipLevel = 0;
34437     img_barrier.subresourceRange.layerCount = 1;
34438     img_barrier.subresourceRange.levelCount = 1;
34439     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
34440                          VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
34441     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
34442     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
34443     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &ds.set_, 0,
34444                             nullptr);
34445 
34446     VkViewport viewport = {0, 0, 16, 16, 0, 1};
34447     VkRect2D scissor = {{0, 0}, {16, 16}};
34448     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
34449     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
34450 
34451     m_commandBuffer->Draw(1, 0, 0, 0);
34452     m_commandBuffer->EndRenderPass();
34453     m_commandBuffer->end();
34454     VkSubmitInfo submit_info = {};
34455     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
34456     submit_info.commandBufferCount = 1;
34457     submit_info.pCommandBuffers = &m_commandBuffer->handle();
34458     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
34459     m_errorMonitor->VerifyNotFound();
34460 
34461     vkQueueWaitIdle(m_device->m_queue);
34462     vkDestroyImageView(m_device->device(), view, NULL);
34463     vkDestroySampler(m_device->device(), sampler, nullptr);
34464 }
34465 
TEST_F(VkPositiveLayerTest,ApiVersionZero)34466 TEST_F(VkPositiveLayerTest, ApiVersionZero) {
34467     TEST_DESCRIPTION("Check that apiVersion = 0 is valid.");
34468     m_errorMonitor->ExpectSuccess();
34469     app_info.apiVersion = 0U;
34470     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
34471     m_errorMonitor->VerifyNotFound();
34472 }
34473 
TEST_F(VkLayerTest,DrawIndirectCountKHR)34474 TEST_F(VkLayerTest, DrawIndirectCountKHR) {
34475     TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndirectCountKHR");
34476 
34477     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
34478     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME)) {
34479         m_device_extension_names.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
34480     } else {
34481         printf("             VK_KHR_draw_indirect_count Extension not supported, skipping test\n");
34482         return;
34483     }
34484     ASSERT_NO_FATAL_FAILURE(InitState());
34485     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
34486 
34487     VkMemoryRequirements memory_requirements;
34488     VkMemoryAllocateInfo memory_allocate_info = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
34489 
34490     auto vkCmdDrawIndirectCountKHR =
34491         (PFN_vkCmdDrawIndirectCountKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdDrawIndirectCountKHR");
34492 
34493     char const *vsSource =
34494         "#version 450\n"
34495         "\n"
34496         "void main() { gl_Position = vec4(0); }\n";
34497     char const *fsSource =
34498         "#version 450\n"
34499         "\n"
34500         "layout(location=0) out vec4 color;\n"
34501         "void main() {\n"
34502         "   color = vec4(1, 0, 0, 1);\n"
34503         "}\n";
34504     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
34505     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
34506 
34507     VkPipelineObj pipe(m_device);
34508     pipe.AddShader(&vs);
34509     pipe.AddShader(&fs);
34510     pipe.AddDefaultColorAttachment();
34511 
34512     VkDescriptorSetObj descriptor_set(m_device);
34513     descriptor_set.AppendDummy();
34514     descriptor_set.CreateVKDescriptorSet(m_commandBuffer);
34515 
34516     VkResult err = pipe.CreateVKPipeline(descriptor_set.GetPipelineLayout(), renderPass());
34517     ASSERT_VK_SUCCESS(err);
34518 
34519     m_commandBuffer->begin();
34520     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
34521 
34522     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
34523     m_commandBuffer->BindDescriptorSet(descriptor_set);
34524 
34525     VkViewport viewport = {0, 0, 16, 16, 0, 1};
34526     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
34527     VkRect2D scissor = {{0, 0}, {16, 16}};
34528     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
34529 
34530     VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
34531     buffer_create_info.size = sizeof(VkDrawIndirectCommand);
34532     buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
34533     VkBuffer draw_buffer;
34534     vkCreateBuffer(m_device->device(), &buffer_create_info, nullptr, &draw_buffer);
34535 
34536     VkBufferCreateInfo count_buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
34537     count_buffer_create_info.size = sizeof(uint32_t);
34538     count_buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
34539     VkBuffer count_buffer;
34540     vkCreateBuffer(m_device->device(), &count_buffer_create_info, nullptr, &count_buffer);
34541     vkGetBufferMemoryRequirements(m_device->device(), count_buffer, &memory_requirements);
34542     memory_allocate_info.allocationSize = memory_requirements.size;
34543     m_device->phy().set_memory_type(memory_requirements.memoryTypeBits, &memory_allocate_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
34544     VkDeviceMemory count_buffer_memory;
34545     vkAllocateMemory(m_device->device(), &memory_allocate_info, NULL, &count_buffer_memory);
34546     vkBindBufferMemory(m_device->device(), count_buffer, count_buffer_memory, 0);
34547 
34548     // VUID-vkCmdDrawIndirectCountKHR-buffer-03104
34549     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndirectCountKHR-buffer-03104");
34550     vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer, 0, 1, sizeof(VkDrawIndirectCommand));
34551     m_errorMonitor->VerifyFound();
34552 
34553     vkGetBufferMemoryRequirements(m_device->device(), draw_buffer, &memory_requirements);
34554     memory_allocate_info.allocationSize = memory_requirements.size;
34555     m_device->phy().set_memory_type(memory_requirements.memoryTypeBits, &memory_allocate_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
34556     VkDeviceMemory draw_buffer_memory;
34557     vkAllocateMemory(m_device->device(), &memory_allocate_info, NULL, &draw_buffer_memory);
34558     vkBindBufferMemory(m_device->device(), draw_buffer, draw_buffer_memory, 0);
34559 
34560     VkBuffer count_buffer_unbound;
34561     vkCreateBuffer(m_device->device(), &count_buffer_create_info, nullptr, &count_buffer_unbound);
34562 
34563     // VUID-vkCmdDrawIndirectCountKHR-countBuffer-03106
34564     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndirectCountKHR-countBuffer-03106");
34565     vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer_unbound, 0, 1, sizeof(VkDrawIndirectCommand));
34566     m_errorMonitor->VerifyFound();
34567 
34568     // VUID-vkCmdDrawIndirectCountKHR-offset-03108
34569     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndirectCountKHR-offset-03108");
34570     vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 1, count_buffer, 0, 1, sizeof(VkDrawIndirectCommand));
34571     m_errorMonitor->VerifyFound();
34572 
34573     // VUID-vkCmdDrawIndirectCountKHR-countBufferOffset-03109
34574     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndirectCountKHR-countBufferOffset-03109");
34575     vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer, 1, 1, sizeof(VkDrawIndirectCommand));
34576     m_errorMonitor->VerifyFound();
34577 
34578     // VUID-vkCmdDrawIndirectCountKHR-stride-03110
34579     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndirectCountKHR-stride-03110");
34580     vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer, 0, 1, 1);
34581     m_errorMonitor->VerifyFound();
34582 
34583     // TODO: These covered VUIDs aren't tested. There is also no test coverage for the core Vulkan 1.0 vkCmdDraw* equivalent of
34584     // these:
34585     //     VUID-vkCmdDrawIndirectCountKHR-renderPass-03113
34586     //     VUID-vkCmdDrawIndirectCountKHR-subpass-03114
34587     //     VUID-vkCmdDrawIndirectCountKHR-None-03120
34588 
34589     m_commandBuffer->EndRenderPass();
34590     m_commandBuffer->end();
34591 
34592     vkDestroyBuffer(m_device->device(), draw_buffer, 0);
34593     vkDestroyBuffer(m_device->device(), count_buffer, 0);
34594     vkDestroyBuffer(m_device->device(), count_buffer_unbound, 0);
34595 
34596     vkFreeMemory(m_device->device(), draw_buffer_memory, 0);
34597     vkFreeMemory(m_device->device(), count_buffer_memory, 0);
34598 }
34599 
TEST_F(VkLayerTest,DrawIndexedIndirectCountKHR)34600 TEST_F(VkLayerTest, DrawIndexedIndirectCountKHR) {
34601     TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndexedIndirectCountKHR");
34602 
34603     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
34604     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME)) {
34605         m_device_extension_names.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
34606     } else {
34607         printf("             VK_KHR_draw_indirect_count Extension not supported, skipping test\n");
34608         return;
34609     }
34610     ASSERT_NO_FATAL_FAILURE(InitState());
34611     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
34612 
34613     VkMemoryRequirements memory_requirements;
34614     VkMemoryAllocateInfo memory_allocate_info = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
34615 
34616     auto vkCmdDrawIndexedIndirectCountKHR =
34617         (PFN_vkCmdDrawIndexedIndirectCountKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdDrawIndexedIndirectCountKHR");
34618 
34619     char const *vsSource =
34620         "#version 450\n"
34621         "\n"
34622         "void main() { gl_Position = vec4(0); }\n";
34623     char const *fsSource =
34624         "#version 450\n"
34625         "\n"
34626         "layout(location=0) out vec4 color;\n"
34627         "void main() {\n"
34628         "   color = vec4(1, 0, 0, 1);\n"
34629         "}\n";
34630     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
34631     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
34632 
34633     VkPipelineObj pipe(m_device);
34634     pipe.AddShader(&vs);
34635     pipe.AddShader(&fs);
34636     pipe.AddDefaultColorAttachment();
34637 
34638     VkDescriptorSetObj descriptorSet(m_device);
34639     descriptorSet.AppendDummy();
34640     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
34641 
34642     VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
34643     ASSERT_VK_SUCCESS(err);
34644 
34645     m_commandBuffer->begin();
34646     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
34647 
34648     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
34649     m_commandBuffer->BindDescriptorSet(descriptorSet);
34650 
34651     VkViewport viewport = {0, 0, 16, 16, 0, 1};
34652     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
34653     VkRect2D scissor = {{0, 0}, {16, 16}};
34654     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
34655 
34656     VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
34657     buffer_create_info.size = sizeof(VkDrawIndexedIndirectCommand);
34658     buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
34659     VkBuffer draw_buffer;
34660     vkCreateBuffer(m_device->device(), &buffer_create_info, nullptr, &draw_buffer);
34661     vkGetBufferMemoryRequirements(m_device->device(), draw_buffer, &memory_requirements);
34662     memory_allocate_info.allocationSize = memory_requirements.size;
34663     m_device->phy().set_memory_type(memory_requirements.memoryTypeBits, &memory_allocate_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
34664     VkDeviceMemory draw_buffer_memory;
34665     vkAllocateMemory(m_device->device(), &memory_allocate_info, NULL, &draw_buffer_memory);
34666     vkBindBufferMemory(m_device->device(), draw_buffer, draw_buffer_memory, 0);
34667 
34668     VkBufferCreateInfo count_buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
34669     count_buffer_create_info.size = sizeof(uint32_t);
34670     count_buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
34671     VkBuffer count_buffer;
34672     vkCreateBuffer(m_device->device(), &count_buffer_create_info, nullptr, &count_buffer);
34673     vkGetBufferMemoryRequirements(m_device->device(), count_buffer, &memory_requirements);
34674     memory_allocate_info.allocationSize = memory_requirements.size;
34675     m_device->phy().set_memory_type(memory_requirements.memoryTypeBits, &memory_allocate_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
34676     VkDeviceMemory count_buffer_memory;
34677     vkAllocateMemory(m_device->device(), &memory_allocate_info, NULL, &count_buffer_memory);
34678     vkBindBufferMemory(m_device->device(), count_buffer, count_buffer_memory, 0);
34679 
34680     VkBufferCreateInfo index_buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
34681     index_buffer_create_info.size = sizeof(uint32_t);
34682     index_buffer_create_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
34683     VkBuffer index_buffer;
34684     vkCreateBuffer(m_device->device(), &index_buffer_create_info, nullptr, &index_buffer);
34685     vkGetBufferMemoryRequirements(m_device->device(), index_buffer, &memory_requirements);
34686     memory_allocate_info.allocationSize = memory_requirements.size;
34687     m_device->phy().set_memory_type(memory_requirements.memoryTypeBits, &memory_allocate_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
34688     VkDeviceMemory index_buffer_memory;
34689     vkAllocateMemory(m_device->device(), &memory_allocate_info, NULL, &index_buffer_memory);
34690     vkBindBufferMemory(m_device->device(), index_buffer, index_buffer_memory, 0);
34691 
34692     // VUID-vkCmdDrawIndexedIndirectCountKHR-None-03152 (partial - only tests whether the index buffer is bound)
34693     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndexedIndirectCountKHR-None-03152");
34694     vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer, 0, 1,
34695                                      sizeof(VkDrawIndexedIndirectCommand));
34696     m_errorMonitor->VerifyFound();
34697 
34698     vkCmdBindIndexBuffer(m_commandBuffer->handle(), index_buffer, 0, VK_INDEX_TYPE_UINT32);
34699 
34700     VkBuffer draw_buffer_unbound;
34701     vkCreateBuffer(m_device->device(), &count_buffer_create_info, nullptr, &draw_buffer_unbound);
34702 
34703     // VUID-vkCmdDrawIndexedIndirectCountKHR-buffer-03136
34704     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndexedIndirectCountKHR-buffer-03136");
34705     vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer_unbound, 0, count_buffer, 0, 1,
34706                                      sizeof(VkDrawIndexedIndirectCommand));
34707     m_errorMonitor->VerifyFound();
34708 
34709     VkBuffer count_buffer_unbound;
34710     vkCreateBuffer(m_device->device(), &count_buffer_create_info, nullptr, &count_buffer_unbound);
34711 
34712     // VUID-vkCmdDrawIndexedIndirectCountKHR-countBuffer-03138
34713     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndexedIndirectCountKHR-countBuffer-03138");
34714     vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer_unbound, 0, 1,
34715                                      sizeof(VkDrawIndexedIndirectCommand));
34716     m_errorMonitor->VerifyFound();
34717 
34718     // VUID-vkCmdDrawIndexedIndirectCountKHR-offset-03140
34719     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndexedIndirectCountKHR-offset-03140");
34720     vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 1, count_buffer, 0, 1,
34721                                      sizeof(VkDrawIndexedIndirectCommand));
34722     m_errorMonitor->VerifyFound();
34723 
34724     // VUID-vkCmdDrawIndexedIndirectCountKHR-countBufferOffset-03141
34725     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
34726                                          "VUID-vkCmdDrawIndexedIndirectCountKHR-countBufferOffset-03141");
34727     vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer, 1, 1,
34728                                      sizeof(VkDrawIndexedIndirectCommand));
34729     m_errorMonitor->VerifyFound();
34730 
34731     // VUID-vkCmdDrawIndexedIndirectCountKHR-stride-03142
34732     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndexedIndirectCountKHR-stride-03142");
34733     vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer, 0, 1, 1);
34734     m_errorMonitor->VerifyFound();
34735 
34736     // TODO: These covered VUIDs aren't tested. There is also no test coverage for the core Vulkan 1.0 vkCmdDraw* equivalent of
34737     // these:
34738     //     VUID-vkCmdDrawIndexedIndirectCountKHR-renderPass-03145
34739     //     VUID-vkCmdDrawIndexedIndirectCountKHR-subpass-03146
34740     //     VUID-vkCmdDrawIndexedIndirectCountKHR-None-03152 (partial)
34741 
34742     m_commandBuffer->EndRenderPass();
34743     m_commandBuffer->end();
34744 
34745     vkDestroyBuffer(m_device->device(), draw_buffer, 0);
34746     vkDestroyBuffer(m_device->device(), draw_buffer_unbound, 0);
34747     vkDestroyBuffer(m_device->device(), count_buffer, 0);
34748     vkDestroyBuffer(m_device->device(), count_buffer_unbound, 0);
34749     vkDestroyBuffer(m_device->device(), index_buffer, 0);
34750 
34751     vkFreeMemory(m_device->device(), draw_buffer_memory, 0);
34752     vkFreeMemory(m_device->device(), count_buffer_memory, 0);
34753     vkFreeMemory(m_device->device(), index_buffer_memory, 0);
34754 }
34755 
TEST_F(VkLayerTest,ExclusiveScissorNV)34756 TEST_F(VkLayerTest, ExclusiveScissorNV) {
34757     TEST_DESCRIPTION("Test VK_NV_scissor_exclusive with multiViewport disabled.");
34758 
34759     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
34760         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
34761     } else {
34762         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
34763                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
34764         return;
34765     }
34766     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
34767     std::array<const char *, 1> required_device_extensions = {{VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME}};
34768     for (auto device_extension : required_device_extensions) {
34769         if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
34770             m_device_extension_names.push_back(device_extension);
34771         } else {
34772             printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
34773             return;
34774         }
34775     }
34776 
34777     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
34778         (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
34779     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
34780 
34781     // Create a device that enables exclusive scissor but disables multiViewport
34782     auto exclusive_scissor_features = lvl_init_struct<VkPhysicalDeviceExclusiveScissorFeaturesNV>();
34783     auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&exclusive_scissor_features);
34784     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
34785 
34786     features2.features.multiViewport = VK_FALSE;
34787 
34788     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
34789     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
34790 
34791     // Based on PSOViewportStateTests
34792     {
34793         VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
34794         VkViewport viewports[] = {viewport, viewport};
34795         VkRect2D scissor = {{0, 0}, {64, 64}};
34796         VkRect2D scissors[100] = {scissor, scissor};
34797 
34798         using std::vector;
34799         struct TestCase {
34800             uint32_t viewport_count;
34801             VkViewport *viewports;
34802             uint32_t scissor_count;
34803             VkRect2D *scissors;
34804             uint32_t exclusive_scissor_count;
34805             VkRect2D *exclusive_scissors;
34806 
34807             vector<std::string> vuids;
34808         };
34809 
34810         vector<TestCase> test_cases = {
34811             {1,
34812              viewports,
34813              1,
34814              scissors,
34815              2,
34816              scissors,
34817              {"VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02027",
34818               "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02029"}},
34819             {1,
34820              viewports,
34821              1,
34822              scissors,
34823              100,
34824              scissors,
34825              {"VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02027",
34826               "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02028",
34827               "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02029"}},
34828             {1,
34829              viewports,
34830              1,
34831              scissors,
34832              1,
34833              nullptr,
34834              {"VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-pDynamicStates-02030"}},
34835         };
34836 
34837         for (const auto &test_case : test_cases) {
34838             VkPipelineViewportExclusiveScissorStateCreateInfoNV exc = {
34839                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV};
34840 
34841             const auto break_vp = [&test_case, &exc](CreatePipelineHelper &helper) {
34842                 helper.vp_state_ci_.viewportCount = test_case.viewport_count;
34843                 helper.vp_state_ci_.pViewports = test_case.viewports;
34844                 helper.vp_state_ci_.scissorCount = test_case.scissor_count;
34845                 helper.vp_state_ci_.pScissors = test_case.scissors;
34846                 helper.vp_state_ci_.pNext = &exc;
34847 
34848                 exc.exclusiveScissorCount = test_case.exclusive_scissor_count;
34849                 exc.pExclusiveScissors = test_case.exclusive_scissors;
34850             };
34851             CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids);
34852         }
34853     }
34854 
34855     // Based on SetDynScissorParamTests
34856     {
34857         auto vkCmdSetExclusiveScissorNV =
34858             (PFN_vkCmdSetExclusiveScissorNV)vkGetDeviceProcAddr(m_device->device(), "vkCmdSetExclusiveScissorNV");
34859 
34860         const VkRect2D scissor = {{0, 0}, {16, 16}};
34861         const VkRect2D scissors[] = {scissor, scissor};
34862 
34863         m_commandBuffer->begin();
34864 
34865         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
34866                                              "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035");
34867         vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 1, 1, scissors);
34868         m_errorMonitor->VerifyFound();
34869 
34870         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
34871                                              "vkCmdSetExclusiveScissorNV: parameter exclusiveScissorCount must be greater than 0");
34872         vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 0, nullptr);
34873         m_errorMonitor->VerifyFound();
34874 
34875         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
34876                                              "VUID-vkCmdSetExclusiveScissorNV-exclusiveScissorCount-02036");
34877         vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 2, scissors);
34878         m_errorMonitor->VerifyFound();
34879 
34880         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
34881                                              "vkCmdSetExclusiveScissorNV: parameter exclusiveScissorCount must be greater than 0");
34882         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
34883                                              "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035");
34884         vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 1, 0, scissors);
34885         m_errorMonitor->VerifyFound();
34886 
34887         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
34888                                              "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035");
34889         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
34890                                              "VUID-vkCmdSetExclusiveScissorNV-exclusiveScissorCount-02036");
34891         vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 1, 2, scissors);
34892         m_errorMonitor->VerifyFound();
34893 
34894         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
34895                                              "vkCmdSetExclusiveScissorNV: required parameter pExclusiveScissors specified as NULL");
34896         vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 1, nullptr);
34897         m_errorMonitor->VerifyFound();
34898 
34899         struct TestCase {
34900             VkRect2D scissor;
34901             std::string vuid;
34902         };
34903 
34904         std::vector<TestCase> test_cases = {
34905             {{{-1, 0}, {16, 16}}, "VUID-vkCmdSetExclusiveScissorNV-x-02037"},
34906             {{{0, -1}, {16, 16}}, "VUID-vkCmdSetExclusiveScissorNV-x-02037"},
34907             {{{1, 0}, {INT32_MAX, 16}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02038"},
34908             {{{INT32_MAX, 0}, {1, 16}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02038"},
34909             {{{0, 0}, {uint32_t{INT32_MAX} + 1, 16}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02038"},
34910             {{{0, 1}, {16, INT32_MAX}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02039"},
34911             {{{0, INT32_MAX}, {16, 1}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02039"},
34912             {{{0, 0}, {16, uint32_t{INT32_MAX} + 1}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02039"}};
34913 
34914         for (const auto &test_case : test_cases) {
34915             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuid);
34916             vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 1, &test_case.scissor);
34917             m_errorMonitor->VerifyFound();
34918         }
34919 
34920         m_commandBuffer->end();
34921     }
34922 }
34923 
TEST_F(VkLayerTest,ShadingRateImageNV)34924 TEST_F(VkLayerTest, ShadingRateImageNV) {
34925     TEST_DESCRIPTION("Test VK_NV_shading_rate_image.");
34926 
34927     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
34928         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
34929     } else {
34930         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
34931                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
34932         return;
34933     }
34934     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
34935     std::array<const char *, 1> required_device_extensions = {{VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME}};
34936     for (auto device_extension : required_device_extensions) {
34937         if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
34938             m_device_extension_names.push_back(device_extension);
34939         } else {
34940             printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
34941             return;
34942         }
34943     }
34944 
34945     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
34946         (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
34947     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
34948 
34949     // Create a device that enables shading_rate_image but disables multiViewport
34950     auto shading_rate_image_features = lvl_init_struct<VkPhysicalDeviceShadingRateImageFeaturesNV>();
34951     auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&shading_rate_image_features);
34952     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
34953 
34954     features2.features.multiViewport = VK_FALSE;
34955 
34956     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
34957     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
34958 
34959     // Test shading rate image creation
34960     VkImage image = VK_NULL_HANDLE;
34961     VkResult result = VK_RESULT_MAX_ENUM;
34962     VkImageCreateInfo image_create_info = {};
34963     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
34964     image_create_info.pNext = NULL;
34965     image_create_info.imageType = VK_IMAGE_TYPE_2D;
34966     image_create_info.format = VK_FORMAT_R8_UINT;
34967     image_create_info.extent.width = 4;
34968     image_create_info.extent.height = 4;
34969     image_create_info.extent.depth = 1;
34970     image_create_info.mipLevels = 1;
34971     image_create_info.arrayLayers = 1;
34972     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
34973     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
34974     image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
34975     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV;
34976     image_create_info.queueFamilyIndexCount = 0;
34977     image_create_info.pQueueFamilyIndices = NULL;
34978     image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
34979     image_create_info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
34980 
34981     // image type must be 2D
34982     image_create_info.imageType = VK_IMAGE_TYPE_3D;
34983     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-imageType-02082");
34984     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
34985     m_errorMonitor->VerifyFound();
34986     if (VK_SUCCESS == result) {
34987         vkDestroyImage(m_device->device(), image, NULL);
34988         image = VK_NULL_HANDLE;
34989     }
34990     image_create_info.imageType = VK_IMAGE_TYPE_2D;
34991 
34992     // must be single sample
34993     image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
34994     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-samples-02083");
34995     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
34996     m_errorMonitor->VerifyFound();
34997     if (VK_SUCCESS == result) {
34998         vkDestroyImage(m_device->device(), image, NULL);
34999         image = VK_NULL_HANDLE;
35000     }
35001     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
35002 
35003     // tiling must be optimal
35004     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
35005     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-tiling-02084");
35006     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
35007     m_errorMonitor->VerifyFound();
35008     if (VK_SUCCESS == result) {
35009         vkDestroyImage(m_device->device(), image, NULL);
35010         image = VK_NULL_HANDLE;
35011     }
35012     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
35013 
35014     // Should succeed.
35015     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
35016     m_errorMonitor->VerifyNotFound();
35017 
35018     // bind memory to the image
35019     VkMemoryRequirements memory_reqs;
35020     VkDeviceMemory image_memory;
35021     bool pass;
35022     VkMemoryAllocateInfo memory_info = {};
35023     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
35024     memory_info.pNext = NULL;
35025     memory_info.allocationSize = 0;
35026     memory_info.memoryTypeIndex = 0;
35027     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
35028     memory_info.allocationSize = memory_reqs.size;
35029     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
35030     ASSERT_TRUE(pass);
35031     result = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
35032     ASSERT_VK_SUCCESS(result);
35033     result = vkBindImageMemory(m_device->device(), image, image_memory, 0);
35034     ASSERT_VK_SUCCESS(result);
35035 
35036     // Test image view creation
35037     VkImageView view;
35038     VkImageViewCreateInfo ivci = {};
35039     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
35040     ivci.image = image;
35041     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
35042     ivci.format = VK_FORMAT_R8_UINT;
35043     ivci.subresourceRange.layerCount = 1;
35044     ivci.subresourceRange.baseMipLevel = 0;
35045     ivci.subresourceRange.levelCount = 1;
35046     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
35047 
35048     // view type must be 2D or 2D_ARRAY
35049     ivci.viewType = VK_IMAGE_VIEW_TYPE_CUBE;
35050     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-image-02086");
35051     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-image-01003");
35052     result = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
35053     m_errorMonitor->VerifyFound();
35054     if (VK_SUCCESS == result) {
35055         vkDestroyImageView(m_device->device(), view, NULL);
35056         view = VK_NULL_HANDLE;
35057     }
35058     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
35059 
35060     // format must be R8_UINT
35061     ivci.format = VK_FORMAT_R8_UNORM;
35062     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-image-02087");
35063     result = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
35064     m_errorMonitor->VerifyFound();
35065     if (VK_SUCCESS == result) {
35066         vkDestroyImageView(m_device->device(), view, NULL);
35067         view = VK_NULL_HANDLE;
35068     }
35069     ivci.format = VK_FORMAT_R8_UINT;
35070 
35071     vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
35072     m_errorMonitor->VerifyNotFound();
35073 
35074     // Test pipeline creation
35075     VkPipelineViewportShadingRateImageStateCreateInfoNV vsrisci = {
35076         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV};
35077 
35078     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
35079     VkViewport viewports[20] = {viewport, viewport};
35080     VkRect2D scissor = {{0, 0}, {64, 64}};
35081     VkRect2D scissors[20] = {scissor, scissor};
35082     VkDynamicState dynPalette = VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV;
35083     VkPipelineDynamicStateCreateInfo dyn = {VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, nullptr, 0, 1, &dynPalette};
35084 
35085     // viewportCount must be 0 or 1 when multiViewport is disabled
35086     {
35087         const auto break_vp = [&](CreatePipelineHelper &helper) {
35088             helper.vp_state_ci_.viewportCount = 2;
35089             helper.vp_state_ci_.pViewports = viewports;
35090             helper.vp_state_ci_.scissorCount = 2;
35091             helper.vp_state_ci_.pScissors = scissors;
35092             helper.vp_state_ci_.pNext = &vsrisci;
35093             helper.dyn_state_ci_ = dyn;
35094 
35095             vsrisci.shadingRateImageEnable = VK_TRUE;
35096             vsrisci.viewportCount = 2;
35097         };
35098         CreatePipelineHelper::OneshotTest(
35099             *this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT,
35100             vector<std::string>({"VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-viewportCount-02054",
35101                                  "VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
35102                                  "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217"}));
35103     }
35104 
35105     // viewportCounts must match
35106     {
35107         const auto break_vp = [&](CreatePipelineHelper &helper) {
35108             helper.vp_state_ci_.viewportCount = 1;
35109             helper.vp_state_ci_.pViewports = viewports;
35110             helper.vp_state_ci_.scissorCount = 1;
35111             helper.vp_state_ci_.pScissors = scissors;
35112             helper.vp_state_ci_.pNext = &vsrisci;
35113             helper.dyn_state_ci_ = dyn;
35114 
35115             vsrisci.shadingRateImageEnable = VK_TRUE;
35116             vsrisci.viewportCount = 0;
35117         };
35118         CreatePipelineHelper::OneshotTest(
35119             *this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT,
35120             vector<std::string>({"VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-shadingRateImageEnable-02056"}));
35121     }
35122 
35123     // pShadingRatePalettes must not be NULL.
35124     {
35125         const auto break_vp = [&](CreatePipelineHelper &helper) {
35126             helper.vp_state_ci_.viewportCount = 1;
35127             helper.vp_state_ci_.pViewports = viewports;
35128             helper.vp_state_ci_.scissorCount = 1;
35129             helper.vp_state_ci_.pScissors = scissors;
35130             helper.vp_state_ci_.pNext = &vsrisci;
35131 
35132             vsrisci.shadingRateImageEnable = VK_TRUE;
35133             vsrisci.viewportCount = 1;
35134         };
35135         CreatePipelineHelper::OneshotTest(
35136             *this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT,
35137             vector<std::string>({"VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-pDynamicStates-02057"}));
35138     }
35139 
35140     // Create an image without the SRI bit
35141     VkImageObj nonSRIimage(m_device);
35142     nonSRIimage.Init(256, 256, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
35143     ASSERT_TRUE(nonSRIimage.initialized());
35144     VkImageView nonSRIview = nonSRIimage.targetView(VK_FORMAT_B8G8R8A8_UNORM);
35145 
35146     // Test SRI layout on non-SRI image
35147     VkImageMemoryBarrier img_barrier = {};
35148     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
35149     img_barrier.pNext = nullptr;
35150     img_barrier.srcAccessMask = 0;
35151     img_barrier.dstAccessMask = 0;
35152     img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
35153     img_barrier.newLayout = VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV;
35154     img_barrier.image = nonSRIimage.handle();
35155     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
35156     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
35157     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
35158     img_barrier.subresourceRange.baseArrayLayer = 0;
35159     img_barrier.subresourceRange.baseMipLevel = 0;
35160     img_barrier.subresourceRange.layerCount = 1;
35161     img_barrier.subresourceRange.levelCount = 1;
35162 
35163     m_commandBuffer->begin();
35164 
35165     // Error trying to convert it to SRI layout
35166     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-oldLayout-02088");
35167     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0,
35168                          nullptr, 0, nullptr, 1, &img_barrier);
35169     m_errorMonitor->VerifyFound();
35170 
35171     // succeed converting it to GENERAL
35172     img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
35173     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0,
35174                          nullptr, 0, nullptr, 1, &img_barrier);
35175     m_errorMonitor->VerifyNotFound();
35176 
35177     // Test vkCmdBindShadingRateImageNV errors
35178     auto vkCmdBindShadingRateImageNV =
35179         (PFN_vkCmdBindShadingRateImageNV)vkGetDeviceProcAddr(m_device->device(), "vkCmdBindShadingRateImageNV");
35180 
35181     // if the view is non-NULL, it must be R8_UINT, USAGE_SRI, image layout must match, layout must be valid
35182     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBindShadingRateImageNV-imageView-02060");
35183     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBindShadingRateImageNV-imageView-02061");
35184     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBindShadingRateImageNV-imageView-02062");
35185     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBindShadingRateImageNV-imageLayout-02063");
35186     vkCmdBindShadingRateImageNV(m_commandBuffer->handle(), nonSRIview, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
35187     m_errorMonitor->VerifyFound();
35188 
35189     // Test vkCmdSetViewportShadingRatePaletteNV errors
35190     auto vkCmdSetViewportShadingRatePaletteNV =
35191         (PFN_vkCmdSetViewportShadingRatePaletteNV)vkGetDeviceProcAddr(m_device->device(), "vkCmdSetViewportShadingRatePaletteNV");
35192 
35193     VkShadingRatePaletteEntryNV paletteEntries[100] = {};
35194     VkShadingRatePaletteNV palette = {100, paletteEntries};
35195     VkShadingRatePaletteNV palettes[] = {palette, palette};
35196 
35197     // errors on firstViewport/viewportCount
35198     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
35199                                          "VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02066");
35200     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
35201                                          "VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02067");
35202     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
35203                                          "VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02068");
35204     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
35205                                          "VUID-vkCmdSetViewportShadingRatePaletteNV-viewportCount-02069");
35206     vkCmdSetViewportShadingRatePaletteNV(m_commandBuffer->handle(), 20, 2, palettes);
35207     m_errorMonitor->VerifyFound();
35208 
35209     // shadingRatePaletteEntryCount must be in range
35210     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
35211                                          "VUID-VkShadingRatePaletteNV-shadingRatePaletteEntryCount-02071");
35212     vkCmdSetViewportShadingRatePaletteNV(m_commandBuffer->handle(), 0, 1, palettes);
35213     m_errorMonitor->VerifyFound();
35214 
35215     VkCoarseSampleLocationNV locations[100] = {
35216         {0, 0, 0},    {0, 0, 1}, {0, 1, 0}, {0, 1, 1}, {0, 1, 1},  // duplicate
35217         {1000, 0, 0},                                              // pixelX too large
35218         {0, 1000, 0},                                              // pixelY too large
35219         {0, 0, 1000},                                              // sample too large
35220     };
35221 
35222     // Test custom sample orders, both via pipeline state and via dynamic state
35223     {
35224         VkCoarseSampleOrderCustomNV sampOrdBadShadingRate = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_PIXEL_NV, 1, 1,
35225                                                              locations};
35226         VkCoarseSampleOrderCustomNV sampOrdBadSampleCount = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV, 3, 1,
35227                                                              locations};
35228         VkCoarseSampleOrderCustomNV sampOrdBadSampleLocationCount = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV,
35229                                                                      2, 2, locations};
35230         VkCoarseSampleOrderCustomNV sampOrdDuplicateLocations = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV, 2,
35231                                                                  1 * 2 * 2, &locations[1]};
35232         VkCoarseSampleOrderCustomNV sampOrdOutOfRangeLocations = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV, 2,
35233                                                                   1 * 2 * 2, &locations[4]};
35234         VkCoarseSampleOrderCustomNV sampOrdTooLargeSampleLocationCount = {
35235             VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV, 4, 64, &locations[8]};
35236         VkCoarseSampleOrderCustomNV sampOrdGood = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV, 2, 1 * 2 * 2,
35237                                                    &locations[0]};
35238 
35239         VkPipelineViewportCoarseSampleOrderStateCreateInfoNV csosci = {
35240             VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV};
35241         csosci.sampleOrderType = VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV;
35242         csosci.customSampleOrderCount = 1;
35243 
35244         using std::vector;
35245         struct TestCase {
35246             const VkCoarseSampleOrderCustomNV *order;
35247             vector<std::string> vuids;
35248         };
35249 
35250         vector<TestCase> test_cases = {
35251             {&sampOrdBadShadingRate, {"VUID-VkCoarseSampleOrderCustomNV-shadingRate-02073"}},
35252             {&sampOrdBadSampleCount,
35253              {"VUID-VkCoarseSampleOrderCustomNV-sampleCount-02074", "VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02075"}},
35254             {&sampOrdBadSampleLocationCount, {"VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02075"}},
35255             {&sampOrdDuplicateLocations, {"VUID-VkCoarseSampleOrderCustomNV-pSampleLocations-02077"}},
35256             {&sampOrdOutOfRangeLocations,
35257              {"VUID-VkCoarseSampleOrderCustomNV-pSampleLocations-02077", "VUID-VkCoarseSampleLocationNV-pixelX-02078",
35258               "VUID-VkCoarseSampleLocationNV-pixelY-02079", "VUID-VkCoarseSampleLocationNV-sample-02080"}},
35259             {&sampOrdTooLargeSampleLocationCount,
35260              {"VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02076",
35261               "VUID-VkCoarseSampleOrderCustomNV-pSampleLocations-02077"}},
35262             {&sampOrdGood, {}},
35263         };
35264 
35265         for (const auto &test_case : test_cases) {
35266             const auto break_vp = [&](CreatePipelineHelper &helper) {
35267                 helper.vp_state_ci_.pNext = &csosci;
35268                 csosci.pCustomSampleOrders = test_case.order;
35269             };
35270             CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids);
35271         }
35272 
35273         // Test vkCmdSetCoarseSampleOrderNV errors
35274         auto vkCmdSetCoarseSampleOrderNV =
35275             (PFN_vkCmdSetCoarseSampleOrderNV)vkGetDeviceProcAddr(m_device->device(), "vkCmdSetCoarseSampleOrderNV");
35276 
35277         for (const auto &test_case : test_cases) {
35278             for (uint32_t i = 0; i < test_case.vuids.size(); ++i) {
35279                 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids[i]);
35280             }
35281             vkCmdSetCoarseSampleOrderNV(m_commandBuffer->handle(), VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV, 1, test_case.order);
35282             if (test_case.vuids.size()) {
35283                 m_errorMonitor->VerifyFound();
35284             } else {
35285                 m_errorMonitor->VerifyNotFound();
35286             }
35287         }
35288 
35289         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
35290                                              "VUID-vkCmdSetCoarseSampleOrderNV-sampleOrderType-02081");
35291         vkCmdSetCoarseSampleOrderNV(m_commandBuffer->handle(), VK_COARSE_SAMPLE_ORDER_TYPE_PIXEL_MAJOR_NV, 1, &sampOrdGood);
35292         m_errorMonitor->VerifyFound();
35293     }
35294 
35295     m_commandBuffer->end();
35296 
35297     vkDestroyImageView(m_device->device(), view, NULL);
35298     vkDestroyImage(m_device->device(), image, NULL);
35299     vkFreeMemory(m_device->device(), image_memory, NULL);
35300 }
35301 
TEST_F(VkLayerTest,CornerSampledImageNV)35302 TEST_F(VkLayerTest, CornerSampledImageNV) {
35303     TEST_DESCRIPTION("Test VK_NV_corner_sampled_image.");
35304 
35305     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
35306         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
35307     } else {
35308         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
35309                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
35310         return;
35311     }
35312     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
35313     std::array<const char *, 1> required_device_extensions = {{VK_NV_CORNER_SAMPLED_IMAGE_EXTENSION_NAME}};
35314     for (auto device_extension : required_device_extensions) {
35315         if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
35316             m_device_extension_names.push_back(device_extension);
35317         } else {
35318             printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
35319             return;
35320         }
35321     }
35322 
35323     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
35324         (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
35325     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
35326 
35327     // Create a device that enables exclusive scissor but disables multiViewport
35328     auto corner_sampled_image_features = lvl_init_struct<VkPhysicalDeviceCornerSampledImageFeaturesNV>();
35329     auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&corner_sampled_image_features);
35330     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
35331 
35332     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
35333 
35334     VkImage image = VK_NULL_HANDLE;
35335     VkResult result = VK_RESULT_MAX_ENUM;
35336     VkImageCreateInfo image_create_info = {};
35337     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
35338     image_create_info.pNext = NULL;
35339     image_create_info.imageType = VK_IMAGE_TYPE_1D;
35340     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
35341     image_create_info.extent.width = 2;
35342     image_create_info.extent.height = 1;
35343     image_create_info.extent.depth = 1;
35344     image_create_info.mipLevels = 1;
35345     image_create_info.arrayLayers = 1;
35346     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
35347     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
35348     image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
35349     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
35350     image_create_info.queueFamilyIndexCount = 0;
35351     image_create_info.pQueueFamilyIndices = NULL;
35352     image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
35353     image_create_info.flags = VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV;
35354 
35355     // image type must be 2D or 3D
35356     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-flags-02050");
35357     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
35358     m_errorMonitor->VerifyFound();
35359     if (VK_SUCCESS == result) {
35360         vkDestroyImage(m_device->device(), image, NULL);
35361         image = VK_NULL_HANDLE;
35362     }
35363 
35364     // cube/depth not supported
35365     image_create_info.imageType = VK_IMAGE_TYPE_2D;
35366     image_create_info.extent.height = 2;
35367     image_create_info.format = VK_FORMAT_D24_UNORM_S8_UINT;
35368     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-flags-02051");
35369     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
35370     m_errorMonitor->VerifyFound();
35371     if (VK_SUCCESS == result) {
35372         vkDestroyImage(m_device->device(), image, NULL);
35373         image = VK_NULL_HANDLE;
35374     }
35375     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
35376 
35377     // 2D width/height must be > 1
35378     image_create_info.imageType = VK_IMAGE_TYPE_2D;
35379     image_create_info.extent.height = 1;
35380     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-flags-02052");
35381     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
35382     m_errorMonitor->VerifyFound();
35383     if (VK_SUCCESS == result) {
35384         vkDestroyImage(m_device->device(), image, NULL);
35385         image = VK_NULL_HANDLE;
35386     }
35387 
35388     // 3D width/height/depth must be > 1
35389     image_create_info.imageType = VK_IMAGE_TYPE_3D;
35390     image_create_info.extent.height = 2;
35391     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-flags-02053");
35392     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
35393     m_errorMonitor->VerifyFound();
35394     if (VK_SUCCESS == result) {
35395         vkDestroyImage(m_device->device(), image, NULL);
35396         image = VK_NULL_HANDLE;
35397     }
35398     image_create_info.imageType = VK_IMAGE_TYPE_2D;
35399 
35400     // Valid # of mip levels
35401     image_create_info.extent = {7, 7, 1};
35402     image_create_info.mipLevels = 3;  // 3 = ceil(log2(7))
35403     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
35404     m_errorMonitor->VerifyNotFound();
35405     if (VK_SUCCESS == result) {
35406         vkDestroyImage(m_device->device(), image, NULL);
35407         image = VK_NULL_HANDLE;
35408     }
35409 
35410     image_create_info.extent = {8, 8, 1};
35411     image_create_info.mipLevels = 3;  // 3 = ceil(log2(8))
35412     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
35413     m_errorMonitor->VerifyNotFound();
35414     if (VK_SUCCESS == result) {
35415         vkDestroyImage(m_device->device(), image, NULL);
35416         image = VK_NULL_HANDLE;
35417     }
35418 
35419     image_create_info.extent = {9, 9, 1};
35420     image_create_info.mipLevels = 3;  // 4 = ceil(log2(9))
35421     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
35422     m_errorMonitor->VerifyNotFound();
35423     if (VK_SUCCESS == result) {
35424         vkDestroyImage(m_device->device(), image, NULL);
35425         image = VK_NULL_HANDLE;
35426     }
35427 
35428     // Invalid # of mip levels
35429     image_create_info.extent = {8, 8, 1};
35430     image_create_info.mipLevels = 4;  // 3 = ceil(log2(8))
35431     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-mipLevels-00958");
35432     result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
35433     m_errorMonitor->VerifyFound();
35434     if (VK_SUCCESS == result) {
35435         vkDestroyImage(m_device->device(), image, NULL);
35436         image = VK_NULL_HANDLE;
35437     }
35438 }
35439 
TEST_F(VkLayerTest,MeshShaderNV)35440 TEST_F(VkLayerTest, MeshShaderNV) {
35441     TEST_DESCRIPTION("Test VK_NV_mesh_shader.");
35442 
35443     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
35444         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
35445     } else {
35446         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
35447                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
35448         return;
35449     }
35450     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
35451     std::array<const char *, 1> required_device_extensions = {{VK_NV_MESH_SHADER_EXTENSION_NAME}};
35452     for (auto device_extension : required_device_extensions) {
35453         if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
35454             m_device_extension_names.push_back(device_extension);
35455         } else {
35456             printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
35457             return;
35458         }
35459     }
35460 
35461     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
35462         (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
35463     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
35464 
35465     // Create a device that enables mesh_shader
35466     auto mesh_shader_features = lvl_init_struct<VkPhysicalDeviceMeshShaderFeaturesNV>();
35467     auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&mesh_shader_features);
35468     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
35469     features2.features.multiDrawIndirect = VK_FALSE;
35470 
35471     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
35472     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
35473 
35474     static const char vertShaderText[] =
35475         "#version 450\n"
35476         "vec2 vertices[3];\n"
35477         "void main() {\n"
35478         "      vertices[0] = vec2(-1.0, -1.0);\n"
35479         "      vertices[1] = vec2( 1.0, -1.0);\n"
35480         "      vertices[2] = vec2( 0.0,  1.0);\n"
35481         "   gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0);\n"
35482         "   gl_PointSize = 1.0f;\n"
35483         "}\n";
35484 
35485     static const char meshShaderText[] =
35486         "#version 450\n"
35487         "#extension GL_NV_mesh_shader : require\n"
35488         "layout(local_size_x = 1) in;\n"
35489         "layout(max_vertices = 3) out;\n"
35490         "layout(max_primitives = 1) out;\n"
35491         "layout(triangles) out;\n"
35492         "void main() {\n"
35493         "      gl_MeshVerticesNV[0].gl_Position = vec4(-1.0, -1.0, 0, 1);\n"
35494         "      gl_MeshVerticesNV[1].gl_Position = vec4( 1.0, -1.0, 0, 1);\n"
35495         "      gl_MeshVerticesNV[2].gl_Position = vec4( 0.0,  1.0, 0, 1);\n"
35496         "      gl_PrimitiveIndicesNV[0] = 0;\n"
35497         "      gl_PrimitiveIndicesNV[1] = 1;\n"
35498         "      gl_PrimitiveIndicesNV[2] = 2;\n"
35499         "      gl_PrimitiveCountNV = 1;\n"
35500         "}\n";
35501 
35502     VkShaderObj vs(m_device, vertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
35503     VkShaderObj ms(m_device, meshShaderText, VK_SHADER_STAGE_MESH_BIT_NV, this);
35504     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
35505 
35506     // Test pipeline creation
35507     {
35508         // can't mix mesh with vertex
35509         const auto break_vp = [&](CreatePipelineHelper &helper) {
35510             helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo(), ms.GetStageCreateInfo()};
35511         };
35512         CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT,
35513                                           vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-pStages-02095"}));
35514 
35515         // vertex or mesh must be present
35516         const auto break_vp2 = [&](CreatePipelineHelper &helper) { helper.shader_stages_ = {fs.GetStageCreateInfo()}; };
35517         CreatePipelineHelper::OneshotTest(*this, break_vp2, VK_DEBUG_REPORT_ERROR_BIT_EXT,
35518                                           vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-stage-02096"}));
35519 
35520         // vertexinput and inputassembly must be valid when vertex stage is present
35521         const auto break_vp3 = [&](CreatePipelineHelper &helper) {
35522             helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
35523             helper.gp_ci_.pVertexInputState = nullptr;
35524             helper.gp_ci_.pInputAssemblyState = nullptr;
35525         };
35526         CreatePipelineHelper::OneshotTest(*this, break_vp3, VK_DEBUG_REPORT_ERROR_BIT_EXT,
35527                                           vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-pStages-02097",
35528                                                                "VUID-VkGraphicsPipelineCreateInfo-pStages-02098"}));
35529     }
35530 
35531     PFN_vkCmdDrawMeshTasksIndirectNV vkCmdDrawMeshTasksIndirectNV =
35532         (PFN_vkCmdDrawMeshTasksIndirectNV)vkGetInstanceProcAddr(instance(), "vkCmdDrawMeshTasksIndirectNV");
35533 
35534     VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
35535     buffer_create_info.size = sizeof(uint32_t);
35536     buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
35537     VkBuffer buffer;
35538     VkResult result = vkCreateBuffer(m_device->device(), &buffer_create_info, nullptr, &buffer);
35539     ASSERT_VK_SUCCESS(result);
35540 
35541     m_commandBuffer->begin();
35542 
35543     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02146");
35544     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02147");
35545     vkCmdDrawMeshTasksIndirectNV(m_commandBuffer->handle(), buffer, 0, 2, 0);
35546     m_errorMonitor->VerifyFound();
35547 
35548     m_commandBuffer->end();
35549 
35550     vkDestroyBuffer(m_device->device(), buffer, 0);
35551 }
35552 
TEST_F(VkLayerTest,MeshShaderDisabledNV)35553 TEST_F(VkLayerTest, MeshShaderDisabledNV) {
35554     TEST_DESCRIPTION("Test VK_NV_mesh_shader VUs with NV_mesh_shader disabled.");
35555     ASSERT_NO_FATAL_FAILURE(Init());
35556     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
35557 
35558     VkEvent event;
35559     VkEventCreateInfo event_create_info{};
35560     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
35561     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
35562 
35563     m_commandBuffer->begin();
35564 
35565     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetEvent-stageMask-02107");
35566     vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV);
35567     m_errorMonitor->VerifyFound();
35568 
35569     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetEvent-stageMask-02108");
35570     vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV);
35571     m_errorMonitor->VerifyFound();
35572 
35573     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResetEvent-stageMask-02109");
35574     vkCmdResetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV);
35575     m_errorMonitor->VerifyFound();
35576 
35577     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResetEvent-stageMask-02110");
35578     vkCmdResetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV);
35579     m_errorMonitor->VerifyFound();
35580 
35581     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdWaitEvents-srcStageMask-02111");
35582     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdWaitEvents-dstStageMask-02113");
35583     vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV,
35584                     VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, 0, nullptr, 0, nullptr, 0, nullptr);
35585     m_errorMonitor->VerifyFound();
35586 
35587     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdWaitEvents-srcStageMask-02112");
35588     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdWaitEvents-dstStageMask-02114");
35589     vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV,
35590                     VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, 0, nullptr, 0, nullptr, 0, nullptr);
35591     m_errorMonitor->VerifyFound();
35592 
35593     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-srcStageMask-02115");
35594     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-dstStageMask-02117");
35595     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, 0,
35596                          0, nullptr, 0, nullptr, 0, nullptr);
35597     m_errorMonitor->VerifyFound();
35598 
35599     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-srcStageMask-02116");
35600     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-dstStageMask-02118");
35601     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, 0,
35602                          0, nullptr, 0, nullptr, 0, nullptr);
35603     m_errorMonitor->VerifyFound();
35604 
35605     m_commandBuffer->end();
35606 
35607     VkSemaphoreCreateInfo semaphore_create_info = {};
35608     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
35609     VkSemaphore semaphore;
35610     ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
35611 
35612     VkPipelineStageFlags stage_flags = VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV | VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV;
35613     VkSubmitInfo submit_info = {};
35614 
35615     // Signal the semaphore so the next test can wait on it.
35616     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
35617     submit_info.signalSemaphoreCount = 1;
35618     submit_info.pSignalSemaphores = &semaphore;
35619     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
35620     m_errorMonitor->VerifyNotFound();
35621 
35622     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
35623     submit_info.signalSemaphoreCount = 0;
35624     submit_info.pSignalSemaphores = nullptr;
35625     submit_info.waitSemaphoreCount = 1;
35626     submit_info.pWaitSemaphores = &semaphore;
35627     submit_info.pWaitDstStageMask = &stage_flags;
35628 
35629     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubmitInfo-pWaitDstStageMask-02089");
35630     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubmitInfo-pWaitDstStageMask-02090");
35631     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
35632     m_errorMonitor->VerifyFound();
35633 
35634     vkQueueWaitIdle(m_device->m_queue);
35635 
35636     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
35637     VkPipelineShaderStageCreateInfo meshStage = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
35638     meshStage = vs.GetStageCreateInfo();
35639     meshStage.stage = VK_SHADER_STAGE_MESH_BIT_NV;
35640     VkPipelineShaderStageCreateInfo taskStage = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
35641     taskStage = vs.GetStageCreateInfo();
35642     taskStage.stage = VK_SHADER_STAGE_TASK_BIT_NV;
35643 
35644     // mesh and task shaders not supported
35645     const auto break_vp = [&](CreatePipelineHelper &helper) {
35646         helper.shader_stages_ = {meshStage, taskStage, vs.GetStageCreateInfo()};
35647     };
35648     CreatePipelineHelper::OneshotTest(
35649         *this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT,
35650         vector<std::string>({"VUID-VkPipelineShaderStageCreateInfo-pName-00707", "VUID-VkPipelineShaderStageCreateInfo-pName-00707",
35651                              "VUID-VkPipelineShaderStageCreateInfo-stage-02091",
35652                              "VUID-VkPipelineShaderStageCreateInfo-stage-02092"}));
35653 
35654     vkDestroyEvent(m_device->device(), event, nullptr);
35655     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
35656 }
35657 
TEST_F(VkLayerTest,InlineUniformBlockEXT)35658 TEST_F(VkLayerTest, InlineUniformBlockEXT) {
35659     TEST_DESCRIPTION("Test VK_EXT_inline_uniform_block.");
35660 
35661     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
35662         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
35663     } else {
35664         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
35665                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
35666         return;
35667     }
35668     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
35669     std::array<const char *, 2> required_device_extensions = {VK_KHR_MAINTENANCE1_EXTENSION_NAME,
35670                                                               VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME};
35671     for (auto device_extension : required_device_extensions) {
35672         if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
35673             m_device_extension_names.push_back(device_extension);
35674         } else {
35675             printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
35676             return;
35677         }
35678     }
35679 
35680     // Enable descriptor indexing if supported, but don't require it.
35681     bool supportsDescriptorIndexing = true;
35682     required_device_extensions = {VK_KHR_MAINTENANCE3_EXTENSION_NAME, VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME};
35683     for (auto device_extension : required_device_extensions) {
35684         if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
35685             m_device_extension_names.push_back(device_extension);
35686         } else {
35687             printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
35688             supportsDescriptorIndexing = false;
35689             return;
35690         }
35691     }
35692 
35693     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
35694         (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
35695     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
35696 
35697     auto descriptor_indexing_features = lvl_init_struct<VkPhysicalDeviceDescriptorIndexingFeaturesEXT>();
35698     void *pNext = supportsDescriptorIndexing ? &descriptor_indexing_features : nullptr;
35699     // Create a device that enables inline_uniform_block
35700     auto inline_uniform_block_features = lvl_init_struct<VkPhysicalDeviceInlineUniformBlockFeaturesEXT>(pNext);
35701     auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&inline_uniform_block_features);
35702     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
35703 
35704     PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR =
35705         (PFN_vkGetPhysicalDeviceProperties2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceProperties2KHR");
35706     assert(vkGetPhysicalDeviceProperties2KHR != nullptr);
35707 
35708     // Get the inline uniform block limits
35709     auto inline_uniform_props = lvl_init_struct<VkPhysicalDeviceInlineUniformBlockPropertiesEXT>();
35710     auto prop2 = lvl_init_struct<VkPhysicalDeviceProperties2KHR>(&inline_uniform_props);
35711     vkGetPhysicalDeviceProperties2KHR(gpu(), &prop2);
35712 
35713     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
35714 
35715     VkDescriptorSetLayoutBinding dslb = {};
35716     std::vector<VkDescriptorSetLayoutBinding> dslb_vec = {};
35717     VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
35718     ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
35719     VkDescriptorSetLayout ds_layout = {};
35720 
35721     // Test too many bindings
35722     dslb_vec.clear();
35723     dslb.binding = 0;
35724     dslb.descriptorType = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT;
35725     dslb.descriptorCount = 4;
35726     dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
35727 
35728     uint32_t maxBlocks = std::max(inline_uniform_props.maxPerStageDescriptorInlineUniformBlocks,
35729                                   inline_uniform_props.maxDescriptorSetInlineUniformBlocks);
35730     for (uint32_t i = 0; i < 1 + maxBlocks; ++i) {
35731         dslb.binding = i;
35732         dslb_vec.push_back(dslb);
35733     }
35734 
35735     ds_layout_ci.bindingCount = dslb_vec.size();
35736     ds_layout_ci.pBindings = dslb_vec.data();
35737     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
35738     ASSERT_VK_SUCCESS(err);
35739 
35740     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-descriptorType-02214");
35741     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-descriptorType-02216");
35742     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-descriptorType-02215");
35743     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkPipelineLayoutCreateInfo-descriptorType-02217");
35744 
35745     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
35746     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
35747     pipeline_layout_ci.pNext = NULL;
35748     pipeline_layout_ci.setLayoutCount = 1;
35749     pipeline_layout_ci.pSetLayouts = &ds_layout;
35750     VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
35751 
35752     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
35753     m_errorMonitor->VerifyFound();
35754     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
35755     pipeline_layout = VK_NULL_HANDLE;
35756     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, nullptr);
35757     ds_layout = VK_NULL_HANDLE;
35758 
35759     // Single binding that's too large and is not a multiple of 4
35760     dslb.binding = 0;
35761     dslb.descriptorCount = inline_uniform_props.maxInlineUniformBlockSize + 1;
35762 
35763     ds_layout_ci.bindingCount = 1;
35764     ds_layout_ci.pBindings = &dslb;
35765     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkDescriptorSetLayoutBinding-descriptorType-02209");
35766     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkDescriptorSetLayoutBinding-descriptorType-02210");
35767     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
35768     m_errorMonitor->VerifyFound();
35769     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, nullptr);
35770     ds_layout = VK_NULL_HANDLE;
35771 
35772     // Pool size must be a multiple of 4
35773     VkDescriptorPoolSize ds_type_count = {};
35774     ds_type_count.type = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT;
35775     ds_type_count.descriptorCount = 33;
35776 
35777     VkDescriptorPoolCreateInfo ds_pool_ci = {};
35778     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
35779     ds_pool_ci.pNext = NULL;
35780     ds_pool_ci.flags = 0;
35781     ds_pool_ci.maxSets = 2;
35782     ds_pool_ci.poolSizeCount = 1;
35783     ds_pool_ci.pPoolSizes = &ds_type_count;
35784 
35785     VkDescriptorPool ds_pool = VK_NULL_HANDLE;
35786     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkDescriptorPoolSize-type-02218");
35787     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
35788     m_errorMonitor->VerifyFound();
35789     if (ds_pool) {
35790         vkDestroyDescriptorPool(m_device->handle(), ds_pool, nullptr);
35791         ds_pool = VK_NULL_HANDLE;
35792     }
35793 
35794     // Create a valid pool
35795     ds_type_count.descriptorCount = 32;
35796     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
35797     m_errorMonitor->VerifyNotFound();
35798 
35799     // Create two valid sets with 8 bytes each
35800     dslb_vec.clear();
35801     dslb.binding = 0;
35802     dslb.descriptorType = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT;
35803     dslb.descriptorCount = 8;
35804     dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
35805     dslb_vec.push_back(dslb);
35806     dslb.binding = 1;
35807     dslb_vec.push_back(dslb);
35808 
35809     ds_layout_ci.bindingCount = dslb_vec.size();
35810     ds_layout_ci.pBindings = &dslb_vec[0];
35811 
35812     err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
35813     m_errorMonitor->VerifyNotFound();
35814 
35815     VkDescriptorSet descriptor_sets[2];
35816     VkDescriptorSetLayout set_layouts[2] = {ds_layout, ds_layout};
35817     VkDescriptorSetAllocateInfo alloc_info = {};
35818     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
35819     alloc_info.descriptorSetCount = 2;
35820     alloc_info.descriptorPool = ds_pool;
35821     alloc_info.pSetLayouts = set_layouts;
35822     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, descriptor_sets);
35823     m_errorMonitor->VerifyNotFound();
35824 
35825     // Test invalid VkWriteDescriptorSet parameters (array element and size must be multiple of 4)
35826     VkWriteDescriptorSet descriptor_write = {};
35827     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
35828     descriptor_write.dstSet = descriptor_sets[0];
35829     descriptor_write.dstBinding = 0;
35830     descriptor_write.dstArrayElement = 0;
35831     descriptor_write.descriptorCount = 3;
35832     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT;
35833 
35834     uint32_t dummyData[8] = {};
35835     VkWriteDescriptorSetInlineUniformBlockEXT write_inline_uniform = {};
35836     write_inline_uniform.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT;
35837     write_inline_uniform.dataSize = 3;
35838     write_inline_uniform.pData = &dummyData[0];
35839     descriptor_write.pNext = &write_inline_uniform;
35840 
35841     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkWriteDescriptorSet-descriptorType-02220");
35842     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
35843     m_errorMonitor->VerifyFound();
35844 
35845     descriptor_write.dstArrayElement = 1;
35846     descriptor_write.descriptorCount = 4;
35847     write_inline_uniform.dataSize = 4;
35848     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkWriteDescriptorSet-descriptorType-02219");
35849     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
35850     m_errorMonitor->VerifyFound();
35851 
35852     descriptor_write.pNext = nullptr;
35853     descriptor_write.dstArrayElement = 0;
35854     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkWriteDescriptorSet-descriptorType-02221");
35855     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
35856     m_errorMonitor->VerifyFound();
35857 
35858     descriptor_write.pNext = &write_inline_uniform;
35859     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
35860     m_errorMonitor->VerifyNotFound();
35861 
35862     // Test invalid VkCopyDescriptorSet parameters (array element and size must be multiple of 4)
35863     VkCopyDescriptorSet copy_ds_update = {};
35864     copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
35865     copy_ds_update.srcSet = descriptor_sets[0];
35866     copy_ds_update.srcBinding = 0;
35867     copy_ds_update.srcArrayElement = 0;
35868     copy_ds_update.dstSet = descriptor_sets[1];
35869     copy_ds_update.dstBinding = 0;
35870     copy_ds_update.dstArrayElement = 0;
35871     copy_ds_update.descriptorCount = 4;
35872 
35873     copy_ds_update.srcArrayElement = 1;
35874     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkCopyDescriptorSet-srcBinding-02223");
35875     vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, &copy_ds_update);
35876     m_errorMonitor->VerifyFound();
35877 
35878     copy_ds_update.srcArrayElement = 0;
35879     copy_ds_update.dstArrayElement = 1;
35880     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkCopyDescriptorSet-dstBinding-02224");
35881     vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, &copy_ds_update);
35882     m_errorMonitor->VerifyFound();
35883 
35884     copy_ds_update.dstArrayElement = 0;
35885     copy_ds_update.descriptorCount = 5;
35886     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkCopyDescriptorSet-srcBinding-02225");
35887     vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, &copy_ds_update);
35888     m_errorMonitor->VerifyFound();
35889 
35890     copy_ds_update.descriptorCount = 4;
35891     vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, &copy_ds_update);
35892     m_errorMonitor->VerifyNotFound();
35893 
35894     vkDestroyDescriptorPool(m_device->handle(), ds_pool, nullptr);
35895     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, nullptr);
35896 }
35897 
TEST_F(VkLayerTest,FramebufferMixedSamplesNV)35898 TEST_F(VkLayerTest, FramebufferMixedSamplesNV) {
35899     TEST_DESCRIPTION("Verify VK_NV_framebuffer_mixed_samples.");
35900 
35901     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
35902 
35903     if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME)) {
35904         m_device_extension_names.push_back(VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME);
35905     } else {
35906         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME);
35907         return;
35908     }
35909 
35910     ASSERT_NO_FATAL_FAILURE(InitState());
35911     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
35912 
35913     struct TestCase {
35914         VkSampleCountFlagBits color_samples;
35915         VkSampleCountFlagBits depth_samples;
35916         VkSampleCountFlagBits raster_samples;
35917         VkBool32 depth_test;
35918         VkBool32 sample_shading;
35919         uint32_t table_count;
35920         bool positiveTest;
35921         std::string vuid;
35922     };
35923 
35924     std::vector<TestCase> test_cases = {
35925         {VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_4_BIT, VK_FALSE, VK_FALSE, 1, true,
35926          "VUID-VkGraphicsPipelineCreateInfo-subpass-00757"},
35927         {VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_8_BIT, VK_FALSE, VK_FALSE, 4, false,
35928          "VUID-VkPipelineCoverageModulationStateCreateInfoNV-coverageModulationTableEnable-01405"},
35929         {VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_8_BIT, VK_FALSE, VK_FALSE, 2, true,
35930          "VUID-VkPipelineCoverageModulationStateCreateInfoNV-coverageModulationTableEnable-01405"},
35931         {VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_8_BIT, VK_TRUE, VK_FALSE, 1, false,
35932          "VUID-VkGraphicsPipelineCreateInfo-subpass-01411"},
35933         {VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_8_BIT, VK_SAMPLE_COUNT_8_BIT, VK_TRUE, VK_FALSE, 1, true,
35934          "VUID-VkGraphicsPipelineCreateInfo-subpass-01411"},
35935         {VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_1_BIT, VK_FALSE, VK_FALSE, 1, false,
35936          "VUID-VkGraphicsPipelineCreateInfo-subpass-01412"},
35937         {VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_4_BIT, VK_FALSE, VK_FALSE, 1, true,
35938          "VUID-VkGraphicsPipelineCreateInfo-subpass-01412"},
35939         {VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_4_BIT, VK_FALSE, VK_TRUE, 1, false,
35940          "VUID-VkPipelineMultisampleStateCreateInfo-rasterizationSamples-01415"},
35941         {VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_4_BIT, VK_FALSE, VK_FALSE, 1, true,
35942          "VUID-VkPipelineMultisampleStateCreateInfo-rasterizationSamples-01415"},
35943         {VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_8_BIT, VK_FALSE, VK_FALSE, 1, true,
35944          "VUID-VkGraphicsPipelineCreateInfo-subpass-00757"}};
35945 
35946     for (const auto &test_case : test_cases) {
35947         VkAttachmentDescription att[2] = {{}, {}};
35948         att[0].format = VK_FORMAT_R8G8B8A8_UNORM;
35949         att[0].samples = test_case.color_samples;
35950         att[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
35951         att[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
35952 
35953         att[1].format = VK_FORMAT_D24_UNORM_S8_UINT;
35954         att[1].samples = test_case.depth_samples;
35955         att[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
35956         att[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
35957 
35958         VkAttachmentReference cr = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
35959         VkAttachmentReference dr = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
35960 
35961         VkSubpassDescription sp = {};
35962         sp.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
35963         sp.colorAttachmentCount = 1;
35964         sp.pColorAttachments = &cr;
35965         sp.pResolveAttachments = NULL;
35966         sp.pDepthStencilAttachment = &dr;
35967 
35968         VkRenderPassCreateInfo rpi = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO};
35969         rpi.attachmentCount = 2;
35970         rpi.pAttachments = att;
35971         rpi.subpassCount = 1;
35972         rpi.pSubpasses = &sp;
35973 
35974         VkRenderPass rp;
35975 
35976         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
35977                                              "VUID-VkSubpassDescription-pDepthStencilAttachment-01418");
35978         VkResult err = vkCreateRenderPass(m_device->device(), &rpi, nullptr, &rp);
35979         m_errorMonitor->VerifyNotFound();
35980 
35981         ASSERT_VK_SUCCESS(err);
35982 
35983         VkPipelineDepthStencilStateCreateInfo ds = {VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO};
35984         VkPipelineCoverageModulationStateCreateInfoNV cmi = {VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV};
35985 
35986         // Create a dummy modulation table that can be used for the positive
35987         // coverageModulationTableCount test.
35988         std::vector<float> cm_table{};
35989 
35990         const auto break_samples = [&cmi, &rp, &ds, &cm_table, &test_case](CreatePipelineHelper &helper) {
35991             cm_table.resize(test_case.raster_samples / test_case.color_samples);
35992 
35993             cmi.flags = 0;
35994             cmi.coverageModulationTableEnable = (test_case.table_count > 1);
35995             cmi.coverageModulationTableCount = test_case.table_count;
35996             cmi.pCoverageModulationTable = cm_table.data();
35997 
35998             ds.depthTestEnable = test_case.depth_test;
35999 
36000             helper.pipe_ms_state_ci_.pNext = &cmi;
36001             helper.pipe_ms_state_ci_.rasterizationSamples = test_case.raster_samples;
36002             helper.pipe_ms_state_ci_.sampleShadingEnable = test_case.sample_shading;
36003 
36004             helper.gp_ci_.renderPass = rp;
36005             helper.gp_ci_.pDepthStencilState = &ds;
36006         };
36007 
36008         CreatePipelineHelper::OneshotTest(*this, break_samples, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuid,
36009                                           test_case.positiveTest);
36010 
36011         vkDestroyRenderPass(m_device->device(), rp, nullptr);
36012     }
36013 }
36014 
TEST_F(VkLayerTest,FramebufferMixedSamples)36015 TEST_F(VkLayerTest, FramebufferMixedSamples) {
36016     TEST_DESCRIPTION("Verify that the expected VUIds are hits when VK_NV_framebuffer_mixed_samples is disabled.");
36017 
36018     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
36019     ASSERT_NO_FATAL_FAILURE(InitState());
36020     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
36021 
36022     struct TestCase {
36023         VkSampleCountFlagBits color_samples;
36024         VkSampleCountFlagBits depth_samples;
36025         VkSampleCountFlagBits raster_samples;
36026         bool positiveTest;
36027     };
36028 
36029     std::vector<TestCase> test_cases = {
36030         {VK_SAMPLE_COUNT_2_BIT, VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_8_BIT,
36031          false},  // Fails vkCreateRenderPass and vkCreateGraphicsPipeline
36032         {VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_8_BIT, false},  // Fails vkCreateGraphicsPipeline
36033         {VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_4_BIT, true}    // Pass
36034     };
36035 
36036     for (const auto &test_case : test_cases) {
36037         VkAttachmentDescription att[2] = {{}, {}};
36038         att[0].format = VK_FORMAT_R8G8B8A8_UNORM;
36039         att[0].samples = test_case.color_samples;
36040         att[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
36041         att[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
36042 
36043         att[1].format = VK_FORMAT_D24_UNORM_S8_UINT;
36044         att[1].samples = test_case.depth_samples;
36045         att[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
36046         att[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
36047 
36048         VkAttachmentReference cr = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
36049         VkAttachmentReference dr = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
36050 
36051         VkSubpassDescription sp = {};
36052         sp.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
36053         sp.colorAttachmentCount = 1;
36054         sp.pColorAttachments = &cr;
36055         sp.pResolveAttachments = NULL;
36056         sp.pDepthStencilAttachment = &dr;
36057 
36058         VkRenderPassCreateInfo rpi = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO};
36059         rpi.attachmentCount = 2;
36060         rpi.pAttachments = att;
36061         rpi.subpassCount = 1;
36062         rpi.pSubpasses = &sp;
36063 
36064         VkRenderPass rp;
36065 
36066         if (test_case.color_samples == test_case.depth_samples) {
36067             m_errorMonitor->ExpectSuccess();
36068         } else {
36069             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
36070                                                  "VUID-VkSubpassDescription-pDepthStencilAttachment-01418");
36071         }
36072 
36073         VkResult err = vkCreateRenderPass(m_device->device(), &rpi, nullptr, &rp);
36074 
36075         if (test_case.color_samples == test_case.depth_samples) {
36076             m_errorMonitor->VerifyNotFound();
36077         } else {
36078             m_errorMonitor->VerifyFound();
36079             continue;
36080         }
36081 
36082         ASSERT_VK_SUCCESS(err);
36083 
36084         VkPipelineDepthStencilStateCreateInfo ds = {VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO};
36085 
36086         const auto break_samples = [&rp, &ds, &test_case](CreatePipelineHelper &helper) {
36087             helper.pipe_ms_state_ci_.rasterizationSamples = test_case.raster_samples;
36088 
36089             helper.gp_ci_.renderPass = rp;
36090             helper.gp_ci_.pDepthStencilState = &ds;
36091         };
36092 
36093         CreatePipelineHelper::OneshotTest(*this, break_samples, VK_DEBUG_REPORT_ERROR_BIT_EXT,
36094                                           "VUID-VkGraphicsPipelineCreateInfo-subpass-00757", test_case.positiveTest);
36095 
36096         vkDestroyRenderPass(m_device->device(), rp, nullptr);
36097     }
36098 }
36099 
TEST_F(VkLayerTest,FragmentCoverageToColorNV)36100 TEST_F(VkLayerTest, FragmentCoverageToColorNV) {
36101     TEST_DESCRIPTION("Verify VK_NV_fragment_coverage_to_color.");
36102 
36103     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
36104 
36105     if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME)) {
36106         m_device_extension_names.push_back(VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME);
36107     } else {
36108         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME);
36109         return;
36110     }
36111 
36112     ASSERT_NO_FATAL_FAILURE(InitState());
36113     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
36114 
36115     struct TestCase {
36116         VkFormat format;
36117         VkBool32 enabled;
36118         uint32_t location;
36119         bool positive;
36120     };
36121 
36122     const std::array<TestCase, 9> test_cases = {{
36123         {VK_FORMAT_R8G8B8A8_UNORM, VK_FALSE, 0, true},
36124         {VK_FORMAT_R8_UINT, VK_TRUE, 1, true},
36125         {VK_FORMAT_R16_UINT, VK_TRUE, 1, true},
36126         {VK_FORMAT_R16_SINT, VK_TRUE, 1, true},
36127         {VK_FORMAT_R32_UINT, VK_TRUE, 1, true},
36128         {VK_FORMAT_R32_SINT, VK_TRUE, 1, true},
36129         {VK_FORMAT_R32_SINT, VK_TRUE, 2, false},
36130         {VK_FORMAT_R8_SINT, VK_TRUE, 3, false},
36131         {VK_FORMAT_R8G8B8A8_UNORM, VK_TRUE, 1, false},
36132     }};
36133 
36134     for (const auto &test_case : test_cases) {
36135         std::array<VkAttachmentDescription, 2> att = {{{}, {}}};
36136         att[0].format = VK_FORMAT_R8G8B8A8_UNORM;
36137         att[0].samples = VK_SAMPLE_COUNT_1_BIT;
36138         att[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
36139         att[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
36140 
36141         att[1].format = VK_FORMAT_R8G8B8A8_UNORM;
36142         att[1].samples = VK_SAMPLE_COUNT_1_BIT;
36143         att[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
36144         att[1].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
36145 
36146         if (test_case.location < att.size()) {
36147             att[test_case.location].format = test_case.format;
36148         }
36149 
36150         const std::array<VkAttachmentReference, 3> cr = {{{0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
36151                                                           {1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
36152                                                           {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}}};
36153 
36154         VkSubpassDescription sp = {};
36155         sp.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
36156         sp.colorAttachmentCount = cr.size();
36157         sp.pColorAttachments = cr.data();
36158 
36159         VkRenderPassCreateInfo rpi = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO};
36160         rpi.attachmentCount = att.size();
36161         rpi.pAttachments = att.data();
36162         rpi.subpassCount = 1;
36163         rpi.pSubpasses = &sp;
36164 
36165         const std::array<VkPipelineColorBlendAttachmentState, 3> cba = {{{}, {}, {}}};
36166 
36167         VkPipelineColorBlendStateCreateInfo cbi = {VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO};
36168         cbi.attachmentCount = cba.size();
36169         cbi.pAttachments = cba.data();
36170 
36171         VkRenderPass rp;
36172         VkResult err = vkCreateRenderPass(m_device->device(), &rpi, nullptr, &rp);
36173         ASSERT_VK_SUCCESS(err);
36174 
36175         VkPipelineCoverageToColorStateCreateInfoNV cci = {VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV};
36176 
36177         const auto break_samples = [&cci, &cbi, &rp, &test_case](CreatePipelineHelper &helper) {
36178             cci.coverageToColorEnable = test_case.enabled;
36179             cci.coverageToColorLocation = test_case.location;
36180 
36181             helper.pipe_ms_state_ci_.pNext = &cci;
36182             helper.gp_ci_.renderPass = rp;
36183             helper.gp_ci_.pColorBlendState = &cbi;
36184         };
36185 
36186         CreatePipelineHelper::OneshotTest(*this, break_samples, VK_DEBUG_REPORT_ERROR_BIT_EXT,
36187                                           "VUID-VkPipelineCoverageToColorStateCreateInfoNV-coverageToColorEnable-01404",
36188                                           test_case.positive);
36189 
36190         vkDestroyRenderPass(m_device->device(), rp, nullptr);
36191     }
36192 }
36193 
TEST_F(VkPositiveLayerTest,RayTracingPipelineNV)36194 TEST_F(VkPositiveLayerTest, RayTracingPipelineNV) {
36195     TEST_DESCRIPTION("Test VK_NV_ray_tracing.");
36196 
36197     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
36198         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
36199     } else {
36200         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
36201                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
36202         return;
36203     }
36204     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
36205     std::array<const char *, 2> required_device_extensions = {
36206         {VK_NV_RAY_TRACING_EXTENSION_NAME, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME}};
36207     for (auto device_extension : required_device_extensions) {
36208         if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
36209             m_device_extension_names.push_back(device_extension);
36210         } else {
36211             printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
36212             return;
36213         }
36214     }
36215 
36216     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
36217         (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
36218     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
36219 
36220     ASSERT_NO_FATAL_FAILURE(InitState());
36221 
36222     m_errorMonitor->ExpectSuccess();
36223 
36224     static const char rayGenShaderText[] =
36225         "#version 460 core                                                \n"
36226         "#extension GL_NV_ray_tracing : require                           \n"
36227         "layout(set = 0, binding = 0, rgba8) uniform image2D image;       \n"
36228         "layout(set = 0, binding = 1) uniform accelerationStructureNV as; \n"
36229         "                                                                 \n"
36230         "layout(location = 0) rayPayloadNV float payload;                 \n"
36231         "                                                                 \n"
36232         "void main()                                                      \n"
36233         "{                                                                \n"
36234         "   vec4 col = vec4(0, 0, 0, 1);                                  \n"
36235         "                                                                 \n"
36236         "   vec3 origin = vec3(float(gl_LaunchIDNV.x)/float(gl_LaunchSizeNV.x), float(gl_LaunchIDNV.y)/float(gl_LaunchSizeNV.y), "
36237         "1.0); \n"
36238         "   vec3 dir = vec3(0.0, 0.0, -1.0);                              \n"
36239         "                                                                 \n"
36240         "   payload = 0.5;                                                \n"
36241         "   traceNV(as, gl_RayFlagsCullBackFacingTrianglesNV, 0xff, 0, 1, 0, origin, 0.0, dir, 1000.0, 0); \n"
36242         "                                                                 \n"
36243         "   col.y = payload;                                              \n"
36244         "                                                                 \n"
36245         "   imageStore(image, ivec2(gl_LaunchIDNV.xy), col);              \n"
36246         "}\n";
36247 
36248     static char const closestHitShaderText[] =
36249         "#version 460 core                              \n"
36250         "#extension GL_NV_ray_tracing : require         \n"
36251         "layout(location = 0) rayPayloadInNV float hitValue;             \n"
36252         "                                               \n"
36253         "void main() {                                  \n"
36254         "    hitValue = 1.0;                            \n"
36255         "}                                              \n";
36256 
36257     static char const missShaderText[] =
36258         "#version 460 core                              \n"
36259         "#extension GL_NV_ray_tracing : require         \n"
36260         "layout(location = 0) rayPayloadInNV float hitValue; \n"
36261         "                                               \n"
36262         "void main() {                                  \n"
36263         "    hitValue = 0.0;                            \n"
36264         "}                                              \n";
36265 
36266     VkShaderObj rgs(m_device, rayGenShaderText, VK_SHADER_STAGE_RAYGEN_BIT_NV, this);
36267     VkShaderObj chs(m_device, closestHitShaderText, VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV, this);
36268     VkShaderObj mis(m_device, missShaderText, VK_SHADER_STAGE_MISS_BIT_NV, this);
36269 
36270     VkPipelineShaderStageCreateInfo rayStages[3];
36271     memset(&rayStages[0], 0, sizeof(rayStages));
36272 
36273     rayStages[0] = rgs.GetStageCreateInfo();
36274     rayStages[0].stage = VK_SHADER_STAGE_RAYGEN_BIT_NV;
36275     rayStages[1] = chs.GetStageCreateInfo();
36276     rayStages[1].stage = VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV;
36277     rayStages[2] = mis.GetStageCreateInfo();
36278     rayStages[2].stage = VK_SHADER_STAGE_MISS_BIT_NV;
36279 
36280     VkRayTracingShaderGroupCreateInfoNV groups[3];
36281     memset(&groups[0], 0, sizeof(groups));
36282 
36283     groups[0].sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV;
36284     groups[0].type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV;
36285     groups[0].generalShader = 0;
36286     groups[0].closestHitShader = VK_SHADER_UNUSED_NV;
36287     groups[0].anyHitShader = VK_SHADER_UNUSED_NV;
36288     groups[0].intersectionShader = VK_SHADER_UNUSED_NV;
36289 
36290     groups[1].sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV;
36291     groups[1].type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_NV;
36292     groups[1].generalShader = VK_SHADER_UNUSED_NV;
36293     groups[1].closestHitShader = 1;
36294     groups[1].anyHitShader = VK_SHADER_UNUSED_NV;
36295     groups[1].intersectionShader = VK_SHADER_UNUSED_NV;
36296 
36297     groups[2].sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV;
36298     groups[2].type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV;
36299     groups[2].generalShader = 2;
36300     groups[2].closestHitShader = VK_SHADER_UNUSED_NV;
36301     groups[2].anyHitShader = VK_SHADER_UNUSED_NV;
36302     groups[2].intersectionShader = VK_SHADER_UNUSED_NV;
36303 
36304     const uint32_t bindingCount = 2;
36305     VkDescriptorSetLayoutBinding binding[bindingCount] = {};
36306     binding[0].binding = 0;
36307     binding[0].descriptorCount = 1;
36308     binding[0].stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_NV;
36309     binding[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
36310     binding[1].binding = 1;
36311     binding[1].descriptorCount = 1;
36312     binding[1].stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_NV;
36313     binding[1].descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV;
36314 
36315     VkDescriptorSetLayoutCreateInfo descriptorSetEntry = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO};
36316     descriptorSetEntry.bindingCount = bindingCount;
36317     descriptorSetEntry.pBindings = binding;
36318 
36319     VkDescriptorSetLayout descriptorSetLayout;
36320     VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &descriptorSetEntry, 0, &descriptorSetLayout);
36321     ASSERT_VK_SUCCESS(err);
36322     VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO};
36323     pipelineLayoutCreateInfo.setLayoutCount = 1;
36324     pipelineLayoutCreateInfo.pSetLayouts = &descriptorSetLayout;
36325     VkPipelineLayout pipelineLayout;
36326     err = vkCreatePipelineLayout(m_device->device(), &pipelineLayoutCreateInfo, 0, &pipelineLayout);
36327     ASSERT_VK_SUCCESS(err);
36328 
36329     PFN_vkCreateRayTracingPipelinesNV vkCreateRayTracingPipelinesNV =
36330         (PFN_vkCreateRayTracingPipelinesNV)vkGetInstanceProcAddr(instance(), "vkCreateRayTracingPipelinesNV");
36331 
36332     VkRayTracingPipelineCreateInfoNV rayPipelineInfo = {VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_NV};
36333     rayPipelineInfo.layout = pipelineLayout;
36334 
36335     rayPipelineInfo.stageCount = 3;
36336     rayPipelineInfo.pStages = &rayStages[0];
36337     rayPipelineInfo.groupCount = 3;
36338     rayPipelineInfo.pGroups = &groups[0];
36339 
36340     VkPipeline rayPipeline;
36341     err = vkCreateRayTracingPipelinesNV(m_device->device(), VK_NULL_HANDLE, 1, &rayPipelineInfo, 0, &rayPipeline);
36342     ASSERT_VK_SUCCESS(err);
36343 
36344     vkDestroyPipeline(m_device->device(), rayPipeline, 0);
36345     vkDestroyPipelineLayout(m_device->device(), pipelineLayout, 0);
36346     vkDestroyDescriptorSetLayout(m_device->device(), descriptorSetLayout, 0);
36347     m_errorMonitor->VerifyNotFound();
36348 }
36349 
TEST_F(VkLayerTest,CreateYCbCrSampler)36350 TEST_F(VkLayerTest, CreateYCbCrSampler) {
36351     TEST_DESCRIPTION("Verify YCbCr sampler creation.");
36352 
36353     // Test requires API 1.1 or (API 1.0 + SamplerYCbCr extension). Request API 1.1
36354     SetTargetApiVersion(VK_API_VERSION_1_1);
36355     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
36356 
36357     // In case we don't have API 1.1+, try enabling the extension directly (and it's dependencies)
36358     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME)) {
36359         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
36360         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
36361         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
36362         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
36363     }
36364 
36365     ASSERT_NO_FATAL_FAILURE(InitState());
36366     VkDevice dev = m_device->device();
36367 
36368     // Verify we have the requested support
36369     bool ycbcr_support = (DeviceExtensionEnabled(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME) ||
36370                           (DeviceValidationVersion() >= VK_API_VERSION_1_1));
36371     if (!ycbcr_support) {
36372         printf("%s Did not find required device extension %s; test skipped.\n", kSkipPrefix,
36373                VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
36374         return;
36375     }
36376 
36377     VkSamplerYcbcrConversion ycbcr_conv = VK_NULL_HANDLE;
36378     VkSamplerYcbcrConversionCreateInfo sycci = {};
36379     sycci.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO;
36380     sycci.format = VK_FORMAT_UNDEFINED;
36381     sycci.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
36382     sycci.ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
36383 
36384     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSamplerYcbcrConversionCreateInfo-format-01649");
36385     vkCreateSamplerYcbcrConversion(dev, &sycci, NULL, &ycbcr_conv);
36386     m_errorMonitor->VerifyFound();
36387 }
36388 
TEST_F(VkPositiveLayerTest,ViewportArray2NV)36389 TEST_F(VkPositiveLayerTest, ViewportArray2NV) {
36390     TEST_DESCRIPTION("Test to validate VK_NV_viewport_array2");
36391 
36392     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
36393 
36394     VkPhysicalDeviceFeatures available_features = {};
36395     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&available_features));
36396 
36397     if (!available_features.multiViewport) {
36398         printf("VkPhysicalDeviceFeatures::multiViewport is not supported, skipping tests\n");
36399         return;
36400     }
36401     if (!available_features.tessellationShader) {
36402         printf("VkPhysicalDeviceFeatures::tessellationShader is not supported, skipping tests\n");
36403         return;
36404     }
36405     if (!available_features.geometryShader) {
36406         printf("VkPhysicalDeviceFeatures::geometryShader is not supported, skipping tests\n");
36407         return;
36408     }
36409 
36410     if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME)) {
36411         m_device_extension_names.push_back(VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME);
36412     } else {
36413         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME);
36414         return;
36415     }
36416 
36417     ASSERT_NO_FATAL_FAILURE(InitState());
36418     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
36419 
36420     const char tcs_src[] = R"(
36421         #version 450
36422         layout(vertices = 3) out;
36423 
36424         void main() {
36425             gl_TessLevelOuter[0] = 4.0f;
36426             gl_TessLevelOuter[1] = 4.0f;
36427             gl_TessLevelOuter[2] = 4.0f;
36428             gl_TessLevelInner[0] = 3.0f;
36429 
36430             gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
36431         })";
36432 
36433     const char fs_src[] = R"(
36434         #version 450
36435         layout(location = 0) out vec4 outColor;
36436         void main() {
36437             outColor = vec4(1.0f);
36438         })";
36439 
36440     // Create tessellation control and fragment shader here since they will not be
36441     // modified by the different test cases.
36442     VkShaderObj tcs(m_device, tcs_src, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
36443     VkShaderObj fs(m_device, fs_src, VK_SHADER_STAGE_FRAGMENT_BIT, this);
36444 
36445     std::vector<VkViewport> vps = {{0.0f, 0.0f, m_width / 2.0f, m_height}, {m_width / 2.0f, 0.0f, m_width / 2.0f, m_height}};
36446     std::vector<VkRect2D> scs = {
36447         {{0, 0}, {static_cast<uint32_t>(m_width) / 2, static_cast<uint32_t>(m_height)}},
36448         {{static_cast<int32_t>(m_width) / 2, 0}, {static_cast<uint32_t>(m_width) / 2, static_cast<uint32_t>(m_height)}}};
36449 
36450     enum class TestStage { VERTEX = 0, TESSELLATION_EVAL = 1, GEOMETRY = 2 };
36451     std::array<TestStage, 3> vertex_stages = {{TestStage::VERTEX, TestStage::TESSELLATION_EVAL, TestStage::GEOMETRY}};
36452 
36453     // Verify that the usage of gl_ViewportMask[] in the allowed vertex processing
36454     // stages does not cause any errors.
36455     for (auto stage : vertex_stages) {
36456         m_errorMonitor->ExpectSuccess();
36457 
36458         VkPipelineInputAssemblyStateCreateInfo iaci = {VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO};
36459         iaci.topology = (stage != TestStage::VERTEX) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
36460 
36461         VkPipelineTessellationStateCreateInfo tsci = {VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO};
36462         tsci.patchControlPoints = 3;
36463 
36464         const VkPipelineLayoutObj pl(m_device);
36465 
36466         VkPipelineObj pipe(m_device);
36467         pipe.AddDefaultColorAttachment();
36468         pipe.SetInputAssembly(&iaci);
36469         pipe.SetViewport(vps);
36470         pipe.SetScissor(scs);
36471         pipe.AddShader(&fs);
36472 
36473         std::stringstream vs_src, tes_src, geom_src;
36474 
36475         vs_src << R"(
36476             #version 450
36477             #extension GL_NV_viewport_array2 : require
36478 
36479             vec2 positions[3] = { vec2( 0.0f, -0.5f),
36480                                   vec2( 0.5f,  0.5f),
36481                                   vec2(-0.5f,  0.5f)
36482                                 };
36483             void main() {)";
36484         // Write viewportMask if the vertex shader is the last vertex processing stage.
36485         if (stage == TestStage::VERTEX) {
36486             vs_src << "gl_ViewportMask[0] = 3;\n";
36487         }
36488         vs_src << R"(
36489                 gl_Position = vec4(positions[gl_VertexIndex % 3], 0.0, 1.0);
36490             })";
36491 
36492         VkShaderObj vs(m_device, vs_src.str().c_str(), VK_SHADER_STAGE_VERTEX_BIT, this);
36493         pipe.AddShader(&vs);
36494 
36495         std::unique_ptr<VkShaderObj> tes, geom;
36496 
36497         if (stage >= TestStage::TESSELLATION_EVAL) {
36498             tes_src << R"(
36499                 #version 450
36500                 #extension GL_NV_viewport_array2 : require
36501                 layout(triangles) in;
36502 
36503                 void main() {
36504                    gl_Position = (gl_in[0].gl_Position * gl_TessCoord.x +
36505                                   gl_in[1].gl_Position * gl_TessCoord.y +
36506                                   gl_in[2].gl_Position * gl_TessCoord.z);)";
36507             // Write viewportMask if the tess eval shader is the last vertex processing stage.
36508             if (stage == TestStage::TESSELLATION_EVAL) {
36509                 tes_src << "gl_ViewportMask[0] = 3;\n";
36510             }
36511             tes_src << "}";
36512 
36513             tes = std::unique_ptr<VkShaderObj>(
36514                 new VkShaderObj(m_device, tes_src.str().c_str(), VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this));
36515             pipe.AddShader(tes.get());
36516             pipe.AddShader(&tcs);
36517             pipe.SetTessellation(&tsci);
36518         }
36519 
36520         if (stage >= TestStage::GEOMETRY) {
36521             geom_src << R"(
36522                 #version 450
36523                 #extension GL_NV_viewport_array2 : require
36524                 layout(triangles)   in;
36525                 layout(triangle_strip, max_vertices = 3) out;
36526 
36527                 void main() {
36528                    gl_ViewportMask[0] = 3;
36529                    for(int i = 0; i < 3; ++i) {
36530                        gl_Position = gl_in[i].gl_Position;
36531                        EmitVertex();
36532                     }
36533                 })";
36534 
36535             geom =
36536                 std::unique_ptr<VkShaderObj>(new VkShaderObj(m_device, geom_src.str().c_str(), VK_SHADER_STAGE_GEOMETRY_BIT, this));
36537             pipe.AddShader(geom.get());
36538         }
36539 
36540         pipe.CreateVKPipeline(pl.handle(), renderPass());
36541         m_errorMonitor->VerifyNotFound();
36542     }
36543 }
36544 
36545 #ifdef VK_USE_PLATFORM_ANDROID_KHR
36546 #include "android_ndk_types.h"
36547 
TEST_F(VkLayerTest,AndroidHardwareBufferImageCreate)36548 TEST_F(VkLayerTest, AndroidHardwareBufferImageCreate) {
36549     TEST_DESCRIPTION("Verify AndroidHardwareBuffer image create info.");
36550 
36551     SetTargetApiVersion(VK_API_VERSION_1_1);
36552     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
36553 
36554     if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
36555         // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
36556         (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
36557         m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
36558         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
36559         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
36560         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
36561         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
36562         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
36563         m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
36564     } else {
36565         printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
36566                VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
36567         return;
36568     }
36569 
36570     ASSERT_NO_FATAL_FAILURE(InitState());
36571     VkDevice dev = m_device->device();
36572 
36573     VkImage img = VK_NULL_HANDLE;
36574     auto reset_img = [&img, dev]() {
36575         if (VK_NULL_HANDLE != img) vkDestroyImage(dev, img, NULL);
36576         img = VK_NULL_HANDLE;
36577     };
36578 
36579     VkImageCreateInfo ici = {};
36580     ici.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
36581     ici.pNext = nullptr;
36582     ici.imageType = VK_IMAGE_TYPE_2D;
36583     ici.arrayLayers = 1;
36584     ici.extent = {64, 64, 1};
36585     ici.format = VK_FORMAT_UNDEFINED;
36586     ici.mipLevels = 1;
36587     ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
36588     ici.samples = VK_SAMPLE_COUNT_1_BIT;
36589     ici.tiling = VK_IMAGE_TILING_OPTIMAL;
36590     ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
36591 
36592     // undefined format
36593     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-pNext-01975");
36594     vkCreateImage(dev, &ici, NULL, &img);
36595     m_errorMonitor->VerifyFound();
36596     reset_img();
36597 
36598     // also undefined format
36599     VkExternalFormatANDROID efa = {};
36600     efa.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID;
36601     efa.externalFormat = 0;
36602     ici.pNext = &efa;
36603     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-pNext-01975");
36604     vkCreateImage(dev, &ici, NULL, &img);
36605     m_errorMonitor->VerifyFound();
36606     reset_img();
36607 
36608     // undefined format with an unknown external format
36609     efa.externalFormat = 0xBADC0DE;
36610     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkExternalFormatANDROID-externalFormat-01894");
36611     vkCreateImage(dev, &ici, NULL, &img);
36612     m_errorMonitor->VerifyFound();
36613     reset_img();
36614 
36615     AHardwareBuffer *ahb;
36616     AHardwareBuffer_Desc ahb_desc = {};
36617     ahb_desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
36618     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
36619     ahb_desc.width = 64;
36620     ahb_desc.height = 64;
36621     ahb_desc.layers = 1;
36622     // Allocate an AHardwareBuffer
36623     AHardwareBuffer_allocate(&ahb_desc, &ahb);
36624 
36625     // Retrieve it's properties to make it's external format 'known' (AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM)
36626     VkAndroidHardwareBufferFormatPropertiesANDROID ahb_fmt_props = {};
36627     ahb_fmt_props.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID;
36628     VkAndroidHardwareBufferPropertiesANDROID ahb_props = {};
36629     ahb_props.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID;
36630     ahb_props.pNext = &ahb_fmt_props;
36631     PFN_vkGetAndroidHardwareBufferPropertiesANDROID pfn_GetAHBProps =
36632         (PFN_vkGetAndroidHardwareBufferPropertiesANDROID)vkGetDeviceProcAddr(dev, "vkGetAndroidHardwareBufferPropertiesANDROID");
36633     ASSERT_TRUE(pfn_GetAHBProps != nullptr);
36634     pfn_GetAHBProps(dev, ahb, &ahb_props);
36635 
36636     // a defined image format with a non-zero external format
36637     ici.format = VK_FORMAT_R8G8B8A8_UNORM;
36638     efa.externalFormat = AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
36639     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-pNext-01974");
36640     vkCreateImage(dev, &ici, NULL, &img);
36641     m_errorMonitor->VerifyFound();
36642     reset_img();
36643     ici.format = VK_FORMAT_UNDEFINED;
36644 
36645     // external format while MUTABLE
36646     ici.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
36647     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-pNext-02396");
36648     vkCreateImage(dev, &ici, NULL, &img);
36649     m_errorMonitor->VerifyFound();
36650     reset_img();
36651     ici.flags = 0;
36652 
36653     // external format while usage other than SAMPLED
36654     ici.usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
36655     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-pNext-02397");
36656     vkCreateImage(dev, &ici, NULL, &img);
36657     m_errorMonitor->VerifyFound();
36658     reset_img();
36659     ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
36660 
36661     // external format while tiline other than OPTIMAL
36662     ici.tiling = VK_IMAGE_TILING_LINEAR;
36663     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-pNext-02398");
36664     vkCreateImage(dev, &ici, NULL, &img);
36665     m_errorMonitor->VerifyFound();
36666     reset_img();
36667     ici.tiling = VK_IMAGE_TILING_OPTIMAL;
36668 
36669     // imageType
36670     VkExternalMemoryImageCreateInfo emici = {};
36671     emici.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO;
36672     emici.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
36673     ici.pNext = &emici;  // remove efa from chain, insert emici
36674     ici.format = VK_FORMAT_R8G8B8A8_UNORM;
36675     ici.imageType = VK_IMAGE_TYPE_3D;
36676     ici.extent = {64, 64, 64};
36677 
36678     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-pNext-02393");
36679     vkCreateImage(dev, &ici, NULL, &img);
36680     m_errorMonitor->VerifyFound();
36681     reset_img();
36682 
36683     // wrong mipLevels
36684     ici.imageType = VK_IMAGE_TYPE_2D;
36685     ici.extent = {64, 64, 1};
36686     ici.mipLevels = 6;  // should be 7
36687     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-pNext-02394");
36688     vkCreateImage(dev, &ici, NULL, &img);
36689     m_errorMonitor->VerifyFound();
36690     reset_img();
36691 }
36692 
TEST_F(VkLayerTest,AndroidHardwareBufferFetchUnboundImageInfo)36693 TEST_F(VkLayerTest, AndroidHardwareBufferFetchUnboundImageInfo) {
36694     TEST_DESCRIPTION("Verify AndroidHardwareBuffer retreive image properties while memory unbound.");
36695 
36696     SetTargetApiVersion(VK_API_VERSION_1_1);
36697     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
36698 
36699     if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
36700         // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
36701         (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
36702         m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
36703         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
36704         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
36705         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
36706         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
36707         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
36708         m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
36709     } else {
36710         printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
36711                VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
36712         return;
36713     }
36714 
36715     ASSERT_NO_FATAL_FAILURE(InitState());
36716     VkDevice dev = m_device->device();
36717 
36718     VkImage img = VK_NULL_HANDLE;
36719     auto reset_img = [&img, dev]() {
36720         if (VK_NULL_HANDLE != img) vkDestroyImage(dev, img, NULL);
36721         img = VK_NULL_HANDLE;
36722     };
36723 
36724     VkImageCreateInfo ici = {};
36725     ici.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
36726     ici.pNext = nullptr;
36727     ici.imageType = VK_IMAGE_TYPE_2D;
36728     ici.arrayLayers = 1;
36729     ici.extent = {64, 64, 1};
36730     ici.format = VK_FORMAT_R8G8B8A8_UNORM;
36731     ici.mipLevels = 1;
36732     ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
36733     ici.samples = VK_SAMPLE_COUNT_1_BIT;
36734     ici.tiling = VK_IMAGE_TILING_LINEAR;
36735     ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
36736 
36737     VkExternalMemoryImageCreateInfo emici = {};
36738     emici.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO;
36739     emici.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
36740     ici.pNext = &emici;
36741 
36742     m_errorMonitor->ExpectSuccess();
36743     vkCreateImage(dev, &ici, NULL, &img);
36744     m_errorMonitor->VerifyNotFound();
36745 
36746     // attempt to fetch layout from unbound image
36747     VkImageSubresource sub_rsrc = {};
36748     sub_rsrc.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
36749     VkSubresourceLayout sub_layout = {};
36750     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkGetImageSubresourceLayout-image-01895");
36751     vkGetImageSubresourceLayout(dev, img, &sub_rsrc, &sub_layout);
36752     m_errorMonitor->VerifyFound();
36753 
36754     // attempt to get memory reqs from unbound image
36755     VkImageMemoryRequirementsInfo2 imri = {};
36756     imri.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2;
36757     imri.image = img;
36758     VkMemoryRequirements2 mem_reqs = {};
36759     mem_reqs.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
36760     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryRequirementsInfo2-image-01897");
36761     vkGetImageMemoryRequirements2(dev, &imri, &mem_reqs);
36762     m_errorMonitor->VerifyFound();
36763 
36764     reset_img();
36765 }
36766 
TEST_F(VkLayerTest,AndroidHardwareBufferMemoryAllocation)36767 TEST_F(VkLayerTest, AndroidHardwareBufferMemoryAllocation) {
36768     TEST_DESCRIPTION("Verify AndroidHardwareBuffer memory allocation.");
36769 
36770     SetTargetApiVersion(VK_API_VERSION_1_1);
36771     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
36772 
36773     if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
36774         // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
36775         (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
36776         m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
36777         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
36778         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
36779         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
36780         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
36781         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
36782         m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
36783     } else {
36784         printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
36785                VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
36786         return;
36787     }
36788 
36789     ASSERT_NO_FATAL_FAILURE(InitState());
36790     VkDevice dev = m_device->device();
36791 
36792     VkImage img = VK_NULL_HANDLE;
36793     auto reset_img = [&img, dev]() {
36794         if (VK_NULL_HANDLE != img) vkDestroyImage(dev, img, NULL);
36795         img = VK_NULL_HANDLE;
36796     };
36797     VkDeviceMemory mem_handle = VK_NULL_HANDLE;
36798     auto reset_mem = [&mem_handle, dev]() {
36799         if (VK_NULL_HANDLE != mem_handle) vkFreeMemory(dev, mem_handle, NULL);
36800         mem_handle = VK_NULL_HANDLE;
36801     };
36802 
36803     PFN_vkGetAndroidHardwareBufferPropertiesANDROID pfn_GetAHBProps =
36804         (PFN_vkGetAndroidHardwareBufferPropertiesANDROID)vkGetDeviceProcAddr(dev, "vkGetAndroidHardwareBufferPropertiesANDROID");
36805     ASSERT_TRUE(pfn_GetAHBProps != nullptr);
36806 
36807     // AHB structs
36808     AHardwareBuffer *ahb = nullptr;
36809     AHardwareBuffer_Desc ahb_desc = {};
36810     VkAndroidHardwareBufferFormatPropertiesANDROID ahb_fmt_props = {};
36811     ahb_fmt_props.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID;
36812     VkAndroidHardwareBufferPropertiesANDROID ahb_props = {};
36813     ahb_props.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID;
36814     ahb_props.pNext = &ahb_fmt_props;
36815     VkImportAndroidHardwareBufferInfoANDROID iahbi = {};
36816     iahbi.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID;
36817 
36818     // destroy and re-acquire an AHB, and fetch it's properties
36819     auto recreate_ahb = [&ahb, &iahbi, &ahb_desc, &ahb_props, dev, pfn_GetAHBProps]() {
36820         if (ahb) AHardwareBuffer_release(ahb);
36821         ahb = nullptr;
36822         AHardwareBuffer_allocate(&ahb_desc, &ahb);
36823         pfn_GetAHBProps(dev, ahb, &ahb_props);
36824         iahbi.buffer = ahb;
36825     };
36826 
36827     // Allocate an AHardwareBuffer
36828     ahb_desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
36829     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
36830     ahb_desc.width = 64;
36831     ahb_desc.height = 64;
36832     ahb_desc.layers = 1;
36833     recreate_ahb();
36834 
36835     // Create an image w/ external format
36836     VkExternalFormatANDROID efa = {};
36837     efa.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID;
36838     efa.externalFormat = AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
36839 
36840     VkImageCreateInfo ici = {};
36841     ici.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
36842     ici.pNext = &efa;
36843     ici.imageType = VK_IMAGE_TYPE_2D;
36844     ici.arrayLayers = 1;
36845     ici.extent = {64, 64, 1};
36846     ici.format = VK_FORMAT_UNDEFINED;
36847     ici.mipLevels = 1;
36848     ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
36849     ici.mipLevels = 1;
36850     ici.samples = VK_SAMPLE_COUNT_1_BIT;
36851     ici.tiling = VK_IMAGE_TILING_OPTIMAL;
36852     ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
36853     VkResult res = vkCreateImage(dev, &ici, NULL, &img);
36854     ASSERT_VK_SUCCESS(res);
36855 
36856     VkMemoryAllocateInfo mai = {};
36857     mai.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
36858     mai.pNext = &iahbi;  // Chained import struct
36859     mai.allocationSize = ahb_props.allocationSize;
36860     mai.memoryTypeIndex = 32;
36861     // Set index to match one of the bits in ahb_props
36862     for (int i = 0; i < 32; i++) {
36863         if (ahb_props.memoryTypeBits & (1 << i)) {
36864             mai.memoryTypeIndex = i;
36865             break;
36866         }
36867     }
36868     ASSERT_NE(32, mai.memoryTypeIndex);
36869 
36870     // Import w/ non-dedicated memory allocation
36871 
36872     // Import requires format AHB_FMT_BLOB and usage AHB_USAGE_GPU_DATA_BUFFER
36873     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-pNext-02384");
36874     vkAllocateMemory(dev, &mai, NULL, &mem_handle);
36875     m_errorMonitor->VerifyFound();
36876     reset_mem();
36877 
36878     // Allocation size mismatch
36879     ahb_desc.format = AHARDWAREBUFFER_FORMAT_BLOB;
36880     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER | AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
36881     recreate_ahb();
36882     mai.allocationSize = ahb_props.allocationSize + 1;
36883     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-allocationSize-02383");
36884     vkAllocateMemory(dev, &mai, NULL, &mem_handle);
36885     m_errorMonitor->VerifyFound();
36886     mai.allocationSize = ahb_props.allocationSize;
36887     reset_mem();
36888 
36889     // memoryTypeIndex mismatch
36890     mai.memoryTypeIndex++;
36891     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-memoryTypeIndex-02385");
36892     vkAllocateMemory(dev, &mai, NULL, &mem_handle);
36893     m_errorMonitor->VerifyFound();
36894     mai.memoryTypeIndex--;
36895     reset_mem();
36896 
36897     // Insert dedicated image memory allocation to mai chain
36898     VkMemoryDedicatedAllocateInfo mdai = {};
36899     mdai.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
36900     mdai.image = img;
36901     mdai.buffer = VK_NULL_HANDLE;
36902     mdai.pNext = mai.pNext;
36903     mai.pNext = &mdai;
36904 
36905     // Dedicated allocation with unmatched usage bits
36906     ahb_desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
36907     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
36908     recreate_ahb();
36909     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-pNext-02390");
36910     vkAllocateMemory(dev, &mai, NULL, &mem_handle);
36911     m_errorMonitor->VerifyFound();
36912     reset_mem();
36913 
36914     // Dedicated allocation with incomplete mip chain
36915     reset_img();
36916     ici.mipLevels = 2;
36917     vkCreateImage(dev, &ici, NULL, &img);
36918     mdai.image = img;
36919     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE;
36920     recreate_ahb();
36921     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-pNext-02389");
36922     vkAllocateMemory(dev, &mai, NULL, &mem_handle);
36923     m_errorMonitor->VerifyFound();
36924     reset_mem();
36925 
36926     // Dedicated allocation with mis-matched dimension
36927     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
36928     ahb_desc.height = 32;
36929     ahb_desc.width = 128;
36930     recreate_ahb();
36931     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-pNext-02388");
36932     vkAllocateMemory(dev, &mai, NULL, &mem_handle);
36933     m_errorMonitor->VerifyFound();
36934     reset_mem();
36935 
36936     // Dedicated allocation with mis-matched VkFormat
36937     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
36938     ahb_desc.height = 64;
36939     ahb_desc.width = 64;
36940     recreate_ahb();
36941     ici.mipLevels = 1;
36942     ici.format = VK_FORMAT_B8G8R8A8_UNORM;
36943     ici.pNext = NULL;
36944     VkImage img2;
36945     vkCreateImage(dev, &ici, NULL, &img2);
36946     mdai.image = img2;
36947     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-pNext-02387");
36948     vkAllocateMemory(dev, &mai, NULL, &mem_handle);
36949     m_errorMonitor->VerifyFound();
36950     vkDestroyImage(dev, img2, NULL);
36951     mdai.image = img;
36952     reset_mem();
36953 
36954     // Missing required ahb usage
36955     ahb_desc.usage = AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
36956     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
36957                                          "VUID-vkGetAndroidHardwareBufferPropertiesANDROID-buffer-01884");
36958     recreate_ahb();
36959     m_errorMonitor->VerifyFound();
36960 
36961     // Dedicated allocation with missing usage bits
36962     // Setting up this test also triggers a slew of others
36963     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-pNext-02390");
36964     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-memoryTypeIndex-02385");
36965     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-allocationSize-02383");
36966     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
36967                                          "VUID-vkGetAndroidHardwareBufferPropertiesANDROID-buffer-01884");
36968 
36969     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-pNext-02386");
36970     vkAllocateMemory(dev, &mai, NULL, &mem_handle);
36971     m_errorMonitor->VerifyFound();
36972     reset_mem();
36973 
36974     // Non-import allocation - replace import struct in chain with export struct
36975     VkExportMemoryAllocateInfo emai = {};
36976     emai.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO;
36977     emai.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
36978     mai.pNext = &emai;
36979     emai.pNext = &mdai;  // still dedicated
36980     mdai.pNext = nullptr;
36981 
36982     // Export with allocation size non-zero
36983     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
36984     recreate_ahb();
36985     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-pNext-01874");
36986     vkAllocateMemory(dev, &mai, NULL, &mem_handle);
36987     m_errorMonitor->VerifyFound();
36988     reset_mem();
36989 
36990     AHardwareBuffer_release(ahb);
36991     reset_mem();
36992     reset_img();
36993 }
36994 
TEST_F(VkLayerTest,AndroidHardwareBufferCreateYCbCrSampler)36995 TEST_F(VkLayerTest, AndroidHardwareBufferCreateYCbCrSampler) {
36996     TEST_DESCRIPTION("Verify AndroidHardwareBuffer YCbCr sampler creation.");
36997 
36998     SetTargetApiVersion(VK_API_VERSION_1_1);
36999     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
37000 
37001     if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
37002         // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
37003         (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
37004         m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
37005         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
37006         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
37007         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
37008         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
37009         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
37010         m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
37011     } else {
37012         printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
37013                VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
37014         return;
37015     }
37016 
37017     ASSERT_NO_FATAL_FAILURE(InitState());
37018     VkDevice dev = m_device->device();
37019 
37020     VkSamplerYcbcrConversion ycbcr_conv = VK_NULL_HANDLE;
37021     VkSamplerYcbcrConversionCreateInfo sycci = {};
37022     sycci.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO;
37023     sycci.format = VK_FORMAT_UNDEFINED;
37024     sycci.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
37025     sycci.ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
37026 
37027     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSamplerYcbcrConversionCreateInfo-format-01904");
37028     vkCreateSamplerYcbcrConversion(dev, &sycci, NULL, &ycbcr_conv);
37029     m_errorMonitor->VerifyFound();
37030 
37031     VkExternalFormatANDROID efa = {};
37032     efa.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID;
37033     efa.externalFormat = AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
37034     sycci.format = VK_FORMAT_R8G8B8A8_UNORM;
37035     sycci.pNext = &efa;
37036     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSamplerYcbcrConversionCreateInfo-format-01904");
37037     vkCreateSamplerYcbcrConversion(dev, &sycci, NULL, &ycbcr_conv);
37038     m_errorMonitor->VerifyFound();
37039 }
37040 
TEST_F(VkLayerTest,AndroidHardwareBufferPhysDevImageFormatProp2)37041 TEST_F(VkLayerTest, AndroidHardwareBufferPhysDevImageFormatProp2) {
37042     TEST_DESCRIPTION("Verify AndroidHardwareBuffer GetPhysicalDeviceImageFormatProperties.");
37043 
37044     SetTargetApiVersion(VK_API_VERSION_1_1);
37045     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
37046 
37047     if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
37048         // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
37049         (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
37050         m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
37051         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
37052         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
37053         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
37054         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
37055         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
37056         m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
37057     } else {
37058         printf("%s %s extension not supported, skipping test\n", kSkipPrefix,
37059                VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
37060         return;
37061     }
37062 
37063     ASSERT_NO_FATAL_FAILURE(InitState());
37064 
37065     if ((m_instance_api_version < VK_API_VERSION_1_1) &&
37066         !InstanceExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
37067         printf("%s %s extension not supported, skipping test\n", kSkipPrefix,
37068                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
37069         return;
37070     }
37071 
37072     VkImageFormatProperties2 ifp = {};
37073     ifp.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
37074     VkPhysicalDeviceImageFormatInfo2 pdifi = {};
37075     pdifi.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2;
37076     pdifi.format = VK_FORMAT_R8G8B8A8_UNORM;
37077     pdifi.tiling = VK_IMAGE_TILING_OPTIMAL;
37078     pdifi.type = VK_IMAGE_TYPE_2D;
37079     pdifi.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
37080     VkAndroidHardwareBufferUsageANDROID ahbu = {};
37081     ahbu.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID;
37082     ahbu.androidHardwareBufferUsage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
37083     ifp.pNext = &ahbu;
37084 
37085     // AHB_usage chained to input without a matching external image format struc chained to output
37086     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
37087                                          "VUID-vkGetPhysicalDeviceImageFormatProperties2-pNext-01868");
37088     vkGetPhysicalDeviceImageFormatProperties2(m_device->phy().handle(), &pdifi, &ifp);
37089     m_errorMonitor->VerifyFound();
37090 
37091     // output struct chained, but does not include VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID usage
37092     VkPhysicalDeviceExternalImageFormatInfo pdeifi = {};
37093     pdeifi.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO;
37094     pdeifi.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
37095     pdifi.pNext = &pdeifi;
37096     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
37097                                          "VUID-vkGetPhysicalDeviceImageFormatProperties2-pNext-01868");
37098     vkGetPhysicalDeviceImageFormatProperties2(m_device->phy().handle(), &pdifi, &ifp);
37099     m_errorMonitor->VerifyFound();
37100 }
37101 
TEST_F(VkLayerTest,AndroidHardwareBufferCreateImageView)37102 TEST_F(VkLayerTest, AndroidHardwareBufferCreateImageView) {
37103     TEST_DESCRIPTION("Verify AndroidHardwareBuffer image view creation.");
37104 
37105     SetTargetApiVersion(VK_API_VERSION_1_1);
37106     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
37107 
37108     if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
37109         // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
37110         (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
37111         m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
37112         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
37113         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
37114         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
37115         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
37116         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
37117         m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
37118     } else {
37119         printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
37120                VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
37121         return;
37122     }
37123 
37124     ASSERT_NO_FATAL_FAILURE(InitState());
37125     VkDevice dev = m_device->device();
37126 
37127     // Expect no validation errors during setup
37128     m_errorMonitor->ExpectSuccess();
37129 
37130     // Allocate an AHB and fetch its properties
37131     AHardwareBuffer *ahb = nullptr;
37132     AHardwareBuffer_Desc ahb_desc = {};
37133     ahb_desc.format = AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
37134     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
37135     ahb_desc.width = 64;
37136     ahb_desc.height = 64;
37137     ahb_desc.layers = 1;
37138     AHardwareBuffer_allocate(&ahb_desc, &ahb);
37139 
37140     // Retrieve AHB properties to make it's external format 'known'
37141     VkAndroidHardwareBufferFormatPropertiesANDROID ahb_fmt_props = {};
37142     ahb_fmt_props.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID;
37143     VkAndroidHardwareBufferPropertiesANDROID ahb_props = {};
37144     ahb_props.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID;
37145     ahb_props.pNext = &ahb_fmt_props;
37146     PFN_vkGetAndroidHardwareBufferPropertiesANDROID pfn_GetAHBProps =
37147         (PFN_vkGetAndroidHardwareBufferPropertiesANDROID)vkGetDeviceProcAddr(dev, "vkGetAndroidHardwareBufferPropertiesANDROID");
37148     ASSERT_TRUE(pfn_GetAHBProps != nullptr);
37149     pfn_GetAHBProps(dev, ahb, &ahb_props);
37150     AHardwareBuffer_release(ahb);
37151 
37152     // Give image an external format
37153     VkExternalFormatANDROID efa = {};
37154     efa.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID;
37155     efa.externalFormat = AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
37156 
37157     // Create the image
37158     VkImage img = VK_NULL_HANDLE;
37159     VkImageCreateInfo ici = {};
37160     ici.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
37161     ici.pNext = &efa;
37162     ici.imageType = VK_IMAGE_TYPE_2D;
37163     ici.arrayLayers = 1;
37164     ici.extent = {64, 64, 1};
37165     ici.format = VK_FORMAT_UNDEFINED;
37166     ici.mipLevels = 1;
37167     ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
37168     ici.samples = VK_SAMPLE_COUNT_1_BIT;
37169     ici.tiling = VK_IMAGE_TILING_OPTIMAL;
37170     ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
37171     vkCreateImage(dev, &ici, NULL, &img);
37172 
37173     // Set up memory allocation
37174     VkDeviceMemory img_mem = VK_NULL_HANDLE;
37175     VkMemoryAllocateInfo mai = {};
37176     mai.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
37177     mai.allocationSize = 64 * 64 * 4;
37178     mai.memoryTypeIndex = 0;
37179     vkAllocateMemory(dev, &mai, NULL, &img_mem);
37180 
37181     // Bind image to memory
37182     vkBindImageMemory(dev, img, img_mem, 0);
37183 
37184     // Create a YCbCr conversion, with different external format, chain to view
37185     VkSamplerYcbcrConversion ycbcr_conv = VK_NULL_HANDLE;
37186     VkSamplerYcbcrConversionCreateInfo sycci = {};
37187     efa.externalFormat = AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
37188     sycci.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO;
37189     sycci.pNext = &efa;
37190     sycci.format = VK_FORMAT_UNDEFINED;
37191     sycci.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
37192     sycci.ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
37193     vkCreateSamplerYcbcrConversion(dev, &sycci, NULL, &ycbcr_conv);
37194     VkSamplerYcbcrConversionInfo syci = {};
37195     syci.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO;
37196     syci.conversion = ycbcr_conv;
37197 
37198     // Create a view
37199     VkImageView image_view = VK_NULL_HANDLE;
37200     VkImageViewCreateInfo ivci = {};
37201     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
37202     ivci.pNext = &syci;
37203     ivci.image = img;
37204     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
37205     ivci.format = VK_FORMAT_UNDEFINED;
37206     ivci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
37207 
37208     auto reset_view = [&image_view, dev]() {
37209         if (VK_NULL_HANDLE != image_view) vkDestroyImageView(dev, image_view, NULL);
37210         image_view = VK_NULL_HANDLE;
37211     };
37212 
37213     // Up to this point, no errors expected
37214     m_errorMonitor->VerifyNotFound();
37215 
37216     // Chained ycbcr conversion has different (external) format than image
37217     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-image-02400");
37218     // Also causes "unsupported format" - should be removed in future spec update
37219     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-None-02273");
37220     vkCreateImageView(dev, &ivci, NULL, &image_view);
37221     m_errorMonitor->VerifyFound();
37222 
37223     reset_view();
37224     vkDestroySamplerYcbcrConversion(dev, ycbcr_conv, NULL);
37225     efa.externalFormat = AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
37226     vkCreateSamplerYcbcrConversion(dev, &sycci, NULL, &ycbcr_conv);
37227     syci.conversion = ycbcr_conv;
37228 
37229     // View component swizzle not IDENTITY
37230     ivci.components.r = VK_COMPONENT_SWIZZLE_B;
37231     ivci.components.b = VK_COMPONENT_SWIZZLE_R;
37232     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-image-02401");
37233     // Also causes "unsupported format" - should be removed in future spec update
37234     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-None-02273");
37235     vkCreateImageView(dev, &ivci, NULL, &image_view);
37236     m_errorMonitor->VerifyFound();
37237 
37238     reset_view();
37239     ivci.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
37240     ivci.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
37241 
37242     // View with external format, when format is not UNDEFINED
37243     ivci.format = VK_FORMAT_R5G6B5_UNORM_PACK16;
37244     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-image-02399");
37245     // Also causes "view format different from image format"
37246     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-image-01019");
37247     vkCreateImageView(dev, &ivci, NULL, &image_view);
37248     m_errorMonitor->VerifyFound();
37249 
37250     reset_view();
37251     vkDestroySamplerYcbcrConversion(dev, ycbcr_conv, NULL);
37252     vkDestroyImageView(dev, image_view, NULL);
37253     vkDestroyImage(dev, img, NULL);
37254     vkFreeMemory(dev, img_mem, NULL);
37255 }
37256 
TEST_F(VkLayerTest,AndroidHardwareBufferImportBuffer)37257 TEST_F(VkLayerTest, AndroidHardwareBufferImportBuffer) {
37258     TEST_DESCRIPTION("Verify AndroidHardwareBuffer import as buffer.");
37259 
37260     SetTargetApiVersion(VK_API_VERSION_1_1);
37261     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
37262 
37263     if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
37264         // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
37265         (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
37266         m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
37267         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
37268         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
37269         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
37270         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
37271         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
37272         m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
37273     } else {
37274         printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
37275                VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
37276         return;
37277     }
37278 
37279     ASSERT_NO_FATAL_FAILURE(InitState());
37280     VkDevice dev = m_device->device();
37281 
37282     VkDeviceMemory mem_handle = VK_NULL_HANDLE;
37283     auto reset_mem = [&mem_handle, dev]() {
37284         if (VK_NULL_HANDLE != mem_handle) vkFreeMemory(dev, mem_handle, NULL);
37285         mem_handle = VK_NULL_HANDLE;
37286     };
37287 
37288     PFN_vkGetAndroidHardwareBufferPropertiesANDROID pfn_GetAHBProps =
37289         (PFN_vkGetAndroidHardwareBufferPropertiesANDROID)vkGetDeviceProcAddr(dev, "vkGetAndroidHardwareBufferPropertiesANDROID");
37290     ASSERT_TRUE(pfn_GetAHBProps != nullptr);
37291 
37292     // AHB structs
37293     AHardwareBuffer *ahb = nullptr;
37294     AHardwareBuffer_Desc ahb_desc = {};
37295     VkAndroidHardwareBufferPropertiesANDROID ahb_props = {};
37296     ahb_props.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID;
37297     VkImportAndroidHardwareBufferInfoANDROID iahbi = {};
37298     iahbi.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID;
37299 
37300     // Allocate an AHardwareBuffer
37301     ahb_desc.format = AHARDWAREBUFFER_FORMAT_BLOB;
37302     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE;
37303     ahb_desc.width = 512;
37304     ahb_desc.height = 1;
37305     ahb_desc.layers = 1;
37306     AHardwareBuffer_allocate(&ahb_desc, &ahb);
37307     pfn_GetAHBProps(dev, ahb, &ahb_props);
37308     iahbi.buffer = ahb;
37309 
37310     // Create export and import buffers
37311     VkExternalMemoryBufferCreateInfo ext_buf_info = {};
37312     ext_buf_info.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR;
37313     ext_buf_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
37314 
37315     VkBufferCreateInfo bci = {};
37316     bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
37317     bci.pNext = &ext_buf_info;
37318     bci.size = ahb_props.allocationSize;
37319     bci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
37320 
37321     VkBuffer buf = VK_NULL_HANDLE;
37322     vkCreateBuffer(dev, &bci, NULL, &buf);
37323     VkMemoryRequirements mem_reqs;
37324     vkGetBufferMemoryRequirements(dev, buf, &mem_reqs);
37325 
37326     // Allocation info
37327     VkMemoryAllocateInfo mai = vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, mem_reqs, 0);
37328     mai.pNext = &iahbi;  // Chained import struct
37329 
37330     // Import as buffer requires format AHB_FMT_BLOB and usage AHB_USAGE_GPU_DATA_BUFFER
37331     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
37332                                          "VUID-VkImportAndroidHardwareBufferInfoANDROID-buffer-01881");
37333     // Also causes "non-dedicated allocation format/usage" error
37334     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-pNext-02384");
37335     vkAllocateMemory(dev, &mai, NULL, &mem_handle);
37336     m_errorMonitor->VerifyFound();
37337 
37338     AHardwareBuffer_release(ahb);
37339     reset_mem();
37340     vkDestroyBuffer(dev, buf, NULL);
37341 }
37342 
TEST_F(VkLayerTest,AndroidHardwareBufferExporttBuffer)37343 TEST_F(VkLayerTest, AndroidHardwareBufferExporttBuffer) {
37344     TEST_DESCRIPTION("Verify AndroidHardwareBuffer export memory as AHB.");
37345 
37346     SetTargetApiVersion(VK_API_VERSION_1_1);
37347     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
37348 
37349     if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
37350         // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
37351         (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
37352         m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
37353         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
37354         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
37355         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
37356         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
37357         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
37358         m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
37359     } else {
37360         printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
37361                VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
37362         return;
37363     }
37364 
37365     ASSERT_NO_FATAL_FAILURE(InitState());
37366     VkDevice dev = m_device->device();
37367 
37368     VkDeviceMemory mem_handle = VK_NULL_HANDLE;
37369 
37370     // Allocate device memory, no linked export struct indicating AHB handle type
37371     VkMemoryAllocateInfo mai = {};
37372     mai.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
37373     mai.allocationSize = 65536;
37374     mai.memoryTypeIndex = 0;
37375     vkAllocateMemory(dev, &mai, NULL, &mem_handle);
37376 
37377     PFN_vkGetMemoryAndroidHardwareBufferANDROID pfn_GetMemAHB =
37378         (PFN_vkGetMemoryAndroidHardwareBufferANDROID)vkGetDeviceProcAddr(dev, "vkGetMemoryAndroidHardwareBufferANDROID");
37379     ASSERT_TRUE(pfn_GetMemAHB != nullptr);
37380 
37381     VkMemoryGetAndroidHardwareBufferInfoANDROID mgahbi = {};
37382     mgahbi.sType = VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID;
37383     mgahbi.memory = mem_handle;
37384     AHardwareBuffer *ahb = nullptr;
37385     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
37386                                          "VUID-VkMemoryGetAndroidHardwareBufferInfoANDROID-handleTypes-01882");
37387     pfn_GetMemAHB(dev, &mgahbi, &ahb);
37388     m_errorMonitor->VerifyFound();
37389 
37390     if (ahb) AHardwareBuffer_release(ahb);
37391     ahb = nullptr;
37392     if (VK_NULL_HANDLE != mem_handle) vkFreeMemory(dev, mem_handle, NULL);
37393     mem_handle = VK_NULL_HANDLE;
37394 
37395     // Add an export struct with AHB handle type to allocation info
37396     VkExportMemoryAllocateInfo emai = {};
37397     emai.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO;
37398     emai.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
37399     mai.pNext = &emai;
37400 
37401     // Create an image, do not bind memory
37402     VkImage img = VK_NULL_HANDLE;
37403     VkImageCreateInfo ici = {};
37404     ici.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
37405     ici.imageType = VK_IMAGE_TYPE_2D;
37406     ici.arrayLayers = 1;
37407     ici.extent = {128, 128, 1};
37408     ici.format = VK_FORMAT_R8G8B8A8_UNORM;
37409     ici.mipLevels = 1;
37410     ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
37411     ici.samples = VK_SAMPLE_COUNT_1_BIT;
37412     ici.tiling = VK_IMAGE_TILING_OPTIMAL;
37413     ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
37414     vkCreateImage(dev, &ici, NULL, &img);
37415     ASSERT_TRUE(VK_NULL_HANDLE != img);
37416 
37417     // Add image to allocation chain as dedicated info, re-allocate
37418     VkMemoryDedicatedAllocateInfo mdai = {VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO};
37419     mdai.image = img;
37420     emai.pNext = &mdai;
37421     mai.allocationSize = 0;
37422     vkAllocateMemory(dev, &mai, NULL, &mem_handle);
37423     mgahbi.memory = mem_handle;
37424 
37425     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
37426                                          "VUID-VkMemoryGetAndroidHardwareBufferInfoANDROID-pNext-01883");
37427     pfn_GetMemAHB(dev, &mgahbi, &ahb);
37428     m_errorMonitor->VerifyFound();
37429 
37430     if (ahb) AHardwareBuffer_release(ahb);
37431     if (VK_NULL_HANDLE != mem_handle) vkFreeMemory(dev, mem_handle, NULL);
37432     vkDestroyImage(dev, img, NULL);
37433 }
37434 
37435 #endif  // VK_USE_PLATFORM_ANDROID_KHR
37436 
TEST_F(VkLayerTest,ViewportSwizzleNV)37437 TEST_F(VkLayerTest, ViewportSwizzleNV) {
37438     TEST_DESCRIPTION("Verify VK_NV_viewprot_swizzle.");
37439 
37440     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
37441 
37442     if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME)) {
37443         m_device_extension_names.push_back(VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME);
37444     } else {
37445         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME);
37446         return;
37447     }
37448 
37449     ASSERT_NO_FATAL_FAILURE(InitState());
37450     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
37451 
37452     VkViewportSwizzleNV invalid_swizzles = {
37453         VkViewportCoordinateSwizzleNV(-1),
37454         VkViewportCoordinateSwizzleNV(-1),
37455         VkViewportCoordinateSwizzleNV(-1),
37456         VkViewportCoordinateSwizzleNV(-1),
37457     };
37458 
37459     VkPipelineViewportSwizzleStateCreateInfoNV vp_swizzle_state = {
37460         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV};
37461     vp_swizzle_state.viewportCount = 1;
37462     vp_swizzle_state.pViewportSwizzles = &invalid_swizzles;
37463 
37464     const std::vector<std::string> expected_vuids = {"VUID-VkViewportSwizzleNV-x-parameter", "VUID-VkViewportSwizzleNV-y-parameter",
37465                                                      "VUID-VkViewportSwizzleNV-z-parameter",
37466                                                      "VUID-VkViewportSwizzleNV-w-parameter"};
37467 
37468     auto break_swizzles = [&vp_swizzle_state](CreatePipelineHelper &helper) { helper.vp_state_ci_.pNext = &vp_swizzle_state; };
37469 
37470     CreatePipelineHelper::OneshotTest(*this, break_swizzles, VK_DEBUG_REPORT_ERROR_BIT_EXT, expected_vuids);
37471 
37472     struct TestCase {
37473         VkBool32 rasterizerDiscardEnable;
37474         uint32_t vp_count;
37475         uint32_t swizzel_vp_count;
37476         bool positive;
37477     };
37478 
37479     const std::array<TestCase, 3> test_cases = {{{VK_TRUE, 1, 2, true}, {VK_FALSE, 1, 1, true}, {VK_FALSE, 1, 2, false}}};
37480 
37481     std::array<VkViewportSwizzleNV, 2> swizzles = {
37482         {{VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV, VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV,
37483           VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV, VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV},
37484          {VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV, VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV,
37485           VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV, VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV}}};
37486 
37487     for (const auto &test_case : test_cases) {
37488         assert(test_case.vp_count <= swizzles.size());
37489 
37490         vp_swizzle_state.viewportCount = test_case.swizzel_vp_count;
37491         vp_swizzle_state.pViewportSwizzles = swizzles.data();
37492 
37493         auto break_vp_count = [&vp_swizzle_state, &test_case](CreatePipelineHelper &helper) {
37494             helper.rs_state_ci_.rasterizerDiscardEnable = test_case.rasterizerDiscardEnable;
37495             helper.vp_state_ci_.viewportCount = test_case.vp_count;
37496 
37497             helper.vp_state_ci_.pNext = &vp_swizzle_state;
37498         };
37499 
37500         CreatePipelineHelper::OneshotTest(*this, break_vp_count, VK_DEBUG_REPORT_ERROR_BIT_EXT,
37501                                           "VUID-VkPipelineViewportSwizzleStateCreateInfoNV-viewportCount-01215",
37502                                           test_case.positive);
37503     }
37504 }
37505 
TEST_F(VkLayerTest,BufferDeviceAddressEXT)37506 TEST_F(VkLayerTest, BufferDeviceAddressEXT) {
37507     TEST_DESCRIPTION("Test VK_EXT_buffer_device_address.");
37508 
37509     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
37510         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
37511     } else {
37512         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
37513                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
37514         return;
37515     }
37516     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
37517     std::array<const char *, 1> required_device_extensions = {{VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME}};
37518     for (auto device_extension : required_device_extensions) {
37519         if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
37520             m_device_extension_names.push_back(device_extension);
37521         } else {
37522             printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
37523             return;
37524         }
37525     }
37526 
37527     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
37528         (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
37529     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
37530 
37531     // Create a device that enables buffer_device_address
37532     auto buffer_device_address_features = lvl_init_struct<VkPhysicalDeviceBufferAddressFeaturesEXT>();
37533     auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&buffer_device_address_features);
37534     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
37535     buffer_device_address_features.bufferDeviceAddressCaptureReplay = VK_FALSE;
37536 
37537     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
37538     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
37539 
37540     PFN_vkGetBufferDeviceAddressEXT vkGetBufferDeviceAddressEXT =
37541         (PFN_vkGetBufferDeviceAddressEXT)vkGetInstanceProcAddr(instance(), "vkGetBufferDeviceAddressEXT");
37542 
37543     VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
37544     buffer_create_info.size = sizeof(uint32_t);
37545     buffer_create_info.usage = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT;
37546     buffer_create_info.flags = VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT;
37547     VkBuffer buffer;
37548     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferCreateInfo-flags-02605");
37549     VkResult result = vkCreateBuffer(m_device->device(), &buffer_create_info, nullptr, &buffer);
37550     m_errorMonitor->VerifyFound();
37551     if (result == VK_SUCCESS) {
37552         vkDestroyBuffer(m_device->device(), buffer, NULL);
37553     }
37554 
37555     buffer_create_info.flags = 0;
37556     VkBufferDeviceAddressCreateInfoEXT addr_ci = {VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT};
37557     addr_ci.deviceAddress = 1;
37558     buffer_create_info.pNext = &addr_ci;
37559 
37560     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferCreateInfo-deviceAddress-02604");
37561     result = vkCreateBuffer(m_device->device(), &buffer_create_info, nullptr, &buffer);
37562     m_errorMonitor->VerifyFound();
37563     if (result == VK_SUCCESS) {
37564         vkDestroyBuffer(m_device->device(), buffer, NULL);
37565     }
37566 
37567     buffer_create_info.pNext = nullptr;
37568     result = vkCreateBuffer(m_device->device(), &buffer_create_info, nullptr, &buffer);
37569     ASSERT_VK_SUCCESS(result);
37570 
37571     VkBufferDeviceAddressInfoEXT info = {VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT};
37572     info.buffer = buffer;
37573 
37574     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferDeviceAddressInfoEXT-buffer-02600");
37575     vkGetBufferDeviceAddressEXT(m_device->device(), &info);
37576     m_errorMonitor->VerifyFound();
37577 
37578     vkDestroyBuffer(m_device->device(), buffer, NULL);
37579 }
37580 
TEST_F(VkLayerTest,BufferDeviceAddressEXTDisabled)37581 TEST_F(VkLayerTest, BufferDeviceAddressEXTDisabled) {
37582     TEST_DESCRIPTION("Test VK_EXT_buffer_device_address.");
37583 
37584     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
37585         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
37586     } else {
37587         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
37588                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
37589         return;
37590     }
37591     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
37592     std::array<const char *, 1> required_device_extensions = {{VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME}};
37593     for (auto device_extension : required_device_extensions) {
37594         if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
37595             m_device_extension_names.push_back(device_extension);
37596         } else {
37597             printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
37598             return;
37599         }
37600     }
37601 
37602     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
37603         (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
37604     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
37605 
37606     // Create a device that disables buffer_device_address
37607     auto buffer_device_address_features = lvl_init_struct<VkPhysicalDeviceBufferAddressFeaturesEXT>();
37608     auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&buffer_device_address_features);
37609     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
37610     buffer_device_address_features.bufferDeviceAddress = VK_FALSE;
37611     buffer_device_address_features.bufferDeviceAddressCaptureReplay = VK_FALSE;
37612 
37613     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
37614     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
37615 
37616     PFN_vkGetBufferDeviceAddressEXT vkGetBufferDeviceAddressEXT =
37617         (PFN_vkGetBufferDeviceAddressEXT)vkGetInstanceProcAddr(instance(), "vkGetBufferDeviceAddressEXT");
37618 
37619     VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
37620     buffer_create_info.size = sizeof(uint32_t);
37621     buffer_create_info.usage = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT;
37622     VkBuffer buffer;
37623     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferCreateInfo-usage-02606");
37624     VkResult result = vkCreateBuffer(m_device->device(), &buffer_create_info, nullptr, &buffer);
37625     m_errorMonitor->VerifyFound();
37626     if (result == VK_SUCCESS) {
37627         vkDestroyBuffer(m_device->device(), buffer, NULL);
37628     }
37629 
37630     buffer_create_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
37631     result = vkCreateBuffer(m_device->device(), &buffer_create_info, nullptr, &buffer);
37632     ASSERT_VK_SUCCESS(result);
37633 
37634     VkBufferDeviceAddressInfoEXT info = {VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT};
37635     info.buffer = buffer;
37636 
37637     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkGetBufferDeviceAddressEXT-None-02598");
37638     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferDeviceAddressInfoEXT-buffer-02601");
37639     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferDeviceAddressInfoEXT-buffer-02600");
37640     vkGetBufferDeviceAddressEXT(m_device->device(), &info);
37641     m_errorMonitor->VerifyFound();
37642 
37643     vkDestroyBuffer(m_device->device(), buffer, NULL);
37644 }
37645 
37646 #if defined(ANDROID) && defined(VALIDATION_APK)
37647 const char *appTag = "VulkanLayerValidationTests";
37648 static bool initialized = false;
37649 static bool active = false;
37650 
37651 // Convert Intents to argv
37652 // Ported from Hologram sample, only difference is flexible key
get_args(android_app & app,const char * intent_extra_data_key)37653 std::vector<std::string> get_args(android_app &app, const char *intent_extra_data_key) {
37654     std::vector<std::string> args;
37655     JavaVM &vm = *app.activity->vm;
37656     JNIEnv *p_env;
37657     if (vm.AttachCurrentThread(&p_env, nullptr) != JNI_OK) return args;
37658 
37659     JNIEnv &env = *p_env;
37660     jobject activity = app.activity->clazz;
37661     jmethodID get_intent_method = env.GetMethodID(env.GetObjectClass(activity), "getIntent", "()Landroid/content/Intent;");
37662     jobject intent = env.CallObjectMethod(activity, get_intent_method);
37663     jmethodID get_string_extra_method =
37664         env.GetMethodID(env.GetObjectClass(intent), "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
37665     jvalue get_string_extra_args;
37666     get_string_extra_args.l = env.NewStringUTF(intent_extra_data_key);
37667     jstring extra_str = static_cast<jstring>(env.CallObjectMethodA(intent, get_string_extra_method, &get_string_extra_args));
37668 
37669     std::string args_str;
37670     if (extra_str) {
37671         const char *extra_utf = env.GetStringUTFChars(extra_str, nullptr);
37672         args_str = extra_utf;
37673         env.ReleaseStringUTFChars(extra_str, extra_utf);
37674         env.DeleteLocalRef(extra_str);
37675     }
37676 
37677     env.DeleteLocalRef(get_string_extra_args.l);
37678     env.DeleteLocalRef(intent);
37679     vm.DetachCurrentThread();
37680 
37681     // split args_str
37682     std::stringstream ss(args_str);
37683     std::string arg;
37684     while (std::getline(ss, arg, ' ')) {
37685         if (!arg.empty()) args.push_back(arg);
37686     }
37687 
37688     return args;
37689 }
37690 
addFullTestCommentIfPresent(const::testing::TestInfo & test_info,std::string & error_message)37691 void addFullTestCommentIfPresent(const ::testing::TestInfo &test_info, std::string &error_message) {
37692     const char *const type_param = test_info.type_param();
37693     const char *const value_param = test_info.value_param();
37694 
37695     if (type_param != NULL || value_param != NULL) {
37696         error_message.append(", where ");
37697         if (type_param != NULL) {
37698             error_message.append("TypeParam = ").append(type_param);
37699             if (value_param != NULL) error_message.append(" and ");
37700         }
37701         if (value_param != NULL) {
37702             error_message.append("GetParam() = ").append(value_param);
37703         }
37704     }
37705 }
37706 
37707 // Inspired by https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md
37708 class LogcatPrinter : public ::testing::EmptyTestEventListener {
37709     // Called before a test starts.
OnTestStart(const::testing::TestInfo & test_info)37710     virtual void OnTestStart(const ::testing::TestInfo &test_info) {
37711         __android_log_print(ANDROID_LOG_INFO, appTag, "[ RUN      ] %s.%s", test_info.test_case_name(), test_info.name());
37712     }
37713 
37714     // Called after a failed assertion or a SUCCEED() invocation.
OnTestPartResult(const::testing::TestPartResult & result)37715     virtual void OnTestPartResult(const ::testing::TestPartResult &result) {
37716         // If the test part succeeded, we don't need to do anything.
37717         if (result.type() == ::testing::TestPartResult::kSuccess) return;
37718 
37719         __android_log_print(ANDROID_LOG_INFO, appTag, "%s in %s:%d %s", result.failed() ? "*** Failure" : "Success",
37720                             result.file_name(), result.line_number(), result.summary());
37721     }
37722 
37723     // Called after a test ends.
OnTestEnd(const::testing::TestInfo & info)37724     virtual void OnTestEnd(const ::testing::TestInfo &info) {
37725         std::string result;
37726         if (info.result()->Passed()) {
37727             result.append("[       OK ]");
37728         } else {
37729             result.append("[  FAILED  ]");
37730         }
37731         result.append(info.test_case_name()).append(".").append(info.name());
37732         if (info.result()->Failed()) addFullTestCommentIfPresent(info, result);
37733 
37734         if (::testing::GTEST_FLAG(print_time)) {
37735             std::ostringstream os;
37736             os << info.result()->elapsed_time();
37737             result.append(" (").append(os.str()).append(" ms)");
37738         }
37739 
37740         __android_log_print(ANDROID_LOG_INFO, appTag, "%s", result.c_str());
37741     };
37742 };
37743 
processInput(struct android_app * app,AInputEvent * event)37744 static int32_t processInput(struct android_app *app, AInputEvent *event) { return 0; }
37745 
processCommand(struct android_app * app,int32_t cmd)37746 static void processCommand(struct android_app *app, int32_t cmd) {
37747     switch (cmd) {
37748         case APP_CMD_INIT_WINDOW: {
37749             if (app->window) {
37750                 initialized = true;
37751             }
37752             break;
37753         }
37754         case APP_CMD_GAINED_FOCUS: {
37755             active = true;
37756             break;
37757         }
37758         case APP_CMD_LOST_FOCUS: {
37759             active = false;
37760             break;
37761         }
37762     }
37763 }
37764 
android_main(struct android_app * app)37765 void android_main(struct android_app *app) {
37766     int vulkanSupport = InitVulkan();
37767     if (vulkanSupport == 0) {
37768         __android_log_print(ANDROID_LOG_INFO, appTag, "==== FAILED ==== No Vulkan support found");
37769         return;
37770     }
37771 
37772     app->onAppCmd = processCommand;
37773     app->onInputEvent = processInput;
37774 
37775     while (1) {
37776         int events;
37777         struct android_poll_source *source;
37778         while (ALooper_pollAll(active ? 0 : -1, NULL, &events, (void **)&source) >= 0) {
37779             if (source) {
37780                 source->process(app, source);
37781             }
37782 
37783             if (app->destroyRequested != 0) {
37784                 VkTestFramework::Finish();
37785                 return;
37786             }
37787         }
37788 
37789         if (initialized && active) {
37790             // Use the following key to send arguments to gtest, i.e.
37791             // --es args "--gtest_filter=-VkLayerTest.foo"
37792             const char key[] = "args";
37793             std::vector<std::string> args = get_args(*app, key);
37794 
37795             std::string filter = "";
37796             if (args.size() > 0) {
37797                 __android_log_print(ANDROID_LOG_INFO, appTag, "Intent args = %s", args[0].c_str());
37798                 filter += args[0];
37799             } else {
37800                 __android_log_print(ANDROID_LOG_INFO, appTag, "No Intent args detected");
37801             }
37802 
37803             int argc = 2;
37804             char *argv[] = {(char *)"foo", (char *)filter.c_str()};
37805             __android_log_print(ANDROID_LOG_DEBUG, appTag, "filter = %s", argv[1]);
37806 
37807             // Route output to files until we can override the gtest output
37808             freopen("/sdcard/Android/data/com.example.VulkanLayerValidationTests/files/out.txt", "w", stdout);
37809             freopen("/sdcard/Android/data/com.example.VulkanLayerValidationTests/files/err.txt", "w", stderr);
37810 
37811             ::testing::InitGoogleTest(&argc, argv);
37812 
37813             ::testing::TestEventListeners &listeners = ::testing::UnitTest::GetInstance()->listeners();
37814             listeners.Append(new LogcatPrinter);
37815 
37816             VkTestFramework::InitArgs(&argc, argv);
37817             ::testing::AddGlobalTestEnvironment(new TestEnvironment);
37818 
37819             int result = RUN_ALL_TESTS();
37820 
37821             if (result != 0) {
37822                 __android_log_print(ANDROID_LOG_INFO, appTag, "==== Tests FAILED ====");
37823             } else {
37824                 __android_log_print(ANDROID_LOG_INFO, appTag, "==== Tests PASSED ====");
37825             }
37826 
37827             VkTestFramework::Finish();
37828 
37829             fclose(stdout);
37830             fclose(stderr);
37831 
37832             ANativeActivity_finish(app->activity);
37833             return;
37834         }
37835     }
37836 }
37837 #endif
37838 
37839 #if defined(_WIN32) && !defined(NDEBUG)
37840 #include <crtdbg.h>
37841 #endif
37842 
main(int argc,char ** argv)37843 int main(int argc, char **argv) {
37844     int result;
37845 
37846 #ifdef ANDROID
37847     int vulkanSupport = InitVulkan();
37848     if (vulkanSupport == 0) return 1;
37849 #endif
37850 
37851 #if defined(_WIN32) && !defined(NDEBUG)
37852     _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
37853     _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
37854 #endif
37855 
37856     ::testing::InitGoogleTest(&argc, argv);
37857     VkTestFramework::InitArgs(&argc, argv);
37858 
37859     ::testing::AddGlobalTestEnvironment(new TestEnvironment);
37860 
37861     result = RUN_ALL_TESTS();
37862 
37863     VkTestFramework::Finish();
37864     return result;
37865 }
37866