1 /* 2 * Copyright (c) 2015-2017 The Khronos Group Inc. 3 * Copyright (c) 2015-2017 Valve Corporation 4 * Copyright (c) 2015-2017 LunarG, Inc. 5 * Copyright (c) 2015-2017 Google, Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Author: Chia-I Wu <olvaffe (at) gmail.com> 14 * Author: Chris Forbes <chrisf (at) ijw.co.nz> 15 * Author: Courtney Goeltzenleuchter <courtney (at) LunarG.com> 16 * Author: Mark Lobodzinski <mark (at) lunarg.com> 17 * Author: Mike Stroyan <mike (at) LunarG.com> 18 * Author: Tobin Ehlis <tobine (at) google.com> 19 * Author: Tony Barbour <tony (at) LunarG.com> 20 * Author: Cody Northrop <cnorthrop (at) google.com> 21 * Author: Dave Houlton <daveh (at) lunarg.com> 22 * Author: Jeremy Kniager <jeremyk (at) lunarg.com> 23 */ 24 25 #ifdef ANDROID 26 #include "vulkan_wrapper.h" 27 #else 28 #define NOMINMAX 29 #include <vulkan/vulkan.h> 30 #endif 31 32 #include "layers/vk_device_profile_api_layer.h" 33 34 #if defined(ANDROID) && defined(VALIDATION_APK) 35 #include <android/log.h> 36 #include <android_native_app_glue.h> 37 #endif 38 39 #include "icd-spv.h" 40 #include "test_common.h" 41 #include "vk_layer_config.h" 42 #include "vk_format_utils.h" 43 #include "vk_validation_error_messages.h" 44 #include "vkrenderframework.h" 45 #include "vk_typemap_helper.h" 46 47 #include <limits.h> 48 49 #include <algorithm> 50 #include <functional> 51 #include <memory> 52 #include <unordered_set> 53 54 //-------------------------------------------------------------------------------------- 55 // Mesh and VertexFormat Data 56 //-------------------------------------------------------------------------------------- 57 58 enum BsoFailSelect { 59 BsoFailNone, 60 BsoFailLineWidth, 61 BsoFailDepthBias, 62 BsoFailViewport, 63 BsoFailScissor, 64 BsoFailBlend, 65 BsoFailDepthBounds, 66 BsoFailStencilReadMask, 67 BsoFailStencilWriteMask, 68 BsoFailStencilReference, 69 BsoFailCmdClearAttachments, 70 BsoFailIndexBuffer 71 }; 72 73 static const char bindStateVertShaderText[] = 74 "#version 450\n" 75 "vec2 vertices[3];\n" 76 "void main() {\n" 77 " vertices[0] = vec2(-1.0, -1.0);\n" 78 " vertices[1] = vec2( 1.0, -1.0);\n" 79 " vertices[2] = vec2( 0.0, 1.0);\n" 80 " gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0);\n" 81 "}\n"; 82 83 static const char bindStateFragShaderText[] = 84 "#version 450\n" 85 "\n" 86 "layout(location = 0) out vec4 uFragColor;\n" 87 "void main(){\n" 88 " uFragColor = vec4(0,1,0,1);\n" 89 "}\n"; 90 91 // Static arrays helper 92 template <class ElementT, size_t array_size> 93 size_t size(ElementT (&)[array_size]) { 94 return array_size; 95 } 96 97 // Format search helper 98 VkFormat FindSupportedDepthStencilFormat(VkPhysicalDevice phy) { 99 VkFormat ds_formats[] = {VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT}; 100 for (uint32_t i = 0; i < sizeof(ds_formats); i++) { 101 VkFormatProperties format_props; 102 vkGetPhysicalDeviceFormatProperties(phy, ds_formats[i], &format_props); 103 104 if (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) { 105 return ds_formats[i]; 106 } 107 } 108 return VK_FORMAT_UNDEFINED; 109 } 110 111 // Returns true if *any* requested features are available. 112 // Assumption is that the framework can successfully create an image as 113 // long as at least one of the feature bits is present (excepting VTX_BUF). 114 bool ImageFormatIsSupported(VkPhysicalDevice phy, VkFormat format, VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL, 115 VkFormatFeatureFlags features = ~VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) { 116 VkFormatProperties format_props; 117 vkGetPhysicalDeviceFormatProperties(phy, format, &format_props); 118 VkFormatFeatureFlags phy_features = 119 (VK_IMAGE_TILING_OPTIMAL == tiling ? format_props.optimalTilingFeatures : format_props.linearTilingFeatures); 120 return (0 != (phy_features & features)); 121 } 122 123 // Returns true if format and *all* requested features are available. 124 bool ImageFormatAndFeaturesSupported(VkPhysicalDevice phy, VkFormat format, VkImageTiling tiling, VkFormatFeatureFlags features) { 125 VkFormatProperties format_props; 126 vkGetPhysicalDeviceFormatProperties(phy, format, &format_props); 127 VkFormatFeatureFlags phy_features = 128 (VK_IMAGE_TILING_OPTIMAL == tiling ? format_props.optimalTilingFeatures : format_props.linearTilingFeatures); 129 return (features == (phy_features & features)); 130 } 131 132 // Validation report callback prototype 133 static VKAPI_ATTR VkBool32 VKAPI_CALL myDbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, 134 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg, 135 void *pUserData); 136 137 // Simple sane SamplerCreateInfo boilerplate 138 static VkSamplerCreateInfo SafeSaneSamplerCreateInfo() { 139 VkSamplerCreateInfo sampler_create_info = {}; 140 sampler_create_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; 141 sampler_create_info.pNext = nullptr; 142 sampler_create_info.magFilter = VK_FILTER_NEAREST; 143 sampler_create_info.minFilter = VK_FILTER_NEAREST; 144 sampler_create_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; 145 sampler_create_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 146 sampler_create_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 147 sampler_create_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 148 sampler_create_info.mipLodBias = 1.0; 149 sampler_create_info.anisotropyEnable = VK_FALSE; 150 sampler_create_info.maxAnisotropy = 1.0; 151 sampler_create_info.compareEnable = VK_FALSE; 152 sampler_create_info.compareOp = VK_COMPARE_OP_NEVER; 153 sampler_create_info.minLod = 1.0; 154 sampler_create_info.maxLod = 1.0; 155 sampler_create_info.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; 156 sampler_create_info.unnormalizedCoordinates = VK_FALSE; 157 158 return sampler_create_info; 159 } 160 161 // Dependent "false" type for the static assert, as GCC will evaluate 162 // non-dependent static_asserts even for non-instantiated templates 163 template <typename T> 164 struct AlwaysFalse : std::false_type {}; 165 166 // Template wrapper of cmath.h versions to avoid portability issues with std::nextafter 167 template <typename T> 168 T NextAfter(T from, T to) { 169 static_assert(AlwaysFalse<T>::value, "must specialize for each supported type"); 170 } 171 template <> 172 float NextAfter(float from, float to) { 173 return nextafterf(from, to); 174 } 175 // lowest <= value <= max non intuitive, thus the named wrapper 176 template <typename T> 177 T NextAfterGreater(const T from) { 178 return NextAfter<T>(from, std::numeric_limits<T>::max()); 179 } 180 template <typename T> 181 T NextAfterLess(const T from) { 182 return NextAfter<T>(from, std::numeric_limits<T>::lowest()); 183 } 184 185 // ErrorMonitor Usage: 186 // 187 // Call SetDesiredFailureMsg with a string to be compared against all 188 // encountered log messages, or a validation error enum identifying 189 // desired error message. Passing NULL or VALIDATION_ERROR_MAX_ENUM 190 // will match all log messages. logMsg will return true for skipCall 191 // only if msg is matched or NULL. 192 // 193 // Call VerifyFound to determine if all desired failure messages 194 // were encountered. Call VerifyNotFound to determine if any unexpected 195 // failure was encountered. 196 class ErrorMonitor { 197 public: 198 ErrorMonitor() { 199 test_platform_thread_create_mutex(&mutex_); 200 test_platform_thread_lock_mutex(&mutex_); 201 Reset(); 202 test_platform_thread_unlock_mutex(&mutex_); 203 } 204 205 ~ErrorMonitor() { test_platform_thread_delete_mutex(&mutex_); } 206 207 // Set monitor to pristine state 208 void Reset() { 209 message_flags_ = VK_DEBUG_REPORT_ERROR_BIT_EXT; 210 bailout_ = NULL; 211 message_found_ = VK_FALSE; 212 failure_message_strings_.clear(); 213 desired_message_strings_.clear(); 214 desired_message_ids_.clear(); 215 ignore_message_strings_.clear(); 216 other_messages_.clear(); 217 message_outstanding_count_ = 0; 218 } 219 220 // ErrorMonitor will look for an error message containing the specified string(s) 221 void SetDesiredFailureMsg(const VkFlags msgFlags, const char *const msgString) { 222 test_platform_thread_lock_mutex(&mutex_); 223 desired_message_strings_.insert(msgString); 224 message_flags_ |= msgFlags; 225 message_outstanding_count_++; 226 test_platform_thread_unlock_mutex(&mutex_); 227 } 228 229 // ErrorMonitor will look for an error message containing the specified string(s) 230 template <typename Iter> 231 void SetDesiredFailureMsg(const VkFlags msgFlags, Iter iter, const Iter end) { 232 for (; iter != end; ++iter) { 233 SetDesiredFailureMsg(msgFlags, *iter); 234 } 235 } 236 237 // ErrorMonitor will look for a message ID matching the specified one(s) 238 void SetDesiredFailureMsg(const VkFlags msgFlags, const UNIQUE_VALIDATION_ERROR_CODE msg_id) { 239 test_platform_thread_lock_mutex(&mutex_); 240 desired_message_ids_.insert(msg_id); 241 message_flags_ |= msgFlags; 242 message_outstanding_count_++; 243 test_platform_thread_unlock_mutex(&mutex_); 244 } 245 246 // Set an error that the error monitor will ignore. Do not use this function if you are creating a new test. 247 // TODO: This is stopgap to block new unexpected errors from being introduced. The long-term goal is to remove the use of this 248 // function and its definition. 249 void SetUnexpectedError(const char *const msg) { 250 test_platform_thread_lock_mutex(&mutex_); 251 252 ignore_message_strings_.emplace_back(msg); 253 254 test_platform_thread_unlock_mutex(&mutex_); 255 } 256 257 VkBool32 CheckForDesiredMsg(const uint32_t message_code, const char *const msgString) { 258 VkBool32 result = VK_FALSE; 259 test_platform_thread_lock_mutex(&mutex_); 260 if (bailout_ != nullptr) { 261 *bailout_ = true; 262 } 263 string errorString(msgString); 264 bool found_expected = false; 265 266 if (!IgnoreMessage(errorString)) { 267 for (auto desired_msg : desired_message_strings_) { 268 if (desired_msg.length() == 0) { 269 // An empty desired_msg string "" indicates a positive test - not expecting an error. 270 // Return true to avoid calling layers/driver with this error. 271 // And don't erase the "" string, so it remains if another error is found. 272 result = VK_TRUE; 273 found_expected = true; 274 message_found_ = true; 275 failure_message_strings_.insert(errorString); 276 } else if (errorString.find(desired_msg) != string::npos) { 277 found_expected = true; 278 message_outstanding_count_--; 279 failure_message_strings_.insert(errorString); 280 message_found_ = true; 281 result = VK_TRUE; 282 // We only want one match for each expected error so remove from set here 283 // Since we're about the break the loop it's ok to remove from set we're iterating over 284 desired_message_strings_.erase(desired_msg); 285 break; 286 } 287 } 288 for (auto desired_id : desired_message_ids_) { 289 if (desired_id == VALIDATION_ERROR_MAX_ENUM) { 290 // A message ID set to MAX_ENUM indicates a positive test - not expecting an error. 291 // Return true to avoid calling layers/driver with this error. 292 result = VK_TRUE; 293 } else if (desired_id == message_code) { 294 // Double-check that the string matches the error enum 295 if (errorString.find(validation_error_map[desired_id]) != string::npos) { 296 found_expected = true; 297 message_outstanding_count_--; 298 result = VK_TRUE; 299 message_found_ = true; 300 desired_message_ids_.erase(desired_id); 301 break; 302 } else { 303 // Treat this message as a regular unexpected error, but print a warning jic 304 printf("Message (%s) from MessageID %d does not correspond to expected message from error Database (%s)\n", 305 errorString.c_str(), desired_id, validation_error_map[desired_id]); 306 } 307 } 308 } 309 310 if (!found_expected) { 311 printf("Unexpected: %s\n", msgString); 312 other_messages_.push_back(errorString); 313 } 314 } 315 316 test_platform_thread_unlock_mutex(&mutex_); 317 return result; 318 } 319 320 vector<string> GetOtherFailureMsgs() const { return other_messages_; } 321 322 VkDebugReportFlagsEXT GetMessageFlags() const { return message_flags_; } 323 324 bool AnyDesiredMsgFound() const { return message_found_; } 325 326 bool AllDesiredMsgsFound() const { return (0 == message_outstanding_count_); } 327 328 void SetBailout(bool *bailout) { bailout_ = bailout; } 329 330 void DumpFailureMsgs() const { 331 vector<string> otherMsgs = GetOtherFailureMsgs(); 332 if (otherMsgs.size()) { 333 cout << "Other error messages logged for this test were:" << endl; 334 for (auto iter = otherMsgs.begin(); iter != otherMsgs.end(); iter++) { 335 cout << " " << *iter << endl; 336 } 337 } 338 } 339 340 // Helpers 341 342 // ExpectSuccess now takes an optional argument allowing a custom combination of debug flags 343 void ExpectSuccess(VkDebugReportFlagsEXT const message_flag_mask = VK_DEBUG_REPORT_ERROR_BIT_EXT) { 344 // Match ANY message matching specified type 345 SetDesiredFailureMsg(message_flag_mask, ""); 346 message_flags_ = message_flag_mask; // override mask handling in SetDesired... 347 } 348 349 void VerifyFound() { 350 // Not seeing the desired message is a failure. /Before/ throwing, dump any other messages. 351 if (!AllDesiredMsgsFound()) { 352 DumpFailureMsgs(); 353 for (auto desired_msg : desired_message_strings_) { 354 ADD_FAILURE() << "Did not receive expected error '" << desired_msg << "'"; 355 } 356 for (auto desired_id : desired_message_ids_) { 357 ADD_FAILURE() << "Did not receive expected error ENUM '0x" << std::hex << desired_id << "'"; 358 } 359 } 360 Reset(); 361 } 362 363 void VerifyNotFound() { 364 // ExpectSuccess() configured us to match anything. Any error is a failure. 365 if (AnyDesiredMsgFound()) { 366 DumpFailureMsgs(); 367 for (auto msg : failure_message_strings_) { 368 ADD_FAILURE() << "Expected to succeed but got error: " << msg; 369 } 370 } 371 Reset(); 372 } 373 374 private: 375 // TODO: This is stopgap to block new unexpected errors from being introduced. The long-term goal is to remove the use of this 376 // function and its definition. 377 bool IgnoreMessage(std::string const &msg) const { 378 if (ignore_message_strings_.empty()) { 379 return false; 380 } 381 382 return std::find_if(ignore_message_strings_.begin(), ignore_message_strings_.end(), [&msg](std::string const &str) { 383 return msg.find(str) != std::string::npos; 384 }) != ignore_message_strings_.end(); 385 } 386 387 VkFlags message_flags_; 388 std::unordered_set<uint32_t> desired_message_ids_; 389 std::unordered_set<string> desired_message_strings_; 390 std::unordered_set<string> failure_message_strings_; 391 std::vector<std::string> ignore_message_strings_; 392 vector<string> other_messages_; 393 test_platform_thread_mutex mutex_; 394 bool *bailout_; 395 bool message_found_; 396 int message_outstanding_count_; 397 }; 398 399 static VKAPI_ATTR VkBool32 VKAPI_CALL myDbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, 400 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg, 401 void *pUserData) { 402 ErrorMonitor *errMonitor = (ErrorMonitor *)pUserData; 403 if (msgFlags & errMonitor->GetMessageFlags()) { 404 #ifdef _DEBUG 405 char embedded_code_string[2048]; 406 snprintf(embedded_code_string, 2048, "%s [%08x]", pMsg, msgCode); 407 return errMonitor->CheckForDesiredMsg(msgCode, embedded_code_string); 408 #else 409 return errMonitor->CheckForDesiredMsg(msgCode, pMsg); 410 #endif 411 } 412 return VK_FALSE; 413 } 414 415 class VkLayerTest : public VkRenderFramework { 416 public: 417 void VKTriangleTest(BsoFailSelect failCase); 418 void GenericDrawPreparation(VkCommandBufferObj *commandBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, 419 BsoFailSelect failCase); 420 421 void Init(VkPhysicalDeviceFeatures *features = nullptr, const VkCommandPoolCreateFlags flags = 0) { 422 InitFramework(myDbgFunc, m_errorMonitor); 423 InitState(features, flags); 424 } 425 426 protected: 427 ErrorMonitor *m_errorMonitor; 428 429 public: 430 ErrorMonitor *Monitor() { return m_errorMonitor; } 431 VkCommandBufferObj *CommandBuffer() { return m_commandBuffer; } 432 433 protected: 434 bool m_enableWSI; 435 436 virtual void SetUp() { 437 m_instance_layer_names.clear(); 438 m_instance_extension_names.clear(); 439 m_device_extension_names.clear(); 440 441 // Add default instance extensions to the list 442 m_instance_extension_names.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); 443 #ifdef _WIN32 444 m_instance_extension_names.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); 445 #endif 446 #ifdef VK_USE_PLATFORM_XCB_KHR 447 m_instance_extension_names.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); 448 #endif 449 450 // Use Threading layer first to protect others from 451 // ThreadCommandBufferCollision test 452 m_instance_layer_names.push_back("VK_LAYER_GOOGLE_threading"); 453 m_instance_layer_names.push_back("VK_LAYER_LUNARG_parameter_validation"); 454 m_instance_layer_names.push_back("VK_LAYER_LUNARG_object_tracker"); 455 m_instance_layer_names.push_back("VK_LAYER_LUNARG_core_validation"); 456 m_instance_layer_names.push_back("VK_LAYER_GOOGLE_unique_objects"); 457 if (VkTestFramework::m_devsim_layer) { 458 if (InstanceLayerSupported("VK_LAYER_LUNARG_device_simulation")) { 459 m_instance_layer_names.push_back("VK_LAYER_LUNARG_device_simulation"); 460 } else { 461 VkTestFramework::m_devsim_layer = false; 462 printf(" Did not find VK_LAYER_LUNARG_device_simulation layer so it will not be enabled.\n"); 463 } 464 } 465 if (m_enableWSI) { 466 m_instance_extension_names.push_back(VK_KHR_SURFACE_EXTENSION_NAME); 467 m_device_extension_names.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); 468 #ifdef NEED_TO_TEST_THIS_ON_PLATFORM 469 #if defined(VK_USE_PLATFORM_ANDROID_KHR) 470 m_instance_extension_names.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); 471 #endif // VK_USE_PLATFORM_ANDROID_KHR 472 #if defined(VK_USE_PLATFORM_MIR_KHR) 473 m_instance_extension_names.push_back(VK_KHR_MIR_SURFACE_EXTENSION_NAME); 474 #endif // VK_USE_PLATFORM_MIR_KHR 475 #if defined(VK_USE_PLATFORM_WAYLAND_KHR) 476 m_instance_extension_names.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); 477 #endif // VK_USE_PLATFORM_WAYLAND_KHR 478 #if defined(VK_USE_PLATFORM_WIN32_KHR) 479 m_instance_extension_names.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); 480 #endif // VK_USE_PLATFORM_WIN32_KHR 481 #endif // NEED_TO_TEST_THIS_ON_PLATFORM 482 #if defined(VK_USE_PLATFORM_XCB_KHR) 483 m_instance_extension_names.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); 484 #elif defined(VK_USE_PLATFORM_XLIB_KHR) 485 m_instance_extension_names.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); 486 #endif // VK_USE_PLATFORM_XLIB_KHR 487 } 488 489 this->app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; 490 this->app_info.pNext = NULL; 491 this->app_info.pApplicationName = "layer_tests"; 492 this->app_info.applicationVersion = 1; 493 this->app_info.pEngineName = "unittest"; 494 this->app_info.engineVersion = 1; 495 this->app_info.apiVersion = VK_API_VERSION_1_0; 496 497 m_errorMonitor = new ErrorMonitor; 498 } 499 500 bool LoadDeviceProfileLayer( 501 PFN_vkSetPhysicalDeviceFormatPropertiesEXT &fpvkSetPhysicalDeviceFormatPropertiesEXT, 502 PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT &fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT) { 503 // Load required functions 504 fpvkSetPhysicalDeviceFormatPropertiesEXT = 505 (PFN_vkSetPhysicalDeviceFormatPropertiesEXT)vkGetInstanceProcAddr(instance(), "vkSetPhysicalDeviceFormatPropertiesEXT"); 506 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = 507 (PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT)vkGetInstanceProcAddr( 508 instance(), "vkGetOriginalPhysicalDeviceFormatPropertiesEXT"); 509 510 if (!(fpvkSetPhysicalDeviceFormatPropertiesEXT) || !(fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) { 511 printf(" Can't find device_profile_api functions; skipped.\n"); 512 return 0; 513 } 514 515 return 1; 516 } 517 518 virtual void TearDown() { 519 // Clean up resources before we reset 520 ShutdownFramework(); 521 delete m_errorMonitor; 522 } 523 524 VkLayerTest() { m_enableWSI = false; } 525 }; 526 527 void VkLayerTest::VKTriangleTest(BsoFailSelect failCase) { 528 ASSERT_TRUE(m_device && m_device->initialized()); // VKTriangleTest assumes Init() has finished 529 530 ASSERT_NO_FATAL_FAILURE(InitViewport()); 531 532 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 533 VkShaderObj ps(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 534 535 VkPipelineObj pipelineobj(m_device); 536 pipelineobj.AddDefaultColorAttachment(); 537 pipelineobj.AddShader(&vs); 538 pipelineobj.AddShader(&ps); 539 540 bool failcase_needs_depth = false; // to mark cases that need depth attachment 541 542 switch (failCase) { 543 case BsoFailLineWidth: { 544 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_LINE_WIDTH); 545 VkPipelineInputAssemblyStateCreateInfo ia_state = {}; 546 ia_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 547 ia_state.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST; 548 pipelineobj.SetInputAssembly(&ia_state); 549 break; 550 } 551 case BsoFailDepthBias: { 552 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_DEPTH_BIAS); 553 VkPipelineRasterizationStateCreateInfo rs_state = {}; 554 rs_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 555 rs_state.depthBiasEnable = VK_TRUE; 556 rs_state.lineWidth = 1.0f; 557 pipelineobj.SetRasterization(&rs_state); 558 break; 559 } 560 case BsoFailViewport: { 561 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_VIEWPORT); 562 break; 563 } 564 case BsoFailScissor: { 565 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_SCISSOR); 566 break; 567 } 568 case BsoFailBlend: { 569 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_BLEND_CONSTANTS); 570 VkPipelineColorBlendAttachmentState att_state = {}; 571 att_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR; 572 att_state.blendEnable = VK_TRUE; 573 pipelineobj.AddColorAttachment(0, att_state); 574 break; 575 } 576 case BsoFailDepthBounds: { 577 failcase_needs_depth = true; 578 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_DEPTH_BOUNDS); 579 break; 580 } 581 case BsoFailStencilReadMask: { 582 failcase_needs_depth = true; 583 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK); 584 break; 585 } 586 case BsoFailStencilWriteMask: { 587 failcase_needs_depth = true; 588 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK); 589 break; 590 } 591 case BsoFailStencilReference: { 592 failcase_needs_depth = true; 593 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_STENCIL_REFERENCE); 594 break; 595 } 596 597 case BsoFailIndexBuffer: 598 break; 599 case BsoFailCmdClearAttachments: 600 break; 601 case BsoFailNone: 602 break; 603 default: 604 break; 605 } 606 607 VkDescriptorSetObj descriptorSet(m_device); 608 609 VkImageView *depth_attachment = nullptr; 610 if (failcase_needs_depth) { 611 m_depth_stencil_fmt = FindSupportedDepthStencilFormat(gpu()); 612 ASSERT_TRUE(m_depth_stencil_fmt != VK_FORMAT_UNDEFINED); 613 614 m_depthStencil->Init(m_device, static_cast<uint32_t>(m_width), static_cast<uint32_t>(m_height), m_depth_stencil_fmt, 615 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); 616 depth_attachment = m_depthStencil->BindInfo(); 617 } 618 619 ASSERT_NO_FATAL_FAILURE(InitRenderTarget(1, depth_attachment)); 620 m_commandBuffer->begin(); 621 622 GenericDrawPreparation(m_commandBuffer, pipelineobj, descriptorSet, failCase); 623 624 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 625 626 // render triangle 627 if (failCase == BsoFailIndexBuffer) { 628 // Use DrawIndexed w/o an index buffer bound 629 m_commandBuffer->DrawIndexed(3, 1, 0, 0, 0); 630 } else { 631 m_commandBuffer->Draw(3, 1, 0, 0); 632 } 633 634 if (failCase == BsoFailCmdClearAttachments) { 635 VkClearAttachment color_attachment = {}; 636 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 637 color_attachment.colorAttachment = 1; // Someone who knew what they were doing would use 0 for the index; 638 VkClearRect clear_rect = {{{0, 0}, {static_cast<uint32_t>(m_width), static_cast<uint32_t>(m_height)}}, 0, 0}; 639 640 vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect); 641 } 642 643 // finalize recording of the command buffer 644 m_commandBuffer->EndRenderPass(); 645 m_commandBuffer->end(); 646 m_commandBuffer->QueueCommandBuffer(true); 647 } 648 649 void VkLayerTest::GenericDrawPreparation(VkCommandBufferObj *commandBuffer, VkPipelineObj &pipelineobj, 650 VkDescriptorSetObj &descriptorSet, BsoFailSelect failCase) { 651 commandBuffer->ClearAllBuffers(m_renderTargets, m_clear_color, m_depthStencil, m_depth_clear_color, m_stencil_clear_color); 652 653 commandBuffer->PrepareAttachments(m_renderTargets, m_depthStencil); 654 // Make sure depthWriteEnable is set so that Depth fail test will work 655 // correctly 656 // Make sure stencilTestEnable is set so that Stencil fail test will work 657 // correctly 658 VkStencilOpState stencil = {}; 659 stencil.failOp = VK_STENCIL_OP_KEEP; 660 stencil.passOp = VK_STENCIL_OP_KEEP; 661 stencil.depthFailOp = VK_STENCIL_OP_KEEP; 662 stencil.compareOp = VK_COMPARE_OP_NEVER; 663 664 VkPipelineDepthStencilStateCreateInfo ds_ci = {}; 665 ds_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; 666 ds_ci.pNext = NULL; 667 ds_ci.depthTestEnable = VK_FALSE; 668 ds_ci.depthWriteEnable = VK_TRUE; 669 ds_ci.depthCompareOp = VK_COMPARE_OP_NEVER; 670 ds_ci.depthBoundsTestEnable = VK_FALSE; 671 if (failCase == BsoFailDepthBounds) { 672 ds_ci.depthBoundsTestEnable = VK_TRUE; 673 ds_ci.maxDepthBounds = 0.0f; 674 ds_ci.minDepthBounds = 0.0f; 675 } 676 ds_ci.stencilTestEnable = VK_TRUE; 677 ds_ci.front = stencil; 678 ds_ci.back = stencil; 679 680 pipelineobj.SetDepthStencil(&ds_ci); 681 pipelineobj.SetViewport(m_viewports); 682 pipelineobj.SetScissor(m_scissors); 683 descriptorSet.CreateVKDescriptorSet(commandBuffer); 684 VkResult err = pipelineobj.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 685 ASSERT_VK_SUCCESS(err); 686 vkCmdBindPipeline(commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineobj.handle()); 687 commandBuffer->BindDescriptorSet(descriptorSet); 688 } 689 690 class VkPositiveLayerTest : public VkLayerTest { 691 public: 692 protected: 693 }; 694 695 class VkWsiEnabledLayerTest : public VkLayerTest { 696 public: 697 protected: 698 VkWsiEnabledLayerTest() { m_enableWSI = true; } 699 }; 700 701 class VkBufferTest { 702 public: 703 enum eTestEnFlags { 704 eDoubleDelete, 705 eInvalidDeviceOffset, 706 eInvalidMemoryOffset, 707 eBindNullBuffer, 708 eBindFakeBuffer, 709 eFreeInvalidHandle, 710 eNone, 711 }; 712 713 enum eTestConditions { eOffsetAlignment = 1 }; 714 715 static bool GetTestConditionValid(VkDeviceObj *aVulkanDevice, eTestEnFlags aTestFlag, VkBufferUsageFlags aBufferUsage = 0) { 716 if (eInvalidDeviceOffset != aTestFlag && eInvalidMemoryOffset != aTestFlag) { 717 return true; 718 } 719 VkDeviceSize offset_limit = 0; 720 if (eInvalidMemoryOffset == aTestFlag) { 721 VkBuffer vulkanBuffer; 722 VkBufferCreateInfo buffer_create_info = {}; 723 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 724 buffer_create_info.size = 32; 725 buffer_create_info.usage = aBufferUsage; 726 727 vkCreateBuffer(aVulkanDevice->device(), &buffer_create_info, nullptr, &vulkanBuffer); 728 VkMemoryRequirements memory_reqs = {}; 729 730 vkGetBufferMemoryRequirements(aVulkanDevice->device(), vulkanBuffer, &memory_reqs); 731 vkDestroyBuffer(aVulkanDevice->device(), vulkanBuffer, nullptr); 732 offset_limit = memory_reqs.alignment; 733 } else if ((VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) & aBufferUsage) { 734 offset_limit = aVulkanDevice->props.limits.minTexelBufferOffsetAlignment; 735 } else if (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT & aBufferUsage) { 736 offset_limit = aVulkanDevice->props.limits.minUniformBufferOffsetAlignment; 737 } else if (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT & aBufferUsage) { 738 offset_limit = aVulkanDevice->props.limits.minStorageBufferOffsetAlignment; 739 } 740 return eOffsetAlignment < offset_limit; 741 } 742 743 // A constructor which performs validation tests within construction. 744 VkBufferTest(VkDeviceObj *aVulkanDevice, VkBufferUsageFlags aBufferUsage, eTestEnFlags aTestFlag = eNone) 745 : AllocateCurrent(true), 746 BoundCurrent(false), 747 CreateCurrent(false), 748 InvalidDeleteEn(false), 749 VulkanDevice(aVulkanDevice->device()) { 750 if (eBindNullBuffer == aTestFlag || eBindFakeBuffer == aTestFlag) { 751 VkMemoryAllocateInfo memory_allocate_info = {}; 752 memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 753 memory_allocate_info.allocationSize = 1; // fake size -- shouldn't matter for the test 754 memory_allocate_info.memoryTypeIndex = 0; // fake type -- shouldn't matter for the test 755 vkAllocateMemory(VulkanDevice, &memory_allocate_info, nullptr, &VulkanMemory); 756 757 VulkanBuffer = (aTestFlag == eBindNullBuffer) ? VK_NULL_HANDLE : (VkBuffer)0xCDCDCDCDCDCDCDCD; 758 759 vkBindBufferMemory(VulkanDevice, VulkanBuffer, VulkanMemory, 0); 760 } else { 761 VkBufferCreateInfo buffer_create_info = {}; 762 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 763 buffer_create_info.size = 32; 764 buffer_create_info.usage = aBufferUsage; 765 766 vkCreateBuffer(VulkanDevice, &buffer_create_info, nullptr, &VulkanBuffer); 767 768 CreateCurrent = true; 769 770 VkMemoryRequirements memory_requirements; 771 vkGetBufferMemoryRequirements(VulkanDevice, VulkanBuffer, &memory_requirements); 772 773 VkMemoryAllocateInfo memory_allocate_info = {}; 774 memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 775 memory_allocate_info.allocationSize = memory_requirements.size + eOffsetAlignment; 776 bool pass = aVulkanDevice->phy().set_memory_type(memory_requirements.memoryTypeBits, &memory_allocate_info, 777 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); 778 if (!pass) { 779 CreateCurrent = false; 780 vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr); 781 return; 782 } 783 784 vkAllocateMemory(VulkanDevice, &memory_allocate_info, NULL, &VulkanMemory); 785 // NB: 1 is intentionally an invalid offset value 786 const bool offset_en = eInvalidDeviceOffset == aTestFlag || eInvalidMemoryOffset == aTestFlag; 787 vkBindBufferMemory(VulkanDevice, VulkanBuffer, VulkanMemory, offset_en ? eOffsetAlignment : 0); 788 BoundCurrent = true; 789 790 InvalidDeleteEn = (eFreeInvalidHandle == aTestFlag); 791 } 792 } 793 794 ~VkBufferTest() { 795 if (CreateCurrent) { 796 vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr); 797 } 798 if (AllocateCurrent) { 799 if (InvalidDeleteEn) { 800 union { 801 VkDeviceMemory device_memory; 802 unsigned long long index_access; 803 } bad_index; 804 805 bad_index.device_memory = VulkanMemory; 806 bad_index.index_access++; 807 808 vkFreeMemory(VulkanDevice, bad_index.device_memory, nullptr); 809 } 810 vkFreeMemory(VulkanDevice, VulkanMemory, nullptr); 811 } 812 } 813 814 bool GetBufferCurrent() { return AllocateCurrent && BoundCurrent && CreateCurrent; } 815 816 const VkBuffer &GetBuffer() { return VulkanBuffer; } 817 818 void TestDoubleDestroy() { 819 // Destroy the buffer but leave the flag set, which will cause 820 // the buffer to be destroyed again in the destructor. 821 vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr); 822 } 823 824 protected: 825 bool AllocateCurrent; 826 bool BoundCurrent; 827 bool CreateCurrent; 828 bool InvalidDeleteEn; 829 830 VkBuffer VulkanBuffer; 831 VkDevice VulkanDevice; 832 VkDeviceMemory VulkanMemory; 833 }; 834 835 class VkVerticesObj { 836 public: 837 VkVerticesObj(VkDeviceObj *aVulkanDevice, unsigned aAttributeCount, unsigned aBindingCount, unsigned aByteStride, 838 VkDeviceSize aVertexCount, const float *aVerticies) 839 : BoundCurrent(false), 840 AttributeCount(aAttributeCount), 841 BindingCount(aBindingCount), 842 BindId(BindIdGenerator), 843 PipelineVertexInputStateCreateInfo(), 844 VulkanMemoryBuffer(aVulkanDevice, static_cast<int>(aByteStride * aVertexCount), 845 reinterpret_cast<const void *>(aVerticies), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) { 846 BindIdGenerator++; // NB: This can wrap w/misuse 847 848 VertexInputAttributeDescription = new VkVertexInputAttributeDescription[AttributeCount]; 849 VertexInputBindingDescription = new VkVertexInputBindingDescription[BindingCount]; 850 851 PipelineVertexInputStateCreateInfo.pVertexAttributeDescriptions = VertexInputAttributeDescription; 852 PipelineVertexInputStateCreateInfo.vertexAttributeDescriptionCount = AttributeCount; 853 PipelineVertexInputStateCreateInfo.pVertexBindingDescriptions = VertexInputBindingDescription; 854 PipelineVertexInputStateCreateInfo.vertexBindingDescriptionCount = BindingCount; 855 PipelineVertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 856 857 unsigned i = 0; 858 do { 859 VertexInputAttributeDescription[i].binding = BindId; 860 VertexInputAttributeDescription[i].location = i; 861 VertexInputAttributeDescription[i].format = VK_FORMAT_R32G32B32_SFLOAT; 862 VertexInputAttributeDescription[i].offset = sizeof(float) * aByteStride; 863 i++; 864 } while (AttributeCount < i); 865 866 i = 0; 867 do { 868 VertexInputBindingDescription[i].binding = BindId; 869 VertexInputBindingDescription[i].stride = aByteStride; 870 VertexInputBindingDescription[i].inputRate = VK_VERTEX_INPUT_RATE_VERTEX; 871 i++; 872 } while (BindingCount < i); 873 } 874 875 ~VkVerticesObj() { 876 if (VertexInputAttributeDescription) { 877 delete[] VertexInputAttributeDescription; 878 } 879 if (VertexInputBindingDescription) { 880 delete[] VertexInputBindingDescription; 881 } 882 } 883 884 bool AddVertexInputToPipe(VkPipelineObj &aPipelineObj) { 885 aPipelineObj.AddVertexInputAttribs(VertexInputAttributeDescription, AttributeCount); 886 aPipelineObj.AddVertexInputBindings(VertexInputBindingDescription, BindingCount); 887 return true; 888 } 889 890 void BindVertexBuffers(VkCommandBuffer aCommandBuffer, unsigned aOffsetCount = 0, VkDeviceSize *aOffsetList = nullptr) { 891 VkDeviceSize *offsetList; 892 unsigned offsetCount; 893 894 if (aOffsetCount) { 895 offsetList = aOffsetList; 896 offsetCount = aOffsetCount; 897 } else { 898 offsetList = new VkDeviceSize[1](); 899 offsetCount = 1; 900 } 901 902 vkCmdBindVertexBuffers(aCommandBuffer, BindId, offsetCount, &VulkanMemoryBuffer.handle(), offsetList); 903 BoundCurrent = true; 904 905 if (!aOffsetCount) { 906 delete[] offsetList; 907 } 908 } 909 910 protected: 911 static uint32_t BindIdGenerator; 912 913 bool BoundCurrent; 914 unsigned AttributeCount; 915 unsigned BindingCount; 916 uint32_t BindId; 917 918 VkPipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo; 919 VkVertexInputAttributeDescription *VertexInputAttributeDescription; 920 VkVertexInputBindingDescription *VertexInputBindingDescription; 921 VkConstantBufferObj VulkanMemoryBuffer; 922 }; 923 924 uint32_t VkVerticesObj::BindIdGenerator; 925 926 struct OneOffDescriptorSet { 927 VkDeviceObj *device_; 928 VkDescriptorPool pool_; 929 VkDescriptorSetLayoutObj layout_; 930 VkDescriptorSet set_; 931 typedef std::vector<VkDescriptorSetLayoutBinding> Bindings; 932 933 OneOffDescriptorSet(VkDeviceObj *device, const Bindings &bindings) 934 : device_{device}, pool_{}, layout_(device, bindings), set_{} { 935 VkResult err; 936 937 std::vector<VkDescriptorPoolSize> sizes; 938 for (const auto &b : bindings) sizes.push_back({b.descriptorType, std::max(1u, b.descriptorCount)}); 939 940 VkDescriptorPoolCreateInfo dspci = { 941 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, nullptr, 0, 1, uint32_t(sizes.size()), sizes.data()}; 942 err = vkCreateDescriptorPool(device_->handle(), &dspci, nullptr, &pool_); 943 if (err != VK_SUCCESS) return; 944 945 VkDescriptorSetAllocateInfo alloc_info = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, nullptr, pool_, 1, 946 &layout_.handle()}; 947 err = vkAllocateDescriptorSets(device_->handle(), &alloc_info, &set_); 948 } 949 950 ~OneOffDescriptorSet() { 951 // No need to destroy set-- it's going away with the pool. 952 vkDestroyDescriptorPool(device_->handle(), pool_, nullptr); 953 } 954 955 bool Initialized() { return pool_ != VK_NULL_HANDLE && layout_.initialized() && set_ != VK_NULL_HANDLE; } 956 }; 957 958 template <typename T> 959 bool IsValidVkStruct(const T &s) { 960 return LvlTypeMap<T>::kSType == s.sType; 961 } 962 963 // Helper class for tersely creating create pipeline tests 964 // 965 // Designed with minimal error checking to ensure easy error state creation 966 // See OneshotTest for typical usage 967 struct CreatePipelineHelper { 968 public: 969 std::vector<VkDescriptorSetLayoutBinding> dsl_bindings_; 970 std::unique_ptr<OneOffDescriptorSet> descriptor_set_; 971 std::vector<VkPipelineShaderStageCreateInfo> shader_stages_; 972 VkPipelineVertexInputStateCreateInfo vi_ci_ = {}; 973 VkPipelineInputAssemblyStateCreateInfo ia_ci_ = {}; 974 VkPipelineTessellationStateCreateInfo tess_ci_ = {}; 975 VkViewport viewport_ = {}; 976 VkRect2D scissor_ = {}; 977 VkPipelineViewportStateCreateInfo vp_state_ci_ = {}; 978 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci_ = {}; 979 VkPipelineLayoutCreateInfo pipeline_layout_ci_ = {}; 980 VkPipelineLayoutObj pipeline_layout_; 981 VkPipelineDynamicStateCreateInfo dyn_state_ci_ = {}; 982 VkPipelineRasterizationStateCreateInfo rs_state_ci_ = {}; 983 VkPipelineColorBlendAttachmentState cb_attachments_ = {}; 984 VkPipelineColorBlendStateCreateInfo cb_ci_ = {}; 985 VkGraphicsPipelineCreateInfo gp_ci_ = {}; 986 VkPipelineCacheCreateInfo pc_ci_ = {}; 987 VkPipeline pipeline_ = VK_NULL_HANDLE; 988 VkPipelineCache pipeline_cache_ = VK_NULL_HANDLE; 989 std::unique_ptr<VkShaderObj> vs_; 990 std::unique_ptr<VkShaderObj> fs_; 991 VkLayerTest &layer_test_; 992 CreatePipelineHelper(VkLayerTest &test) : layer_test_(test) {} 993 ~CreatePipelineHelper() { 994 VkDevice device = layer_test_.device(); 995 vkDestroyPipelineCache(device, pipeline_cache_, nullptr); 996 vkDestroyPipeline(device, pipeline_, nullptr); 997 } 998 999 void InitDescriptorSetInfo() { dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}}; } 1000 1001 void InitInputAndVertexInfo() { 1002 vi_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 1003 1004 ia_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 1005 ia_ci_.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 1006 } 1007 1008 void InitMultisampleInfo() { 1009 pipe_ms_state_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 1010 pipe_ms_state_ci_.pNext = nullptr; 1011 pipe_ms_state_ci_.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; 1012 pipe_ms_state_ci_.sampleShadingEnable = VK_FALSE; 1013 pipe_ms_state_ci_.minSampleShading = 1.0; 1014 pipe_ms_state_ci_.pSampleMask = NULL; 1015 } 1016 1017 void InitPipelineLayoutInfo() { 1018 pipeline_layout_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 1019 pipeline_layout_ci_.setLayoutCount = 1; // Not really changeable because InitState() sets exactly one pSetLayout 1020 pipeline_layout_ci_.pSetLayouts = nullptr; // must bound after it is created 1021 } 1022 1023 void InitViewportInfo() { 1024 viewport_ = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f}; 1025 scissor_ = {{0, 0}, {64, 64}}; 1026 1027 vp_state_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 1028 vp_state_ci_.pNext = nullptr; 1029 vp_state_ci_.viewportCount = 1; 1030 vp_state_ci_.pViewports = &viewport_; // ignored if dynamic 1031 vp_state_ci_.scissorCount = 1; 1032 vp_state_ci_.pScissors = &scissor_; // ignored if dynamic 1033 } 1034 1035 void InitDynamicStateInfo() { 1036 // Use a "validity" check on the {} initialized structure to detect initialization 1037 // during late bind 1038 } 1039 1040 void InitShaderInfo() { 1041 vs_.reset(new VkShaderObj(layer_test_.DeviceObj(), bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, &layer_test_)); 1042 fs_.reset(new VkShaderObj(layer_test_.DeviceObj(), bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, &layer_test_)); 1043 // We shouldn't need a fragment shader but add it to be able to run on more devices 1044 shader_stages_ = {vs_->GetStageCreateInfo(), fs_->GetStageCreateInfo()}; 1045 } 1046 1047 void InitRasterizationInfo() { 1048 rs_state_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 1049 rs_state_ci_.pNext = nullptr; 1050 rs_state_ci_.flags = 0; 1051 rs_state_ci_.depthClampEnable = VK_FALSE; 1052 rs_state_ci_.rasterizerDiscardEnable = VK_FALSE; 1053 rs_state_ci_.polygonMode = VK_POLYGON_MODE_FILL; 1054 rs_state_ci_.cullMode = VK_CULL_MODE_BACK_BIT; 1055 rs_state_ci_.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; 1056 rs_state_ci_.depthBiasEnable = VK_FALSE; 1057 rs_state_ci_.lineWidth = 1.0F; 1058 } 1059 1060 void InitBlendStateInfo() { 1061 cb_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; 1062 cb_ci_.logicOpEnable = VK_FALSE; 1063 cb_ci_.logicOp = VK_LOGIC_OP_COPY; // ignored if enable is VK_FALSE above 1064 cb_ci_.attachmentCount = layer_test_.RenderPassInfo().subpassCount; 1065 ASSERT_TRUE(IsValidVkStruct(layer_test_.RenderPassInfo())); 1066 cb_ci_.pAttachments = &cb_attachments_; 1067 for (int i = 0; i < 4; i++) { 1068 cb_ci_.blendConstants[0] = 1.0F; 1069 } 1070 } 1071 1072 void InitGraphicsPipelineInfo() { 1073 // Color-only rendering in a subpass with no depth/stencil attachment 1074 // Active Pipeline Shader Stages 1075 // Vertex Shader 1076 // Fragment Shader 1077 // Required: Fixed-Function Pipeline Stages 1078 // VkPipelineVertexInputStateCreateInfo 1079 // VkPipelineInputAssemblyStateCreateInfo 1080 // VkPipelineViewportStateCreateInfo 1081 // VkPipelineRasterizationStateCreateInfo 1082 // VkPipelineMultisampleStateCreateInfo 1083 // VkPipelineColorBlendStateCreateInfo 1084 gp_ci_.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 1085 gp_ci_.pNext = nullptr; 1086 gp_ci_.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; 1087 gp_ci_.pVertexInputState = &vi_ci_; 1088 gp_ci_.pInputAssemblyState = &ia_ci_; 1089 gp_ci_.pTessellationState = nullptr; 1090 gp_ci_.pViewportState = &vp_state_ci_; 1091 gp_ci_.pRasterizationState = &rs_state_ci_; 1092 gp_ci_.pMultisampleState = &pipe_ms_state_ci_; 1093 gp_ci_.pDepthStencilState = nullptr; 1094 gp_ci_.pColorBlendState = &cb_ci_; 1095 gp_ci_.pDynamicState = nullptr; 1096 gp_ci_.renderPass = layer_test_.renderPass(); 1097 } 1098 1099 void InitPipelineCacheInfo() { 1100 pc_ci_.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 1101 pc_ci_.pNext = nullptr; 1102 pc_ci_.flags = 0; 1103 pc_ci_.initialDataSize = 0; 1104 pc_ci_.pInitialData = nullptr; 1105 } 1106 1107 // Not called by default during init_info 1108 void InitTesselationState() { 1109 // TBD -- add shaders and create_info 1110 } 1111 1112 // TDB -- add control for optional and/or additional initialization 1113 void InitInfo() { 1114 InitDescriptorSetInfo(); 1115 InitInputAndVertexInfo(); 1116 InitMultisampleInfo(); 1117 InitPipelineLayoutInfo(); 1118 InitViewportInfo(); 1119 InitDynamicStateInfo(); 1120 InitShaderInfo(); 1121 InitRasterizationInfo(); 1122 InitBlendStateInfo(); 1123 InitGraphicsPipelineInfo(); 1124 InitPipelineCacheInfo(); 1125 } 1126 1127 void InitState() { 1128 VkResult err; 1129 descriptor_set_.reset(new OneOffDescriptorSet(layer_test_.DeviceObj(), dsl_bindings_)); 1130 ASSERT_TRUE(descriptor_set_->Initialized()); 1131 1132 const std::vector<VkPushConstantRange> push_ranges( 1133 pipeline_layout_ci_.pPushConstantRanges, 1134 pipeline_layout_ci_.pPushConstantRanges + pipeline_layout_ci_.pushConstantRangeCount); 1135 pipeline_layout_ = VkPipelineLayoutObj(layer_test_.DeviceObj(), {&descriptor_set_->layout_}, push_ranges); 1136 1137 err = vkCreatePipelineCache(layer_test_.device(), &pc_ci_, NULL, &pipeline_cache_); 1138 ASSERT_VK_SUCCESS(err); 1139 } 1140 1141 void LateBindPipelineInfo() { 1142 // By value or dynamically located items must be late bound 1143 gp_ci_.layout = pipeline_layout_.handle(); 1144 gp_ci_.stageCount = shader_stages_.size(); 1145 gp_ci_.pStages = shader_stages_.data(); 1146 if ((gp_ci_.pTessellationState == nullptr) && IsValidVkStruct(tess_ci_)) { 1147 gp_ci_.pTessellationState = &tess_ci_; 1148 } 1149 if ((gp_ci_.pDynamicState == nullptr) && IsValidVkStruct(dyn_state_ci_)) { 1150 gp_ci_.pDynamicState = &dyn_state_ci_; 1151 } 1152 } 1153 1154 VkResult CreateGraphicsPipeline(bool implicit_destroy = true, bool do_late_bind = true) { 1155 VkResult err; 1156 if (do_late_bind) { 1157 LateBindPipelineInfo(); 1158 } 1159 if (implicit_destroy && (pipeline_ != VK_NULL_HANDLE)) { 1160 vkDestroyPipeline(layer_test_.device(), pipeline_, nullptr); 1161 pipeline_ = VK_NULL_HANDLE; 1162 } 1163 err = vkCreateGraphicsPipelines(layer_test_.device(), pipeline_cache_, 1, &gp_ci_, NULL, &pipeline_); 1164 return err; 1165 } 1166 1167 // Helper function to create a simple test case (postive or negative) 1168 // 1169 // info_override can be any callable that takes a CreatePipelineHeper & 1170 // flags, error can be any args accepted by "SetDesiredFailure". 1171 template <typename Test, typename OverrideFunc, typename Error> 1172 static void OneshotTest(Test &test, OverrideFunc &info_override, const VkFlags flags, const std::vector<Error> &errors, 1173 bool positive_test = false) { 1174 CreatePipelineHelper helper(test); 1175 helper.InitInfo(); 1176 info_override(helper); 1177 helper.InitState(); 1178 1179 for (const auto &error : errors) test.Monitor()->SetDesiredFailureMsg(flags, error); 1180 helper.CreateGraphicsPipeline(); 1181 1182 if (positive_test) { 1183 test.Monitor()->VerifyNotFound(); 1184 } else { 1185 test.Monitor()->VerifyFound(); 1186 } 1187 } 1188 1189 template <typename Test, typename OverrideFunc, typename Error> 1190 static void OneshotTest(Test &test, OverrideFunc &info_override, const VkFlags flags, Error error, bool positive_test = false) { 1191 OneshotTest(test, info_override, flags, std::vector<Error>(1, error), positive_test); 1192 } 1193 }; 1194 namespace chain_util { 1195 template <typename T> 1196 T Init(const void *pnext_in = nullptr) { 1197 T pnext_obj = {}; 1198 pnext_obj.sType = LvlTypeMap<T>::kSType; 1199 pnext_obj.pNext = pnext_in; 1200 return pnext_obj; 1201 } 1202 class ExtensionChain { 1203 const void *head_ = nullptr; 1204 typedef std::function<bool(const char *)> AddIfFunction; 1205 AddIfFunction add_if_; 1206 typedef std::vector<const char *> List; 1207 List *list_; 1208 1209 public: 1210 template <typename F> 1211 ExtensionChain(F &add_if, List *list) : add_if_(add_if), list_(list) {} 1212 template <typename T> 1213 void Add(const char *name, T &obj) { 1214 if (add_if_(name)) { 1215 if (list_) { 1216 list_->push_back(name); 1217 } 1218 obj.pNext = head_; 1219 head_ = &obj; 1220 } 1221 } 1222 const void *Head() const { return head_; } 1223 }; 1224 } // namespace chain_util 1225 1226 // ******************************************************************************************************************** 1227 // ******************************************************************************************************************** 1228 // ******************************************************************************************************************** 1229 // ******************************************************************************************************************** 1230 TEST_F(VkLayerTest, RequiredParameter) { 1231 TEST_DESCRIPTION("Specify VK_NULL_HANDLE, NULL, and 0 for required handle, pointer, array, and array count parameters"); 1232 1233 ASSERT_NO_FATAL_FAILURE(Init()); 1234 1235 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pFeatures specified as NULL"); 1236 // Specify NULL for a pointer to a handle 1237 // Expected to trigger an error with 1238 // parameter_validation::validate_required_pointer 1239 vkGetPhysicalDeviceFeatures(gpu(), NULL); 1240 m_errorMonitor->VerifyFound(); 1241 1242 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 1243 "required parameter pQueueFamilyPropertyCount specified as NULL"); 1244 // Specify NULL for pointer to array count 1245 // Expected to trigger an error with parameter_validation::validate_array 1246 vkGetPhysicalDeviceQueueFamilyProperties(gpu(), NULL, NULL); 1247 m_errorMonitor->VerifyFound(); 1248 1249 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1e030a1b); 1250 // Specify 0 for a required array count 1251 // Expected to trigger an error with parameter_validation::validate_array 1252 VkViewport view_port = {}; 1253 m_commandBuffer->SetViewport(0, 0, &view_port); 1254 m_errorMonitor->VerifyFound(); 1255 1256 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1e03fa01); 1257 // Specify NULL for a required array 1258 // Expected to trigger an error with parameter_validation::validate_array 1259 m_commandBuffer->SetViewport(0, 1, NULL); 1260 m_errorMonitor->VerifyFound(); 1261 1262 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter memory specified as VK_NULL_HANDLE"); 1263 // Specify VK_NULL_HANDLE for a required handle 1264 // Expected to trigger an error with 1265 // parameter_validation::validate_required_handle 1266 vkUnmapMemory(device(), VK_NULL_HANDLE); 1267 m_errorMonitor->VerifyFound(); 1268 1269 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 1270 "required parameter pFences[0] specified as VK_NULL_HANDLE"); 1271 // Specify VK_NULL_HANDLE for a required handle array entry 1272 // Expected to trigger an error with 1273 // parameter_validation::validate_required_handle_array 1274 VkFence fence = VK_NULL_HANDLE; 1275 vkResetFences(device(), 1, &fence); 1276 m_errorMonitor->VerifyFound(); 1277 1278 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pAllocateInfo specified as NULL"); 1279 // Specify NULL for a required struct pointer 1280 // Expected to trigger an error with 1281 // parameter_validation::validate_struct_type 1282 VkDeviceMemory memory = VK_NULL_HANDLE; 1283 vkAllocateMemory(device(), NULL, NULL, &memory); 1284 m_errorMonitor->VerifyFound(); 1285 1286 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "value of faceMask must not be 0"); 1287 // Specify 0 for a required VkFlags parameter 1288 // Expected to trigger an error with parameter_validation::validate_flags 1289 m_commandBuffer->SetStencilReference(0, 0); 1290 m_errorMonitor->VerifyFound(); 1291 1292 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "value of pSubmits[0].pWaitDstStageMask[0] must not be 0"); 1293 // Specify 0 for a required VkFlags array entry 1294 // Expected to trigger an error with 1295 // parameter_validation::validate_flags_array 1296 VkSemaphore semaphore = VK_NULL_HANDLE; 1297 VkPipelineStageFlags stageFlags = 0; 1298 VkSubmitInfo submitInfo = {}; 1299 submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 1300 submitInfo.waitSemaphoreCount = 1; 1301 submitInfo.pWaitSemaphores = &semaphore; 1302 submitInfo.pWaitDstStageMask = &stageFlags; 1303 vkQueueSubmit(m_device->m_queue, 1, &submitInfo, VK_NULL_HANDLE); 1304 m_errorMonitor->VerifyFound(); 1305 } 1306 1307 TEST_F(VkLayerTest, ReservedParameter) { 1308 TEST_DESCRIPTION("Specify a non-zero value for a reserved parameter"); 1309 1310 ASSERT_NO_FATAL_FAILURE(Init()); 1311 1312 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " must be 0"); 1313 // Specify 0 for a reserved VkFlags parameter 1314 // Expected to trigger an error with 1315 // parameter_validation::validate_reserved_flags 1316 VkEvent event_handle = VK_NULL_HANDLE; 1317 VkEventCreateInfo event_info = {}; 1318 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 1319 event_info.flags = 1; 1320 vkCreateEvent(device(), &event_info, NULL, &event_handle); 1321 m_errorMonitor->VerifyFound(); 1322 } 1323 1324 TEST_F(VkLayerTest, DebugMarkerNameTest) { 1325 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 1326 if (DeviceExtensionSupported(gpu(), "VK_LAYER_LUNARG_core_validation", VK_EXT_DEBUG_MARKER_EXTENSION_NAME)) { 1327 m_device_extension_names.push_back(VK_EXT_DEBUG_MARKER_EXTENSION_NAME); 1328 } else { 1329 printf(" Debug Marker Extension not supported, skipping test\n"); 1330 return; 1331 } 1332 ASSERT_NO_FATAL_FAILURE(InitState()); 1333 1334 PFN_vkDebugMarkerSetObjectNameEXT fpvkDebugMarkerSetObjectNameEXT = 1335 (PFN_vkDebugMarkerSetObjectNameEXT)vkGetInstanceProcAddr(instance(), "vkDebugMarkerSetObjectNameEXT"); 1336 if (!(fpvkDebugMarkerSetObjectNameEXT)) { 1337 printf(" Can't find fpvkDebugMarkerSetObjectNameEXT; skipped.\n"); 1338 return; 1339 } 1340 1341 VkEvent event_handle = VK_NULL_HANDLE; 1342 VkEventCreateInfo event_info = {}; 1343 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 1344 vkCreateEvent(device(), &event_info, NULL, &event_handle); 1345 VkDebugMarkerObjectNameInfoEXT name_info = {}; 1346 name_info.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT; 1347 name_info.pNext = nullptr; 1348 name_info.object = (uint64_t)event_handle; 1349 name_info.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT; 1350 name_info.pObjectName = "UnimaginablyImprobableString"; 1351 fpvkDebugMarkerSetObjectNameEXT(device(), &name_info); 1352 1353 m_commandBuffer->begin(); 1354 vkCmdSetEvent(m_commandBuffer->handle(), event_handle, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT); 1355 m_commandBuffer->end(); 1356 VkSubmitInfo submit_info = {}; 1357 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 1358 submit_info.commandBufferCount = 1; 1359 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 1360 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 1361 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "UnimaginablyImprobableString"); 1362 vkDestroyEvent(m_device->device(), event_handle, NULL); 1363 m_errorMonitor->VerifyFound(); 1364 vkQueueWaitIdle(m_device->m_queue); 1365 } 1366 1367 TEST_F(VkLayerTest, InvalidStructSType) { 1368 TEST_DESCRIPTION("Specify an invalid VkStructureType for a Vulkan structure's sType field"); 1369 1370 ASSERT_NO_FATAL_FAILURE(Init()); 1371 1372 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pAllocateInfo->sType must be"); 1373 // Zero struct memory, effectively setting sType to 1374 // VK_STRUCTURE_TYPE_APPLICATION_INFO 1375 // Expected to trigger an error with 1376 // parameter_validation::validate_struct_type 1377 VkMemoryAllocateInfo alloc_info = {}; 1378 VkDeviceMemory memory = VK_NULL_HANDLE; 1379 vkAllocateMemory(device(), &alloc_info, NULL, &memory); 1380 m_errorMonitor->VerifyFound(); 1381 1382 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pSubmits[0].sType must be"); 1383 // Zero struct memory, effectively setting sType to 1384 // VK_STRUCTURE_TYPE_APPLICATION_INFO 1385 // Expected to trigger an error with 1386 // parameter_validation::validate_struct_type_array 1387 VkSubmitInfo submit_info = {}; 1388 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 1389 m_errorMonitor->VerifyFound(); 1390 } 1391 1392 TEST_F(VkLayerTest, InvalidStructPNext) { 1393 TEST_DESCRIPTION("Specify an invalid value for a Vulkan structure's pNext field"); 1394 1395 ASSERT_NO_FATAL_FAILURE(Init()); 1396 1397 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "value of pCreateInfo->pNext must be NULL"); 1398 // Set VkMemoryAllocateInfo::pNext to a non-NULL value, when pNext must be NULL. 1399 // Need to pick a function that has no allowed pNext structure types. 1400 // Expected to trigger an error with parameter_validation::validate_struct_pnext 1401 VkEvent event = VK_NULL_HANDLE; 1402 VkEventCreateInfo event_alloc_info = {}; 1403 // Zero-initialization will provide the correct sType 1404 VkApplicationInfo app_info = {}; 1405 event_alloc_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 1406 event_alloc_info.pNext = &app_info; 1407 vkCreateEvent(device(), &event_alloc_info, NULL, &event); 1408 m_errorMonitor->VerifyFound(); 1409 1410 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, 1411 " chain includes a structure with unexpected VkStructureType "); 1412 // Set VkMemoryAllocateInfo::pNext to a non-NULL value, but use 1413 // a function that has allowed pNext structure types and specify 1414 // a structure type that is not allowed. 1415 // Expected to trigger an error with parameter_validation::validate_struct_pnext 1416 VkDeviceMemory memory = VK_NULL_HANDLE; 1417 VkMemoryAllocateInfo memory_alloc_info = {}; 1418 memory_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 1419 memory_alloc_info.pNext = &app_info; 1420 vkAllocateMemory(device(), &memory_alloc_info, NULL, &memory); 1421 m_errorMonitor->VerifyFound(); 1422 } 1423 1424 TEST_F(VkLayerTest, UnrecognizedValueOutOfRange) { 1425 ASSERT_NO_FATAL_FAILURE(Init()); 1426 1427 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 1428 "does not fall within the begin..end range of the core VkFormat enumeration tokens"); 1429 // Specify an invalid VkFormat value 1430 // Expected to trigger an error with 1431 // parameter_validation::validate_ranged_enum 1432 VkFormatProperties format_properties; 1433 vkGetPhysicalDeviceFormatProperties(gpu(), static_cast<VkFormat>(8000), &format_properties); 1434 m_errorMonitor->VerifyFound(); 1435 } 1436 1437 TEST_F(VkLayerTest, UnrecognizedValueBadMask) { 1438 ASSERT_NO_FATAL_FAILURE(Init()); 1439 1440 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "contains flag bits that are not recognized members of"); 1441 // Specify an invalid VkFlags bitmask value 1442 // Expected to trigger an error with parameter_validation::validate_flags 1443 VkImageFormatProperties image_format_properties; 1444 vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, 1445 static_cast<VkImageUsageFlags>(1 << 25), 0, &image_format_properties); 1446 m_errorMonitor->VerifyFound(); 1447 } 1448 1449 TEST_F(VkLayerTest, UnrecognizedValueBadFlag) { 1450 ASSERT_NO_FATAL_FAILURE(Init()); 1451 1452 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "contains flag bits that are not recognized members of"); 1453 // Specify an invalid VkFlags array entry 1454 // Expected to trigger an error with 1455 // parameter_validation::validate_flags_array 1456 VkSemaphore semaphore = VK_NULL_HANDLE; 1457 VkPipelineStageFlags stage_flags = static_cast<VkPipelineStageFlags>(1 << 25); 1458 VkSubmitInfo submit_info = {}; 1459 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 1460 submit_info.waitSemaphoreCount = 1; 1461 submit_info.pWaitSemaphores = &semaphore; 1462 submit_info.pWaitDstStageMask = &stage_flags; 1463 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 1464 m_errorMonitor->VerifyFound(); 1465 } 1466 1467 TEST_F(VkLayerTest, UnrecognizedValueBadBool) { 1468 // Make sure using VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE doesn't trigger a false positive. 1469 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 1470 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME)) { 1471 m_device_extension_names.push_back(VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME); 1472 } else { 1473 printf(" VK_KHR_sampler_mirror_clamp_to_edge extension not supported, skipping test\n"); 1474 return; 1475 } 1476 ASSERT_NO_FATAL_FAILURE(InitState()); 1477 1478 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "is neither VK_TRUE nor VK_FALSE"); 1479 // Specify an invalid VkBool32 value, expecting a warning with parameter_validation::validate_bool32 1480 VkSampler sampler = VK_NULL_HANDLE; 1481 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo(); 1482 sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; 1483 sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; 1484 sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; 1485 1486 // Not VK_TRUE or VK_FALSE 1487 sampler_info.anisotropyEnable = 3; 1488 vkCreateSampler(m_device->device(), &sampler_info, NULL, &sampler); 1489 m_errorMonitor->VerifyFound(); 1490 } 1491 1492 TEST_F(VkLayerTest, MirrorClampToEdgeNotEnabled) { 1493 TEST_DESCRIPTION("Validation should catch using CLAMP_TO_EDGE addressing mode if the extension is not enabled."); 1494 1495 ASSERT_NO_FATAL_FAILURE(Init()); 1496 1497 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1260086e); 1498 VkSampler sampler = VK_NULL_HANDLE; 1499 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo(); 1500 // Set the modes to cause the error 1501 sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; 1502 sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; 1503 sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; 1504 1505 vkCreateSampler(m_device->device(), &sampler_info, NULL, &sampler); 1506 m_errorMonitor->VerifyFound(); 1507 } 1508 1509 TEST_F(VkLayerTest, AnisotropyFeatureDisabled) { 1510 TEST_DESCRIPTION("Validation should check anisotropy parameters are correct with samplerAnisotropy disabled."); 1511 1512 // Determine if required device features are available 1513 VkPhysicalDeviceFeatures device_features = {}; 1514 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 1515 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features)); 1516 device_features.samplerAnisotropy = VK_FALSE; // force anisotropy off 1517 ASSERT_NO_FATAL_FAILURE(InitState(&device_features)); 1518 1519 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1260085c); 1520 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo(); 1521 // With the samplerAnisotropy disable, the sampler must not enable it. 1522 sampler_info.anisotropyEnable = VK_TRUE; 1523 VkSampler sampler = VK_NULL_HANDLE; 1524 1525 VkResult err; 1526 err = vkCreateSampler(m_device->device(), &sampler_info, NULL, &sampler); 1527 m_errorMonitor->VerifyFound(); 1528 if (VK_SUCCESS == err) { 1529 vkDestroySampler(m_device->device(), sampler, NULL); 1530 } 1531 sampler = VK_NULL_HANDLE; 1532 } 1533 1534 TEST_F(VkLayerTest, AnisotropyFeatureEnabled) { 1535 TEST_DESCRIPTION("Validation must check several conditons that apply only when Anisotropy is enabled."); 1536 1537 // Determine if required device features are available 1538 VkPhysicalDeviceFeatures device_features = {}; 1539 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 1540 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features)); 1541 1542 // These tests require that the device support sparse residency for 2D images 1543 if (VK_TRUE != device_features.samplerAnisotropy) { 1544 printf(" Test requires unsupported samplerAnisotropy feature. Skipped.\n"); 1545 return; 1546 } 1547 1548 bool cubic_support = false; 1549 if (DeviceExtensionSupported(gpu(), nullptr, "VK_IMG_filter_cubic")) { 1550 m_device_extension_names.push_back("VK_IMG_filter_cubic"); 1551 cubic_support = true; 1552 } 1553 1554 VkSamplerCreateInfo sampler_info_ref = SafeSaneSamplerCreateInfo(); 1555 sampler_info_ref.anisotropyEnable = VK_TRUE; 1556 VkSamplerCreateInfo sampler_info = sampler_info_ref; 1557 ASSERT_NO_FATAL_FAILURE(InitState()); 1558 1559 auto do_test = [this](UNIQUE_VALIDATION_ERROR_CODE code, const VkSamplerCreateInfo *pCreateInfo) -> void { 1560 VkResult err; 1561 VkSampler sampler = VK_NULL_HANDLE; 1562 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, code); 1563 err = vkCreateSampler(m_device->device(), pCreateInfo, NULL, &sampler); 1564 m_errorMonitor->VerifyFound(); 1565 if (VK_SUCCESS == err) { 1566 vkDestroySampler(m_device->device(), sampler, NULL); 1567 } 1568 }; 1569 1570 // maxAnisotropy out-of-bounds low. 1571 sampler_info.maxAnisotropy = NextAfterLess(1.0F); 1572 do_test(VALIDATION_ERROR_1260085e, &sampler_info); 1573 sampler_info.maxAnisotropy = sampler_info_ref.maxAnisotropy; 1574 1575 // maxAnisotropy out-of-bounds high. 1576 sampler_info.maxAnisotropy = NextAfterGreater(m_device->phy().properties().limits.maxSamplerAnisotropy); 1577 do_test(VALIDATION_ERROR_1260085e, &sampler_info); 1578 sampler_info.maxAnisotropy = sampler_info_ref.maxAnisotropy; 1579 1580 // Both anisotropy and unnormalized coords enabled 1581 sampler_info.unnormalizedCoordinates = VK_TRUE; 1582 do_test(VALIDATION_ERROR_12600868, &sampler_info); 1583 sampler_info.unnormalizedCoordinates = sampler_info_ref.unnormalizedCoordinates; 1584 1585 // Both anisotropy and cubic filtering enabled 1586 if (cubic_support) { 1587 sampler_info.minFilter = VK_FILTER_CUBIC_IMG; 1588 do_test(VALIDATION_ERROR_12600872, &sampler_info); 1589 sampler_info.minFilter = sampler_info_ref.minFilter; 1590 1591 sampler_info.magFilter = VK_FILTER_CUBIC_IMG; 1592 do_test(VALIDATION_ERROR_12600872, &sampler_info); 1593 sampler_info.magFilter = sampler_info_ref.magFilter; 1594 } else { 1595 printf(" Test requires unsupported extension \"VK_IMG_filter_cubic\". Skipped.\n"); 1596 } 1597 } 1598 1599 TEST_F(VkLayerTest, UnrecognizedValueMaxEnum) { 1600 ASSERT_NO_FATAL_FAILURE(Init()); 1601 1602 // Specify MAX_ENUM 1603 VkFormatProperties format_properties; 1604 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "does not fall within the begin..end range"); 1605 vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_MAX_ENUM, &format_properties); 1606 m_errorMonitor->VerifyFound(); 1607 } 1608 1609 TEST_F(VkLayerTest, UpdateBufferAlignment) { 1610 TEST_DESCRIPTION("Check alignment parameters for vkCmdUpdateBuffer"); 1611 uint32_t updateData[] = {1, 2, 3, 4, 5, 6, 7, 8}; 1612 1613 ASSERT_NO_FATAL_FAILURE(Init()); 1614 1615 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; 1616 vk_testing::Buffer buffer; 1617 buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs); 1618 1619 m_commandBuffer->begin(); 1620 // Introduce failure by using dstOffset that is not multiple of 4 1621 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4"); 1622 m_commandBuffer->UpdateBuffer(buffer.handle(), 1, 4, updateData); 1623 m_errorMonitor->VerifyFound(); 1624 1625 // Introduce failure by using dataSize that is not multiple of 4 1626 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4"); 1627 m_commandBuffer->UpdateBuffer(buffer.handle(), 0, 6, updateData); 1628 m_errorMonitor->VerifyFound(); 1629 1630 // Introduce failure by using dataSize that is < 0 1631 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 1632 "must be greater than zero and less than or equal to 65536"); 1633 m_commandBuffer->UpdateBuffer(buffer.handle(), 0, (VkDeviceSize)-44, updateData); 1634 m_errorMonitor->VerifyFound(); 1635 1636 // Introduce failure by using dataSize that is > 65536 1637 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 1638 "must be greater than zero and less than or equal to 65536"); 1639 m_commandBuffer->UpdateBuffer(buffer.handle(), 0, (VkDeviceSize)80000, updateData); 1640 m_errorMonitor->VerifyFound(); 1641 1642 m_commandBuffer->end(); 1643 } 1644 1645 TEST_F(VkLayerTest, FillBufferAlignment) { 1646 TEST_DESCRIPTION("Check alignment parameters for vkCmdFillBuffer"); 1647 1648 ASSERT_NO_FATAL_FAILURE(Init()); 1649 1650 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; 1651 vk_testing::Buffer buffer; 1652 buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs); 1653 1654 m_commandBuffer->begin(); 1655 1656 // Introduce failure by using dstOffset that is not multiple of 4 1657 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4"); 1658 m_commandBuffer->FillBuffer(buffer.handle(), 1, 4, 0x11111111); 1659 m_errorMonitor->VerifyFound(); 1660 1661 // Introduce failure by using size that is not multiple of 4 1662 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4"); 1663 m_commandBuffer->FillBuffer(buffer.handle(), 0, 6, 0x11111111); 1664 m_errorMonitor->VerifyFound(); 1665 1666 // Introduce failure by using size that is zero 1667 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must be greater than zero"); 1668 m_commandBuffer->FillBuffer(buffer.handle(), 0, 0, 0x11111111); 1669 m_errorMonitor->VerifyFound(); 1670 1671 m_commandBuffer->end(); 1672 } 1673 1674 TEST_F(VkLayerTest, PSOPolygonModeInvalid) { 1675 TEST_DESCRIPTION("Attempt to use a non-solid polygon fill mode in a pipeline when this feature is not enabled."); 1676 1677 ASSERT_NO_FATAL_FAILURE(Init()); 1678 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 1679 1680 std::vector<const char *> device_extension_names; 1681 auto features = m_device->phy().features(); 1682 // Artificially disable support for non-solid fill modes 1683 features.fillModeNonSolid = VK_FALSE; 1684 // The sacrificial device object 1685 VkDeviceObj test_device(0, gpu(), device_extension_names, &features); 1686 1687 VkRenderpassObj render_pass(&test_device); 1688 1689 const VkPipelineLayoutObj pipeline_layout(&test_device); 1690 1691 VkPipelineRasterizationStateCreateInfo rs_ci = {}; 1692 rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 1693 rs_ci.pNext = nullptr; 1694 rs_ci.lineWidth = 1.0f; 1695 rs_ci.rasterizerDiscardEnable = VK_TRUE; 1696 1697 VkShaderObj vs(&test_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 1698 VkShaderObj fs(&test_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 1699 1700 // Set polygonMode to unsupported value POINT, should fail 1701 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 1702 "polygonMode cannot be VK_POLYGON_MODE_POINT or VK_POLYGON_MODE_LINE"); 1703 { 1704 VkPipelineObj pipe(&test_device); 1705 pipe.AddShader(&vs); 1706 pipe.AddShader(&fs); 1707 pipe.AddDefaultColorAttachment(); 1708 // Introduce failure by setting unsupported polygon mode 1709 rs_ci.polygonMode = VK_POLYGON_MODE_POINT; 1710 pipe.SetRasterization(&rs_ci); 1711 pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle()); 1712 } 1713 m_errorMonitor->VerifyFound(); 1714 1715 // Try again with polygonMode=LINE, should fail 1716 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 1717 "polygonMode cannot be VK_POLYGON_MODE_POINT or VK_POLYGON_MODE_LINE"); 1718 { 1719 VkPipelineObj pipe(&test_device); 1720 pipe.AddShader(&vs); 1721 pipe.AddShader(&fs); 1722 pipe.AddDefaultColorAttachment(); 1723 // Introduce failure by setting unsupported polygon mode 1724 rs_ci.polygonMode = VK_POLYGON_MODE_LINE; 1725 pipe.SetRasterization(&rs_ci); 1726 pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle()); 1727 } 1728 m_errorMonitor->VerifyFound(); 1729 } 1730 1731 TEST_F(VkLayerTest, SparseBindingImageBufferCreate) { 1732 TEST_DESCRIPTION("Create buffer/image with sparse attributes but without the sparse_binding bit set"); 1733 1734 ASSERT_NO_FATAL_FAILURE(Init()); 1735 1736 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0140072c); 1737 VkBuffer buffer; 1738 VkBufferCreateInfo buf_info = {}; 1739 buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 1740 buf_info.pNext = NULL; 1741 buf_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; 1742 buf_info.size = 2048; 1743 buf_info.queueFamilyIndexCount = 0; 1744 buf_info.pQueueFamilyIndices = NULL; 1745 buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 1746 buf_info.flags = VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT; 1747 vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer); 1748 m_errorMonitor->VerifyFound(); 1749 1750 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e007b6); 1751 VkImage image; 1752 VkImageCreateInfo image_create_info = {}; 1753 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 1754 image_create_info.pNext = NULL; 1755 image_create_info.imageType = VK_IMAGE_TYPE_2D; 1756 image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM; 1757 image_create_info.extent.width = 512; 1758 image_create_info.extent.height = 64; 1759 image_create_info.extent.depth = 1; 1760 image_create_info.mipLevels = 1; 1761 image_create_info.arrayLayers = 1; 1762 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 1763 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 1764 image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; 1765 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 1766 image_create_info.queueFamilyIndexCount = 0; 1767 image_create_info.pQueueFamilyIndices = NULL; 1768 image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 1769 image_create_info.flags = VK_BUFFER_CREATE_SPARSE_ALIASED_BIT; 1770 vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 1771 m_errorMonitor->VerifyFound(); 1772 } 1773 1774 TEST_F(VkLayerTest, SparseResidencyImageCreateUnsupportedTypes) { 1775 TEST_DESCRIPTION("Create images with sparse residency with unsupported types"); 1776 1777 // Determine which device feature are available 1778 VkPhysicalDeviceFeatures device_features = {}; 1779 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 1780 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features)); 1781 1782 // Mask out device features we don't want and initialize device state 1783 device_features.sparseResidencyImage2D = VK_FALSE; 1784 device_features.sparseResidencyImage3D = VK_FALSE; 1785 ASSERT_NO_FATAL_FAILURE(InitState(&device_features)); 1786 1787 VkImage image = VK_NULL_HANDLE; 1788 VkResult result = VK_RESULT_MAX_ENUM; 1789 VkImageCreateInfo image_create_info = {}; 1790 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 1791 image_create_info.pNext = NULL; 1792 image_create_info.imageType = VK_IMAGE_TYPE_1D; 1793 image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM; 1794 image_create_info.extent.width = 512; 1795 image_create_info.extent.height = 1; 1796 image_create_info.extent.depth = 1; 1797 image_create_info.mipLevels = 1; 1798 image_create_info.arrayLayers = 1; 1799 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 1800 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 1801 image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; 1802 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 1803 image_create_info.queueFamilyIndexCount = 0; 1804 image_create_info.pQueueFamilyIndices = NULL; 1805 image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 1806 image_create_info.flags = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_BUFFER_CREATE_SPARSE_BINDING_BIT; 1807 1808 // 1D image w/ sparse residency is an error 1809 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00794); 1810 result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 1811 m_errorMonitor->VerifyFound(); 1812 if (VK_SUCCESS == result) { 1813 vkDestroyImage(m_device->device(), image, NULL); 1814 image = VK_NULL_HANDLE; 1815 } 1816 1817 // 2D image w/ sparse residency when feature isn't available 1818 image_create_info.imageType = VK_IMAGE_TYPE_2D; 1819 image_create_info.extent.height = 64; 1820 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00796); 1821 result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 1822 m_errorMonitor->VerifyFound(); 1823 if (VK_SUCCESS == result) { 1824 vkDestroyImage(m_device->device(), image, NULL); 1825 image = VK_NULL_HANDLE; 1826 } 1827 1828 // 3D image w/ sparse residency when feature isn't available 1829 image_create_info.imageType = VK_IMAGE_TYPE_3D; 1830 image_create_info.extent.depth = 8; 1831 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00798); 1832 result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 1833 m_errorMonitor->VerifyFound(); 1834 if (VK_SUCCESS == result) { 1835 vkDestroyImage(m_device->device(), image, NULL); 1836 image = VK_NULL_HANDLE; 1837 } 1838 } 1839 1840 TEST_F(VkLayerTest, SparseResidencyImageCreateUnsupportedSamples) { 1841 TEST_DESCRIPTION("Create images with sparse residency with unsupported tiling or sample counts"); 1842 1843 // Determine which device feature are available 1844 VkPhysicalDeviceFeatures device_features = {}; 1845 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 1846 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features)); 1847 1848 // These tests require that the device support sparse residency for 2D images 1849 if (VK_TRUE != device_features.sparseResidencyImage2D) { 1850 printf(" Test requires unsupported SparseResidencyImage2D feature. Skipped.\n"); 1851 return; 1852 } 1853 1854 // Mask out device features we don't want and initialize device state 1855 device_features.sparseResidency2Samples = VK_FALSE; 1856 device_features.sparseResidency4Samples = VK_FALSE; 1857 device_features.sparseResidency8Samples = VK_FALSE; 1858 device_features.sparseResidency16Samples = VK_FALSE; 1859 ASSERT_NO_FATAL_FAILURE(InitState(&device_features)); 1860 1861 VkImage image = VK_NULL_HANDLE; 1862 VkResult result = VK_RESULT_MAX_ENUM; 1863 VkImageCreateInfo image_create_info = {}; 1864 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 1865 image_create_info.pNext = NULL; 1866 image_create_info.imageType = VK_IMAGE_TYPE_2D; 1867 image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM; 1868 image_create_info.extent.width = 64; 1869 image_create_info.extent.height = 64; 1870 image_create_info.extent.depth = 1; 1871 image_create_info.mipLevels = 1; 1872 image_create_info.arrayLayers = 1; 1873 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 1874 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 1875 image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; 1876 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 1877 image_create_info.queueFamilyIndexCount = 0; 1878 image_create_info.pQueueFamilyIndices = NULL; 1879 image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 1880 image_create_info.flags = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_BUFFER_CREATE_SPARSE_BINDING_BIT; 1881 1882 // 2D image w/ sparse residency and linear tiling is an error 1883 m_errorMonitor->SetDesiredFailureMsg( 1884 VK_DEBUG_REPORT_ERROR_BIT_EXT, 1885 "VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT then image tiling of VK_IMAGE_TILING_LINEAR is not supported"); 1886 result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 1887 m_errorMonitor->VerifyFound(); 1888 if (VK_SUCCESS == result) { 1889 vkDestroyImage(m_device->device(), image, NULL); 1890 image = VK_NULL_HANDLE; 1891 } 1892 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 1893 1894 // Multi-sample image w/ sparse residency when feature isn't available (4 flavors) 1895 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT; 1896 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e0079a); 1897 result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 1898 m_errorMonitor->VerifyFound(); 1899 if (VK_SUCCESS == result) { 1900 vkDestroyImage(m_device->device(), image, NULL); 1901 image = VK_NULL_HANDLE; 1902 } 1903 1904 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; 1905 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e0079c); 1906 result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 1907 m_errorMonitor->VerifyFound(); 1908 if (VK_SUCCESS == result) { 1909 vkDestroyImage(m_device->device(), image, NULL); 1910 image = VK_NULL_HANDLE; 1911 } 1912 1913 image_create_info.samples = VK_SAMPLE_COUNT_8_BIT; 1914 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e0079e); 1915 result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 1916 m_errorMonitor->VerifyFound(); 1917 if (VK_SUCCESS == result) { 1918 vkDestroyImage(m_device->device(), image, NULL); 1919 image = VK_NULL_HANDLE; 1920 } 1921 1922 image_create_info.samples = VK_SAMPLE_COUNT_16_BIT; 1923 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e007a0); 1924 result = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 1925 m_errorMonitor->VerifyFound(); 1926 if (VK_SUCCESS == result) { 1927 vkDestroyImage(m_device->device(), image, NULL); 1928 image = VK_NULL_HANDLE; 1929 } 1930 } 1931 1932 TEST_F(VkLayerTest, InvalidMemoryAliasing) { 1933 TEST_DESCRIPTION( 1934 "Create a buffer and image, allocate memory, and bind the buffer and image to memory such that they will alias."); 1935 VkResult err; 1936 bool pass; 1937 ASSERT_NO_FATAL_FAILURE(Init()); 1938 1939 VkBuffer buffer, buffer2; 1940 VkImage image; 1941 VkImage image2; 1942 VkDeviceMemory mem; // buffer will be bound first 1943 VkDeviceMemory mem_img; // image bound first 1944 VkMemoryRequirements buff_mem_reqs, img_mem_reqs; 1945 VkMemoryRequirements buff_mem_reqs2, img_mem_reqs2; 1946 1947 VkBufferCreateInfo buf_info = {}; 1948 buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 1949 buf_info.pNext = NULL; 1950 buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 1951 buf_info.size = 256; 1952 buf_info.queueFamilyIndexCount = 0; 1953 buf_info.pQueueFamilyIndices = NULL; 1954 buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 1955 buf_info.flags = 0; 1956 err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer); 1957 ASSERT_VK_SUCCESS(err); 1958 1959 vkGetBufferMemoryRequirements(m_device->device(), buffer, &buff_mem_reqs); 1960 1961 VkImageCreateInfo image_create_info = {}; 1962 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 1963 image_create_info.pNext = NULL; 1964 image_create_info.imageType = VK_IMAGE_TYPE_2D; 1965 image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM; 1966 image_create_info.extent.width = 64; 1967 image_create_info.extent.height = 64; 1968 image_create_info.extent.depth = 1; 1969 image_create_info.mipLevels = 1; 1970 image_create_info.arrayLayers = 1; 1971 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 1972 // Image tiling must be optimal to trigger error when aliasing linear buffer 1973 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 1974 image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; 1975 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 1976 image_create_info.queueFamilyIndexCount = 0; 1977 image_create_info.pQueueFamilyIndices = NULL; 1978 image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 1979 image_create_info.flags = 0; 1980 1981 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 1982 ASSERT_VK_SUCCESS(err); 1983 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image2); 1984 ASSERT_VK_SUCCESS(err); 1985 1986 vkGetImageMemoryRequirements(m_device->device(), image, &img_mem_reqs); 1987 1988 VkMemoryAllocateInfo alloc_info = {}; 1989 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 1990 alloc_info.pNext = NULL; 1991 alloc_info.memoryTypeIndex = 0; 1992 // Ensure memory is big enough for both bindings 1993 alloc_info.allocationSize = buff_mem_reqs.size + img_mem_reqs.size; 1994 pass = m_device->phy().set_memory_type(buff_mem_reqs.memoryTypeBits & img_mem_reqs.memoryTypeBits, &alloc_info, 1995 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); 1996 if (!pass) { 1997 vkDestroyBuffer(m_device->device(), buffer, NULL); 1998 vkDestroyImage(m_device->device(), image, NULL); 1999 vkDestroyImage(m_device->device(), image2, NULL); 2000 return; 2001 } 2002 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem); 2003 ASSERT_VK_SUCCESS(err); 2004 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0); 2005 ASSERT_VK_SUCCESS(err); 2006 2007 vkGetImageMemoryRequirements(m_device->device(), image2, &img_mem_reqs2); 2008 2009 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, " is aliased with linear buffer 0x"); 2010 // VALIDATION FAILURE due to image mapping overlapping buffer mapping 2011 err = vkBindImageMemory(m_device->device(), image, mem, 0); 2012 m_errorMonitor->VerifyFound(); 2013 2014 // Now correctly bind image2 to second mem allocation before incorrectly 2015 // aliasing buffer2 2016 err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer2); 2017 ASSERT_VK_SUCCESS(err); 2018 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem_img); 2019 ASSERT_VK_SUCCESS(err); 2020 err = vkBindImageMemory(m_device->device(), image2, mem_img, 0); 2021 ASSERT_VK_SUCCESS(err); 2022 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "is aliased with non-linear image 0x"); 2023 vkGetBufferMemoryRequirements(m_device->device(), buffer2, &buff_mem_reqs2); 2024 err = vkBindBufferMemory(m_device->device(), buffer2, mem_img, 0); 2025 m_errorMonitor->VerifyFound(); 2026 2027 vkDestroyBuffer(m_device->device(), buffer, NULL); 2028 vkDestroyBuffer(m_device->device(), buffer2, NULL); 2029 vkDestroyImage(m_device->device(), image, NULL); 2030 vkDestroyImage(m_device->device(), image2, NULL); 2031 vkFreeMemory(m_device->device(), mem, NULL); 2032 vkFreeMemory(m_device->device(), mem_img, NULL); 2033 } 2034 2035 TEST_F(VkLayerTest, InvalidMemoryMapping) { 2036 TEST_DESCRIPTION("Attempt to map memory in a number of incorrect ways"); 2037 VkResult err; 2038 bool pass; 2039 ASSERT_NO_FATAL_FAILURE(Init()); 2040 2041 VkBuffer buffer; 2042 VkDeviceMemory mem; 2043 VkMemoryRequirements mem_reqs; 2044 2045 const VkDeviceSize atom_size = m_device->props.limits.nonCoherentAtomSize; 2046 2047 VkBufferCreateInfo buf_info = {}; 2048 buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 2049 buf_info.pNext = NULL; 2050 buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 2051 buf_info.size = 256; 2052 buf_info.queueFamilyIndexCount = 0; 2053 buf_info.pQueueFamilyIndices = NULL; 2054 buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 2055 buf_info.flags = 0; 2056 err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer); 2057 ASSERT_VK_SUCCESS(err); 2058 2059 vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs); 2060 VkMemoryAllocateInfo alloc_info = {}; 2061 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 2062 alloc_info.pNext = NULL; 2063 alloc_info.memoryTypeIndex = 0; 2064 2065 // Ensure memory is big enough for both bindings 2066 static const VkDeviceSize allocation_size = 0x10000; 2067 alloc_info.allocationSize = allocation_size; 2068 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); 2069 if (!pass) { 2070 vkDestroyBuffer(m_device->device(), buffer, NULL); 2071 return; 2072 } 2073 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem); 2074 ASSERT_VK_SUCCESS(err); 2075 2076 uint8_t *pData; 2077 // Attempt to map memory size 0 is invalid 2078 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VkMapMemory: Attempting to map memory range of size zero"); 2079 err = vkMapMemory(m_device->device(), mem, 0, 0, 0, (void **)&pData); 2080 m_errorMonitor->VerifyFound(); 2081 // Map memory twice 2082 err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData); 2083 ASSERT_VK_SUCCESS(err); 2084 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 2085 "VkMapMemory: Attempting to map memory on an already-mapped object "); 2086 err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData); 2087 m_errorMonitor->VerifyFound(); 2088 2089 // Unmap the memory to avoid re-map error 2090 vkUnmapMemory(m_device->device(), mem); 2091 // overstep allocation with VK_WHOLE_SIZE 2092 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 2093 " with size of VK_WHOLE_SIZE oversteps total array size 0x"); 2094 err = vkMapMemory(m_device->device(), mem, allocation_size + 1, VK_WHOLE_SIZE, 0, (void **)&pData); 2095 m_errorMonitor->VerifyFound(); 2096 // overstep allocation w/o VK_WHOLE_SIZE 2097 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " oversteps total array size 0x"); 2098 err = vkMapMemory(m_device->device(), mem, 1, allocation_size, 0, (void **)&pData); 2099 m_errorMonitor->VerifyFound(); 2100 // Now error due to unmapping memory that's not mapped 2101 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Unmapping Memory without memory being mapped: "); 2102 vkUnmapMemory(m_device->device(), mem); 2103 m_errorMonitor->VerifyFound(); 2104 2105 // Now map memory and cause errors due to flushing invalid ranges 2106 err = vkMapMemory(m_device->device(), mem, 4 * atom_size, VK_WHOLE_SIZE, 0, (void **)&pData); 2107 ASSERT_VK_SUCCESS(err); 2108 VkMappedMemoryRange mmr = {}; 2109 mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; 2110 mmr.memory = mem; 2111 mmr.offset = atom_size; // Error b/c offset less than offset of mapped mem 2112 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0c20055a); 2113 vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr); 2114 m_errorMonitor->VerifyFound(); 2115 2116 // Now flush range that oversteps mapped range 2117 vkUnmapMemory(m_device->device(), mem); 2118 err = vkMapMemory(m_device->device(), mem, 0, 4 * atom_size, 0, (void **)&pData); 2119 ASSERT_VK_SUCCESS(err); 2120 mmr.offset = atom_size; 2121 mmr.size = 4 * atom_size; // Flushing bounds exceed mapped bounds 2122 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0c20055a); 2123 vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr); 2124 m_errorMonitor->VerifyFound(); 2125 2126 // Now flush range with VK_WHOLE_SIZE that oversteps offset 2127 vkUnmapMemory(m_device->device(), mem); 2128 err = vkMapMemory(m_device->device(), mem, 2 * atom_size, 4 * atom_size, 0, (void **)&pData); 2129 ASSERT_VK_SUCCESS(err); 2130 mmr.offset = atom_size; 2131 mmr.size = VK_WHOLE_SIZE; 2132 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0c20055c); 2133 vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr); 2134 m_errorMonitor->VerifyFound(); 2135 2136 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 2137 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); 2138 if (!pass) { 2139 vkFreeMemory(m_device->device(), mem, NULL); 2140 vkDestroyBuffer(m_device->device(), buffer, NULL); 2141 return; 2142 } 2143 // TODO : If we can get HOST_VISIBLE w/o HOST_COHERENT we can test cases of 2144 // MEMTRACK_INVALID_MAP in validateAndCopyNoncoherentMemoryToDriver() 2145 2146 vkDestroyBuffer(m_device->device(), buffer, NULL); 2147 vkFreeMemory(m_device->device(), mem, NULL); 2148 } 2149 2150 TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit) { 2151 VkResult err; 2152 bool pass; 2153 2154 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 2155 "Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT"); 2156 2157 ASSERT_NO_FATAL_FAILURE(Init()); 2158 2159 // Create an image, allocate memory, free it, and then try to bind it 2160 VkImage image; 2161 VkDeviceMemory mem; 2162 VkMemoryRequirements mem_reqs; 2163 2164 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 2165 const int32_t tex_width = 32; 2166 const int32_t tex_height = 32; 2167 2168 VkImageCreateInfo image_create_info = {}; 2169 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 2170 image_create_info.pNext = NULL; 2171 image_create_info.imageType = VK_IMAGE_TYPE_2D; 2172 image_create_info.format = tex_format; 2173 image_create_info.extent.width = tex_width; 2174 image_create_info.extent.height = tex_height; 2175 image_create_info.extent.depth = 1; 2176 image_create_info.mipLevels = 1; 2177 image_create_info.arrayLayers = 1; 2178 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 2179 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 2180 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 2181 image_create_info.flags = 0; 2182 image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; 2183 2184 VkMemoryAllocateInfo mem_alloc = {}; 2185 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 2186 mem_alloc.pNext = NULL; 2187 mem_alloc.allocationSize = 0; 2188 2189 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 2190 ASSERT_VK_SUCCESS(err); 2191 2192 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs); 2193 2194 mem_alloc.allocationSize = mem_reqs.size; 2195 2196 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); 2197 if (!pass) { // If we can't find any unmappable memory this test doesn't 2198 // make sense 2199 vkDestroyImage(m_device->device(), image, NULL); 2200 return; 2201 } 2202 2203 // allocate memory 2204 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem); 2205 ASSERT_VK_SUCCESS(err); 2206 2207 // Try to bind free memory that has been freed 2208 err = vkBindImageMemory(m_device->device(), image, mem, 0); 2209 ASSERT_VK_SUCCESS(err); 2210 2211 // Map memory as if to initialize the image 2212 void *mappedAddress = NULL; 2213 err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, &mappedAddress); 2214 2215 m_errorMonitor->VerifyFound(); 2216 2217 vkDestroyImage(m_device->device(), image, NULL); 2218 vkFreeMemory(m_device->device(), mem, NULL); 2219 } 2220 2221 TEST_F(VkLayerTest, RebindMemory) { 2222 VkResult err; 2223 bool pass; 2224 2225 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "which has already been bound to mem object"); 2226 2227 ASSERT_NO_FATAL_FAILURE(Init()); 2228 2229 // Create an image, allocate memory, free it, and then try to bind it 2230 VkImage image; 2231 VkDeviceMemory mem1; 2232 VkDeviceMemory mem2; 2233 VkMemoryRequirements mem_reqs; 2234 2235 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 2236 const int32_t tex_width = 32; 2237 const int32_t tex_height = 32; 2238 2239 VkImageCreateInfo image_create_info = {}; 2240 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 2241 image_create_info.pNext = NULL; 2242 image_create_info.imageType = VK_IMAGE_TYPE_2D; 2243 image_create_info.format = tex_format; 2244 image_create_info.extent.width = tex_width; 2245 image_create_info.extent.height = tex_height; 2246 image_create_info.extent.depth = 1; 2247 image_create_info.mipLevels = 1; 2248 image_create_info.arrayLayers = 1; 2249 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 2250 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 2251 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 2252 image_create_info.flags = 0; 2253 2254 VkMemoryAllocateInfo mem_alloc = {}; 2255 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 2256 mem_alloc.pNext = NULL; 2257 mem_alloc.allocationSize = 0; 2258 mem_alloc.memoryTypeIndex = 0; 2259 2260 // Introduce failure, do NOT set memProps to 2261 // VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT 2262 mem_alloc.memoryTypeIndex = 1; 2263 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 2264 ASSERT_VK_SUCCESS(err); 2265 2266 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs); 2267 2268 mem_alloc.allocationSize = mem_reqs.size; 2269 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0); 2270 ASSERT_TRUE(pass); 2271 2272 // allocate 2 memory objects 2273 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem1); 2274 ASSERT_VK_SUCCESS(err); 2275 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem2); 2276 ASSERT_VK_SUCCESS(err); 2277 2278 // Bind first memory object to Image object 2279 err = vkBindImageMemory(m_device->device(), image, mem1, 0); 2280 ASSERT_VK_SUCCESS(err); 2281 2282 // Introduce validation failure, try to bind a different memory object to 2283 // the same image object 2284 err = vkBindImageMemory(m_device->device(), image, mem2, 0); 2285 2286 m_errorMonitor->VerifyFound(); 2287 2288 vkDestroyImage(m_device->device(), image, NULL); 2289 vkFreeMemory(m_device->device(), mem1, NULL); 2290 vkFreeMemory(m_device->device(), mem2, NULL); 2291 } 2292 2293 TEST_F(VkLayerTest, SubmitSignaledFence) { 2294 vk_testing::Fence testFence; 2295 2296 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 2297 "submitted in SIGNALED state. Fences must be reset before being submitted"); 2298 2299 VkFenceCreateInfo fenceInfo = {}; 2300 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 2301 fenceInfo.pNext = NULL; 2302 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; 2303 2304 ASSERT_NO_FATAL_FAILURE(Init()); 2305 ASSERT_NO_FATAL_FAILURE(InitViewport()); 2306 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 2307 2308 m_commandBuffer->begin(); 2309 m_commandBuffer->ClearAllBuffers(m_renderTargets, m_clear_color, nullptr, m_depth_clear_color, m_stencil_clear_color); 2310 m_commandBuffer->end(); 2311 2312 testFence.init(*m_device, fenceInfo); 2313 2314 VkSubmitInfo submit_info; 2315 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 2316 submit_info.pNext = NULL; 2317 submit_info.waitSemaphoreCount = 0; 2318 submit_info.pWaitSemaphores = NULL; 2319 submit_info.pWaitDstStageMask = NULL; 2320 submit_info.commandBufferCount = 1; 2321 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 2322 submit_info.signalSemaphoreCount = 0; 2323 submit_info.pSignalSemaphores = NULL; 2324 2325 vkQueueSubmit(m_device->m_queue, 1, &submit_info, testFence.handle()); 2326 vkQueueWaitIdle(m_device->m_queue); 2327 2328 m_errorMonitor->VerifyFound(); 2329 } 2330 2331 TEST_F(VkLayerTest, InvalidUsageBits) { 2332 TEST_DESCRIPTION( 2333 "Specify wrong usage for image then create conflicting view of image Initialize buffer with wrong usage then perform copy " 2334 "expecting errors from both the image and the buffer (2 calls)"); 2335 2336 ASSERT_NO_FATAL_FAILURE(Init()); 2337 auto format = FindSupportedDepthStencilFormat(gpu()); 2338 if (!format) { 2339 printf(" No Depth + Stencil format found. Skipped.\n"); 2340 return; 2341 } 2342 2343 VkImageObj image(m_device); 2344 // Initialize image with transfer source usage 2345 image.Init(128, 128, 1, format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 2346 ASSERT_TRUE(image.initialized()); 2347 2348 VkImageView dsv; 2349 VkImageViewCreateInfo dsvci = {}; 2350 dsvci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 2351 dsvci.image = image.handle(); 2352 dsvci.viewType = VK_IMAGE_VIEW_TYPE_2D; 2353 dsvci.format = format; 2354 dsvci.subresourceRange.layerCount = 1; 2355 dsvci.subresourceRange.baseMipLevel = 0; 2356 dsvci.subresourceRange.levelCount = 1; 2357 dsvci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 2358 2359 // Create a view with depth / stencil aspect for image with different usage 2360 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid usage flag for Image "); 2361 vkCreateImageView(m_device->device(), &dsvci, NULL, &dsv); 2362 m_errorMonitor->VerifyFound(); 2363 2364 // Initialize buffer with TRANSFER_DST usage 2365 vk_testing::Buffer buffer; 2366 VkMemoryPropertyFlags reqs = 0; 2367 buffer.init_as_dst(*m_device, 128 * 128, reqs); 2368 VkBufferImageCopy region = {}; 2369 region.bufferRowLength = 128; 2370 region.bufferImageHeight = 128; 2371 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 2372 region.imageSubresource.layerCount = 1; 2373 region.imageExtent.height = 16; 2374 region.imageExtent.width = 16; 2375 region.imageExtent.depth = 1; 2376 2377 // Buffer usage not set to TRANSFER_SRC and image usage not set to TRANSFER_DST 2378 m_commandBuffer->begin(); 2379 2380 // two separate errors from this call: 2381 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18e00162); 2382 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18e0015c); 2383 2384 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 2385 ®ion); 2386 m_errorMonitor->VerifyFound(); 2387 } 2388 2389 TEST_F(VkLayerTest, LeakAnObject) { 2390 VkResult err; 2391 2392 TEST_DESCRIPTION("Create a fence and destroy its device without first destroying the fence."); 2393 2394 // Note that we have to create a new device since destroying the 2395 // framework's device causes Teardown() to fail and just calling Teardown 2396 // will destroy the errorMonitor. 2397 2398 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "has not been destroyed."); 2399 2400 ASSERT_NO_FATAL_FAILURE(Init()); 2401 2402 vk_testing::QueueCreateInfoArray queue_info(m_device->queue_props); 2403 2404 // The sacrificial device object 2405 VkDevice testDevice; 2406 VkDeviceCreateInfo device_create_info = {}; 2407 auto features = m_device->phy().features(); 2408 device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; 2409 device_create_info.pNext = NULL; 2410 device_create_info.queueCreateInfoCount = queue_info.size(); 2411 device_create_info.pQueueCreateInfos = queue_info.data(); 2412 device_create_info.enabledLayerCount = 0; 2413 device_create_info.ppEnabledLayerNames = NULL; 2414 device_create_info.pEnabledFeatures = &features; 2415 err = vkCreateDevice(gpu(), &device_create_info, NULL, &testDevice); 2416 ASSERT_VK_SUCCESS(err); 2417 2418 VkFence fence; 2419 VkFenceCreateInfo fence_create_info = {}; 2420 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 2421 fence_create_info.pNext = NULL; 2422 fence_create_info.flags = 0; 2423 err = vkCreateFence(testDevice, &fence_create_info, NULL, &fence); 2424 ASSERT_VK_SUCCESS(err); 2425 2426 // Induce failure by not calling vkDestroyFence 2427 vkDestroyDevice(testDevice, NULL); 2428 m_errorMonitor->VerifyFound(); 2429 } 2430 2431 TEST_F(VkLayerTest, InvalidCommandPoolConsistency) { 2432 TEST_DESCRIPTION("Allocate command buffers from one command pool and attempt to delete them from another."); 2433 2434 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "FreeCommandBuffers is attempting to free Command Buffer"); 2435 2436 ASSERT_NO_FATAL_FAILURE(Init()); 2437 VkCommandPool command_pool_one; 2438 VkCommandPool command_pool_two; 2439 2440 VkCommandPoolCreateInfo pool_create_info{}; 2441 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 2442 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 2443 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 2444 2445 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_one); 2446 2447 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_two); 2448 2449 VkCommandBuffer cb; 2450 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 2451 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 2452 command_buffer_allocate_info.commandPool = command_pool_one; 2453 command_buffer_allocate_info.commandBufferCount = 1; 2454 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 2455 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &cb); 2456 2457 vkFreeCommandBuffers(m_device->device(), command_pool_two, 1, &cb); 2458 2459 m_errorMonitor->VerifyFound(); 2460 2461 vkDestroyCommandPool(m_device->device(), command_pool_one, NULL); 2462 vkDestroyCommandPool(m_device->device(), command_pool_two, NULL); 2463 } 2464 2465 TEST_F(VkLayerTest, InvalidDescriptorPoolConsistency) { 2466 VkResult err; 2467 2468 TEST_DESCRIPTION("Allocate descriptor sets from one DS pool and attempt to delete them from another."); 2469 2470 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "FreeDescriptorSets is attempting to free descriptorSet"); 2471 2472 ASSERT_NO_FATAL_FAILURE(Init()); 2473 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 2474 2475 VkDescriptorPoolSize ds_type_count = {}; 2476 ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER; 2477 ds_type_count.descriptorCount = 1; 2478 2479 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 2480 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 2481 ds_pool_ci.pNext = NULL; 2482 ds_pool_ci.flags = 0; 2483 ds_pool_ci.maxSets = 1; 2484 ds_pool_ci.poolSizeCount = 1; 2485 ds_pool_ci.pPoolSizes = &ds_type_count; 2486 2487 VkDescriptorPool bad_pool; 2488 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &bad_pool); 2489 ASSERT_VK_SUCCESS(err); 2490 2491 OneOffDescriptorSet ds(m_device, { 2492 {0, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr}, 2493 }); 2494 2495 err = vkFreeDescriptorSets(m_device->device(), bad_pool, 1, &ds.set_); 2496 2497 m_errorMonitor->VerifyFound(); 2498 2499 vkDestroyDescriptorPool(m_device->device(), bad_pool, NULL); 2500 } 2501 2502 TEST_F(VkLayerTest, CreateUnknownObject) { 2503 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_2a20a001); 2504 2505 TEST_DESCRIPTION("Pass an invalid image object handle into a Vulkan API call."); 2506 2507 ASSERT_NO_FATAL_FAILURE(Init()); 2508 2509 // Pass bogus handle into GetImageMemoryRequirements 2510 VkMemoryRequirements mem_reqs; 2511 uint64_t fakeImageHandle = 0xCADECADE; 2512 VkImage fauxImage = reinterpret_cast<VkImage &>(fakeImageHandle); 2513 2514 vkGetImageMemoryRequirements(m_device->device(), fauxImage, &mem_reqs); 2515 2516 m_errorMonitor->VerifyFound(); 2517 } 2518 2519 TEST_F(VkLayerTest, UseObjectWithWrongDevice) { 2520 TEST_DESCRIPTION( 2521 "Try to destroy a render pass object using a device other than the one it was created on. This should generate a distinct " 2522 "error from the invalid handle error."); 2523 // Create first device and renderpass 2524 ASSERT_NO_FATAL_FAILURE(Init()); 2525 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 2526 2527 // Create second device 2528 float priorities[] = {1.0f}; 2529 VkDeviceQueueCreateInfo queue_info{}; 2530 queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 2531 queue_info.pNext = NULL; 2532 queue_info.flags = 0; 2533 queue_info.queueFamilyIndex = 0; 2534 queue_info.queueCount = 1; 2535 queue_info.pQueuePriorities = &priorities[0]; 2536 2537 VkDeviceCreateInfo device_create_info = {}; 2538 auto features = m_device->phy().features(); 2539 device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; 2540 device_create_info.pNext = NULL; 2541 device_create_info.queueCreateInfoCount = 1; 2542 device_create_info.pQueueCreateInfos = &queue_info; 2543 device_create_info.enabledLayerCount = 0; 2544 device_create_info.ppEnabledLayerNames = NULL; 2545 device_create_info.pEnabledFeatures = &features; 2546 2547 VkDevice second_device; 2548 ASSERT_VK_SUCCESS(vkCreateDevice(gpu(), &device_create_info, NULL, &second_device)); 2549 2550 // Try to destroy the renderpass from the first device using the second device 2551 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_2642ae07); 2552 vkDestroyRenderPass(second_device, m_renderPass, NULL); 2553 m_errorMonitor->VerifyFound(); 2554 2555 vkDestroyDevice(second_device, NULL); 2556 } 2557 2558 TEST_F(VkLayerTest, PipelineNotBound) { 2559 TEST_DESCRIPTION("Pass in an invalid pipeline object handle into a Vulkan API call."); 2560 2561 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18027c01); 2562 2563 ASSERT_NO_FATAL_FAILURE(Init()); 2564 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 2565 2566 VkPipeline badPipeline = (VkPipeline)((size_t)0xbaadb1be); 2567 2568 m_commandBuffer->begin(); 2569 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline); 2570 2571 m_errorMonitor->VerifyFound(); 2572 } 2573 2574 TEST_F(VkLayerTest, BindImageInvalidMemoryType) { 2575 VkResult err; 2576 2577 TEST_DESCRIPTION("Test validation check for an invalid memory type index during bind[Buffer|Image]Memory time"); 2578 2579 ASSERT_NO_FATAL_FAILURE(Init()); 2580 2581 // Create an image, allocate memory, set a bad typeIndex and then try to 2582 // bind it 2583 VkImage image; 2584 VkDeviceMemory mem; 2585 VkMemoryRequirements mem_reqs; 2586 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 2587 const int32_t tex_width = 32; 2588 const int32_t tex_height = 32; 2589 2590 VkImageCreateInfo image_create_info = {}; 2591 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 2592 image_create_info.pNext = NULL; 2593 image_create_info.imageType = VK_IMAGE_TYPE_2D; 2594 image_create_info.format = tex_format; 2595 image_create_info.extent.width = tex_width; 2596 image_create_info.extent.height = tex_height; 2597 image_create_info.extent.depth = 1; 2598 image_create_info.mipLevels = 1; 2599 image_create_info.arrayLayers = 1; 2600 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 2601 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 2602 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 2603 image_create_info.flags = 0; 2604 2605 VkMemoryAllocateInfo mem_alloc = {}; 2606 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 2607 mem_alloc.pNext = NULL; 2608 mem_alloc.allocationSize = 0; 2609 mem_alloc.memoryTypeIndex = 0; 2610 2611 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 2612 ASSERT_VK_SUCCESS(err); 2613 2614 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs); 2615 mem_alloc.allocationSize = mem_reqs.size; 2616 2617 // Introduce Failure, select invalid TypeIndex 2618 VkPhysicalDeviceMemoryProperties memory_info; 2619 2620 vkGetPhysicalDeviceMemoryProperties(gpu(), &memory_info); 2621 unsigned int i; 2622 for (i = 0; i < memory_info.memoryTypeCount; i++) { 2623 if ((mem_reqs.memoryTypeBits & (1 << i)) == 0) { 2624 mem_alloc.memoryTypeIndex = i; 2625 break; 2626 } 2627 } 2628 if (i >= memory_info.memoryTypeCount) { 2629 printf(" No invalid memory type index could be found; skipped.\n"); 2630 vkDestroyImage(m_device->device(), image, NULL); 2631 return; 2632 } 2633 2634 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "for this object type are not compatible with the memory"); 2635 2636 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem); 2637 ASSERT_VK_SUCCESS(err); 2638 2639 err = vkBindImageMemory(m_device->device(), image, mem, 0); 2640 (void)err; 2641 2642 m_errorMonitor->VerifyFound(); 2643 2644 vkDestroyImage(m_device->device(), image, NULL); 2645 vkFreeMemory(m_device->device(), mem, NULL); 2646 } 2647 2648 TEST_F(VkLayerTest, BindInvalidMemory) { 2649 VkResult err; 2650 bool pass; 2651 2652 ASSERT_NO_FATAL_FAILURE(Init()); 2653 2654 const VkFormat tex_format = VK_FORMAT_R8G8B8A8_UNORM; 2655 const int32_t tex_width = 256; 2656 const int32_t tex_height = 256; 2657 2658 VkImageCreateInfo image_create_info = {}; 2659 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 2660 image_create_info.pNext = NULL; 2661 image_create_info.imageType = VK_IMAGE_TYPE_2D; 2662 image_create_info.format = tex_format; 2663 image_create_info.extent.width = tex_width; 2664 image_create_info.extent.height = tex_height; 2665 image_create_info.extent.depth = 1; 2666 image_create_info.mipLevels = 1; 2667 image_create_info.arrayLayers = 1; 2668 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 2669 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 2670 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 2671 image_create_info.flags = 0; 2672 2673 VkBufferCreateInfo buffer_create_info = {}; 2674 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 2675 buffer_create_info.pNext = NULL; 2676 buffer_create_info.flags = 0; 2677 buffer_create_info.size = 4 * 1024 * 1024; 2678 buffer_create_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; 2679 buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 2680 2681 // Create an image/buffer, allocate memory, free it, and then try to bind it 2682 { 2683 VkImage image = VK_NULL_HANDLE; 2684 VkBuffer buffer = VK_NULL_HANDLE; 2685 err = vkCreateImage(device(), &image_create_info, NULL, &image); 2686 ASSERT_VK_SUCCESS(err); 2687 err = vkCreateBuffer(device(), &buffer_create_info, NULL, &buffer); 2688 ASSERT_VK_SUCCESS(err); 2689 VkMemoryRequirements image_mem_reqs = {}, buffer_mem_reqs = {}; 2690 vkGetImageMemoryRequirements(device(), image, &image_mem_reqs); 2691 vkGetBufferMemoryRequirements(device(), buffer, &buffer_mem_reqs); 2692 2693 VkMemoryAllocateInfo image_mem_alloc = {}, buffer_mem_alloc = {}; 2694 image_mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 2695 image_mem_alloc.allocationSize = image_mem_reqs.size; 2696 pass = m_device->phy().set_memory_type(image_mem_reqs.memoryTypeBits, &image_mem_alloc, 0); 2697 ASSERT_TRUE(pass); 2698 buffer_mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 2699 buffer_mem_alloc.allocationSize = buffer_mem_reqs.size; 2700 pass = m_device->phy().set_memory_type(buffer_mem_reqs.memoryTypeBits, &buffer_mem_alloc, 0); 2701 ASSERT_TRUE(pass); 2702 2703 VkDeviceMemory image_mem = VK_NULL_HANDLE, buffer_mem = VK_NULL_HANDLE; 2704 err = vkAllocateMemory(device(), &image_mem_alloc, NULL, &image_mem); 2705 ASSERT_VK_SUCCESS(err); 2706 err = vkAllocateMemory(device(), &buffer_mem_alloc, NULL, &buffer_mem); 2707 ASSERT_VK_SUCCESS(err); 2708 2709 vkFreeMemory(device(), image_mem, NULL); 2710 vkFreeMemory(device(), buffer_mem, NULL); 2711 2712 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1740c601); 2713 err = vkBindImageMemory(device(), image, image_mem, 0); 2714 (void)err; // This may very well return an error. 2715 m_errorMonitor->VerifyFound(); 2716 2717 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1700c601); 2718 err = vkBindBufferMemory(device(), buffer, buffer_mem, 0); 2719 (void)err; // This may very well return an error. 2720 m_errorMonitor->VerifyFound(); 2721 2722 vkDestroyImage(m_device->device(), image, NULL); 2723 vkDestroyBuffer(m_device->device(), buffer, NULL); 2724 } 2725 2726 // Try to bind memory to an object that already has a memory binding 2727 { 2728 VkImage image = VK_NULL_HANDLE; 2729 err = vkCreateImage(device(), &image_create_info, NULL, &image); 2730 ASSERT_VK_SUCCESS(err); 2731 VkBuffer buffer = VK_NULL_HANDLE; 2732 err = vkCreateBuffer(device(), &buffer_create_info, NULL, &buffer); 2733 ASSERT_VK_SUCCESS(err); 2734 VkMemoryRequirements image_mem_reqs = {}, buffer_mem_reqs = {}; 2735 vkGetImageMemoryRequirements(device(), image, &image_mem_reqs); 2736 vkGetBufferMemoryRequirements(device(), buffer, &buffer_mem_reqs); 2737 VkMemoryAllocateInfo image_alloc_info = {}, buffer_alloc_info = {}; 2738 image_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 2739 image_alloc_info.allocationSize = image_mem_reqs.size; 2740 buffer_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 2741 buffer_alloc_info.allocationSize = buffer_mem_reqs.size; 2742 pass = m_device->phy().set_memory_type(image_mem_reqs.memoryTypeBits, &image_alloc_info, 0); 2743 ASSERT_TRUE(pass); 2744 pass = m_device->phy().set_memory_type(buffer_mem_reqs.memoryTypeBits, &buffer_alloc_info, 0); 2745 ASSERT_TRUE(pass); 2746 VkDeviceMemory image_mem, buffer_mem; 2747 err = vkAllocateMemory(device(), &image_alloc_info, NULL, &image_mem); 2748 ASSERT_VK_SUCCESS(err); 2749 err = vkAllocateMemory(device(), &buffer_alloc_info, NULL, &buffer_mem); 2750 ASSERT_VK_SUCCESS(err); 2751 2752 err = vkBindImageMemory(device(), image, image_mem, 0); 2753 ASSERT_VK_SUCCESS(err); 2754 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_17400828); 2755 err = vkBindImageMemory(device(), image, image_mem, 0); 2756 (void)err; // This may very well return an error. 2757 m_errorMonitor->VerifyFound(); 2758 2759 err = vkBindBufferMemory(device(), buffer, buffer_mem, 0); 2760 ASSERT_VK_SUCCESS(err); 2761 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1700080a); 2762 err = vkBindBufferMemory(device(), buffer, buffer_mem, 0); 2763 (void)err; // This may very well return an error. 2764 m_errorMonitor->VerifyFound(); 2765 2766 vkFreeMemory(device(), image_mem, NULL); 2767 vkFreeMemory(device(), buffer_mem, NULL); 2768 vkDestroyImage(device(), image, NULL); 2769 vkDestroyBuffer(device(), buffer, NULL); 2770 } 2771 2772 // Try to bind memory to an object with an invalid memoryOffset 2773 { 2774 VkImage image = VK_NULL_HANDLE; 2775 err = vkCreateImage(device(), &image_create_info, NULL, &image); 2776 ASSERT_VK_SUCCESS(err); 2777 VkBuffer buffer = VK_NULL_HANDLE; 2778 err = vkCreateBuffer(device(), &buffer_create_info, NULL, &buffer); 2779 ASSERT_VK_SUCCESS(err); 2780 VkMemoryRequirements image_mem_reqs = {}, buffer_mem_reqs = {}; 2781 vkGetImageMemoryRequirements(device(), image, &image_mem_reqs); 2782 vkGetBufferMemoryRequirements(device(), buffer, &buffer_mem_reqs); 2783 VkMemoryAllocateInfo image_alloc_info = {}, buffer_alloc_info = {}; 2784 image_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 2785 // Leave some extra space for alignment wiggle room 2786 image_alloc_info.allocationSize = image_mem_reqs.size + image_mem_reqs.alignment; 2787 buffer_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 2788 buffer_alloc_info.allocationSize = buffer_mem_reqs.size + buffer_mem_reqs.alignment; 2789 pass = m_device->phy().set_memory_type(image_mem_reqs.memoryTypeBits, &image_alloc_info, 0); 2790 ASSERT_TRUE(pass); 2791 pass = m_device->phy().set_memory_type(buffer_mem_reqs.memoryTypeBits, &buffer_alloc_info, 0); 2792 ASSERT_TRUE(pass); 2793 VkDeviceMemory image_mem, buffer_mem; 2794 err = vkAllocateMemory(device(), &image_alloc_info, NULL, &image_mem); 2795 ASSERT_VK_SUCCESS(err); 2796 err = vkAllocateMemory(device(), &buffer_alloc_info, NULL, &buffer_mem); 2797 ASSERT_VK_SUCCESS(err); 2798 2799 // Test unaligned memory offset 2800 { 2801 if (image_mem_reqs.alignment > 1) { 2802 VkDeviceSize image_offset = 1; 2803 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_17400830); 2804 err = vkBindImageMemory(device(), image, image_mem, image_offset); 2805 (void)err; // This may very well return an error. 2806 m_errorMonitor->VerifyFound(); 2807 } 2808 2809 if (buffer_mem_reqs.alignment > 1) { 2810 VkDeviceSize buffer_offset = 1; 2811 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_17000818); 2812 err = vkBindBufferMemory(device(), buffer, buffer_mem, buffer_offset); 2813 (void)err; // This may very well return an error. 2814 m_errorMonitor->VerifyFound(); 2815 } 2816 } 2817 2818 // Test memory offsets outside the memory allocation 2819 { 2820 VkDeviceSize image_offset = 2821 (image_alloc_info.allocationSize + image_mem_reqs.alignment) & ~(image_mem_reqs.alignment - 1); 2822 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1740082c); 2823 err = vkBindImageMemory(device(), image, image_mem, image_offset); 2824 (void)err; // This may very well return an error. 2825 m_errorMonitor->VerifyFound(); 2826 2827 VkDeviceSize buffer_offset = 2828 (buffer_alloc_info.allocationSize + buffer_mem_reqs.alignment) & ~(buffer_mem_reqs.alignment - 1); 2829 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1700080e); 2830 err = vkBindBufferMemory(device(), buffer, buffer_mem, buffer_offset); 2831 (void)err; // This may very well return an error. 2832 m_errorMonitor->VerifyFound(); 2833 } 2834 2835 // Test memory offsets within the memory allocation, but which leave too little memory for 2836 // the resource. 2837 { 2838 VkDeviceSize image_offset = (image_mem_reqs.size - 1) & ~(image_mem_reqs.alignment - 1); 2839 if ((image_offset > 0) && (image_mem_reqs.size < (image_alloc_info.allocationSize - image_mem_reqs.alignment))) { 2840 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_17400832); 2841 err = vkBindImageMemory(device(), image, image_mem, image_offset); 2842 (void)err; // This may very well return an error. 2843 m_errorMonitor->VerifyFound(); 2844 } 2845 2846 VkDeviceSize buffer_offset = (buffer_mem_reqs.size - 1) & ~(buffer_mem_reqs.alignment - 1); 2847 if (buffer_offset > 0) { 2848 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1700081a); 2849 err = vkBindBufferMemory(device(), buffer, buffer_mem, buffer_offset); 2850 (void)err; // This may very well return an error. 2851 m_errorMonitor->VerifyFound(); 2852 } 2853 } 2854 2855 vkFreeMemory(device(), image_mem, NULL); 2856 vkFreeMemory(device(), buffer_mem, NULL); 2857 vkDestroyImage(device(), image, NULL); 2858 vkDestroyBuffer(device(), buffer, NULL); 2859 } 2860 2861 // Try to bind memory to an object with an invalid memory type 2862 { 2863 VkImage image = VK_NULL_HANDLE; 2864 err = vkCreateImage(device(), &image_create_info, NULL, &image); 2865 ASSERT_VK_SUCCESS(err); 2866 VkBuffer buffer = VK_NULL_HANDLE; 2867 err = vkCreateBuffer(device(), &buffer_create_info, NULL, &buffer); 2868 ASSERT_VK_SUCCESS(err); 2869 VkMemoryRequirements image_mem_reqs = {}, buffer_mem_reqs = {}; 2870 vkGetImageMemoryRequirements(device(), image, &image_mem_reqs); 2871 vkGetBufferMemoryRequirements(device(), buffer, &buffer_mem_reqs); 2872 VkMemoryAllocateInfo image_alloc_info = {}, buffer_alloc_info = {}; 2873 image_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 2874 image_alloc_info.allocationSize = image_mem_reqs.size; 2875 buffer_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 2876 buffer_alloc_info.allocationSize = buffer_mem_reqs.size; 2877 // Create a mask of available memory types *not* supported by these resources, 2878 // and try to use one of them. 2879 VkPhysicalDeviceMemoryProperties memory_properties = {}; 2880 vkGetPhysicalDeviceMemoryProperties(m_device->phy().handle(), &memory_properties); 2881 VkDeviceMemory image_mem, buffer_mem; 2882 2883 uint32_t image_unsupported_mem_type_bits = ((1 << memory_properties.memoryTypeCount) - 1) & ~image_mem_reqs.memoryTypeBits; 2884 if (image_unsupported_mem_type_bits != 0) { 2885 pass = m_device->phy().set_memory_type(image_unsupported_mem_type_bits, &image_alloc_info, 0); 2886 ASSERT_TRUE(pass); 2887 err = vkAllocateMemory(device(), &image_alloc_info, NULL, &image_mem); 2888 ASSERT_VK_SUCCESS(err); 2889 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1740082e); 2890 err = vkBindImageMemory(device(), image, image_mem, 0); 2891 (void)err; // This may very well return an error. 2892 m_errorMonitor->VerifyFound(); 2893 vkFreeMemory(device(), image_mem, NULL); 2894 } 2895 2896 uint32_t buffer_unsupported_mem_type_bits = 2897 ((1 << memory_properties.memoryTypeCount) - 1) & ~buffer_mem_reqs.memoryTypeBits; 2898 if (buffer_unsupported_mem_type_bits != 0) { 2899 pass = m_device->phy().set_memory_type(buffer_unsupported_mem_type_bits, &buffer_alloc_info, 0); 2900 ASSERT_TRUE(pass); 2901 err = vkAllocateMemory(device(), &buffer_alloc_info, NULL, &buffer_mem); 2902 ASSERT_VK_SUCCESS(err); 2903 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_17000816); 2904 err = vkBindBufferMemory(device(), buffer, buffer_mem, 0); 2905 (void)err; // This may very well return an error. 2906 m_errorMonitor->VerifyFound(); 2907 vkFreeMemory(device(), buffer_mem, NULL); 2908 } 2909 2910 vkDestroyImage(device(), image, NULL); 2911 vkDestroyBuffer(device(), buffer, NULL); 2912 } 2913 2914 // Try to bind memory to an image created with sparse memory flags 2915 { 2916 VkImageCreateInfo sparse_image_create_info = image_create_info; 2917 sparse_image_create_info.flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT; 2918 VkImageFormatProperties image_format_properties = {}; 2919 err = vkGetPhysicalDeviceImageFormatProperties(m_device->phy().handle(), sparse_image_create_info.format, 2920 sparse_image_create_info.imageType, sparse_image_create_info.tiling, 2921 sparse_image_create_info.usage, sparse_image_create_info.flags, 2922 &image_format_properties); 2923 if (!m_device->phy().features().sparseResidencyImage2D || err == VK_ERROR_FORMAT_NOT_SUPPORTED) { 2924 // most likely means sparse formats aren't supported here; skip this test. 2925 } else { 2926 ASSERT_VK_SUCCESS(err); 2927 if (image_format_properties.maxExtent.width == 0) { 2928 printf(" Sparse image format not supported; skipped.\n"); 2929 return; 2930 } else { 2931 VkImage sparse_image = VK_NULL_HANDLE; 2932 err = vkCreateImage(m_device->device(), &sparse_image_create_info, NULL, &sparse_image); 2933 ASSERT_VK_SUCCESS(err); 2934 VkMemoryRequirements sparse_mem_reqs = {}; 2935 vkGetImageMemoryRequirements(m_device->device(), sparse_image, &sparse_mem_reqs); 2936 if (sparse_mem_reqs.memoryTypeBits != 0) { 2937 VkMemoryAllocateInfo sparse_mem_alloc = {}; 2938 sparse_mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 2939 sparse_mem_alloc.pNext = NULL; 2940 sparse_mem_alloc.allocationSize = sparse_mem_reqs.size; 2941 sparse_mem_alloc.memoryTypeIndex = 0; 2942 pass = m_device->phy().set_memory_type(sparse_mem_reqs.memoryTypeBits, &sparse_mem_alloc, 0); 2943 ASSERT_TRUE(pass); 2944 VkDeviceMemory sparse_mem = VK_NULL_HANDLE; 2945 err = vkAllocateMemory(m_device->device(), &sparse_mem_alloc, NULL, &sparse_mem); 2946 ASSERT_VK_SUCCESS(err); 2947 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1740082a); 2948 err = vkBindImageMemory(m_device->device(), sparse_image, sparse_mem, 0); 2949 // This may very well return an error. 2950 (void)err; 2951 m_errorMonitor->VerifyFound(); 2952 vkFreeMemory(m_device->device(), sparse_mem, NULL); 2953 } 2954 vkDestroyImage(m_device->device(), sparse_image, NULL); 2955 } 2956 } 2957 } 2958 2959 // Try to bind memory to a buffer created with sparse memory flags 2960 { 2961 VkBufferCreateInfo sparse_buffer_create_info = buffer_create_info; 2962 sparse_buffer_create_info.flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT; 2963 if (!m_device->phy().features().sparseResidencyBuffer) { 2964 // most likely means sparse formats aren't supported here; skip this test. 2965 } else { 2966 VkBuffer sparse_buffer = VK_NULL_HANDLE; 2967 err = vkCreateBuffer(m_device->device(), &sparse_buffer_create_info, NULL, &sparse_buffer); 2968 ASSERT_VK_SUCCESS(err); 2969 VkMemoryRequirements sparse_mem_reqs = {}; 2970 vkGetBufferMemoryRequirements(m_device->device(), sparse_buffer, &sparse_mem_reqs); 2971 if (sparse_mem_reqs.memoryTypeBits != 0) { 2972 VkMemoryAllocateInfo sparse_mem_alloc = {}; 2973 sparse_mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 2974 sparse_mem_alloc.pNext = NULL; 2975 sparse_mem_alloc.allocationSize = sparse_mem_reqs.size; 2976 sparse_mem_alloc.memoryTypeIndex = 0; 2977 pass = m_device->phy().set_memory_type(sparse_mem_reqs.memoryTypeBits, &sparse_mem_alloc, 0); 2978 ASSERT_TRUE(pass); 2979 VkDeviceMemory sparse_mem = VK_NULL_HANDLE; 2980 err = vkAllocateMemory(m_device->device(), &sparse_mem_alloc, NULL, &sparse_mem); 2981 ASSERT_VK_SUCCESS(err); 2982 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1700080c); 2983 err = vkBindBufferMemory(m_device->device(), sparse_buffer, sparse_mem, 0); 2984 // This may very well return an error. 2985 (void)err; 2986 m_errorMonitor->VerifyFound(); 2987 vkFreeMemory(m_device->device(), sparse_mem, NULL); 2988 } 2989 vkDestroyBuffer(m_device->device(), sparse_buffer, NULL); 2990 } 2991 } 2992 } 2993 2994 TEST_F(VkLayerTest, BindMemoryToDestroyedObject) { 2995 VkResult err; 2996 bool pass; 2997 2998 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1740a001); 2999 3000 ASSERT_NO_FATAL_FAILURE(Init()); 3001 3002 // Create an image object, allocate memory, destroy the object and then try 3003 // to bind it 3004 VkImage image; 3005 VkDeviceMemory mem; 3006 VkMemoryRequirements mem_reqs; 3007 3008 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 3009 const int32_t tex_width = 32; 3010 const int32_t tex_height = 32; 3011 3012 VkImageCreateInfo image_create_info = {}; 3013 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 3014 image_create_info.pNext = NULL; 3015 image_create_info.imageType = VK_IMAGE_TYPE_2D; 3016 image_create_info.format = tex_format; 3017 image_create_info.extent.width = tex_width; 3018 image_create_info.extent.height = tex_height; 3019 image_create_info.extent.depth = 1; 3020 image_create_info.mipLevels = 1; 3021 image_create_info.arrayLayers = 1; 3022 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 3023 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 3024 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 3025 image_create_info.flags = 0; 3026 3027 VkMemoryAllocateInfo mem_alloc = {}; 3028 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 3029 mem_alloc.pNext = NULL; 3030 mem_alloc.allocationSize = 0; 3031 mem_alloc.memoryTypeIndex = 0; 3032 3033 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 3034 ASSERT_VK_SUCCESS(err); 3035 3036 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs); 3037 3038 mem_alloc.allocationSize = mem_reqs.size; 3039 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0); 3040 ASSERT_TRUE(pass); 3041 3042 // Allocate memory 3043 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem); 3044 ASSERT_VK_SUCCESS(err); 3045 3046 // Introduce validation failure, destroy Image object before binding 3047 vkDestroyImage(m_device->device(), image, NULL); 3048 ASSERT_VK_SUCCESS(err); 3049 3050 // Now Try to bind memory to this destroyed object 3051 err = vkBindImageMemory(m_device->device(), image, mem, 0); 3052 // This may very well return an error. 3053 (void)err; 3054 3055 m_errorMonitor->VerifyFound(); 3056 3057 vkFreeMemory(m_device->device(), mem, NULL); 3058 } 3059 3060 TEST_F(VkLayerTest, ExceedMemoryAllocationCount) { 3061 VkResult err = VK_SUCCESS; 3062 const int max_mems = 32; 3063 VkDeviceMemory mems[max_mems + 1]; 3064 3065 if (!EnableDeviceProfileLayer()) return; 3066 3067 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 3068 3069 PFN_vkSetPhysicalDeviceLimitsEXT fpvkSetPhysicalDeviceLimitsEXT = 3070 (PFN_vkSetPhysicalDeviceLimitsEXT)vkGetInstanceProcAddr(instance(), "vkSetPhysicalDeviceLimitsEXT"); 3071 PFN_vkGetOriginalPhysicalDeviceLimitsEXT fpvkGetOriginalPhysicalDeviceLimitsEXT = 3072 (PFN_vkGetOriginalPhysicalDeviceLimitsEXT)vkGetInstanceProcAddr(instance(), "vkGetOriginalPhysicalDeviceLimitsEXT"); 3073 3074 if (!(fpvkSetPhysicalDeviceLimitsEXT) || !(fpvkGetOriginalPhysicalDeviceLimitsEXT)) { 3075 printf(" Can't find device_profile_api functions; skipped.\n"); 3076 return; 3077 } 3078 VkPhysicalDeviceProperties props; 3079 fpvkGetOriginalPhysicalDeviceLimitsEXT(gpu(), &props.limits); 3080 if (props.limits.maxMemoryAllocationCount > max_mems) { 3081 props.limits.maxMemoryAllocationCount = max_mems; 3082 fpvkSetPhysicalDeviceLimitsEXT(gpu(), &props.limits); 3083 } 3084 ASSERT_NO_FATAL_FAILURE(InitState()); 3085 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_16c004f8); 3086 3087 VkMemoryAllocateInfo mem_alloc = {}; 3088 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 3089 mem_alloc.pNext = NULL; 3090 mem_alloc.memoryTypeIndex = 0; 3091 mem_alloc.allocationSize = 4; 3092 3093 int i; 3094 for (i = 0; i <= max_mems; i++) { 3095 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mems[i]); 3096 if (err != VK_SUCCESS) { 3097 break; 3098 } 3099 } 3100 m_errorMonitor->VerifyFound(); 3101 3102 for (int j = 0; j < i; j++) { 3103 vkFreeMemory(m_device->device(), mems[j], NULL); 3104 } 3105 } 3106 3107 TEST_F(VkLayerTest, CreatePipelineBadVertexAttributeFormat) { 3108 TEST_DESCRIPTION("Test that pipeline validation catches invalid vertex attribute formats"); 3109 3110 ASSERT_NO_FATAL_FAILURE(Init()); 3111 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 3112 3113 VkVertexInputBindingDescription input_binding; 3114 memset(&input_binding, 0, sizeof(input_binding)); 3115 3116 VkVertexInputAttributeDescription input_attribs; 3117 memset(&input_attribs, 0, sizeof(input_attribs)); 3118 3119 // Pick a really bad format for this purpose and make sure it should fail 3120 input_attribs.format = VK_FORMAT_BC2_UNORM_BLOCK; 3121 VkFormatProperties format_props = m_device->format_properties(input_attribs.format); 3122 if ((format_props.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) != 0) { 3123 printf(" Format unsuitable for test; skipped.\n"); 3124 return; 3125 } 3126 3127 input_attribs.location = 0; 3128 char const *vsSource = 3129 "#version 450\n" 3130 "\n" 3131 "void main(){\n" 3132 " gl_Position = vec4(1);\n" 3133 "}\n"; 3134 char const *fsSource = 3135 "#version 450\n" 3136 "\n" 3137 "layout(location=0) out vec4 color;\n" 3138 "void main(){\n" 3139 " color = vec4(1);\n" 3140 "}\n"; 3141 3142 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_14a004de); 3143 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 3144 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 3145 3146 VkPipelineObj pipe(m_device); 3147 pipe.AddDefaultColorAttachment(); 3148 pipe.AddShader(&vs); 3149 pipe.AddShader(&fs); 3150 3151 pipe.AddVertexInputBindings(&input_binding, 1); 3152 pipe.AddVertexInputAttribs(&input_attribs, 1); 3153 3154 VkDescriptorSetObj descriptorSet(m_device); 3155 descriptorSet.AppendDummy(); 3156 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 3157 3158 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 3159 3160 m_errorMonitor->VerifyFound(); 3161 } 3162 3163 TEST_F(VkLayerTest, ImageSampleCounts) { 3164 TEST_DESCRIPTION("Use bad sample counts in image transfer calls to trigger validation errors."); 3165 ASSERT_NO_FATAL_FAILURE(Init(nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)); 3166 3167 VkMemoryPropertyFlags reqs = 0; 3168 VkImageCreateInfo image_create_info = {}; 3169 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 3170 image_create_info.pNext = NULL; 3171 image_create_info.imageType = VK_IMAGE_TYPE_2D; 3172 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; 3173 image_create_info.extent.width = 256; 3174 image_create_info.extent.height = 256; 3175 image_create_info.extent.depth = 1; 3176 image_create_info.mipLevels = 1; 3177 image_create_info.arrayLayers = 1; 3178 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 3179 image_create_info.flags = 0; 3180 3181 VkImageBlit blit_region = {}; 3182 blit_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3183 blit_region.srcSubresource.baseArrayLayer = 0; 3184 blit_region.srcSubresource.layerCount = 1; 3185 blit_region.srcSubresource.mipLevel = 0; 3186 blit_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3187 blit_region.dstSubresource.baseArrayLayer = 0; 3188 blit_region.dstSubresource.layerCount = 1; 3189 blit_region.dstSubresource.mipLevel = 0; 3190 blit_region.srcOffsets[0] = {0, 0, 0}; 3191 blit_region.srcOffsets[1] = {256, 256, 1}; 3192 blit_region.dstOffsets[0] = {0, 0, 0}; 3193 blit_region.dstOffsets[1] = {128, 128, 1}; 3194 3195 // Create two images, the source with sampleCount = 4, and attempt to blit 3196 // between them 3197 { 3198 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; 3199 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 3200 VkImageObj src_image(m_device); 3201 src_image.init(&image_create_info); 3202 src_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); 3203 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 3204 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 3205 VkImageObj dst_image(m_device); 3206 dst_image.init(&image_create_info); 3207 dst_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); 3208 m_commandBuffer->begin(); 3209 // TODO: These 2 VUs are redundant - expect one of them to go away 3210 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001d2); 3211 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001c8); 3212 vkCmdBlitImage(m_commandBuffer->handle(), src_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_image.handle(), 3213 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit_region, VK_FILTER_NEAREST); 3214 m_errorMonitor->VerifyFound(); 3215 m_commandBuffer->end(); 3216 } 3217 3218 // Create two images, the dest with sampleCount = 4, and attempt to blit 3219 // between them 3220 { 3221 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 3222 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 3223 VkImageObj src_image(m_device); 3224 src_image.init(&image_create_info); 3225 src_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); 3226 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; 3227 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 3228 VkImageObj dst_image(m_device); 3229 dst_image.init(&image_create_info); 3230 dst_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); 3231 m_commandBuffer->begin(); 3232 // TODO: These 2 VUs are redundant - expect one of them to go away 3233 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001d4); 3234 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001c8); 3235 vkCmdBlitImage(m_commandBuffer->handle(), src_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_image.handle(), 3236 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit_region, VK_FILTER_NEAREST); 3237 m_errorMonitor->VerifyFound(); 3238 m_commandBuffer->end(); 3239 } 3240 3241 VkBufferImageCopy copy_region = {}; 3242 copy_region.bufferRowLength = 128; 3243 copy_region.bufferImageHeight = 128; 3244 copy_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3245 copy_region.imageSubresource.layerCount = 1; 3246 copy_region.imageExtent.height = 64; 3247 copy_region.imageExtent.width = 64; 3248 copy_region.imageExtent.depth = 1; 3249 3250 // Create src buffer and dst image with sampleCount = 4 and attempt to copy 3251 // buffer to image 3252 { 3253 vk_testing::Buffer src_buffer; 3254 src_buffer.init_as_src(*m_device, 128 * 128 * 4, reqs); 3255 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; 3256 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 3257 VkImageObj dst_image(m_device); 3258 dst_image.init(&image_create_info); 3259 dst_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); 3260 m_commandBuffer->begin(); 3261 m_errorMonitor->SetDesiredFailureMsg( 3262 VK_DEBUG_REPORT_ERROR_BIT_EXT, 3263 "was created with a sample count of VK_SAMPLE_COUNT_4_BIT but must be VK_SAMPLE_COUNT_1_BIT"); 3264 vkCmdCopyBufferToImage(m_commandBuffer->handle(), src_buffer.handle(), dst_image.handle(), 3265 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©_region); 3266 m_errorMonitor->VerifyFound(); 3267 m_commandBuffer->end(); 3268 } 3269 3270 // Create dst buffer and src image with sampleCount = 4 and attempt to copy 3271 // image to buffer 3272 { 3273 vk_testing::Buffer dst_buffer; 3274 dst_buffer.init_as_dst(*m_device, 128 * 128 * 4, reqs); 3275 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; 3276 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 3277 vk_testing::Image src_image; 3278 src_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs); 3279 m_commandBuffer->begin(); 3280 m_errorMonitor->SetDesiredFailureMsg( 3281 VK_DEBUG_REPORT_ERROR_BIT_EXT, 3282 "was created with a sample count of VK_SAMPLE_COUNT_4_BIT but must be VK_SAMPLE_COUNT_1_BIT"); 3283 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), src_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 3284 dst_buffer.handle(), 1, ©_region); 3285 m_errorMonitor->VerifyFound(); 3286 m_commandBuffer->end(); 3287 } 3288 } 3289 3290 TEST_F(VkLayerTest, BlitImageFormatTypes) { 3291 ASSERT_NO_FATAL_FAILURE(Init()); 3292 3293 VkFormat f_unsigned = VK_FORMAT_R8G8B8A8_UINT; 3294 VkFormat f_signed = VK_FORMAT_R8G8B8A8_SINT; 3295 VkFormat f_float = VK_FORMAT_R32_SFLOAT; 3296 VkFormat f_depth = VK_FORMAT_D32_SFLOAT_S8_UINT; 3297 VkFormat f_depth2 = VK_FORMAT_D32_SFLOAT; 3298 3299 if (!ImageFormatIsSupported(gpu(), f_unsigned, VK_IMAGE_TILING_OPTIMAL) || 3300 !ImageFormatIsSupported(gpu(), f_signed, VK_IMAGE_TILING_OPTIMAL) || 3301 !ImageFormatIsSupported(gpu(), f_float, VK_IMAGE_TILING_OPTIMAL) || 3302 !ImageFormatIsSupported(gpu(), f_depth, VK_IMAGE_TILING_OPTIMAL) || 3303 !ImageFormatIsSupported(gpu(), f_depth2, VK_IMAGE_TILING_OPTIMAL)) { 3304 printf(" Requested formats not supported - BlitImageFormatTypes skipped.\n"); 3305 return; 3306 } 3307 3308 // Note any missing feature bits 3309 bool usrc = !ImageFormatAndFeaturesSupported(gpu(), f_unsigned, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_SRC_BIT); 3310 bool udst = !ImageFormatAndFeaturesSupported(gpu(), f_unsigned, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_DST_BIT); 3311 bool ssrc = !ImageFormatAndFeaturesSupported(gpu(), f_signed, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_SRC_BIT); 3312 bool sdst = !ImageFormatAndFeaturesSupported(gpu(), f_signed, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_DST_BIT); 3313 bool fsrc = !ImageFormatAndFeaturesSupported(gpu(), f_float, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_SRC_BIT); 3314 bool fdst = !ImageFormatAndFeaturesSupported(gpu(), f_float, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_DST_BIT); 3315 bool d1dst = !ImageFormatAndFeaturesSupported(gpu(), f_depth, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_DST_BIT); 3316 bool d2src = !ImageFormatAndFeaturesSupported(gpu(), f_depth2, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_SRC_BIT); 3317 3318 VkImageObj unsigned_image(m_device); 3319 unsigned_image.Init(64, 64, 1, f_unsigned, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 3320 VK_IMAGE_TILING_OPTIMAL, 0); 3321 ASSERT_TRUE(unsigned_image.initialized()); 3322 unsigned_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL); 3323 3324 VkImageObj signed_image(m_device); 3325 signed_image.Init(64, 64, 1, f_signed, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 3326 VK_IMAGE_TILING_OPTIMAL, 0); 3327 ASSERT_TRUE(signed_image.initialized()); 3328 signed_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL); 3329 3330 VkImageObj float_image(m_device); 3331 float_image.Init(64, 64, 1, f_float, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 3332 0); 3333 ASSERT_TRUE(float_image.initialized()); 3334 float_image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL); 3335 3336 VkImageObj depth_image(m_device); 3337 depth_image.Init(64, 64, 1, f_depth, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 3338 0); 3339 ASSERT_TRUE(depth_image.initialized()); 3340 depth_image.SetLayout(VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_LAYOUT_GENERAL); 3341 3342 VkImageObj depth_image2(m_device); 3343 depth_image2.Init(64, 64, 1, f_depth2, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 3344 VK_IMAGE_TILING_OPTIMAL, 0); 3345 ASSERT_TRUE(depth_image2.initialized()); 3346 depth_image2.SetLayout(VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_LAYOUT_GENERAL); 3347 3348 VkImageBlit blitRegion = {}; 3349 blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3350 blitRegion.srcSubresource.baseArrayLayer = 0; 3351 blitRegion.srcSubresource.layerCount = 1; 3352 blitRegion.srcSubresource.mipLevel = 0; 3353 blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3354 blitRegion.dstSubresource.baseArrayLayer = 0; 3355 blitRegion.dstSubresource.layerCount = 1; 3356 blitRegion.dstSubresource.mipLevel = 0; 3357 blitRegion.srcOffsets[0] = {0, 0, 0}; 3358 blitRegion.srcOffsets[1] = {64, 64, 1}; 3359 blitRegion.dstOffsets[0] = {0, 0, 0}; 3360 blitRegion.dstOffsets[1] = {32, 32, 1}; 3361 3362 m_commandBuffer->begin(); 3363 3364 // Unsigned int vs not an int 3365 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001cc); 3366 if (usrc) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001b4); 3367 if (fdst) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001be); 3368 vkCmdBlitImage(m_commandBuffer->handle(), unsigned_image.image(), unsigned_image.Layout(), float_image.image(), 3369 float_image.Layout(), 1, &blitRegion, VK_FILTER_NEAREST); 3370 m_errorMonitor->VerifyFound(); 3371 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001cc); 3372 if (fsrc) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001b4); 3373 if (udst) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001be); 3374 vkCmdBlitImage(m_commandBuffer->handle(), float_image.image(), float_image.Layout(), unsigned_image.image(), 3375 unsigned_image.Layout(), 1, &blitRegion, VK_FILTER_NEAREST); 3376 m_errorMonitor->VerifyFound(); 3377 3378 // Signed int vs not an int, 3379 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001ca); 3380 if (ssrc) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001b4); 3381 if (fdst) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001be); 3382 vkCmdBlitImage(m_commandBuffer->handle(), signed_image.image(), signed_image.Layout(), float_image.image(), 3383 float_image.Layout(), 1, &blitRegion, VK_FILTER_NEAREST); 3384 m_errorMonitor->VerifyFound(); 3385 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001ca); 3386 if (fsrc) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001b4); 3387 if (sdst) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001be); 3388 vkCmdBlitImage(m_commandBuffer->handle(), float_image.image(), float_image.Layout(), signed_image.image(), 3389 signed_image.Layout(), 1, &blitRegion, VK_FILTER_NEAREST); 3390 m_errorMonitor->VerifyFound(); 3391 3392 // Signed vs Unsigned int - generates both VUs 3393 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001ca); 3394 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001cc); 3395 if (ssrc) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001b4); 3396 if (udst) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001be); 3397 vkCmdBlitImage(m_commandBuffer->handle(), signed_image.image(), signed_image.Layout(), unsigned_image.image(), 3398 unsigned_image.Layout(), 1, &blitRegion, VK_FILTER_NEAREST); 3399 m_errorMonitor->VerifyFound(); 3400 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001ca); 3401 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001cc); 3402 if (usrc) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001b4); 3403 if (sdst) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001be); 3404 vkCmdBlitImage(m_commandBuffer->handle(), unsigned_image.image(), unsigned_image.Layout(), signed_image.image(), 3405 signed_image.Layout(), 1, &blitRegion, VK_FILTER_NEAREST); 3406 m_errorMonitor->VerifyFound(); 3407 3408 // Depth vs any non-identical depth format 3409 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001ce); 3410 blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 3411 blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 3412 if (d2src) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001b4); 3413 if (d1dst) m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001be); 3414 vkCmdBlitImage(m_commandBuffer->handle(), depth_image2.image(), depth_image2.Layout(), depth_image.image(), 3415 depth_image.Layout(), 1, &blitRegion, VK_FILTER_NEAREST); 3416 m_errorMonitor->VerifyFound(); 3417 3418 m_commandBuffer->end(); 3419 } 3420 3421 TEST_F(VkLayerTest, BlitImageFilters) { 3422 bool cubic_support = false; 3423 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 3424 if (DeviceExtensionSupported(gpu(), nullptr, "VK_IMG_filter_cubic")) { 3425 m_device_extension_names.push_back("VK_IMG_filter_cubic"); 3426 cubic_support = true; 3427 } 3428 ASSERT_NO_FATAL_FAILURE(InitState()); 3429 3430 VkFormat fmt = VK_FORMAT_R8_UINT; 3431 if (!ImageFormatIsSupported(gpu(), fmt, VK_IMAGE_TILING_OPTIMAL)) { 3432 printf(" No R8_UINT format support - BlitImageFilters skipped.\n"); 3433 return; 3434 } 3435 3436 // Create 2D images 3437 VkImageObj src2D(m_device); 3438 VkImageObj dst2D(m_device); 3439 src2D.Init(64, 64, 1, fmt, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 3440 dst2D.Init(64, 64, 1, fmt, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 3441 ASSERT_TRUE(src2D.initialized()); 3442 ASSERT_TRUE(dst2D.initialized()); 3443 src2D.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL); 3444 dst2D.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL); 3445 3446 // Create 3D image 3447 VkImageCreateInfo ci; 3448 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 3449 ci.pNext = NULL; 3450 ci.flags = 0; 3451 ci.imageType = VK_IMAGE_TYPE_3D; 3452 ci.format = fmt; 3453 ci.extent = {64, 64, 4}; 3454 ci.mipLevels = 1; 3455 ci.arrayLayers = 1; 3456 ci.samples = VK_SAMPLE_COUNT_1_BIT; 3457 ci.tiling = VK_IMAGE_TILING_OPTIMAL; 3458 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 3459 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 3460 ci.queueFamilyIndexCount = 0; 3461 ci.pQueueFamilyIndices = NULL; 3462 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 3463 3464 VkImageObj src3D(m_device); 3465 src3D.init(&ci); 3466 ASSERT_TRUE(src3D.initialized()); 3467 3468 VkImageBlit blitRegion = {}; 3469 blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3470 blitRegion.srcSubresource.baseArrayLayer = 0; 3471 blitRegion.srcSubresource.layerCount = 1; 3472 blitRegion.srcSubresource.mipLevel = 0; 3473 blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3474 blitRegion.dstSubresource.baseArrayLayer = 0; 3475 blitRegion.dstSubresource.layerCount = 1; 3476 blitRegion.dstSubresource.mipLevel = 0; 3477 blitRegion.srcOffsets[0] = {0, 0, 0}; 3478 blitRegion.srcOffsets[1] = {48, 48, 1}; 3479 blitRegion.dstOffsets[0] = {0, 0, 0}; 3480 blitRegion.dstOffsets[1] = {64, 64, 1}; 3481 3482 m_commandBuffer->begin(); 3483 3484 // UINT format should not support linear filtering, but check to be sure 3485 if (!ImageFormatAndFeaturesSupported(gpu(), fmt, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)) { 3486 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001d6); 3487 vkCmdBlitImage(m_commandBuffer->handle(), src2D.image(), src2D.Layout(), dst2D.image(), dst2D.Layout(), 1, &blitRegion, 3488 VK_FILTER_LINEAR); 3489 m_errorMonitor->VerifyFound(); 3490 } 3491 3492 if (cubic_support && !ImageFormatAndFeaturesSupported(gpu(), fmt, VK_IMAGE_TILING_OPTIMAL, 3493 VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG)) { 3494 // Invalid filter CUBIC_IMG 3495 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001d8); 3496 vkCmdBlitImage(m_commandBuffer->handle(), src3D.image(), src3D.Layout(), dst2D.image(), dst2D.Layout(), 1, &blitRegion, 3497 VK_FILTER_CUBIC_IMG); 3498 m_errorMonitor->VerifyFound(); 3499 3500 // Invalid filter CUBIC_IMG + invalid 2D source image 3501 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001d8); 3502 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001da); 3503 vkCmdBlitImage(m_commandBuffer->handle(), src2D.image(), src2D.Layout(), dst2D.image(), dst2D.Layout(), 1, &blitRegion, 3504 VK_FILTER_CUBIC_IMG); 3505 m_errorMonitor->VerifyFound(); 3506 } 3507 3508 m_commandBuffer->end(); 3509 } 3510 3511 TEST_F(VkLayerTest, BlitImageLayout) { 3512 TEST_DESCRIPTION("Incorrect vkCmdBlitImage layouts"); 3513 3514 ASSERT_NO_FATAL_FAILURE(Init(nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)); 3515 3516 VkResult err; 3517 VkFormat fmt = VK_FORMAT_R8G8B8A8_UNORM; 3518 3519 VkSubmitInfo submit_info = {}; 3520 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 3521 submit_info.commandBufferCount = 1; 3522 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 3523 3524 // Create images 3525 VkImageObj img_src_transfer(m_device); 3526 VkImageObj img_dst_transfer(m_device); 3527 VkImageObj img_general(m_device); 3528 VkImageObj img_color(m_device); 3529 3530 img_src_transfer.InitNoLayout(64, 64, 1, fmt, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 3531 VK_IMAGE_TILING_OPTIMAL, 0); 3532 img_dst_transfer.InitNoLayout(64, 64, 1, fmt, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 3533 VK_IMAGE_TILING_OPTIMAL, 0); 3534 img_general.InitNoLayout(64, 64, 1, fmt, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 3535 VK_IMAGE_TILING_OPTIMAL, 0); 3536 img_color.InitNoLayout(64, 64, 1, fmt, 3537 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 3538 VK_IMAGE_TILING_OPTIMAL, 0); 3539 3540 ASSERT_TRUE(img_src_transfer.initialized()); 3541 ASSERT_TRUE(img_dst_transfer.initialized()); 3542 ASSERT_TRUE(img_general.initialized()); 3543 ASSERT_TRUE(img_color.initialized()); 3544 3545 img_src_transfer.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); 3546 img_dst_transfer.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); 3547 img_general.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL); 3548 img_color.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); 3549 3550 VkImageBlit blit_region = {}; 3551 blit_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3552 blit_region.srcSubresource.baseArrayLayer = 0; 3553 blit_region.srcSubresource.layerCount = 1; 3554 blit_region.srcSubresource.mipLevel = 0; 3555 blit_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3556 blit_region.dstSubresource.baseArrayLayer = 0; 3557 blit_region.dstSubresource.layerCount = 1; 3558 blit_region.dstSubresource.mipLevel = 0; 3559 blit_region.srcOffsets[0] = {0, 0, 0}; 3560 blit_region.srcOffsets[1] = {48, 48, 1}; 3561 blit_region.dstOffsets[0] = {0, 0, 0}; 3562 blit_region.dstOffsets[1] = {64, 64, 1}; 3563 3564 m_commandBuffer->begin(); 3565 3566 // Illegal srcImageLayout 3567 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001bc); 3568 vkCmdBlitImage(m_commandBuffer->handle(), img_src_transfer.image(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 3569 img_dst_transfer.image(), img_dst_transfer.Layout(), 1, &blit_region, VK_FILTER_LINEAR); 3570 m_errorMonitor->VerifyFound(); 3571 3572 // Illegal destImageLayout 3573 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001c6); 3574 vkCmdBlitImage(m_commandBuffer->handle(), img_src_transfer.image(), img_src_transfer.Layout(), img_dst_transfer.image(), 3575 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, &blit_region, VK_FILTER_LINEAR); 3576 3577 m_commandBuffer->end(); 3578 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 3579 m_errorMonitor->VerifyFound(); 3580 3581 err = vkQueueWaitIdle(m_device->m_queue); 3582 ASSERT_VK_SUCCESS(err); 3583 3584 m_commandBuffer->reset(0); 3585 m_commandBuffer->begin(); 3586 3587 // Source image in invalid layout at start of the CB 3588 m_errorMonitor->SetDesiredFailureMsg( 3589 VK_DEBUG_REPORT_ERROR_BIT_EXT, "layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL when first use is VK_IMAGE_LAYOUT_GENERAL"); 3590 vkCmdBlitImage(m_commandBuffer->handle(), img_src_transfer.image(), img_src_transfer.Layout(), img_color.image(), 3591 VK_IMAGE_LAYOUT_GENERAL, 1, &blit_region, VK_FILTER_LINEAR); 3592 3593 m_commandBuffer->end(); 3594 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 3595 m_errorMonitor->VerifyFound(); 3596 err = vkQueueWaitIdle(m_device->m_queue); 3597 ASSERT_VK_SUCCESS(err); 3598 3599 m_commandBuffer->reset(0); 3600 m_commandBuffer->begin(); 3601 3602 // Destination image in invalid layout at start of the CB 3603 m_errorMonitor->SetDesiredFailureMsg( 3604 VK_DEBUG_REPORT_ERROR_BIT_EXT, "layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL when first use is VK_IMAGE_LAYOUT_GENERAL"); 3605 vkCmdBlitImage(m_commandBuffer->handle(), img_color.image(), VK_IMAGE_LAYOUT_GENERAL, img_dst_transfer.image(), 3606 img_dst_transfer.Layout(), 1, &blit_region, VK_FILTER_LINEAR); 3607 3608 m_commandBuffer->end(); 3609 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 3610 m_errorMonitor->VerifyFound(); 3611 err = vkQueueWaitIdle(m_device->m_queue); 3612 ASSERT_VK_SUCCESS(err); 3613 3614 // Source image in invalid layout in the middle of CB 3615 m_commandBuffer->reset(0); 3616 m_commandBuffer->begin(); 3617 3618 VkImageMemoryBarrier img_barrier = {}; 3619 img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 3620 img_barrier.pNext = nullptr; 3621 img_barrier.srcAccessMask = 0; 3622 img_barrier.dstAccessMask = 0; 3623 img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL; 3624 img_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 3625 img_barrier.image = img_general.handle(); 3626 img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 3627 img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 3628 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3629 img_barrier.subresourceRange.baseArrayLayer = 0; 3630 img_barrier.subresourceRange.baseMipLevel = 0; 3631 img_barrier.subresourceRange.layerCount = 1; 3632 img_barrier.subresourceRange.levelCount = 1; 3633 3634 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, 3635 nullptr, 0, nullptr, 1, &img_barrier); 3636 3637 m_errorMonitor->SetDesiredFailureMsg( 3638 VK_DEBUG_REPORT_ERROR_BIT_EXT, 3639 "layout VK_IMAGE_LAYOUT_GENERAL that doesn't match the actual current layout VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL"); 3640 vkCmdBlitImage(m_commandBuffer->handle(), img_general.image(), VK_IMAGE_LAYOUT_GENERAL, img_dst_transfer.image(), 3641 img_dst_transfer.Layout(), 1, &blit_region, VK_FILTER_LINEAR); 3642 3643 m_commandBuffer->end(); 3644 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 3645 m_errorMonitor->VerifyFound(); 3646 err = vkQueueWaitIdle(m_device->m_queue); 3647 ASSERT_VK_SUCCESS(err); 3648 3649 // Destination image in invalid layout in the middle of CB 3650 m_commandBuffer->reset(0); 3651 m_commandBuffer->begin(); 3652 3653 img_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 3654 img_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 3655 img_barrier.image = img_dst_transfer.handle(); 3656 3657 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, 3658 nullptr, 0, nullptr, 1, &img_barrier); 3659 3660 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 3661 "layout VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL that doesn't match the actual current layout " 3662 "VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL"); 3663 vkCmdBlitImage(m_commandBuffer->handle(), img_src_transfer.image(), img_src_transfer.Layout(), img_dst_transfer.image(), 3664 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit_region, VK_FILTER_LINEAR); 3665 3666 m_commandBuffer->end(); 3667 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 3668 m_errorMonitor->VerifyFound(); 3669 err = vkQueueWaitIdle(m_device->m_queue); 3670 ASSERT_VK_SUCCESS(err); 3671 } 3672 3673 TEST_F(VkLayerTest, BlitImageOffsets) { 3674 ASSERT_NO_FATAL_FAILURE(Init()); 3675 3676 VkFormat fmt = VK_FORMAT_R8G8B8A8_UNORM; 3677 if (!ImageFormatAndFeaturesSupported(gpu(), fmt, VK_IMAGE_TILING_OPTIMAL, 3678 VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT)) { 3679 printf(" No blit feature bits - BlitImageOffsets skipped.\n"); 3680 return; 3681 } 3682 3683 VkImageCreateInfo ci; 3684 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 3685 ci.pNext = NULL; 3686 ci.flags = 0; 3687 ci.imageType = VK_IMAGE_TYPE_1D; 3688 ci.format = fmt; 3689 ci.extent = {64, 1, 1}; 3690 ci.mipLevels = 1; 3691 ci.arrayLayers = 1; 3692 ci.samples = VK_SAMPLE_COUNT_1_BIT; 3693 ci.tiling = VK_IMAGE_TILING_OPTIMAL; 3694 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 3695 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 3696 ci.queueFamilyIndexCount = 0; 3697 ci.pQueueFamilyIndices = NULL; 3698 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 3699 3700 VkImageObj image_1D(m_device); 3701 image_1D.init(&ci); 3702 ASSERT_TRUE(image_1D.initialized()); 3703 3704 ci.imageType = VK_IMAGE_TYPE_2D; 3705 ci.extent = {64, 64, 1}; 3706 VkImageObj image_2D(m_device); 3707 image_2D.init(&ci); 3708 ASSERT_TRUE(image_2D.initialized()); 3709 3710 ci.imageType = VK_IMAGE_TYPE_3D; 3711 ci.extent = {64, 64, 64}; 3712 VkImageObj image_3D(m_device); 3713 image_3D.init(&ci); 3714 ASSERT_TRUE(image_3D.initialized()); 3715 3716 VkImageBlit blit_region = {}; 3717 blit_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3718 blit_region.srcSubresource.baseArrayLayer = 0; 3719 blit_region.srcSubresource.layerCount = 1; 3720 blit_region.srcSubresource.mipLevel = 0; 3721 blit_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3722 blit_region.dstSubresource.baseArrayLayer = 0; 3723 blit_region.dstSubresource.layerCount = 1; 3724 blit_region.dstSubresource.mipLevel = 0; 3725 3726 m_commandBuffer->begin(); 3727 3728 // 1D, with src/dest y offsets other than (0,1) 3729 blit_region.srcOffsets[0] = {0, 1, 0}; 3730 blit_region.srcOffsets[1] = {30, 1, 1}; 3731 blit_region.dstOffsets[0] = {32, 0, 0}; 3732 blit_region.dstOffsets[1] = {64, 1, 1}; 3733 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001ea); 3734 vkCmdBlitImage(m_commandBuffer->handle(), image_1D.image(), image_1D.Layout(), image_1D.image(), image_1D.Layout(), 1, 3735 &blit_region, VK_FILTER_NEAREST); 3736 m_errorMonitor->VerifyFound(); 3737 3738 blit_region.srcOffsets[0] = {0, 0, 0}; 3739 blit_region.dstOffsets[0] = {32, 1, 0}; 3740 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001f4); 3741 vkCmdBlitImage(m_commandBuffer->handle(), image_1D.image(), image_1D.Layout(), image_1D.image(), image_1D.Layout(), 1, 3742 &blit_region, VK_FILTER_NEAREST); 3743 m_errorMonitor->VerifyFound(); 3744 3745 // 2D, with src/dest z offsets other than (0,1) 3746 blit_region.srcOffsets[0] = {0, 0, 1}; 3747 blit_region.srcOffsets[1] = {24, 31, 1}; 3748 blit_region.dstOffsets[0] = {32, 32, 0}; 3749 blit_region.dstOffsets[1] = {64, 64, 1}; 3750 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001ee); 3751 vkCmdBlitImage(m_commandBuffer->handle(), image_2D.image(), image_2D.Layout(), image_2D.image(), image_2D.Layout(), 1, 3752 &blit_region, VK_FILTER_NEAREST); 3753 m_errorMonitor->VerifyFound(); 3754 3755 blit_region.srcOffsets[0] = {0, 0, 0}; 3756 blit_region.dstOffsets[0] = {32, 32, 1}; 3757 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001f8); 3758 vkCmdBlitImage(m_commandBuffer->handle(), image_2D.image(), image_2D.Layout(), image_2D.image(), image_2D.Layout(), 1, 3759 &blit_region, VK_FILTER_NEAREST); 3760 m_errorMonitor->VerifyFound(); 3761 3762 // Source offsets exceeding source image dimensions 3763 blit_region.srcOffsets[0] = {0, 0, 0}; 3764 blit_region.srcOffsets[1] = {65, 64, 1}; // src x 3765 blit_region.dstOffsets[0] = {0, 0, 0}; 3766 blit_region.dstOffsets[1] = {64, 64, 1}; 3767 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001e6); // x 3768 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001ae); // src region 3769 vkCmdBlitImage(m_commandBuffer->handle(), image_3D.image(), image_3D.Layout(), image_2D.image(), image_2D.Layout(), 1, 3770 &blit_region, VK_FILTER_NEAREST); 3771 m_errorMonitor->VerifyFound(); 3772 3773 blit_region.srcOffsets[1] = {64, 65, 1}; // src y 3774 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001e8); // y 3775 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001ae); // src region 3776 vkCmdBlitImage(m_commandBuffer->handle(), image_3D.image(), image_3D.Layout(), image_2D.image(), image_2D.Layout(), 1, 3777 &blit_region, VK_FILTER_NEAREST); 3778 m_errorMonitor->VerifyFound(); 3779 3780 blit_region.srcOffsets[0] = {0, 0, 65}; // src z 3781 blit_region.srcOffsets[1] = {64, 64, 64}; 3782 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001ec); // z 3783 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001ae); // src region 3784 vkCmdBlitImage(m_commandBuffer->handle(), image_3D.image(), image_3D.Layout(), image_2D.image(), image_2D.Layout(), 1, 3785 &blit_region, VK_FILTER_NEAREST); 3786 m_errorMonitor->VerifyFound(); 3787 3788 // Dest offsets exceeding source image dimensions 3789 blit_region.srcOffsets[0] = {0, 0, 0}; 3790 blit_region.srcOffsets[1] = {64, 64, 1}; 3791 blit_region.dstOffsets[0] = {96, 64, 32}; // dst x 3792 blit_region.dstOffsets[1] = {64, 0, 33}; 3793 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001f0); // x 3794 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001b0); // dst region 3795 vkCmdBlitImage(m_commandBuffer->handle(), image_2D.image(), image_2D.Layout(), image_3D.image(), image_3D.Layout(), 1, 3796 &blit_region, VK_FILTER_NEAREST); 3797 m_errorMonitor->VerifyFound(); 3798 3799 blit_region.dstOffsets[0] = {0, 65, 32}; // dst y 3800 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001f2); // y 3801 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001b0); // dst region 3802 vkCmdBlitImage(m_commandBuffer->handle(), image_2D.image(), image_2D.Layout(), image_3D.image(), image_3D.Layout(), 1, 3803 &blit_region, VK_FILTER_NEAREST); 3804 m_errorMonitor->VerifyFound(); 3805 3806 blit_region.dstOffsets[0] = {0, 64, 65}; // dst z 3807 blit_region.dstOffsets[1] = {64, 0, 64}; 3808 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001f6); // z 3809 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001b0); // dst region 3810 vkCmdBlitImage(m_commandBuffer->handle(), image_2D.image(), image_2D.Layout(), image_3D.image(), image_3D.Layout(), 1, 3811 &blit_region, VK_FILTER_NEAREST); 3812 m_errorMonitor->VerifyFound(); 3813 3814 m_commandBuffer->end(); 3815 } 3816 3817 TEST_F(VkLayerTest, MiscBlitImageTests) { 3818 ASSERT_NO_FATAL_FAILURE(Init()); 3819 3820 VkFormat f_color = VK_FORMAT_R32_SFLOAT; // Need features ..BLIT_SRC_BIT & ..BLIT_DST_BIT 3821 VkFormat f_depth = VK_FORMAT_D32_SFLOAT; // Need feature ..BLIT_SRC_BIT but not ..BLIT_DST_BIT 3822 3823 if (!ImageFormatAndFeaturesSupported(gpu(), f_color, VK_IMAGE_TILING_OPTIMAL, 3824 VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT) || 3825 !ImageFormatAndFeaturesSupported(gpu(), f_depth, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_SRC_BIT) || 3826 ImageFormatAndFeaturesSupported(gpu(), f_depth, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_BLIT_DST_BIT)) { 3827 printf(" Requested format features unavailable - MiscBlitImageTests skipped.\n"); 3828 return; 3829 } 3830 3831 VkImageCreateInfo ci; 3832 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 3833 ci.pNext = NULL; 3834 ci.flags = 0; 3835 ci.imageType = VK_IMAGE_TYPE_2D; 3836 ci.format = f_color; 3837 ci.extent = {64, 64, 1}; 3838 ci.mipLevels = 1; 3839 ci.arrayLayers = 1; 3840 ci.samples = VK_SAMPLE_COUNT_1_BIT; 3841 ci.tiling = VK_IMAGE_TILING_OPTIMAL; 3842 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 3843 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 3844 ci.queueFamilyIndexCount = 0; 3845 ci.pQueueFamilyIndices = NULL; 3846 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 3847 3848 // 2D color image 3849 VkImageObj color_img(m_device); 3850 color_img.init(&ci); 3851 ASSERT_TRUE(color_img.initialized()); 3852 3853 // 2D multi-sample image 3854 ci.samples = VK_SAMPLE_COUNT_4_BIT; 3855 VkImageObj ms_img(m_device); 3856 ms_img.init(&ci); 3857 ASSERT_TRUE(ms_img.initialized()); 3858 3859 // 2D depth image 3860 ci.format = f_depth; 3861 ci.samples = VK_SAMPLE_COUNT_1_BIT; 3862 VkImageObj depth_img(m_device); 3863 depth_img.init(&ci); 3864 ASSERT_TRUE(depth_img.initialized()); 3865 3866 // 3D color image 3867 ci.format = f_color; 3868 ci.imageType = VK_IMAGE_TYPE_3D; 3869 ci.extent = {64, 64, 8}; 3870 VkImageObj color_3D_img(m_device); 3871 color_3D_img.init(&ci); 3872 ASSERT_TRUE(color_3D_img.initialized()); 3873 3874 VkImageBlit blitRegion = {}; 3875 blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3876 blitRegion.srcSubresource.baseArrayLayer = 0; 3877 blitRegion.srcSubresource.layerCount = 1; 3878 blitRegion.srcSubresource.mipLevel = 0; 3879 blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3880 blitRegion.dstSubresource.baseArrayLayer = 0; 3881 blitRegion.dstSubresource.layerCount = 1; 3882 blitRegion.dstSubresource.mipLevel = 0; 3883 blitRegion.srcOffsets[0] = {0, 0, 0}; 3884 blitRegion.srcOffsets[1] = {16, 16, 1}; 3885 blitRegion.dstOffsets[0] = {32, 32, 0}; 3886 blitRegion.dstOffsets[1] = {64, 64, 1}; 3887 3888 m_commandBuffer->begin(); 3889 3890 // Blit depth image - has SRC_BIT but not DST_BIT 3891 blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 3892 blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 3893 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001be); 3894 vkCmdBlitImage(m_commandBuffer->handle(), depth_img.image(), depth_img.Layout(), depth_img.image(), depth_img.Layout(), 1, 3895 &blitRegion, VK_FILTER_NEAREST); 3896 m_errorMonitor->VerifyFound(); 3897 3898 // Blit with aspectMask errors 3899 blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 3900 blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 3901 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001e2); 3902 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001e4); 3903 vkCmdBlitImage(m_commandBuffer->handle(), color_img.image(), color_img.Layout(), color_img.image(), color_img.Layout(), 1, 3904 &blitRegion, VK_FILTER_NEAREST); 3905 m_errorMonitor->VerifyFound(); 3906 3907 // Blit multi-sample image 3908 blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3909 blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3910 // TODO: redundant VUs, one (1c8) or two (1d2 & 1d4) should be eliminated. 3911 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001c8); 3912 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001d2); 3913 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_184001d4); 3914 vkCmdBlitImage(m_commandBuffer->handle(), ms_img.image(), ms_img.Layout(), ms_img.image(), ms_img.Layout(), 1, &blitRegion, 3915 VK_FILTER_NEAREST); 3916 m_errorMonitor->VerifyFound(); 3917 3918 // Blit 3D with baseArrayLayer != 0 or layerCount != 1 3919 blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3920 blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3921 blitRegion.srcSubresource.baseArrayLayer = 1; 3922 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001e0); 3923 vkCmdBlitImage(m_commandBuffer->handle(), color_3D_img.image(), color_3D_img.Layout(), color_3D_img.image(), 3924 color_3D_img.Layout(), 1, &blitRegion, VK_FILTER_NEAREST); 3925 m_errorMonitor->VerifyFound(); 3926 blitRegion.srcSubresource.baseArrayLayer = 0; 3927 blitRegion.srcSubresource.layerCount = 0; 3928 blitRegion.dstSubresource.layerCount = 0; 3929 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09a001e0); 3930 vkCmdBlitImage(m_commandBuffer->handle(), color_3D_img.image(), color_3D_img.Layout(), color_3D_img.image(), 3931 color_3D_img.Layout(), 1, &blitRegion, VK_FILTER_NEAREST); 3932 m_errorMonitor->VerifyFound(); 3933 3934 m_commandBuffer->end(); 3935 } 3936 3937 TEST_F(VkLayerTest, DSImageTransferGranularityTests) { 3938 VkResult err; 3939 bool pass; 3940 3941 TEST_DESCRIPTION("Tests for validaiton of Queue Family property minImageTransferGranularity."); 3942 ASSERT_NO_FATAL_FAILURE(Init()); 3943 3944 // If w/d/h granularity is 1, test is not meaningful 3945 // TODO: When virtual device limits are available, create a set of limits for this test that 3946 // will always have a granularity of > 1 for w, h, and d 3947 auto index = m_device->graphics_queue_node_index_; 3948 auto queue_family_properties = m_device->phy().queue_properties(); 3949 3950 if ((queue_family_properties[index].minImageTransferGranularity.depth < 4) || 3951 (queue_family_properties[index].minImageTransferGranularity.width < 4) || 3952 (queue_family_properties[index].minImageTransferGranularity.height < 4)) { 3953 return; 3954 } 3955 3956 // Create two images of different types and try to copy between them 3957 VkImage srcImage; 3958 VkImage dstImage; 3959 VkDeviceMemory srcMem; 3960 VkDeviceMemory destMem; 3961 VkMemoryRequirements memReqs; 3962 3963 VkImageCreateInfo image_create_info = {}; 3964 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 3965 image_create_info.pNext = NULL; 3966 image_create_info.imageType = VK_IMAGE_TYPE_2D; 3967 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; 3968 image_create_info.extent.width = 32; 3969 image_create_info.extent.height = 32; 3970 image_create_info.extent.depth = 1; 3971 image_create_info.mipLevels = 1; 3972 image_create_info.arrayLayers = 4; 3973 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 3974 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 3975 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 3976 image_create_info.flags = 0; 3977 3978 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage); 3979 ASSERT_VK_SUCCESS(err); 3980 3981 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage); 3982 ASSERT_VK_SUCCESS(err); 3983 3984 // Allocate memory 3985 VkMemoryAllocateInfo memAlloc = {}; 3986 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 3987 memAlloc.pNext = NULL; 3988 memAlloc.allocationSize = 0; 3989 memAlloc.memoryTypeIndex = 0; 3990 3991 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs); 3992 memAlloc.allocationSize = memReqs.size; 3993 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 3994 ASSERT_TRUE(pass); 3995 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem); 3996 ASSERT_VK_SUCCESS(err); 3997 3998 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs); 3999 memAlloc.allocationSize = memReqs.size; 4000 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 4001 ASSERT_VK_SUCCESS(err); 4002 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem); 4003 ASSERT_VK_SUCCESS(err); 4004 4005 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0); 4006 ASSERT_VK_SUCCESS(err); 4007 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0); 4008 ASSERT_VK_SUCCESS(err); 4009 4010 m_commandBuffer->begin(); 4011 VkImageCopy copyRegion; 4012 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 4013 copyRegion.srcSubresource.mipLevel = 0; 4014 copyRegion.srcSubresource.baseArrayLayer = 0; 4015 copyRegion.srcSubresource.layerCount = 1; 4016 copyRegion.srcOffset.x = 0; 4017 copyRegion.srcOffset.y = 0; 4018 copyRegion.srcOffset.z = 0; 4019 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 4020 copyRegion.dstSubresource.mipLevel = 0; 4021 copyRegion.dstSubresource.baseArrayLayer = 0; 4022 copyRegion.dstSubresource.layerCount = 1; 4023 copyRegion.dstOffset.x = 0; 4024 copyRegion.dstOffset.y = 0; 4025 copyRegion.dstOffset.z = 0; 4026 copyRegion.extent.width = 1; 4027 copyRegion.extent.height = 1; 4028 copyRegion.extent.depth = 1; 4029 4030 // Introduce failure by setting srcOffset to a bad granularity value 4031 copyRegion.srcOffset.y = 3; 4032 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 4033 m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region); 4034 m_errorMonitor->VerifyFound(); 4035 4036 // Introduce failure by setting extent to a bad granularity value 4037 copyRegion.srcOffset.y = 0; 4038 copyRegion.extent.width = 3; 4039 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 4040 m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region); 4041 m_errorMonitor->VerifyFound(); 4042 4043 // Now do some buffer/image copies 4044 vk_testing::Buffer buffer; 4045 VkMemoryPropertyFlags reqs = 0; 4046 buffer.init_as_dst(*m_device, 128 * 128, reqs); 4047 VkBufferImageCopy region = {}; 4048 region.bufferOffset = 0; 4049 region.bufferRowLength = 3; 4050 region.bufferImageHeight = 128; 4051 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 4052 region.imageSubresource.layerCount = 1; 4053 region.imageExtent.height = 16; 4054 region.imageExtent.width = 16; 4055 region.imageExtent.depth = 1; 4056 region.imageOffset.x = 0; 4057 region.imageOffset.y = 0; 4058 region.imageOffset.z = 0; 4059 4060 // Introduce failure by setting bufferRowLength to a bad granularity value 4061 region.bufferRowLength = 3; 4062 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 4063 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); 4064 m_errorMonitor->VerifyFound(); 4065 region.bufferRowLength = 128; 4066 4067 // Introduce failure by setting bufferOffset to a bad granularity value 4068 region.bufferOffset = 3; 4069 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 4070 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1, ®ion); 4071 m_errorMonitor->VerifyFound(); 4072 region.bufferOffset = 0; 4073 4074 // Introduce failure by setting bufferImageHeight to a bad granularity value 4075 region.bufferImageHeight = 3; 4076 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 4077 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1, ®ion); 4078 m_errorMonitor->VerifyFound(); 4079 region.bufferImageHeight = 128; 4080 4081 // Introduce failure by setting imageExtent to a bad granularity value 4082 region.imageExtent.width = 3; 4083 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 4084 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1, ®ion); 4085 m_errorMonitor->VerifyFound(); 4086 region.imageExtent.width = 16; 4087 4088 // Introduce failure by setting imageOffset to a bad granularity value 4089 region.imageOffset.z = 3; 4090 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 4091 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); 4092 m_errorMonitor->VerifyFound(); 4093 4094 m_commandBuffer->end(); 4095 4096 vkDestroyImage(m_device->device(), srcImage, NULL); 4097 vkDestroyImage(m_device->device(), dstImage, NULL); 4098 vkFreeMemory(m_device->device(), srcMem, NULL); 4099 vkFreeMemory(m_device->device(), destMem, NULL); 4100 } 4101 4102 TEST_F(VkLayerTest, MismatchedQueueFamiliesOnSubmit) { 4103 TEST_DESCRIPTION( 4104 "Submit command buffer created using one queue family and attempt to submit them on a queue created in a different queue " 4105 "family."); 4106 4107 ASSERT_NO_FATAL_FAILURE(Init()); // assumes it initializes all queue families on vkCreateDevice 4108 4109 // This test is meaningless unless we have multiple queue families 4110 auto queue_family_properties = m_device->phy().queue_properties(); 4111 std::vector<uint32_t> queue_families; 4112 for (uint32_t i = 0; i < queue_family_properties.size(); ++i) 4113 if (queue_family_properties[i].queueCount > 0) queue_families.push_back(i); 4114 4115 if (queue_families.size() < 2) { 4116 printf(" Device only has one queue family; skipped.\n"); 4117 return; 4118 } 4119 4120 const uint32_t queue_family = queue_families[0]; 4121 4122 const uint32_t other_queue_family = queue_families[1]; 4123 VkQueue other_queue; 4124 vkGetDeviceQueue(m_device->device(), other_queue_family, 0, &other_queue); 4125 4126 VkCommandPoolObj cmd_pool(m_device, queue_family); 4127 VkCommandBufferObj cmd_buff(m_device, &cmd_pool); 4128 4129 cmd_buff.begin(); 4130 cmd_buff.end(); 4131 4132 // Submit on the wrong queue 4133 VkSubmitInfo submit_info = {}; 4134 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 4135 submit_info.commandBufferCount = 1; 4136 submit_info.pCommandBuffers = &cmd_buff.handle(); 4137 4138 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_31a00094); 4139 vkQueueSubmit(other_queue, 1, &submit_info, VK_NULL_HANDLE); 4140 m_errorMonitor->VerifyFound(); 4141 } 4142 4143 TEST_F(VkLayerTest, RenderPassAttachmentIndexOutOfRange) { 4144 ASSERT_NO_FATAL_FAILURE(Init()); 4145 4146 // There are no attachments, but refer to attachment 0. 4147 VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; 4148 VkSubpassDescription subpasses[] = { 4149 {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr}, 4150 }; 4151 4152 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, subpasses, 0, nullptr}; 4153 VkRenderPass rp; 4154 4155 // "... must be less than the total number of attachments ..." 4156 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_12200684); 4157 vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 4158 m_errorMonitor->VerifyFound(); 4159 } 4160 4161 TEST_F(VkLayerTest, RenderPassPipelineSubpassMismatch) { 4162 TEST_DESCRIPTION("Use a pipeline for the wrong subpass in a render pass instance"); 4163 ASSERT_NO_FATAL_FAILURE(Init()); 4164 4165 // A renderpass with two subpasses, both writing the same attachment. 4166 VkAttachmentDescription attach[] = { 4167 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 4168 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, 4169 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 4170 }; 4171 VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; 4172 VkSubpassDescription subpasses[] = { 4173 {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr}, 4174 {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr}, 4175 }; 4176 VkSubpassDependency dep = {0, 4177 1, 4178 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 4179 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 4180 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 4181 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 4182 VK_DEPENDENCY_BY_REGION_BIT}; 4183 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 2, subpasses, 1, &dep}; 4184 VkRenderPass rp; 4185 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 4186 ASSERT_VK_SUCCESS(err); 4187 4188 VkImageObj image(m_device); 4189 image.InitNoLayout(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 4190 VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM); 4191 4192 VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &imageView, 32, 32, 1}; 4193 VkFramebuffer fb; 4194 err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb); 4195 ASSERT_VK_SUCCESS(err); 4196 4197 char const *vsSource = 4198 "#version 450\n" 4199 "void main() { gl_Position = vec4(1); }\n"; 4200 char const *fsSource = 4201 "#version 450\n" 4202 "layout(location=0) out vec4 color;\n" 4203 "void main() { color = vec4(1); }\n"; 4204 4205 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 4206 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 4207 VkPipelineObj pipe(m_device); 4208 pipe.AddDefaultColorAttachment(); 4209 pipe.AddShader(&vs); 4210 pipe.AddShader(&fs); 4211 VkViewport view_port = {}; 4212 m_viewports.push_back(view_port); 4213 pipe.SetViewport(m_viewports); 4214 VkRect2D rect = {}; 4215 m_scissors.push_back(rect); 4216 pipe.SetScissor(m_scissors); 4217 4218 const VkPipelineLayoutObj pl(m_device); 4219 pipe.CreateVKPipeline(pl.handle(), rp); 4220 4221 m_commandBuffer->begin(); 4222 4223 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, 4224 nullptr, 4225 rp, 4226 fb, 4227 {{ 4228 0, 4229 0, 4230 }, 4231 {32, 32}}, 4232 0, 4233 nullptr}; 4234 4235 // subtest 1: bind in the wrong subpass 4236 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); 4237 vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE); 4238 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "built for subpass 0 but used in subpass 1"); 4239 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 4240 vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); 4241 m_errorMonitor->VerifyFound(); 4242 4243 vkCmdEndRenderPass(m_commandBuffer->handle()); 4244 4245 // subtest 2: bind in correct subpass, then transition to next subpass 4246 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); 4247 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 4248 vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE); 4249 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "built for subpass 0 but used in subpass 1"); 4250 vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); 4251 m_errorMonitor->VerifyFound(); 4252 4253 vkCmdEndRenderPass(m_commandBuffer->handle()); 4254 4255 m_commandBuffer->end(); 4256 4257 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 4258 vkDestroyRenderPass(m_device->device(), rp, nullptr); 4259 } 4260 4261 TEST_F(VkLayerTest, RenderPassBarrierConflicts) { 4262 TEST_DESCRIPTION("Add a pipeline barrier within a subpass that has conflicting state"); 4263 ASSERT_NO_FATAL_FAILURE(Init()); 4264 4265 // A renderpass with a single subpass that declared a self-dependency 4266 VkAttachmentDescription attach[] = { 4267 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 4268 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, 4269 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 4270 }; 4271 VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; 4272 VkSubpassDescription subpasses[] = { 4273 {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr}, 4274 }; 4275 VkSubpassDependency dep = {0, 4276 0, 4277 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 4278 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 4279 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 4280 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 4281 VK_DEPENDENCY_BY_REGION_BIT}; 4282 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 1, &dep}; 4283 VkRenderPass rp; 4284 VkRenderPass rp_noselfdep; 4285 4286 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 4287 ASSERT_VK_SUCCESS(err); 4288 rpci.dependencyCount = 0; 4289 rpci.pDependencies = nullptr; 4290 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp_noselfdep); 4291 ASSERT_VK_SUCCESS(err); 4292 4293 VkImageObj image(m_device); 4294 image.InitNoLayout(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 4295 VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM); 4296 4297 VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &imageView, 32, 32, 1}; 4298 VkFramebuffer fb; 4299 err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb); 4300 ASSERT_VK_SUCCESS(err); 4301 4302 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800928); 4303 m_commandBuffer->begin(); 4304 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, 4305 nullptr, 4306 rp_noselfdep, 4307 fb, 4308 {{ 4309 0, 4310 0, 4311 }, 4312 {32, 32}}, 4313 0, 4314 nullptr}; 4315 4316 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); 4317 VkMemoryBarrier mem_barrier = {}; 4318 mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; 4319 mem_barrier.pNext = NULL; 4320 mem_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; 4321 mem_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 4322 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 1, 4323 &mem_barrier, 0, nullptr, 0, nullptr); 4324 m_errorMonitor->VerifyFound(); 4325 vkCmdEndRenderPass(m_commandBuffer->handle()); 4326 4327 rpbi.renderPass = rp; 4328 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); 4329 VkImageMemoryBarrier img_barrier = {}; 4330 img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 4331 img_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 4332 img_barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 4333 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 4334 img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 4335 img_barrier.image = image.handle(); 4336 img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 4337 img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 4338 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 4339 img_barrier.subresourceRange.baseArrayLayer = 0; 4340 img_barrier.subresourceRange.baseMipLevel = 0; 4341 img_barrier.subresourceRange.layerCount = 1; 4342 img_barrier.subresourceRange.levelCount = 1; 4343 // Mis-match src stage mask 4344 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b80092a); 4345 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 4346 VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier); 4347 m_errorMonitor->VerifyFound(); 4348 // Now mis-match dst stage mask 4349 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b80092c); 4350 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_HOST_BIT, 4351 VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier); 4352 m_errorMonitor->VerifyFound(); 4353 // Set srcQueueFamilyIndex to something other than IGNORED 4354 img_barrier.srcQueueFamilyIndex = 0; 4355 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b80093c); 4356 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 4357 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 4358 &img_barrier); 4359 m_errorMonitor->VerifyFound(); 4360 img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 4361 // Mis-match mem barrier src access mask 4362 mem_barrier = {}; 4363 mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; 4364 mem_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; 4365 mem_barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 4366 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b80092e); 4367 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 4368 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 1, &mem_barrier, 0, nullptr, 0, 4369 nullptr); 4370 m_errorMonitor->VerifyFound(); 4371 // Mis-match mem barrier dst access mask. Also set srcAccessMask to 0 which should not cause an error 4372 mem_barrier.srcAccessMask = 0; 4373 mem_barrier.dstAccessMask = VK_ACCESS_HOST_WRITE_BIT; 4374 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800930); 4375 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 4376 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 1, &mem_barrier, 0, nullptr, 0, 4377 nullptr); 4378 m_errorMonitor->VerifyFound(); 4379 // Mis-match image barrier src access mask 4380 img_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; 4381 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b80092e); 4382 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 4383 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 4384 &img_barrier); 4385 m_errorMonitor->VerifyFound(); 4386 // Mis-match image barrier dst access mask 4387 img_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 4388 img_barrier.dstAccessMask = VK_ACCESS_HOST_WRITE_BIT; 4389 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800930); 4390 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 4391 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 4392 &img_barrier); 4393 m_errorMonitor->VerifyFound(); 4394 // Mis-match dependencyFlags 4395 img_barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 4396 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800932); 4397 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 4398 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0 /* wrong */, 0, nullptr, 0, nullptr, 1, &img_barrier); 4399 m_errorMonitor->VerifyFound(); 4400 // Send non-zero bufferMemoryBarrierCount 4401 // Construct a valid BufferMemoryBarrier to avoid any parameter errors 4402 // First we need a valid buffer to reference 4403 vk_testing::Buffer buffer; 4404 VkMemoryPropertyFlags mem_reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; 4405 buffer.init_as_src_and_dst(*m_device, 256, mem_reqs); 4406 VkBufferMemoryBarrier bmb = {}; 4407 bmb.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; 4408 bmb.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; 4409 bmb.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 4410 bmb.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 4411 bmb.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 4412 bmb.buffer = buffer.handle(); 4413 bmb.offset = 0; 4414 bmb.size = VK_WHOLE_SIZE; 4415 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800934); 4416 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 4417 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1, &bmb, 0, 4418 nullptr); 4419 m_errorMonitor->VerifyFound(); 4420 // Add image barrier w/ image handle that's not in framebuffer 4421 VkImageObj lone_image(m_device); 4422 lone_image.InitNoLayout(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 4423 img_barrier.image = lone_image.handle(); 4424 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800936); 4425 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 4426 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 4427 &img_barrier); 4428 m_errorMonitor->VerifyFound(); 4429 // Have image barrier with mis-matched layouts 4430 img_barrier.image = image.handle(); 4431 img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; 4432 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b80093a); 4433 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 4434 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 4435 &img_barrier); 4436 m_errorMonitor->VerifyFound(); 4437 4438 img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL; 4439 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; 4440 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800938); 4441 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 4442 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 4443 &img_barrier); 4444 m_errorMonitor->VerifyFound(); 4445 vkCmdEndRenderPass(m_commandBuffer->handle()); 4446 4447 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 4448 vkDestroyRenderPass(m_device->device(), rp, nullptr); 4449 vkDestroyRenderPass(m_device->device(), rp_noselfdep, nullptr); 4450 } 4451 4452 TEST_F(VkLayerTest, InvalidSecondaryCommandBufferBarrier) { 4453 TEST_DESCRIPTION("Add an invalid image barrier in a secondary command buffer"); 4454 ASSERT_NO_FATAL_FAILURE(Init()); 4455 4456 // A renderpass with a single subpass that declared a self-dependency 4457 VkAttachmentDescription attach[] = { 4458 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 4459 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, 4460 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 4461 }; 4462 VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; 4463 VkSubpassDescription subpasses[] = { 4464 {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr}, 4465 }; 4466 VkSubpassDependency dep = {0, 4467 0, 4468 VK_PIPELINE_STAGE_HOST_BIT, 4469 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 4470 VK_ACCESS_HOST_WRITE_BIT, 4471 VK_ACCESS_SHADER_WRITE_BIT, 4472 VK_DEPENDENCY_BY_REGION_BIT}; 4473 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 1, &dep}; 4474 VkRenderPass rp; 4475 4476 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 4477 ASSERT_VK_SUCCESS(err); 4478 4479 VkImageObj image(m_device); 4480 image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 4481 VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM); 4482 // Second image that img_barrier will incorrectly use 4483 VkImageObj image2(m_device); 4484 image2.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 4485 4486 VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &imageView, 32, 32, 1}; 4487 VkFramebuffer fb; 4488 err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb); 4489 ASSERT_VK_SUCCESS(err); 4490 4491 m_commandBuffer->begin(); 4492 4493 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, 4494 nullptr, 4495 rp, 4496 fb, 4497 {{ 4498 0, 4499 0, 4500 }, 4501 {32, 32}}, 4502 0, 4503 nullptr}; 4504 4505 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); 4506 4507 VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); 4508 VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); 4509 4510 VkCommandBufferInheritanceInfo cbii = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 4511 nullptr, 4512 rp, 4513 0, 4514 VK_NULL_HANDLE, // Set to NULL FB handle intentionally to flesh out any errors 4515 VK_FALSE, 4516 0, 4517 0}; 4518 VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 4519 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, 4520 &cbii}; 4521 vkBeginCommandBuffer(secondary.handle(), &cbbi); 4522 VkImageMemoryBarrier img_barrier = {}; 4523 img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 4524 img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; 4525 img_barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT; 4526 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 4527 img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 4528 img_barrier.image = image2.handle(); // Image mis-matches with FB image 4529 img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 4530 img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 4531 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 4532 img_barrier.subresourceRange.baseArrayLayer = 0; 4533 img_barrier.subresourceRange.baseMipLevel = 0; 4534 img_barrier.subresourceRange.layerCount = 1; 4535 img_barrier.subresourceRange.levelCount = 1; 4536 vkCmdPipelineBarrier(secondary.handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 4537 VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier); 4538 secondary.end(); 4539 4540 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800936); 4541 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle()); 4542 m_errorMonitor->VerifyFound(); 4543 4544 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 4545 vkDestroyRenderPass(m_device->device(), rp, nullptr); 4546 } 4547 4548 TEST_F(VkLayerTest, ImageBarrierSubpassConflict) { 4549 TEST_DESCRIPTION("Check case where subpass index references different image from image barrier"); 4550 ASSERT_NO_FATAL_FAILURE(Init()); 4551 4552 // Create RP/FB combo where subpass has incorrect index attachment, this is 2nd half of VALIDATION_ERROR_1b800936 4553 VkAttachmentDescription attach[] = { 4554 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 4555 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, 4556 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 4557 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 4558 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, 4559 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 4560 }; 4561 // ref attachment points to wrong attachment index compared to img_barrier below 4562 VkAttachmentReference ref = {1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; 4563 VkSubpassDescription subpasses[] = { 4564 {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr}, 4565 }; 4566 VkSubpassDependency dep = {0, 4567 0, 4568 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 4569 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 4570 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 4571 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 4572 VK_DEPENDENCY_BY_REGION_BIT}; 4573 4574 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attach, 1, subpasses, 1, &dep}; 4575 VkRenderPass rp; 4576 4577 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 4578 ASSERT_VK_SUCCESS(err); 4579 4580 VkImageObj image(m_device); 4581 image.InitNoLayout(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 4582 VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM); 4583 VkImageObj image2(m_device); 4584 image2.InitNoLayout(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 4585 VkImageView imageView2 = image2.targetView(VK_FORMAT_R8G8B8A8_UNORM); 4586 // re-use imageView from start of test 4587 VkImageView iv_array[2] = {imageView, imageView2}; 4588 4589 VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 2, iv_array, 32, 32, 1}; 4590 VkFramebuffer fb; 4591 err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb); 4592 ASSERT_VK_SUCCESS(err); 4593 4594 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, 4595 nullptr, 4596 rp, 4597 fb, 4598 {{ 4599 0, 4600 0, 4601 }, 4602 {32, 32}}, 4603 0, 4604 nullptr}; 4605 4606 VkImageMemoryBarrier img_barrier = {}; 4607 img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 4608 img_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 4609 img_barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 4610 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 4611 img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 4612 img_barrier.image = image.handle(); /* barrier references image from attachment index 0 */ 4613 img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 4614 img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 4615 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 4616 img_barrier.subresourceRange.baseArrayLayer = 0; 4617 img_barrier.subresourceRange.baseMipLevel = 0; 4618 img_barrier.subresourceRange.layerCount = 1; 4619 img_barrier.subresourceRange.levelCount = 1; 4620 m_commandBuffer->begin(); 4621 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); 4622 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800936); 4623 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 4624 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 4625 &img_barrier); 4626 m_errorMonitor->VerifyFound(); 4627 4628 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 4629 vkDestroyRenderPass(m_device->device(), rp, nullptr); 4630 } 4631 4632 TEST_F(VkLayerTest, TemporaryExternalSemaphore) { 4633 #ifdef _WIN32 4634 const auto extension_name = VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME; 4635 const auto handle_type = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR; 4636 #else 4637 const auto extension_name = VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME; 4638 const auto handle_type = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR; 4639 #endif 4640 // Check for external semaphore instance extensions 4641 if (InstanceExtensionSupported(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME)) { 4642 m_instance_extension_names.push_back(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME); 4643 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 4644 } else { 4645 printf(" External semaphore extension not supported, skipping test\n"); 4646 return; 4647 } 4648 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 4649 4650 // Check for external semaphore device extensions 4651 if (DeviceExtensionSupported(gpu(), nullptr, extension_name)) { 4652 m_device_extension_names.push_back(extension_name); 4653 m_device_extension_names.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME); 4654 } else { 4655 printf(" External semaphore extension not supported, skipping test\n"); 4656 return; 4657 } 4658 ASSERT_NO_FATAL_FAILURE(InitState()); 4659 4660 // Check for external semaphore import and export capability 4661 VkPhysicalDeviceExternalSemaphoreInfoKHR esi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR, nullptr, 4662 handle_type}; 4663 VkExternalSemaphorePropertiesKHR esp = {VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR, nullptr}; 4664 auto vkGetPhysicalDeviceExternalSemaphorePropertiesKHR = 4665 (PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)vkGetInstanceProcAddr( 4666 instance(), "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR"); 4667 vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(gpu(), &esi, &esp); 4668 4669 if (!(esp.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR) || 4670 !(esp.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR)) { 4671 printf(" External semaphore does not support importing and exporting, skipping test\n"); 4672 return; 4673 } 4674 4675 VkResult err; 4676 4677 // Create a semaphore to export payload from 4678 VkExportSemaphoreCreateInfoKHR esci = {VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR, nullptr, handle_type}; 4679 VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &esci, 0}; 4680 4681 VkSemaphore export_semaphore; 4682 err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &export_semaphore); 4683 ASSERT_VK_SUCCESS(err); 4684 4685 // Create a semaphore to import payload into 4686 sci.pNext = nullptr; 4687 VkSemaphore import_semaphore; 4688 err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &import_semaphore); 4689 ASSERT_VK_SUCCESS(err); 4690 4691 #ifdef _WIN32 4692 // Export semaphore payload to an opaque handle 4693 HANDLE handle = nullptr; 4694 VkSemaphoreGetWin32HandleInfoKHR ghi = {VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR, nullptr, export_semaphore, 4695 handle_type}; 4696 auto vkGetSemaphoreWin32HandleKHR = 4697 (PFN_vkGetSemaphoreWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetSemaphoreWin32HandleKHR"); 4698 err = vkGetSemaphoreWin32HandleKHR(m_device->device(), &ghi, &handle); 4699 ASSERT_VK_SUCCESS(err); 4700 4701 // Import opaque handle exported above *temporarily* 4702 VkImportSemaphoreWin32HandleInfoKHR ihi = {VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR, 4703 nullptr, 4704 import_semaphore, 4705 VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR, 4706 handle_type, 4707 handle, 4708 nullptr}; 4709 auto vkImportSemaphoreWin32HandleKHR = 4710 (PFN_vkImportSemaphoreWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportSemaphoreWin32HandleKHR"); 4711 err = vkImportSemaphoreWin32HandleKHR(m_device->device(), &ihi); 4712 ASSERT_VK_SUCCESS(err); 4713 #else 4714 // Export semaphore payload to an opaque handle 4715 int fd = 0; 4716 VkSemaphoreGetFdInfoKHR ghi = {VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR, nullptr, export_semaphore, handle_type}; 4717 auto vkGetSemaphoreFdKHR = (PFN_vkGetSemaphoreFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetSemaphoreFdKHR"); 4718 err = vkGetSemaphoreFdKHR(m_device->device(), &ghi, &fd); 4719 ASSERT_VK_SUCCESS(err); 4720 4721 // Import opaque handle exported above *temporarily* 4722 VkImportSemaphoreFdInfoKHR ihi = {VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR, nullptr, import_semaphore, 4723 VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR, handle_type, fd}; 4724 auto vkImportSemaphoreFdKHR = (PFN_vkImportSemaphoreFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportSemaphoreFdKHR"); 4725 err = vkImportSemaphoreFdKHR(m_device->device(), &ihi); 4726 ASSERT_VK_SUCCESS(err); 4727 #endif 4728 4729 // Wait on the imported semaphore twice in vkQueueSubmit, the second wait should be an error 4730 VkPipelineStageFlags flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; 4731 VkSubmitInfo si[] = { 4732 {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, &flags, 0, nullptr, 1, &export_semaphore}, 4733 {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &import_semaphore, &flags, 0, nullptr, 0, nullptr}, 4734 {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, &flags, 0, nullptr, 1, &export_semaphore}, 4735 {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &import_semaphore, &flags, 0, nullptr, 0, nullptr}, 4736 }; 4737 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "has no way to be signaled"); 4738 vkQueueSubmit(m_device->m_queue, 4, si, VK_NULL_HANDLE); 4739 m_errorMonitor->VerifyFound(); 4740 4741 // Wait on the imported semaphore twice in vkQueueBindSparse, the second wait should be an error 4742 VkBindSparseInfo bi[] = { 4743 {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 1, &export_semaphore}, 4744 {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 1, &import_semaphore, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr}, 4745 {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 1, &export_semaphore}, 4746 {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 1, &import_semaphore, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr}, 4747 }; 4748 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "has no way to be signaled"); 4749 vkQueueBindSparse(m_device->m_queue, 4, bi, VK_NULL_HANDLE); 4750 m_errorMonitor->VerifyFound(); 4751 4752 // Cleanup 4753 err = vkQueueWaitIdle(m_device->m_queue); 4754 ASSERT_VK_SUCCESS(err); 4755 vkDestroySemaphore(m_device->device(), export_semaphore, nullptr); 4756 vkDestroySemaphore(m_device->device(), import_semaphore, nullptr); 4757 } 4758 4759 TEST_F(VkLayerTest, TemporaryExternalFence) { 4760 #ifdef _WIN32 4761 const auto extension_name = VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME; 4762 const auto handle_type = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR; 4763 #else 4764 const auto extension_name = VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME; 4765 const auto handle_type = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR; 4766 #endif 4767 // Check for external fence instance extensions 4768 if (InstanceExtensionSupported(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME)) { 4769 m_instance_extension_names.push_back(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME); 4770 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 4771 } else { 4772 printf(" External fence extension not supported, skipping test\n"); 4773 return; 4774 } 4775 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 4776 4777 // Check for external fence device extensions 4778 if (DeviceExtensionSupported(gpu(), nullptr, extension_name)) { 4779 m_device_extension_names.push_back(extension_name); 4780 m_device_extension_names.push_back(VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME); 4781 } else { 4782 printf(" External fence extension not supported, skipping test\n"); 4783 return; 4784 } 4785 ASSERT_NO_FATAL_FAILURE(InitState()); 4786 4787 // Check for external fence import and export capability 4788 VkPhysicalDeviceExternalFenceInfoKHR efi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR, nullptr, handle_type}; 4789 VkExternalFencePropertiesKHR efp = {VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR, nullptr}; 4790 auto vkGetPhysicalDeviceExternalFencePropertiesKHR = (PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR)vkGetInstanceProcAddr( 4791 instance(), "vkGetPhysicalDeviceExternalFencePropertiesKHR"); 4792 vkGetPhysicalDeviceExternalFencePropertiesKHR(gpu(), &efi, &efp); 4793 4794 if (!(efp.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR) || 4795 !(efp.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR)) { 4796 printf(" External fence does not support importing and exporting, skipping test\n"); 4797 return; 4798 } 4799 4800 VkResult err; 4801 4802 // Create a fence to export payload from 4803 VkFence export_fence; 4804 { 4805 VkExportFenceCreateInfoKHR efci = {VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR, nullptr, handle_type}; 4806 VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, &efci, 0}; 4807 err = vkCreateFence(m_device->device(), &fci, nullptr, &export_fence); 4808 ASSERT_VK_SUCCESS(err); 4809 } 4810 4811 // Create a fence to import payload into 4812 VkFence import_fence; 4813 { 4814 VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0}; 4815 err = vkCreateFence(m_device->device(), &fci, nullptr, &import_fence); 4816 ASSERT_VK_SUCCESS(err); 4817 } 4818 4819 #ifdef _WIN32 4820 // Export fence payload to an opaque handle 4821 HANDLE handle = nullptr; 4822 { 4823 VkFenceGetWin32HandleInfoKHR ghi = {VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR, nullptr, export_fence, handle_type}; 4824 auto vkGetFenceWin32HandleKHR = 4825 (PFN_vkGetFenceWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetFenceWin32HandleKHR"); 4826 err = vkGetFenceWin32HandleKHR(m_device->device(), &ghi, &handle); 4827 ASSERT_VK_SUCCESS(err); 4828 } 4829 4830 // Import opaque handle exported above 4831 { 4832 VkImportFenceWin32HandleInfoKHR ifi = {VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR, 4833 nullptr, 4834 import_fence, 4835 VK_FENCE_IMPORT_TEMPORARY_BIT_KHR, 4836 handle_type, 4837 handle, 4838 nullptr}; 4839 auto vkImportFenceWin32HandleKHR = 4840 (PFN_vkImportFenceWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportFenceWin32HandleKHR"); 4841 err = vkImportFenceWin32HandleKHR(m_device->device(), &ifi); 4842 ASSERT_VK_SUCCESS(err); 4843 } 4844 #else 4845 // Export fence payload to an opaque handle 4846 int fd = 0; 4847 { 4848 VkFenceGetFdInfoKHR gfi = {VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR, nullptr, export_fence, handle_type}; 4849 auto vkGetFenceFdKHR = (PFN_vkGetFenceFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetFenceFdKHR"); 4850 err = vkGetFenceFdKHR(m_device->device(), &gfi, &fd); 4851 ASSERT_VK_SUCCESS(err); 4852 } 4853 4854 // Import opaque handle exported above 4855 { 4856 VkImportFenceFdInfoKHR ifi = {VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR, nullptr, import_fence, 4857 VK_FENCE_IMPORT_TEMPORARY_BIT_KHR, handle_type, fd}; 4858 auto vkImportFenceFdKHR = (PFN_vkImportFenceFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportFenceFdKHR"); 4859 err = vkImportFenceFdKHR(m_device->device(), &ifi); 4860 ASSERT_VK_SUCCESS(err); 4861 } 4862 #endif 4863 4864 // Undo the temporary import 4865 vkResetFences(m_device->device(), 1, &import_fence); 4866 4867 // Signal the previously imported fence twice, the second signal should produce a validation error 4868 vkQueueSubmit(m_device->m_queue, 0, nullptr, import_fence); 4869 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is already in use by another submission."); 4870 vkQueueSubmit(m_device->m_queue, 0, nullptr, import_fence); 4871 m_errorMonitor->VerifyFound(); 4872 4873 // Cleanup 4874 err = vkQueueWaitIdle(m_device->m_queue); 4875 ASSERT_VK_SUCCESS(err); 4876 vkDestroyFence(m_device->device(), export_fence, nullptr); 4877 vkDestroyFence(m_device->device(), import_fence, nullptr); 4878 } 4879 4880 TEST_F(VkPositiveLayerTest, SecondaryCommandBufferBarrier) { 4881 TEST_DESCRIPTION("Add a pipeline barrier in a secondary command buffer"); 4882 ASSERT_NO_FATAL_FAILURE(Init()); 4883 4884 // A renderpass with a single subpass that declared a self-dependency 4885 VkAttachmentDescription attach[] = { 4886 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 4887 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, 4888 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 4889 }; 4890 VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; 4891 VkSubpassDescription subpasses[] = { 4892 {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr}, 4893 }; 4894 VkSubpassDependency dep = {0, 4895 0, 4896 VK_PIPELINE_STAGE_HOST_BIT, 4897 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 4898 VK_ACCESS_HOST_WRITE_BIT, 4899 VK_ACCESS_SHADER_WRITE_BIT, 4900 VK_DEPENDENCY_BY_REGION_BIT}; 4901 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 1, &dep}; 4902 VkRenderPass rp; 4903 4904 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 4905 ASSERT_VK_SUCCESS(err); 4906 4907 VkImageObj image(m_device); 4908 image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 4909 VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM); 4910 4911 VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &imageView, 32, 32, 1}; 4912 VkFramebuffer fb; 4913 err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb); 4914 ASSERT_VK_SUCCESS(err); 4915 4916 m_commandBuffer->begin(); 4917 4918 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, 4919 nullptr, 4920 rp, 4921 fb, 4922 {{ 4923 0, 4924 0, 4925 }, 4926 {32, 32}}, 4927 0, 4928 nullptr}; 4929 4930 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); 4931 4932 VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); 4933 VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); 4934 4935 VkCommandBufferInheritanceInfo cbii = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 4936 nullptr, 4937 rp, 4938 0, 4939 VK_NULL_HANDLE, // Set to NULL FB handle intentionally to flesh out any errors 4940 VK_FALSE, 4941 0, 4942 0}; 4943 VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 4944 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, 4945 &cbii}; 4946 vkBeginCommandBuffer(secondary.handle(), &cbbi); 4947 VkMemoryBarrier mem_barrier = {}; 4948 mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; 4949 mem_barrier.pNext = NULL; 4950 mem_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; 4951 mem_barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT; 4952 vkCmdPipelineBarrier(secondary.handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 4953 VK_DEPENDENCY_BY_REGION_BIT, 1, &mem_barrier, 0, nullptr, 0, nullptr); 4954 VkImageMemoryBarrier img_barrier = {}; 4955 img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 4956 img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; 4957 img_barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT; 4958 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 4959 img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 4960 img_barrier.image = image.handle(); 4961 img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 4962 img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 4963 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 4964 img_barrier.subresourceRange.baseArrayLayer = 0; 4965 img_barrier.subresourceRange.baseMipLevel = 0; 4966 img_barrier.subresourceRange.layerCount = 1; 4967 img_barrier.subresourceRange.levelCount = 1; 4968 vkCmdPipelineBarrier(secondary.handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 4969 VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier); 4970 secondary.end(); 4971 4972 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle()); 4973 vkCmdEndRenderPass(m_commandBuffer->handle()); 4974 m_commandBuffer->end(); 4975 4976 VkSubmitInfo submit_info = {}; 4977 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 4978 submit_info.commandBufferCount = 1; 4979 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 4980 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 4981 vkQueueWaitIdle(m_device->m_queue); 4982 4983 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 4984 vkDestroyRenderPass(m_device->device(), rp, nullptr); 4985 } 4986 4987 TEST_F(VkLayerTest, RenderPassInvalidRenderArea) { 4988 TEST_DESCRIPTION("Generate INVALID_RENDER_AREA error by beginning renderpass with extent outside of framebuffer"); 4989 ASSERT_NO_FATAL_FAILURE(Init()); 4990 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 4991 4992 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 4993 "Cannot execute a render pass with renderArea not within the bound of the framebuffer."); 4994 4995 // Framebuffer for render target is 256x256, exceed that for INVALID_RENDER_AREA 4996 m_renderPassBeginInfo.renderArea.extent.width = 257; 4997 m_renderPassBeginInfo.renderArea.extent.height = 257; 4998 m_commandBuffer->begin(); 4999 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 5000 m_errorMonitor->VerifyFound(); 5001 } 5002 5003 TEST_F(VkLayerTest, DisabledIndependentBlend) { 5004 TEST_DESCRIPTION( 5005 "Generate INDEPENDENT_BLEND by disabling independent blend and then specifying different blend states for two " 5006 "attachements"); 5007 VkPhysicalDeviceFeatures features = {}; 5008 features.independentBlend = VK_FALSE; 5009 ASSERT_NO_FATAL_FAILURE(Init(&features)); 5010 5011 m_errorMonitor->SetDesiredFailureMsg( 5012 VK_DEBUG_REPORT_ERROR_BIT_EXT, 5013 "Invalid Pipeline CreateInfo: If independent blend feature not enabled, all elements of pAttachments must be identical"); 5014 5015 VkDescriptorSetObj descriptorSet(m_device); 5016 descriptorSet.AppendDummy(); 5017 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 5018 5019 VkPipelineObj pipeline(m_device); 5020 // Create a renderPass with two color attachments 5021 VkAttachmentReference attachments[2] = {}; 5022 attachments[0].layout = VK_IMAGE_LAYOUT_GENERAL; 5023 attachments[1].attachment = 1; 5024 attachments[1].layout = VK_IMAGE_LAYOUT_GENERAL; 5025 5026 VkSubpassDescription subpass = {}; 5027 subpass.pColorAttachments = attachments; 5028 subpass.colorAttachmentCount = 2; 5029 5030 VkRenderPassCreateInfo rpci = {}; 5031 rpci.subpassCount = 1; 5032 rpci.pSubpasses = &subpass; 5033 rpci.attachmentCount = 2; 5034 5035 VkAttachmentDescription attach_desc[2] = {}; 5036 attach_desc[0].format = VK_FORMAT_B8G8R8A8_UNORM; 5037 attach_desc[0].samples = VK_SAMPLE_COUNT_1_BIT; 5038 attach_desc[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 5039 attach_desc[0].finalLayout = VK_IMAGE_LAYOUT_GENERAL; 5040 attach_desc[1].format = VK_FORMAT_B8G8R8A8_UNORM; 5041 attach_desc[1].samples = VK_SAMPLE_COUNT_1_BIT; 5042 attach_desc[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 5043 attach_desc[1].finalLayout = VK_IMAGE_LAYOUT_GENERAL; 5044 5045 rpci.pAttachments = attach_desc; 5046 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 5047 5048 VkRenderPass renderpass; 5049 vkCreateRenderPass(m_device->device(), &rpci, NULL, &renderpass); 5050 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 5051 pipeline.AddShader(&vs); 5052 5053 VkPipelineColorBlendAttachmentState att_state1 = {}, att_state2 = {}; 5054 att_state1.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR; 5055 att_state1.blendEnable = VK_TRUE; 5056 att_state2.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR; 5057 att_state2.blendEnable = VK_FALSE; 5058 pipeline.AddColorAttachment(0, att_state1); 5059 pipeline.AddColorAttachment(1, att_state2); 5060 pipeline.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderpass); 5061 m_errorMonitor->VerifyFound(); 5062 vkDestroyRenderPass(m_device->device(), renderpass, NULL); 5063 } 5064 5065 // Is the Pipeline compatible with the expectations of the Renderpass/subpasses? 5066 TEST_F(VkLayerTest, PipelineRenderpassCompatibility) { 5067 TEST_DESCRIPTION( 5068 "Create a graphics pipeline that is incompatible with the requirements of its contained Renderpass/subpasses."); 5069 ASSERT_NO_FATAL_FAILURE(Init()); 5070 5071 VkDescriptorSetObj ds_obj(m_device); 5072 ds_obj.AppendDummy(); 5073 ds_obj.CreateVKDescriptorSet(m_commandBuffer); 5074 5075 VkShaderObj vs_obj(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 5076 5077 VkPipelineColorBlendAttachmentState att_state1 = {}; 5078 att_state1.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR; 5079 att_state1.blendEnable = VK_TRUE; 5080 5081 VkRenderpassObj rp_obj(m_device); 5082 5083 { 5084 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_096005e2); 5085 VkPipelineObj pipeline(m_device); 5086 pipeline.AddShader(&vs_obj); 5087 pipeline.AddColorAttachment(0, att_state1); 5088 5089 VkGraphicsPipelineCreateInfo info = {}; 5090 pipeline.InitGraphicsPipelineCreateInfo(&info); 5091 info.pColorBlendState = nullptr; 5092 5093 pipeline.CreateVKPipeline(ds_obj.GetPipelineLayout(), rp_obj.handle(), &info); 5094 m_errorMonitor->VerifyFound(); 5095 } 5096 } 5097 5098 TEST_F(VkLayerTest, CreateRenderPassAttachments) { 5099 TEST_DESCRIPTION( 5100 "Ensure that CreateRenderPass produces the expected validation errors when a subpass's attachments violate the valid usage " 5101 "conditions."); 5102 5103 ASSERT_NO_FATAL_FAILURE(Init()); 5104 5105 std::vector<VkAttachmentDescription> attachments = { 5106 // input attachments 5107 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 5108 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL}, 5109 // color attachments 5110 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 5111 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5112 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 5113 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 5114 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5115 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 5116 // depth attachment 5117 {0, VK_FORMAT_D24_UNORM_S8_UINT, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 5118 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 5119 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}, 5120 // resolve attachment 5121 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 5122 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5123 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 5124 // preserve attachments 5125 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 5126 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 5127 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 5128 }; 5129 5130 std::vector<VkAttachmentReference> input = { 5131 {0, VK_IMAGE_LAYOUT_GENERAL}, 5132 }; 5133 std::vector<VkAttachmentReference> color = { 5134 {1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 5135 {2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 5136 }; 5137 VkAttachmentReference depth = {3, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; 5138 std::vector<VkAttachmentReference> resolve = { 5139 {4, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 5140 {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 5141 }; 5142 std::vector<uint32_t> preserve = {5}; 5143 5144 VkSubpassDescription subpass = {0, 5145 VK_PIPELINE_BIND_POINT_GRAPHICS, 5146 (uint32_t)input.size(), 5147 input.data(), 5148 (uint32_t)color.size(), 5149 color.data(), 5150 resolve.data(), 5151 &depth, 5152 (uint32_t)preserve.size(), 5153 preserve.data()}; 5154 5155 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, 5156 nullptr, 5157 0, 5158 (uint32_t)attachments.size(), 5159 attachments.data(), 5160 1, 5161 &subpass, 5162 0, 5163 nullptr}; 5164 5165 VkRenderPass rp; 5166 VkResult err; 5167 // Test too many color attachments 5168 { 5169 std::vector<VkAttachmentReference> too_many_colors(m_device->props.limits.maxColorAttachments + 1, color[0]); 5170 subpass.colorAttachmentCount = (uint32_t)too_many_colors.size(); 5171 subpass.pColorAttachments = too_many_colors.data(); 5172 subpass.pResolveAttachments = NULL; 5173 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1400069a); 5174 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 5175 m_errorMonitor->VerifyFound(); 5176 if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); 5177 subpass.colorAttachmentCount = (uint32_t)color.size(); 5178 subpass.pColorAttachments = color.data(); 5179 subpass.pResolveAttachments = resolve.data(); 5180 } 5181 // Test sample count mismatch between color buffers 5182 attachments[subpass.pColorAttachments[1].attachment].samples = VK_SAMPLE_COUNT_8_BIT; 5183 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0082b401); 5184 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 5185 m_errorMonitor->VerifyFound(); 5186 if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); 5187 attachments[subpass.pColorAttachments[1].attachment].samples = attachments[subpass.pColorAttachments[0].attachment].samples; 5188 // Test sample count mismatch between color buffers and depth buffer 5189 attachments[subpass.pDepthStencilAttachment->attachment].samples = VK_SAMPLE_COUNT_8_BIT; 5190 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0082b401); 5191 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 5192 m_errorMonitor->VerifyFound(); 5193 if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); 5194 attachments[subpass.pDepthStencilAttachment->attachment].samples = attachments[subpass.pColorAttachments[0].attachment].samples; 5195 // Test resolve attachment with UNUSED color attachment 5196 color[0].attachment = VK_ATTACHMENT_UNUSED; 5197 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1400069e); 5198 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 5199 m_errorMonitor->VerifyFound(); 5200 if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); 5201 color[0].attachment = 1; 5202 // Test resolve from a single-sampled color attachment 5203 attachments[subpass.pColorAttachments[0].attachment].samples = VK_SAMPLE_COUNT_1_BIT; 5204 attachments[subpass.pColorAttachments[1].attachment].samples = VK_SAMPLE_COUNT_1_BIT; // avoid mismatch (00337) 5205 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_140006a0); 5206 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 5207 m_errorMonitor->VerifyFound(); 5208 if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); 5209 attachments[subpass.pColorAttachments[0].attachment].samples = VK_SAMPLE_COUNT_4_BIT; 5210 attachments[subpass.pColorAttachments[1].attachment].samples = VK_SAMPLE_COUNT_4_BIT; 5211 // Test resolve to a multi-sampled resolve attachment 5212 attachments[subpass.pResolveAttachments[0].attachment].samples = VK_SAMPLE_COUNT_4_BIT; 5213 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_140006a2); 5214 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 5215 m_errorMonitor->VerifyFound(); 5216 if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); 5217 attachments[subpass.pResolveAttachments[0].attachment].samples = VK_SAMPLE_COUNT_1_BIT; 5218 // Test with color/resolve format mismatch 5219 attachments[subpass.pColorAttachments[0].attachment].format = VK_FORMAT_R8G8B8A8_SRGB; 5220 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_140006a4); 5221 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 5222 m_errorMonitor->VerifyFound(); 5223 if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); 5224 attachments[subpass.pColorAttachments[0].attachment].format = attachments[subpass.pResolveAttachments[0].attachment].format; 5225 // Test for UNUSED preserve attachments 5226 preserve[0] = VK_ATTACHMENT_UNUSED; 5227 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_140006aa); 5228 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 5229 m_errorMonitor->VerifyFound(); 5230 if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); 5231 preserve[0] = 5; 5232 // Test for preserve attachments used elsewhere in the subpass 5233 color[0].attachment = preserve[0]; 5234 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_140006ac); 5235 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 5236 m_errorMonitor->VerifyFound(); 5237 if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); 5238 color[0].attachment = 1; 5239 // test for layout mismatch between input attachment and color attachment 5240 input[0].attachment = color[0].attachment; 5241 input[0].layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 5242 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_140006ae); 5243 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 5244 m_errorMonitor->VerifyFound(); 5245 if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); 5246 input[0].attachment = 0; 5247 input[0].layout = VK_IMAGE_LAYOUT_GENERAL; 5248 // test for layout mismatch between input attachment and depth attachment 5249 input[0].attachment = depth.attachment; 5250 input[0].layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 5251 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_140006ae); 5252 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 5253 m_errorMonitor->VerifyFound(); 5254 if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); 5255 input[0].attachment = 0; 5256 input[0].layout = VK_IMAGE_LAYOUT_GENERAL; 5257 // Test for attachment used first as input with loadOp=CLEAR 5258 { 5259 std::vector<VkSubpassDescription> subpasses = {subpass, subpass, subpass}; 5260 subpasses[0].inputAttachmentCount = 0; 5261 subpasses[1].inputAttachmentCount = 0; 5262 attachments[input[0].attachment].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 5263 VkRenderPassCreateInfo rpci_multipass = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, 5264 nullptr, 5265 0, 5266 (uint32_t)attachments.size(), 5267 attachments.data(), 5268 (uint32_t)subpasses.size(), 5269 subpasses.data(), 5270 0, 5271 nullptr}; 5272 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1400069c); 5273 err = vkCreateRenderPass(m_device->device(), &rpci_multipass, nullptr, &rp); 5274 m_errorMonitor->VerifyFound(); 5275 if (err == VK_SUCCESS) vkDestroyRenderPass(m_device->device(), rp, nullptr); 5276 attachments[input[0].attachment].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; 5277 } 5278 } 5279 5280 TEST_F(VkLayerTest, FramebufferCreateErrors) { 5281 TEST_DESCRIPTION( 5282 "Hit errors when attempting to create a framebuffer :\n" 5283 " 1. Mismatch between framebuffer & renderPass attachmentCount\n" 5284 " 2. Use a color image as depthStencil attachment\n" 5285 " 3. Mismatch framebuffer & renderPass attachment formats\n" 5286 " 4. Mismatch framebuffer & renderPass attachment #samples\n" 5287 " 5. Framebuffer attachment w/ non-1 mip-levels\n" 5288 " 6. Framebuffer attachment where dimensions don't match\n" 5289 " 7. Framebuffer attachment where dimensions don't match\n" 5290 " 8. Framebuffer attachment w/o identity swizzle\n" 5291 " 9. framebuffer dimensions exceed physical device limits\n"); 5292 5293 ASSERT_NO_FATAL_FAILURE(Init()); 5294 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 5295 5296 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006d8); 5297 5298 // Create a renderPass with a single color attachment 5299 VkAttachmentReference attach = {}; 5300 attach.layout = VK_IMAGE_LAYOUT_GENERAL; 5301 VkSubpassDescription subpass = {}; 5302 subpass.pColorAttachments = &attach; 5303 VkRenderPassCreateInfo rpci = {}; 5304 rpci.subpassCount = 1; 5305 rpci.pSubpasses = &subpass; 5306 rpci.attachmentCount = 1; 5307 VkAttachmentDescription attach_desc = {}; 5308 attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM; 5309 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; 5310 attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; 5311 rpci.pAttachments = &attach_desc; 5312 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 5313 VkRenderPass rp; 5314 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 5315 ASSERT_VK_SUCCESS(err); 5316 5317 VkImageView ivs[2]; 5318 ivs[0] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM); 5319 ivs[1] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM); 5320 VkFramebufferCreateInfo fb_info = {}; 5321 fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; 5322 fb_info.pNext = NULL; 5323 fb_info.renderPass = rp; 5324 // Set mis-matching attachmentCount 5325 fb_info.attachmentCount = 2; 5326 fb_info.pAttachments = ivs; 5327 fb_info.width = 100; 5328 fb_info.height = 100; 5329 fb_info.layers = 1; 5330 5331 VkFramebuffer fb; 5332 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 5333 5334 m_errorMonitor->VerifyFound(); 5335 if (err == VK_SUCCESS) { 5336 vkDestroyFramebuffer(m_device->device(), fb, NULL); 5337 } 5338 vkDestroyRenderPass(m_device->device(), rp, NULL); 5339 5340 // Create a renderPass with a depth-stencil attachment created with 5341 // IMAGE_USAGE_COLOR_ATTACHMENT 5342 // Add our color attachment to pDepthStencilAttachment 5343 subpass.pDepthStencilAttachment = &attach; 5344 subpass.pColorAttachments = NULL; 5345 VkRenderPass rp_ds; 5346 err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_ds); 5347 ASSERT_VK_SUCCESS(err); 5348 // Set correct attachment count, but attachment has COLOR usage bit set 5349 fb_info.attachmentCount = 1; 5350 fb_info.renderPass = rp_ds; 5351 5352 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006dc); 5353 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 5354 5355 m_errorMonitor->VerifyFound(); 5356 if (err == VK_SUCCESS) { 5357 vkDestroyFramebuffer(m_device->device(), fb, NULL); 5358 } 5359 vkDestroyRenderPass(m_device->device(), rp_ds, NULL); 5360 5361 // Create new renderpass with alternate attachment format from fb 5362 attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM; 5363 subpass.pDepthStencilAttachment = NULL; 5364 subpass.pColorAttachments = &attach; 5365 err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 5366 ASSERT_VK_SUCCESS(err); 5367 5368 // Cause error due to mis-matched formats between rp & fb 5369 // rp attachment 0 now has RGBA8 but corresponding fb attach is BGRA8 5370 fb_info.renderPass = rp; 5371 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006e0); 5372 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 5373 5374 m_errorMonitor->VerifyFound(); 5375 if (err == VK_SUCCESS) { 5376 vkDestroyFramebuffer(m_device->device(), fb, NULL); 5377 } 5378 vkDestroyRenderPass(m_device->device(), rp, NULL); 5379 5380 // Create new renderpass with alternate sample count from fb 5381 attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM; 5382 attach_desc.samples = VK_SAMPLE_COUNT_4_BIT; 5383 err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 5384 ASSERT_VK_SUCCESS(err); 5385 5386 // Cause error due to mis-matched sample count between rp & fb 5387 fb_info.renderPass = rp; 5388 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006e2); 5389 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 5390 5391 m_errorMonitor->VerifyFound(); 5392 if (err == VK_SUCCESS) { 5393 vkDestroyFramebuffer(m_device->device(), fb, NULL); 5394 } 5395 5396 vkDestroyRenderPass(m_device->device(), rp, NULL); 5397 5398 { 5399 // Create an image with 2 mip levels. 5400 VkImageObj image(m_device); 5401 image.Init(128, 128, 2, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 5402 ASSERT_TRUE(image.initialized()); 5403 5404 // Create a image view with two mip levels. 5405 VkImageView view; 5406 VkImageViewCreateInfo ivci = {}; 5407 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 5408 ivci.image = image.handle(); 5409 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; 5410 ivci.format = VK_FORMAT_B8G8R8A8_UNORM; 5411 ivci.subresourceRange.layerCount = 1; 5412 ivci.subresourceRange.baseMipLevel = 0; 5413 // Set level count to 2 (only 1 is allowed for FB attachment) 5414 ivci.subresourceRange.levelCount = 2; 5415 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 5416 err = vkCreateImageView(m_device->device(), &ivci, NULL, &view); 5417 ASSERT_VK_SUCCESS(err); 5418 5419 // Re-create renderpass to have matching sample count 5420 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; 5421 err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 5422 ASSERT_VK_SUCCESS(err); 5423 5424 fb_info.renderPass = rp; 5425 fb_info.pAttachments = &view; 5426 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006e6); 5427 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 5428 5429 m_errorMonitor->VerifyFound(); 5430 if (err == VK_SUCCESS) { 5431 vkDestroyFramebuffer(m_device->device(), fb, NULL); 5432 } 5433 vkDestroyImageView(m_device->device(), view, NULL); 5434 } 5435 5436 // Update view to original color buffer and grow FB dimensions too big 5437 fb_info.pAttachments = ivs; 5438 fb_info.height = 1024; 5439 fb_info.width = 1024; 5440 fb_info.layers = 2; 5441 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006e4); 5442 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 5443 5444 m_errorMonitor->VerifyFound(); 5445 if (err == VK_SUCCESS) { 5446 vkDestroyFramebuffer(m_device->device(), fb, NULL); 5447 } 5448 5449 { 5450 // Create an image with one mip level. 5451 VkImageObj image(m_device); 5452 image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 5453 ASSERT_TRUE(image.initialized()); 5454 5455 // Create view attachment with non-identity swizzle 5456 VkImageView view; 5457 VkImageViewCreateInfo ivci = {}; 5458 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 5459 ivci.image = image.handle(); 5460 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; 5461 ivci.format = VK_FORMAT_B8G8R8A8_UNORM; 5462 ivci.subresourceRange.layerCount = 1; 5463 ivci.subresourceRange.baseMipLevel = 0; 5464 ivci.subresourceRange.levelCount = 1; 5465 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 5466 ivci.components.r = VK_COMPONENT_SWIZZLE_G; 5467 ivci.components.g = VK_COMPONENT_SWIZZLE_R; 5468 ivci.components.b = VK_COMPONENT_SWIZZLE_A; 5469 ivci.components.a = VK_COMPONENT_SWIZZLE_B; 5470 err = vkCreateImageView(m_device->device(), &ivci, NULL, &view); 5471 ASSERT_VK_SUCCESS(err); 5472 5473 fb_info.pAttachments = &view; 5474 fb_info.height = 100; 5475 fb_info.width = 100; 5476 fb_info.layers = 1; 5477 5478 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006e8); 5479 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 5480 5481 m_errorMonitor->VerifyFound(); 5482 if (err == VK_SUCCESS) { 5483 vkDestroyFramebuffer(m_device->device(), fb, NULL); 5484 } 5485 vkDestroyImageView(m_device->device(), view, NULL); 5486 } 5487 5488 // reset attachment to color attachment 5489 fb_info.pAttachments = ivs; 5490 5491 // Request fb that exceeds max width 5492 fb_info.width = m_device->props.limits.maxFramebufferWidth + 1; 5493 fb_info.height = 100; 5494 fb_info.layers = 1; 5495 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006ec); 5496 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006e4); 5497 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 5498 m_errorMonitor->VerifyFound(); 5499 if (err == VK_SUCCESS) { 5500 vkDestroyFramebuffer(m_device->device(), fb, NULL); 5501 } 5502 // and width=0 5503 fb_info.width = 0; 5504 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006ea); 5505 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 5506 m_errorMonitor->VerifyFound(); 5507 if (err == VK_SUCCESS) { 5508 vkDestroyFramebuffer(m_device->device(), fb, NULL); 5509 } 5510 5511 // Request fb that exceeds max height 5512 fb_info.width = 100; 5513 fb_info.height = m_device->props.limits.maxFramebufferHeight + 1; 5514 fb_info.layers = 1; 5515 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006f0); 5516 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006e4); 5517 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 5518 m_errorMonitor->VerifyFound(); 5519 if (err == VK_SUCCESS) { 5520 vkDestroyFramebuffer(m_device->device(), fb, NULL); 5521 } 5522 // and height=0 5523 fb_info.height = 0; 5524 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006ee); 5525 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 5526 m_errorMonitor->VerifyFound(); 5527 if (err == VK_SUCCESS) { 5528 vkDestroyFramebuffer(m_device->device(), fb, NULL); 5529 } 5530 5531 // Request fb that exceeds max layers 5532 fb_info.width = 100; 5533 fb_info.height = 100; 5534 fb_info.layers = m_device->props.limits.maxFramebufferLayers + 1; 5535 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006f4); 5536 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006e4); 5537 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 5538 m_errorMonitor->VerifyFound(); 5539 if (err == VK_SUCCESS) { 5540 vkDestroyFramebuffer(m_device->device(), fb, NULL); 5541 } 5542 // and layers=0 5543 fb_info.layers = 0; 5544 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_094006f2); 5545 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 5546 m_errorMonitor->VerifyFound(); 5547 if (err == VK_SUCCESS) { 5548 vkDestroyFramebuffer(m_device->device(), fb, NULL); 5549 } 5550 5551 vkDestroyRenderPass(m_device->device(), rp, NULL); 5552 } 5553 5554 TEST_F(VkLayerTest, DynamicDepthBiasNotBound) { 5555 TEST_DESCRIPTION( 5556 "Run a simple draw calls to validate failure when Depth Bias dynamic state is required but not correctly bound."); 5557 5558 ASSERT_NO_FATAL_FAILURE(Init()); 5559 // Dynamic depth bias 5560 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic depth bias state not set for this command buffer"); 5561 VKTriangleTest(BsoFailDepthBias); 5562 m_errorMonitor->VerifyFound(); 5563 } 5564 5565 TEST_F(VkLayerTest, DynamicLineWidthNotBound) { 5566 TEST_DESCRIPTION( 5567 "Run a simple draw calls to validate failure when Line Width dynamic state is required but not correctly bound."); 5568 5569 ASSERT_NO_FATAL_FAILURE(Init()); 5570 // Dynamic line width 5571 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic line width state not set for this command buffer"); 5572 VKTriangleTest(BsoFailLineWidth); 5573 m_errorMonitor->VerifyFound(); 5574 } 5575 5576 TEST_F(VkLayerTest, DynamicViewportNotBound) { 5577 TEST_DESCRIPTION( 5578 "Run a simple draw calls to validate failure when Viewport dynamic state is required but not correctly bound."); 5579 5580 ASSERT_NO_FATAL_FAILURE(Init()); 5581 // Dynamic viewport state 5582 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 5583 "Dynamic viewport(s) 0 are used by pipeline state object, but were not provided"); 5584 VKTriangleTest(BsoFailViewport); 5585 m_errorMonitor->VerifyFound(); 5586 } 5587 5588 TEST_F(VkLayerTest, DynamicScissorNotBound) { 5589 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Scissor dynamic state is required but not correctly bound."); 5590 5591 ASSERT_NO_FATAL_FAILURE(Init()); 5592 // Dynamic scissor state 5593 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 5594 "Dynamic scissor(s) 0 are used by pipeline state object, but were not provided"); 5595 VKTriangleTest(BsoFailScissor); 5596 m_errorMonitor->VerifyFound(); 5597 } 5598 5599 TEST_F(VkLayerTest, DynamicBlendConstantsNotBound) { 5600 TEST_DESCRIPTION( 5601 "Run a simple draw calls to validate failure when Blend Constants dynamic state is required but not correctly bound."); 5602 5603 ASSERT_NO_FATAL_FAILURE(Init()); 5604 // Dynamic blend constant state 5605 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 5606 "Dynamic blend constants state not set for this command buffer"); 5607 VKTriangleTest(BsoFailBlend); 5608 m_errorMonitor->VerifyFound(); 5609 } 5610 5611 TEST_F(VkLayerTest, DynamicDepthBoundsNotBound) { 5612 TEST_DESCRIPTION( 5613 "Run a simple draw calls to validate failure when Depth Bounds dynamic state is required but not correctly bound."); 5614 5615 ASSERT_NO_FATAL_FAILURE(Init()); 5616 if (!m_device->phy().features().depthBounds) { 5617 printf(" Device does not support depthBounds test; skipped.\n"); 5618 return; 5619 } 5620 // Dynamic depth bounds 5621 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 5622 "Dynamic depth bounds state not set for this command buffer"); 5623 VKTriangleTest(BsoFailDepthBounds); 5624 m_errorMonitor->VerifyFound(); 5625 } 5626 5627 TEST_F(VkLayerTest, DynamicStencilReadNotBound) { 5628 TEST_DESCRIPTION( 5629 "Run a simple draw calls to validate failure when Stencil Read dynamic state is required but not correctly bound."); 5630 5631 ASSERT_NO_FATAL_FAILURE(Init()); 5632 // Dynamic stencil read mask 5633 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 5634 "Dynamic stencil read mask state not set for this command buffer"); 5635 VKTriangleTest(BsoFailStencilReadMask); 5636 m_errorMonitor->VerifyFound(); 5637 } 5638 5639 TEST_F(VkLayerTest, DynamicStencilWriteNotBound) { 5640 TEST_DESCRIPTION( 5641 "Run a simple draw calls to validate failure when Stencil Write dynamic state is required but not correctly bound."); 5642 5643 ASSERT_NO_FATAL_FAILURE(Init()); 5644 // Dynamic stencil write mask 5645 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 5646 "Dynamic stencil write mask state not set for this command buffer"); 5647 VKTriangleTest(BsoFailStencilWriteMask); 5648 m_errorMonitor->VerifyFound(); 5649 } 5650 5651 TEST_F(VkLayerTest, DynamicStencilRefNotBound) { 5652 TEST_DESCRIPTION( 5653 "Run a simple draw calls to validate failure when Stencil Ref dynamic state is required but not correctly bound."); 5654 5655 ASSERT_NO_FATAL_FAILURE(Init()); 5656 // Dynamic stencil reference 5657 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 5658 "Dynamic stencil reference state not set for this command buffer"); 5659 VKTriangleTest(BsoFailStencilReference); 5660 m_errorMonitor->VerifyFound(); 5661 } 5662 5663 TEST_F(VkLayerTest, IndexBufferNotBound) { 5664 TEST_DESCRIPTION("Run an indexed draw call without an index buffer bound."); 5665 5666 ASSERT_NO_FATAL_FAILURE(Init()); 5667 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 5668 "Index buffer object not bound to this command buffer when Indexed "); 5669 VKTriangleTest(BsoFailIndexBuffer); 5670 m_errorMonitor->VerifyFound(); 5671 } 5672 5673 TEST_F(VkLayerTest, CommandBufferTwoSubmits) { 5674 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 5675 "was begun w/ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has been submitted"); 5676 5677 ASSERT_NO_FATAL_FAILURE(Init()); 5678 ASSERT_NO_FATAL_FAILURE(InitViewport()); 5679 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 5680 5681 // We luck out b/c by default the framework creates CB w/ the 5682 // VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set 5683 m_commandBuffer->begin(); 5684 m_commandBuffer->ClearAllBuffers(m_renderTargets, m_clear_color, nullptr, m_depth_clear_color, m_stencil_clear_color); 5685 m_commandBuffer->end(); 5686 5687 // Bypass framework since it does the waits automatically 5688 VkResult err = VK_SUCCESS; 5689 VkSubmitInfo submit_info; 5690 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 5691 submit_info.pNext = NULL; 5692 submit_info.waitSemaphoreCount = 0; 5693 submit_info.pWaitSemaphores = NULL; 5694 submit_info.pWaitDstStageMask = NULL; 5695 submit_info.commandBufferCount = 1; 5696 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 5697 submit_info.signalSemaphoreCount = 0; 5698 submit_info.pSignalSemaphores = NULL; 5699 5700 err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 5701 ASSERT_VK_SUCCESS(err); 5702 vkQueueWaitIdle(m_device->m_queue); 5703 5704 // Cause validation error by re-submitting cmd buffer that should only be 5705 // submitted once 5706 err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 5707 vkQueueWaitIdle(m_device->m_queue); 5708 5709 m_errorMonitor->VerifyFound(); 5710 } 5711 5712 TEST_F(VkLayerTest, AllocDescriptorFromEmptyPool) { 5713 TEST_DESCRIPTION("Attempt to allocate more sets and descriptors than descriptor pool has available."); 5714 VkResult err; 5715 5716 ASSERT_NO_FATAL_FAILURE(Init()); 5717 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 5718 5719 // Create Pool w/ 1 Sampler descriptor, but try to alloc Uniform Buffer 5720 // descriptor from it 5721 VkDescriptorPoolSize ds_type_count = {}; 5722 ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER; 5723 ds_type_count.descriptorCount = 2; 5724 5725 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 5726 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 5727 ds_pool_ci.pNext = NULL; 5728 ds_pool_ci.flags = 0; 5729 ds_pool_ci.maxSets = 1; 5730 ds_pool_ci.poolSizeCount = 1; 5731 ds_pool_ci.pPoolSizes = &ds_type_count; 5732 5733 VkDescriptorPool ds_pool; 5734 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 5735 ASSERT_VK_SUCCESS(err); 5736 5737 VkDescriptorSetLayoutBinding dsl_binding_samp = {}; 5738 dsl_binding_samp.binding = 0; 5739 dsl_binding_samp.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 5740 dsl_binding_samp.descriptorCount = 1; 5741 dsl_binding_samp.stageFlags = VK_SHADER_STAGE_ALL; 5742 dsl_binding_samp.pImmutableSamplers = NULL; 5743 5744 const VkDescriptorSetLayoutObj ds_layout_samp(m_device, {dsl_binding_samp}); 5745 5746 // Try to allocate 2 sets when pool only has 1 set 5747 VkDescriptorSet descriptor_sets[2]; 5748 VkDescriptorSetLayout set_layouts[2] = {ds_layout_samp.handle(), ds_layout_samp.handle()}; 5749 VkDescriptorSetAllocateInfo alloc_info = {}; 5750 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 5751 alloc_info.descriptorSetCount = 2; 5752 alloc_info.descriptorPool = ds_pool; 5753 alloc_info.pSetLayouts = set_layouts; 5754 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_04c00264); 5755 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, descriptor_sets); 5756 m_errorMonitor->VerifyFound(); 5757 5758 alloc_info.descriptorSetCount = 1; 5759 // Create layout w/ descriptor type not available in pool 5760 VkDescriptorSetLayoutBinding dsl_binding = {}; 5761 dsl_binding.binding = 0; 5762 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 5763 dsl_binding.descriptorCount = 1; 5764 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 5765 dsl_binding.pImmutableSamplers = NULL; 5766 5767 const VkDescriptorSetLayoutObj ds_layout_ub(m_device, {dsl_binding}); 5768 5769 VkDescriptorSet descriptor_set; 5770 alloc_info.descriptorSetCount = 1; 5771 alloc_info.pSetLayouts = &ds_layout_ub.handle(); 5772 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_04c00266); 5773 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set); 5774 5775 m_errorMonitor->VerifyFound(); 5776 5777 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 5778 } 5779 5780 TEST_F(VkLayerTest, FreeDescriptorFromOneShotPool) { 5781 VkResult err; 5782 5783 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_28600270); 5784 5785 ASSERT_NO_FATAL_FAILURE(Init()); 5786 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 5787 5788 VkDescriptorPoolSize ds_type_count = {}; 5789 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 5790 ds_type_count.descriptorCount = 1; 5791 5792 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 5793 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 5794 ds_pool_ci.pNext = NULL; 5795 ds_pool_ci.maxSets = 1; 5796 ds_pool_ci.poolSizeCount = 1; 5797 ds_pool_ci.flags = 0; 5798 // Not specifying VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT means 5799 // app can only call vkResetDescriptorPool on this pool.; 5800 ds_pool_ci.pPoolSizes = &ds_type_count; 5801 5802 VkDescriptorPool ds_pool; 5803 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 5804 ASSERT_VK_SUCCESS(err); 5805 5806 VkDescriptorSetLayoutBinding dsl_binding = {}; 5807 dsl_binding.binding = 0; 5808 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 5809 dsl_binding.descriptorCount = 1; 5810 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 5811 dsl_binding.pImmutableSamplers = NULL; 5812 5813 const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding}); 5814 5815 VkDescriptorSet descriptorSet; 5816 VkDescriptorSetAllocateInfo alloc_info = {}; 5817 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 5818 alloc_info.descriptorSetCount = 1; 5819 alloc_info.descriptorPool = ds_pool; 5820 alloc_info.pSetLayouts = &ds_layout.handle(); 5821 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 5822 ASSERT_VK_SUCCESS(err); 5823 5824 err = vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptorSet); 5825 m_errorMonitor->VerifyFound(); 5826 5827 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 5828 } 5829 5830 TEST_F(VkLayerTest, InvalidDescriptorPool) { 5831 // Attempt to clear Descriptor Pool with bad object. 5832 // ObjectTracker should catch this. 5833 5834 ASSERT_NO_FATAL_FAILURE(Init()); 5835 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_32a04601); 5836 uint64_t fake_pool_handle = 0xbaad6001; 5837 VkDescriptorPool bad_pool = reinterpret_cast<VkDescriptorPool &>(fake_pool_handle); 5838 vkResetDescriptorPool(device(), bad_pool, 0); 5839 m_errorMonitor->VerifyFound(); 5840 } 5841 5842 TEST_F(VkLayerTest, InvalidDescriptorSet) { 5843 // Attempt to bind an invalid Descriptor Set to a valid Command Buffer 5844 // ObjectTracker should catch this. 5845 // Create a valid cmd buffer 5846 // call vkCmdBindDescriptorSets w/ false Descriptor Set 5847 5848 uint64_t fake_set_handle = 0xbaad6001; 5849 VkDescriptorSet bad_set = reinterpret_cast<VkDescriptorSet &>(fake_set_handle); 5850 5851 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_17c13001); 5852 5853 ASSERT_NO_FATAL_FAILURE(Init()); 5854 5855 VkDescriptorSetLayoutBinding layout_binding = {}; 5856 layout_binding.binding = 0; 5857 layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 5858 layout_binding.descriptorCount = 1; 5859 layout_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; 5860 layout_binding.pImmutableSamplers = NULL; 5861 5862 const VkDescriptorSetLayoutObj descriptor_set_layout(m_device, {layout_binding}); 5863 5864 const VkPipelineLayoutObj pipeline_layout(DeviceObj(), {&descriptor_set_layout}); 5865 5866 m_commandBuffer->begin(); 5867 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &bad_set, 0, 5868 NULL); 5869 m_errorMonitor->VerifyFound(); 5870 m_commandBuffer->end(); 5871 } 5872 5873 TEST_F(VkLayerTest, InvalidDescriptorSetLayout) { 5874 // Attempt to create a Pipeline Layout with an invalid Descriptor Set Layout. 5875 // ObjectTracker should catch this. 5876 uint64_t fake_layout_handle = 0xbaad6001; 5877 VkDescriptorSetLayout bad_layout = reinterpret_cast<VkDescriptorSetLayout &>(fake_layout_handle); 5878 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe22c01); 5879 ASSERT_NO_FATAL_FAILURE(Init()); 5880 VkPipelineLayout pipeline_layout; 5881 VkPipelineLayoutCreateInfo plci = {}; 5882 plci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 5883 plci.pNext = NULL; 5884 plci.setLayoutCount = 1; 5885 plci.pSetLayouts = &bad_layout; 5886 vkCreatePipelineLayout(device(), &plci, NULL, &pipeline_layout); 5887 5888 m_errorMonitor->VerifyFound(); 5889 } 5890 5891 TEST_F(VkLayerTest, WriteDescriptorSetIntegrityCheck) { 5892 TEST_DESCRIPTION( 5893 "This test verifies some requirements of chapter 13.2.3 of the Vulkan Spec " 5894 "1) A uniform buffer update must have a valid buffer index. " 5895 "2) When using an array of descriptors in a single WriteDescriptor, the descriptor types and stageflags " 5896 "must all be the same. " 5897 "3) Immutable Sampler state must match across descriptors"); 5898 5899 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15c00288); 5900 5901 ASSERT_NO_FATAL_FAILURE(Init()); 5902 VkDescriptorPoolSize ds_type_count[4] = {}; 5903 ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 5904 ds_type_count[0].descriptorCount = 1; 5905 ds_type_count[1].type = VK_DESCRIPTOR_TYPE_SAMPLER; 5906 ds_type_count[1].descriptorCount = 1; 5907 ds_type_count[2].type = VK_DESCRIPTOR_TYPE_SAMPLER; 5908 ds_type_count[2].descriptorCount = 1; 5909 ds_type_count[3].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; 5910 ds_type_count[3].descriptorCount = 1; 5911 5912 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 5913 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 5914 ds_pool_ci.maxSets = 1; 5915 ds_pool_ci.poolSizeCount = sizeof(ds_type_count) / sizeof(VkDescriptorPoolSize); 5916 ds_pool_ci.pPoolSizes = ds_type_count; 5917 5918 VkDescriptorPool ds_pool; 5919 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 5920 ASSERT_VK_SUCCESS(err); 5921 5922 VkDescriptorSetLayoutBinding dslb1 = {}; 5923 dslb1.binding = 0; 5924 dslb1.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 5925 dslb1.descriptorCount = 1; 5926 dslb1.stageFlags = VK_SHADER_STAGE_ALL; 5927 dslb1.pImmutableSamplers = NULL; 5928 5929 VkDescriptorSetLayoutBinding dslb2 = {}; 5930 dslb2.binding = 1; 5931 dslb2.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 5932 dslb2.descriptorCount = 1; 5933 dslb2.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 5934 dslb2.pImmutableSamplers = NULL; 5935 5936 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo(); 5937 VkSampler sampler; 5938 5939 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 5940 ASSERT_VK_SUCCESS(err); 5941 5942 VkDescriptorSetLayoutBinding dslb3 = {}; 5943 dslb3.binding = 2; 5944 dslb3.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 5945 dslb3.descriptorCount = 1; 5946 dslb3.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 5947 dslb3.pImmutableSamplers = static_cast<VkSampler *>(&sampler); 5948 5949 const std::vector<VkDescriptorSetLayoutBinding> layout_bindings = {dslb1, dslb2, dslb3}; 5950 const VkDescriptorSetLayoutObj ds_layout(m_device, layout_bindings); 5951 5952 VkDescriptorSetAllocateInfo alloc_info = {}; 5953 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 5954 alloc_info.descriptorSetCount = 1; 5955 alloc_info.descriptorPool = ds_pool; 5956 alloc_info.pSetLayouts = &ds_layout.handle(); 5957 VkDescriptorSet descriptorSet; 5958 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 5959 ASSERT_VK_SUCCESS(err); 5960 5961 VkWriteDescriptorSet descriptor_write = {}; 5962 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 5963 descriptor_write.dstSet = descriptorSet; 5964 descriptor_write.dstBinding = 0; 5965 descriptor_write.descriptorCount = 1; 5966 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 5967 5968 // 1) The uniform buffer is intentionally invalid here 5969 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 5970 m_errorMonitor->VerifyFound(); 5971 5972 // Create a buffer to update the descriptor with 5973 uint32_t qfi = 0; 5974 VkBufferCreateInfo buffCI = {}; 5975 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 5976 buffCI.size = 1024; 5977 buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 5978 buffCI.queueFamilyIndexCount = 1; 5979 buffCI.pQueueFamilyIndices = &qfi; 5980 5981 VkBuffer dyub; 5982 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub); 5983 ASSERT_VK_SUCCESS(err); 5984 5985 VkDeviceMemory mem; 5986 VkMemoryRequirements mem_reqs; 5987 vkGetBufferMemoryRequirements(m_device->device(), dyub, &mem_reqs); 5988 5989 VkMemoryAllocateInfo mem_alloc_info = {}; 5990 mem_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 5991 mem_alloc_info.allocationSize = mem_reqs.size; 5992 m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); 5993 err = vkAllocateMemory(m_device->device(), &mem_alloc_info, NULL, &mem); 5994 ASSERT_VK_SUCCESS(err); 5995 5996 err = vkBindBufferMemory(m_device->device(), dyub, mem, 0); 5997 ASSERT_VK_SUCCESS(err); 5998 5999 VkDescriptorBufferInfo buffInfo[2] = {}; 6000 buffInfo[0].buffer = dyub; 6001 buffInfo[0].offset = 0; 6002 buffInfo[0].range = 1024; 6003 buffInfo[1].buffer = dyub; 6004 buffInfo[1].offset = 0; 6005 buffInfo[1].range = 1024; 6006 descriptor_write.pBufferInfo = buffInfo; 6007 descriptor_write.descriptorCount = 2; 6008 6009 // 2) The stateFlags don't match between the first and second descriptor 6010 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15c00282); 6011 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 6012 m_errorMonitor->VerifyFound(); 6013 6014 // 3) The second descriptor has a null_ptr pImmutableSamplers and 6015 // the third descriptor contains an immutable sampler 6016 descriptor_write.dstBinding = 1; 6017 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 6018 6019 // Make pImageInfo index non-null to avoid complaints of it missing 6020 VkDescriptorImageInfo imageInfo = {}; 6021 imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 6022 descriptor_write.pImageInfo = &imageInfo; 6023 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15c00282); 6024 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 6025 m_errorMonitor->VerifyFound(); 6026 6027 vkDestroyBuffer(m_device->device(), dyub, NULL); 6028 vkFreeMemory(m_device->device(), mem, NULL); 6029 vkDestroySampler(m_device->device(), sampler, NULL); 6030 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 6031 } 6032 6033 TEST_F(VkLayerTest, WriteDescriptorSetConsecutiveUpdates) { 6034 TEST_DESCRIPTION( 6035 "Verifies that updates rolling over to next descriptor work correctly by destroying buffer from consecutive update known " 6036 "to be used in descriptor set and verifying that error is flagged."); 6037 6038 ASSERT_NO_FATAL_FAILURE(Init()); 6039 ASSERT_NO_FATAL_FAILURE(InitViewport()); 6040 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 6041 6042 OneOffDescriptorSet ds(m_device, { 6043 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2, VK_SHADER_STAGE_ALL, nullptr}, 6044 {1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, 6045 }); 6046 6047 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_}); 6048 6049 uint32_t qfi = 0; 6050 VkBufferCreateInfo bci = {}; 6051 bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 6052 bci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 6053 bci.size = 2048; 6054 bci.queueFamilyIndexCount = 1; 6055 bci.pQueueFamilyIndices = &qfi; 6056 vk_testing::Buffer buffer0; 6057 buffer0.init(*m_device, bci); 6058 VkPipelineObj pipe(m_device); 6059 { // Scope 2nd buffer to cause early destruction 6060 vk_testing::Buffer buffer1; 6061 bci.size = 1024; 6062 buffer1.init(*m_device, bci); 6063 6064 VkDescriptorBufferInfo buffer_info[3] = {}; 6065 buffer_info[0].buffer = buffer0.handle(); 6066 buffer_info[0].offset = 0; 6067 buffer_info[0].range = 1024; 6068 buffer_info[1].buffer = buffer0.handle(); 6069 buffer_info[1].offset = 1024; 6070 buffer_info[1].range = 1024; 6071 buffer_info[2].buffer = buffer1.handle(); 6072 buffer_info[2].offset = 0; 6073 buffer_info[2].range = 1024; 6074 6075 VkWriteDescriptorSet descriptor_write = {}; 6076 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 6077 descriptor_write.dstSet = ds.set_; // descriptor_set; 6078 descriptor_write.dstBinding = 0; 6079 descriptor_write.descriptorCount = 3; 6080 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 6081 descriptor_write.pBufferInfo = buffer_info; 6082 6083 // Update descriptor 6084 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 6085 6086 // Create PSO that uses the uniform buffers 6087 char const *vsSource = 6088 "#version 450\n" 6089 "\n" 6090 "void main(){\n" 6091 " gl_Position = vec4(1);\n" 6092 "}\n"; 6093 char const *fsSource = 6094 "#version 450\n" 6095 "\n" 6096 "layout(location=0) out vec4 x;\n" 6097 "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n" 6098 "layout(set=0) layout(binding=1) uniform blah { int x; } duh;\n" 6099 "void main(){\n" 6100 " x = vec4(duh.x, bar.y, bar.x, 1);\n" 6101 "}\n"; 6102 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 6103 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 6104 6105 pipe.AddShader(&vs); 6106 pipe.AddShader(&fs); 6107 pipe.AddDefaultColorAttachment(); 6108 6109 VkResult err = pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 6110 ASSERT_VK_SUCCESS(err); 6111 6112 m_commandBuffer->begin(); 6113 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 6114 6115 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 6116 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, 6117 &ds.set_, 0, nullptr); 6118 6119 VkViewport viewport = {0, 0, 16, 16, 0, 1}; 6120 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 6121 VkRect2D scissor = {{0, 0}, {16, 16}}; 6122 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 6123 vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); 6124 vkCmdEndRenderPass(m_commandBuffer->handle()); 6125 m_commandBuffer->end(); 6126 } 6127 // buffer2 just went out of scope and was destroyed along with its memory 6128 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Buffer "); 6129 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound DeviceMemory "); 6130 VkSubmitInfo submit_info = {}; 6131 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 6132 submit_info.commandBufferCount = 1; 6133 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 6134 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 6135 m_errorMonitor->VerifyFound(); 6136 } 6137 6138 TEST_F(VkLayerTest, CreatePipelineLayoutExceedsSetLimit) { 6139 TEST_DESCRIPTION("Attempt to create a pipeline layout using more than the physical limit of SetLayouts."); 6140 6141 ASSERT_NO_FATAL_FAILURE(Init()); 6142 6143 VkDescriptorSetLayoutBinding layout_binding = {}; 6144 layout_binding.binding = 0; 6145 layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 6146 layout_binding.descriptorCount = 1; 6147 layout_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; 6148 layout_binding.pImmutableSamplers = NULL; 6149 6150 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 6151 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 6152 ds_layout_ci.bindingCount = 1; 6153 ds_layout_ci.pBindings = &layout_binding; 6154 VkDescriptorSetLayout ds_layout = {}; 6155 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 6156 ASSERT_VK_SUCCESS(err); 6157 6158 // Create an array of DSLs, one larger than the physical limit 6159 const auto excess_layouts = 1 + m_device->phy().properties().limits.maxBoundDescriptorSets; 6160 std::vector<VkDescriptorSetLayout> dsl_array(excess_layouts, ds_layout); 6161 6162 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 6163 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 6164 pipeline_layout_ci.pNext = NULL; 6165 pipeline_layout_ci.setLayoutCount = excess_layouts; 6166 pipeline_layout_ci.pSetLayouts = dsl_array.data(); 6167 6168 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe0023c); 6169 VkPipelineLayout pipeline_layout = VK_NULL_HANDLE; 6170 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 6171 m_errorMonitor->VerifyFound(); 6172 6173 // Clean up 6174 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 6175 } 6176 6177 TEST_F(VkLayerTest, CreatePipelineLayoutExcessPerStageDescriptors) { 6178 TEST_DESCRIPTION("Attempt to create a pipeline layout where total descriptors exceed per-stage limits"); 6179 6180 ASSERT_NO_FATAL_FAILURE(Init()); 6181 6182 uint32_t max_uniform_buffers = m_device->phy().properties().limits.maxPerStageDescriptorUniformBuffers; 6183 uint32_t max_storage_buffers = m_device->phy().properties().limits.maxPerStageDescriptorStorageBuffers; 6184 uint32_t max_sampled_images = m_device->phy().properties().limits.maxPerStageDescriptorSampledImages; 6185 uint32_t max_storage_images = m_device->phy().properties().limits.maxPerStageDescriptorStorageImages; 6186 uint32_t max_samplers = m_device->phy().properties().limits.maxPerStageDescriptorSamplers; 6187 uint32_t max_combined = std::min(max_samplers, max_sampled_images); 6188 uint32_t max_input_attachments = m_device->phy().properties().limits.maxPerStageDescriptorInputAttachments; 6189 6190 uint32_t sum_dyn_uniform_buffers = m_device->phy().properties().limits.maxDescriptorSetUniformBuffersDynamic; 6191 uint32_t sum_uniform_buffers = m_device->phy().properties().limits.maxDescriptorSetUniformBuffers; 6192 uint32_t sum_dyn_storage_buffers = m_device->phy().properties().limits.maxDescriptorSetStorageBuffersDynamic; 6193 uint32_t sum_storage_buffers = m_device->phy().properties().limits.maxDescriptorSetStorageBuffers; 6194 uint32_t sum_sampled_images = m_device->phy().properties().limits.maxDescriptorSetSampledImages; 6195 uint32_t sum_storage_images = m_device->phy().properties().limits.maxDescriptorSetStorageImages; 6196 uint32_t sum_samplers = m_device->phy().properties().limits.maxDescriptorSetSamplers; 6197 uint32_t sum_input_attachments = m_device->phy().properties().limits.maxDescriptorSetInputAttachments; 6198 6199 uint32_t gfx_stages = 2; // vtx, frag 6200 gfx_stages += (m_device->phy().features().geometryShader ? 1 : 0); 6201 gfx_stages += (m_device->phy().features().tessellationShader ? 2 : 0); 6202 6203 // Devices that report UINT_MAX for any of these limits can't run this test 6204 if (UINT_MAX == std::max({max_uniform_buffers, max_storage_buffers, max_sampled_images, max_storage_images, max_samplers})) { 6205 printf(" Physical device limits report as 2^32-1. Skipping test.\n"); 6206 return; 6207 } 6208 6209 VkDescriptorSetLayoutBinding dslb = {}; 6210 std::vector<VkDescriptorSetLayoutBinding> dslb_vec = {}; 6211 VkDescriptorSetLayout ds_layout = VK_NULL_HANDLE; 6212 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 6213 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 6214 ds_layout_ci.pNext = NULL; 6215 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 6216 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 6217 pipeline_layout_ci.pNext = NULL; 6218 pipeline_layout_ci.setLayoutCount = 1; 6219 pipeline_layout_ci.pSetLayouts = &ds_layout; 6220 VkPipelineLayout pipeline_layout = VK_NULL_HANDLE; 6221 6222 // VU 0fe0023e - too many sampler type descriptors in fragment stage 6223 dslb_vec.clear(); 6224 dslb.binding = 0; 6225 dslb.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 6226 dslb.descriptorCount = max_samplers; 6227 dslb.stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS; 6228 dslb.pImmutableSamplers = NULL; 6229 dslb_vec.push_back(dslb); 6230 dslb.binding = 1; 6231 dslb.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 6232 dslb.descriptorCount = max_combined; 6233 dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 6234 dslb_vec.push_back(dslb); 6235 6236 ds_layout_ci.bindingCount = dslb_vec.size(); 6237 ds_layout_ci.pBindings = dslb_vec.data(); 6238 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 6239 ASSERT_VK_SUCCESS(err); 6240 6241 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe0023e); 6242 if ((max_samplers * gfx_stages + max_combined) > sum_samplers) { 6243 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6244 VALIDATION_ERROR_0fe00d1a); // expect all-stages sum too 6245 } 6246 if (max_combined > sum_sampled_images) { 6247 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6248 VALIDATION_ERROR_0fe00d24); // expect all-stages sum too 6249 } 6250 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 6251 m_errorMonitor->VerifyFound(); 6252 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed 6253 pipeline_layout = VK_NULL_HANDLE; 6254 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 6255 6256 // VU 0fe00240 - too many uniform buffer type descriptors in vertex stage 6257 dslb_vec.clear(); 6258 dslb.binding = 0; 6259 dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 6260 dslb.descriptorCount = 1 + (max_uniform_buffers / 2); 6261 dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; 6262 dslb_vec.push_back(dslb); 6263 dslb.binding = 1; 6264 dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 6265 dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; 6266 dslb_vec.push_back(dslb); 6267 6268 ds_layout_ci.bindingCount = dslb_vec.size(); 6269 ds_layout_ci.pBindings = dslb_vec.data(); 6270 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 6271 ASSERT_VK_SUCCESS(err); 6272 6273 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00240); 6274 if ((2 * dslb.descriptorCount) > sum_uniform_buffers) { 6275 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6276 VALIDATION_ERROR_0fe00d1c); // expect all-stages sum too 6277 } 6278 if (dslb.descriptorCount > sum_dyn_uniform_buffers) { 6279 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6280 VALIDATION_ERROR_0fe00d1e); // expect all-stages sum too 6281 } 6282 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 6283 m_errorMonitor->VerifyFound(); 6284 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed 6285 pipeline_layout = VK_NULL_HANDLE; 6286 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 6287 6288 // VU 0fe00242 - too many storage buffer type descriptors in compute stage 6289 dslb_vec.clear(); 6290 dslb.binding = 0; 6291 dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; 6292 dslb.descriptorCount = 1 + (max_storage_buffers / 3); 6293 dslb.stageFlags = VK_SHADER_STAGE_ALL; 6294 dslb_vec.push_back(dslb); 6295 dslb.binding = 1; 6296 dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC; 6297 dslb_vec.push_back(dslb); 6298 dslb.binding = 2; 6299 dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; 6300 dslb.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; 6301 dslb_vec.push_back(dslb); 6302 6303 ds_layout_ci.bindingCount = dslb_vec.size(); 6304 ds_layout_ci.pBindings = dslb_vec.data(); 6305 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 6306 ASSERT_VK_SUCCESS(err); 6307 6308 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00242); 6309 if (((gfx_stages + 1) * dslb.descriptorCount) > sum_dyn_storage_buffers) { 6310 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6311 VALIDATION_ERROR_0fe00d22); // expect all-stages sum too 6312 } 6313 if (((gfx_stages + 2) * dslb.descriptorCount) > sum_storage_buffers) { 6314 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6315 VALIDATION_ERROR_0fe00d20); // expect all-stages sum too 6316 } 6317 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 6318 m_errorMonitor->VerifyFound(); 6319 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed 6320 pipeline_layout = VK_NULL_HANDLE; 6321 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 6322 6323 // VU 0fe00244 - too many sampled image type descriptors in multiple stages 6324 dslb_vec.clear(); 6325 dslb.binding = 0; 6326 dslb.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; 6327 dslb.descriptorCount = max_sampled_images / 2; 6328 dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; 6329 dslb_vec.push_back(dslb); 6330 dslb.binding = 1; 6331 dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; 6332 dslb.stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS; 6333 dslb_vec.push_back(dslb); 6334 dslb.binding = 2; 6335 dslb.descriptorCount = max_combined; 6336 dslb.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 6337 dslb_vec.push_back(dslb); 6338 6339 ds_layout_ci.bindingCount = dslb_vec.size(); 6340 ds_layout_ci.pBindings = dslb_vec.data(); 6341 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 6342 ASSERT_VK_SUCCESS(err); 6343 6344 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00244); 6345 if (max_combined + ((gfx_stages + 2) * (max_sampled_images / 2)) > sum_sampled_images) { 6346 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6347 VALIDATION_ERROR_0fe00d24); // expect all-stages sum too 6348 } 6349 if ((gfx_stages * max_combined) > sum_samplers) { 6350 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6351 VALIDATION_ERROR_0fe00d1a); // expect all-stages sum too 6352 } 6353 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 6354 m_errorMonitor->VerifyFound(); 6355 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed 6356 pipeline_layout = VK_NULL_HANDLE; 6357 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 6358 6359 // VU 0fe00246 - too many storage image type descriptors in fragment stage 6360 dslb_vec.clear(); 6361 dslb.binding = 0; 6362 dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; 6363 dslb.descriptorCount = 1 + (max_storage_images / 2); 6364 dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 6365 dslb_vec.push_back(dslb); 6366 dslb.binding = 1; 6367 dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 6368 dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT; 6369 dslb_vec.push_back(dslb); 6370 6371 ds_layout_ci.bindingCount = dslb_vec.size(); 6372 ds_layout_ci.pBindings = dslb_vec.data(); 6373 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 6374 ASSERT_VK_SUCCESS(err); 6375 6376 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00246); 6377 if ((4 * dslb.descriptorCount) > sum_storage_images) { 6378 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6379 VALIDATION_ERROR_0fe00d26); // expect all-stages sum too 6380 } 6381 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 6382 m_errorMonitor->VerifyFound(); 6383 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed 6384 pipeline_layout = VK_NULL_HANDLE; 6385 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 6386 6387 // VU 0fe00d18 - too many input attachments in fragment stage 6388 dslb_vec.clear(); 6389 dslb.binding = 0; 6390 dslb.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; 6391 dslb.descriptorCount = 1 + max_input_attachments; 6392 dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 6393 dslb_vec.push_back(dslb); 6394 6395 ds_layout_ci.bindingCount = dslb_vec.size(); 6396 ds_layout_ci.pBindings = dslb_vec.data(); 6397 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 6398 ASSERT_VK_SUCCESS(err); 6399 6400 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00d18); 6401 if (dslb.descriptorCount > sum_input_attachments) { 6402 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6403 VALIDATION_ERROR_0fe00d28); // expect all-stages sum too 6404 } 6405 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 6406 m_errorMonitor->VerifyFound(); 6407 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed 6408 pipeline_layout = VK_NULL_HANDLE; 6409 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 6410 } 6411 6412 TEST_F(VkLayerTest, CreatePipelineLayoutExcessDescriptorsOverall) { 6413 TEST_DESCRIPTION("Attempt to create a pipeline layout where total descriptors summed over all stages exceed limits"); 6414 6415 ASSERT_NO_FATAL_FAILURE(Init()); 6416 6417 uint32_t max_uniform_buffers = m_device->phy().properties().limits.maxPerStageDescriptorUniformBuffers; 6418 uint32_t max_storage_buffers = m_device->phy().properties().limits.maxPerStageDescriptorStorageBuffers; 6419 uint32_t max_sampled_images = m_device->phy().properties().limits.maxPerStageDescriptorSampledImages; 6420 uint32_t max_storage_images = m_device->phy().properties().limits.maxPerStageDescriptorStorageImages; 6421 uint32_t max_samplers = m_device->phy().properties().limits.maxPerStageDescriptorSamplers; 6422 uint32_t max_input_attachments = m_device->phy().properties().limits.maxPerStageDescriptorInputAttachments; 6423 6424 uint32_t sum_dyn_uniform_buffers = m_device->phy().properties().limits.maxDescriptorSetUniformBuffersDynamic; 6425 uint32_t sum_uniform_buffers = m_device->phy().properties().limits.maxDescriptorSetUniformBuffers; 6426 uint32_t sum_dyn_storage_buffers = m_device->phy().properties().limits.maxDescriptorSetStorageBuffersDynamic; 6427 uint32_t sum_storage_buffers = m_device->phy().properties().limits.maxDescriptorSetStorageBuffers; 6428 uint32_t sum_sampled_images = m_device->phy().properties().limits.maxDescriptorSetSampledImages; 6429 uint32_t sum_storage_images = m_device->phy().properties().limits.maxDescriptorSetStorageImages; 6430 uint32_t sum_samplers = m_device->phy().properties().limits.maxDescriptorSetSamplers; 6431 uint32_t sum_input_attachments = m_device->phy().properties().limits.maxDescriptorSetInputAttachments; 6432 6433 // Devices that report UINT_MAX for any of these limits can't run this test 6434 if (UINT_MAX == std::max({sum_dyn_uniform_buffers, sum_uniform_buffers, sum_dyn_storage_buffers, sum_storage_buffers, 6435 sum_sampled_images, sum_storage_images, sum_samplers, sum_input_attachments})) { 6436 printf(" Physical device limits report as 2^32-1. Skipping test.\n"); 6437 return; 6438 } 6439 6440 VkDescriptorSetLayoutBinding dslb = {}; 6441 std::vector<VkDescriptorSetLayoutBinding> dslb_vec = {}; 6442 VkDescriptorSetLayout ds_layout = VK_NULL_HANDLE; 6443 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 6444 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 6445 ds_layout_ci.pNext = NULL; 6446 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 6447 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 6448 pipeline_layout_ci.pNext = NULL; 6449 pipeline_layout_ci.setLayoutCount = 1; 6450 pipeline_layout_ci.pSetLayouts = &ds_layout; 6451 VkPipelineLayout pipeline_layout = VK_NULL_HANDLE; 6452 6453 // VU 0fe00d1a - too many sampler type descriptors overall 6454 dslb_vec.clear(); 6455 dslb.binding = 0; 6456 dslb.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 6457 dslb.descriptorCount = 1 + (sum_samplers / 2); 6458 dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; 6459 dslb.pImmutableSamplers = NULL; 6460 dslb_vec.push_back(dslb); 6461 dslb.binding = 1; 6462 dslb.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 6463 dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 6464 dslb_vec.push_back(dslb); 6465 6466 ds_layout_ci.bindingCount = dslb_vec.size(); 6467 ds_layout_ci.pBindings = dslb_vec.data(); 6468 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 6469 ASSERT_VK_SUCCESS(err); 6470 6471 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00d1a); 6472 if (dslb.descriptorCount > max_samplers) { 6473 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6474 VALIDATION_ERROR_0fe0023e); // expect max-per-stage too 6475 } 6476 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 6477 m_errorMonitor->VerifyFound(); 6478 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed 6479 pipeline_layout = VK_NULL_HANDLE; 6480 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 6481 6482 // VU 0fe00d1c - too many uniform buffer type descriptors overall 6483 dslb_vec.clear(); 6484 dslb.binding = 0; 6485 dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 6486 dslb.descriptorCount = 1 + (sum_uniform_buffers / 2); 6487 dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; 6488 dslb.pImmutableSamplers = NULL; 6489 dslb_vec.push_back(dslb); 6490 6491 ds_layout_ci.bindingCount = dslb_vec.size(); 6492 ds_layout_ci.pBindings = dslb_vec.data(); 6493 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 6494 ASSERT_VK_SUCCESS(err); 6495 6496 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00d1c); 6497 if (dslb.descriptorCount > max_uniform_buffers) { 6498 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6499 VALIDATION_ERROR_0fe00240); // expect max-per-stage too 6500 } 6501 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 6502 m_errorMonitor->VerifyFound(); 6503 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed 6504 pipeline_layout = VK_NULL_HANDLE; 6505 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 6506 6507 // VU 0fe00d1e - too many dynamic uniform buffer type descriptors overall 6508 dslb_vec.clear(); 6509 dslb.binding = 0; 6510 dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 6511 dslb.descriptorCount = 1 + (sum_dyn_uniform_buffers / 2); 6512 dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; 6513 dslb.pImmutableSamplers = NULL; 6514 dslb_vec.push_back(dslb); 6515 6516 ds_layout_ci.bindingCount = dslb_vec.size(); 6517 ds_layout_ci.pBindings = dslb_vec.data(); 6518 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 6519 ASSERT_VK_SUCCESS(err); 6520 6521 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00d1e); 6522 if (dslb.descriptorCount > max_uniform_buffers) { 6523 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6524 VALIDATION_ERROR_0fe00240); // expect max-per-stage too 6525 } 6526 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 6527 m_errorMonitor->VerifyFound(); 6528 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed 6529 pipeline_layout = VK_NULL_HANDLE; 6530 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 6531 6532 // VU 0fe00d20 - too many storage buffer type descriptors overall 6533 dslb_vec.clear(); 6534 dslb.binding = 0; 6535 dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; 6536 dslb.descriptorCount = 1 + (sum_storage_buffers / 2); 6537 dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; 6538 dslb.pImmutableSamplers = NULL; 6539 dslb_vec.push_back(dslb); 6540 6541 ds_layout_ci.bindingCount = dslb_vec.size(); 6542 ds_layout_ci.pBindings = dslb_vec.data(); 6543 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 6544 ASSERT_VK_SUCCESS(err); 6545 6546 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00d20); 6547 if (dslb.descriptorCount > max_storage_buffers) { 6548 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6549 VALIDATION_ERROR_0fe00242); // expect max-per-stage too 6550 } 6551 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 6552 m_errorMonitor->VerifyFound(); 6553 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed 6554 pipeline_layout = VK_NULL_HANDLE; 6555 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 6556 6557 // VU 0fe00d22 - too many dynamic storage buffer type descriptors overall 6558 dslb_vec.clear(); 6559 dslb.binding = 0; 6560 dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC; 6561 dslb.descriptorCount = 1 + (sum_dyn_storage_buffers / 2); 6562 dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; 6563 dslb.pImmutableSamplers = NULL; 6564 dslb_vec.push_back(dslb); 6565 6566 ds_layout_ci.bindingCount = dslb_vec.size(); 6567 ds_layout_ci.pBindings = dslb_vec.data(); 6568 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 6569 ASSERT_VK_SUCCESS(err); 6570 6571 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00d22); 6572 if (dslb.descriptorCount > max_storage_buffers) { 6573 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6574 VALIDATION_ERROR_0fe00242); // expect max-per-stage too 6575 } 6576 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 6577 m_errorMonitor->VerifyFound(); 6578 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed 6579 pipeline_layout = VK_NULL_HANDLE; 6580 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 6581 6582 // VU 0fe00d24 - too many sampled image type descriptors overall 6583 dslb_vec.clear(); 6584 dslb.binding = 0; 6585 dslb.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 6586 dslb.descriptorCount = max_samplers; 6587 dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; 6588 dslb.pImmutableSamplers = NULL; 6589 dslb_vec.push_back(dslb); 6590 dslb.binding = 1; 6591 dslb.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; 6592 uint32_t remaining = (max_samplers > sum_sampled_images ? 0 : (sum_sampled_images - max_samplers) / 2); 6593 dslb.descriptorCount = 1 + remaining; 6594 dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 6595 dslb_vec.push_back(dslb); 6596 dslb.binding = 2; 6597 dslb.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; 6598 dslb.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; 6599 dslb_vec.push_back(dslb); 6600 6601 ds_layout_ci.bindingCount = dslb_vec.size(); 6602 ds_layout_ci.pBindings = dslb_vec.data(); 6603 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 6604 ASSERT_VK_SUCCESS(err); 6605 6606 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00d24); 6607 if (dslb.descriptorCount > max_sampled_images) { 6608 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6609 VALIDATION_ERROR_0fe00244); // expect max-per-stage too 6610 } 6611 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 6612 m_errorMonitor->VerifyFound(); 6613 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed 6614 pipeline_layout = VK_NULL_HANDLE; 6615 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 6616 6617 // VU 0fe00d26 - too many storage image type descriptors overall 6618 dslb_vec.clear(); 6619 dslb.binding = 0; 6620 dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; 6621 dslb.descriptorCount = 1 + (sum_storage_images / 2); 6622 dslb.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; 6623 dslb.pImmutableSamplers = NULL; 6624 dslb_vec.push_back(dslb); 6625 dslb.binding = 1; 6626 dslb.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 6627 dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 6628 dslb_vec.push_back(dslb); 6629 6630 ds_layout_ci.bindingCount = dslb_vec.size(); 6631 ds_layout_ci.pBindings = dslb_vec.data(); 6632 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 6633 ASSERT_VK_SUCCESS(err); 6634 6635 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00d26); 6636 if (dslb.descriptorCount > max_storage_images) { 6637 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6638 VALIDATION_ERROR_0fe00246); // expect max-per-stage too 6639 } 6640 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 6641 m_errorMonitor->VerifyFound(); 6642 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed 6643 pipeline_layout = VK_NULL_HANDLE; 6644 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 6645 6646 // VU 0fe00d28 - too many input attachment type descriptors overall 6647 dslb_vec.clear(); 6648 dslb.binding = 0; 6649 dslb.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; 6650 dslb.descriptorCount = 1 + (sum_input_attachments / 2); 6651 dslb.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT; 6652 dslb.pImmutableSamplers = NULL; 6653 dslb_vec.push_back(dslb); 6654 6655 ds_layout_ci.bindingCount = dslb_vec.size(); 6656 ds_layout_ci.pBindings = dslb_vec.data(); 6657 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 6658 ASSERT_VK_SUCCESS(err); 6659 6660 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe00d28); 6661 if (dslb.descriptorCount > max_input_attachments) { 6662 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6663 VALIDATION_ERROR_0fe00d18); // expect max-per-stage too 6664 } 6665 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 6666 m_errorMonitor->VerifyFound(); 6667 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); // Unnecessary but harmless if test passed 6668 pipeline_layout = VK_NULL_HANDLE; 6669 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 6670 } 6671 6672 TEST_F(VkLayerTest, InvalidCmdBufferBufferDestroyed) { 6673 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid due to a buffer dependency being destroyed."); 6674 ASSERT_NO_FATAL_FAILURE(Init()); 6675 6676 VkBuffer buffer; 6677 VkDeviceMemory mem; 6678 VkMemoryRequirements mem_reqs; 6679 6680 VkBufferCreateInfo buf_info = {}; 6681 buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 6682 buf_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT; 6683 buf_info.size = 256; 6684 buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 6685 VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer); 6686 ASSERT_VK_SUCCESS(err); 6687 6688 vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs); 6689 6690 VkMemoryAllocateInfo alloc_info = {}; 6691 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 6692 alloc_info.allocationSize = mem_reqs.size; 6693 bool pass = false; 6694 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); 6695 if (!pass) { 6696 vkDestroyBuffer(m_device->device(), buffer, NULL); 6697 return; 6698 } 6699 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem); 6700 ASSERT_VK_SUCCESS(err); 6701 6702 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0); 6703 ASSERT_VK_SUCCESS(err); 6704 6705 m_commandBuffer->begin(); 6706 vkCmdFillBuffer(m_commandBuffer->handle(), buffer, 0, VK_WHOLE_SIZE, 0); 6707 m_commandBuffer->end(); 6708 6709 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Buffer "); 6710 // Destroy buffer dependency prior to submit to cause ERROR 6711 vkDestroyBuffer(m_device->device(), buffer, NULL); 6712 6713 VkSubmitInfo submit_info = {}; 6714 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 6715 submit_info.commandBufferCount = 1; 6716 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 6717 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 6718 6719 m_errorMonitor->VerifyFound(); 6720 vkQueueWaitIdle(m_device->m_queue); 6721 vkFreeMemory(m_device->handle(), mem, NULL); 6722 } 6723 6724 TEST_F(VkLayerTest, InvalidCmdBufferBufferViewDestroyed) { 6725 TEST_DESCRIPTION("Delete bufferView bound to cmd buffer, then attempt to submit cmd buffer."); 6726 6727 ASSERT_NO_FATAL_FAILURE(Init()); 6728 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 6729 6730 VkDescriptorPoolSize ds_type_count; 6731 ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 6732 ds_type_count.descriptorCount = 1; 6733 6734 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 6735 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 6736 ds_pool_ci.maxSets = 1; 6737 ds_pool_ci.poolSizeCount = 1; 6738 ds_pool_ci.pPoolSizes = &ds_type_count; 6739 6740 VkDescriptorPool ds_pool; 6741 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 6742 ASSERT_VK_SUCCESS(err); 6743 6744 VkDescriptorSetLayoutBinding layout_binding; 6745 layout_binding.binding = 0; 6746 layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 6747 layout_binding.descriptorCount = 1; 6748 layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 6749 layout_binding.pImmutableSamplers = NULL; 6750 6751 const VkDescriptorSetLayoutObj ds_layout(m_device, {layout_binding}); 6752 6753 VkDescriptorSetAllocateInfo alloc_info = {}; 6754 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 6755 alloc_info.descriptorSetCount = 1; 6756 alloc_info.descriptorPool = ds_pool; 6757 alloc_info.pSetLayouts = &ds_layout.handle(); 6758 VkDescriptorSet descriptor_set; 6759 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set); 6760 ASSERT_VK_SUCCESS(err); 6761 6762 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout}); 6763 6764 VkBuffer buffer; 6765 uint32_t queue_family_index = 0; 6766 VkBufferCreateInfo buffer_create_info = {}; 6767 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 6768 buffer_create_info.size = 1024; 6769 buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; 6770 buffer_create_info.queueFamilyIndexCount = 1; 6771 buffer_create_info.pQueueFamilyIndices = &queue_family_index; 6772 6773 err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer); 6774 ASSERT_VK_SUCCESS(err); 6775 6776 VkMemoryRequirements memory_reqs; 6777 VkDeviceMemory buffer_memory; 6778 6779 VkMemoryAllocateInfo memory_info = {}; 6780 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 6781 memory_info.allocationSize = 0; 6782 memory_info.memoryTypeIndex = 0; 6783 6784 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs); 6785 memory_info.allocationSize = memory_reqs.size; 6786 bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 6787 ASSERT_TRUE(pass); 6788 6789 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory); 6790 ASSERT_VK_SUCCESS(err); 6791 err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0); 6792 ASSERT_VK_SUCCESS(err); 6793 6794 VkBufferView view; 6795 VkBufferViewCreateInfo bvci = {}; 6796 bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; 6797 bvci.buffer = buffer; 6798 bvci.format = VK_FORMAT_R32_SFLOAT; 6799 bvci.range = VK_WHOLE_SIZE; 6800 6801 err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view); 6802 ASSERT_VK_SUCCESS(err); 6803 6804 VkWriteDescriptorSet descriptor_write = {}; 6805 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 6806 descriptor_write.dstSet = descriptor_set; 6807 descriptor_write.dstBinding = 0; 6808 descriptor_write.descriptorCount = 1; 6809 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 6810 descriptor_write.pTexelBufferView = &view; 6811 6812 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 6813 6814 char const *vsSource = 6815 "#version 450\n" 6816 "\n" 6817 "void main(){\n" 6818 " gl_Position = vec4(1);\n" 6819 "}\n"; 6820 char const *fsSource = 6821 "#version 450\n" 6822 "\n" 6823 "layout(set=0, binding=0, r32f) uniform imageBuffer s;\n" 6824 "layout(location=0) out vec4 x;\n" 6825 "void main(){\n" 6826 " x = imageLoad(s, 0);\n" 6827 "}\n"; 6828 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 6829 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 6830 VkPipelineObj pipe(m_device); 6831 pipe.AddShader(&vs); 6832 pipe.AddShader(&fs); 6833 pipe.AddDefaultColorAttachment(); 6834 pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 6835 6836 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound BufferView "); 6837 6838 m_commandBuffer->begin(); 6839 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 6840 6841 VkViewport viewport = {0, 0, 16, 16, 0, 1}; 6842 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 6843 VkRect2D scissor = {{0, 0}, {16, 16}}; 6844 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 6845 // Bind pipeline to cmd buffer - This causes crash on Mali 6846 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 6847 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, 6848 &descriptor_set, 0, nullptr); 6849 m_commandBuffer->Draw(1, 0, 0, 0); 6850 m_commandBuffer->EndRenderPass(); 6851 m_commandBuffer->end(); 6852 6853 // Delete BufferView in order to invalidate cmd buffer 6854 vkDestroyBufferView(m_device->device(), view, NULL); 6855 // Now attempt submit of cmd buffer 6856 VkSubmitInfo submit_info = {}; 6857 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 6858 submit_info.commandBufferCount = 1; 6859 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 6860 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 6861 m_errorMonitor->VerifyFound(); 6862 6863 // Clean-up 6864 vkDestroyBuffer(m_device->device(), buffer, NULL); 6865 vkFreeMemory(m_device->device(), buffer_memory, NULL); 6866 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 6867 } 6868 6869 TEST_F(VkLayerTest, InvalidCmdBufferImageDestroyed) { 6870 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid due to an image dependency being destroyed."); 6871 ASSERT_NO_FATAL_FAILURE(Init()); 6872 6873 VkImage image; 6874 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 6875 VkImageCreateInfo image_create_info = {}; 6876 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 6877 image_create_info.pNext = NULL; 6878 image_create_info.imageType = VK_IMAGE_TYPE_2D; 6879 image_create_info.format = tex_format; 6880 image_create_info.extent.width = 32; 6881 image_create_info.extent.height = 32; 6882 image_create_info.extent.depth = 1; 6883 image_create_info.mipLevels = 1; 6884 image_create_info.arrayLayers = 1; 6885 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 6886 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 6887 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 6888 image_create_info.flags = 0; 6889 VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 6890 ASSERT_VK_SUCCESS(err); 6891 // Have to bind memory to image before recording cmd in cmd buffer using it 6892 VkMemoryRequirements mem_reqs; 6893 VkDeviceMemory image_mem; 6894 bool pass; 6895 VkMemoryAllocateInfo mem_alloc = {}; 6896 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 6897 mem_alloc.pNext = NULL; 6898 mem_alloc.memoryTypeIndex = 0; 6899 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs); 6900 mem_alloc.allocationSize = mem_reqs.size; 6901 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0); 6902 ASSERT_TRUE(pass); 6903 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem); 6904 ASSERT_VK_SUCCESS(err); 6905 err = vkBindImageMemory(m_device->device(), image, image_mem, 0); 6906 ASSERT_VK_SUCCESS(err); 6907 6908 m_commandBuffer->begin(); 6909 VkClearColorValue ccv; 6910 ccv.float32[0] = 1.0f; 6911 ccv.float32[1] = 1.0f; 6912 ccv.float32[2] = 1.0f; 6913 ccv.float32[3] = 1.0f; 6914 VkImageSubresourceRange isr = {}; 6915 isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 6916 isr.baseArrayLayer = 0; 6917 isr.baseMipLevel = 0; 6918 isr.layerCount = 1; 6919 isr.levelCount = 1; 6920 vkCmdClearColorImage(m_commandBuffer->handle(), image, VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &isr); 6921 m_commandBuffer->end(); 6922 6923 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Image "); 6924 // Destroy image dependency prior to submit to cause ERROR 6925 vkDestroyImage(m_device->device(), image, NULL); 6926 6927 VkSubmitInfo submit_info = {}; 6928 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 6929 submit_info.commandBufferCount = 1; 6930 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 6931 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 6932 6933 m_errorMonitor->VerifyFound(); 6934 vkFreeMemory(m_device->device(), image_mem, nullptr); 6935 } 6936 6937 TEST_F(VkLayerTest, InvalidCmdBufferFramebufferImageDestroyed) { 6938 TEST_DESCRIPTION( 6939 "Attempt to draw with a command buffer that is invalid due to a framebuffer image dependency being destroyed."); 6940 ASSERT_NO_FATAL_FAILURE(Init()); 6941 VkFormatProperties format_properties; 6942 VkResult err = VK_SUCCESS; 6943 vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties); 6944 if (!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { 6945 return; 6946 } 6947 6948 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 6949 6950 VkImageCreateInfo image_ci = {}; 6951 image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 6952 image_ci.pNext = NULL; 6953 image_ci.imageType = VK_IMAGE_TYPE_2D; 6954 image_ci.format = VK_FORMAT_B8G8R8A8_UNORM; 6955 image_ci.extent.width = 32; 6956 image_ci.extent.height = 32; 6957 image_ci.extent.depth = 1; 6958 image_ci.mipLevels = 1; 6959 image_ci.arrayLayers = 1; 6960 image_ci.samples = VK_SAMPLE_COUNT_1_BIT; 6961 image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; 6962 image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; 6963 image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 6964 image_ci.flags = 0; 6965 VkImage image; 6966 ASSERT_VK_SUCCESS(vkCreateImage(m_device->handle(), &image_ci, NULL, &image)); 6967 6968 VkMemoryRequirements memory_reqs; 6969 VkDeviceMemory image_memory; 6970 bool pass; 6971 VkMemoryAllocateInfo memory_info = {}; 6972 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 6973 memory_info.pNext = NULL; 6974 memory_info.allocationSize = 0; 6975 memory_info.memoryTypeIndex = 0; 6976 vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs); 6977 memory_info.allocationSize = memory_reqs.size; 6978 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 6979 ASSERT_TRUE(pass); 6980 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory); 6981 ASSERT_VK_SUCCESS(err); 6982 err = vkBindImageMemory(m_device->device(), image, image_memory, 0); 6983 ASSERT_VK_SUCCESS(err); 6984 6985 VkImageViewCreateInfo ivci = { 6986 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 6987 nullptr, 6988 0, 6989 image, 6990 VK_IMAGE_VIEW_TYPE_2D, 6991 VK_FORMAT_B8G8R8A8_UNORM, 6992 {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A}, 6993 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}, 6994 }; 6995 VkImageView view; 6996 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view); 6997 ASSERT_VK_SUCCESS(err); 6998 6999 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 32, 32, 1}; 7000 VkFramebuffer fb; 7001 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); 7002 ASSERT_VK_SUCCESS(err); 7003 7004 // Just use default renderpass with our framebuffer 7005 m_renderPassBeginInfo.framebuffer = fb; 7006 m_renderPassBeginInfo.renderArea.extent.width = 32; 7007 m_renderPassBeginInfo.renderArea.extent.height = 32; 7008 // Create Null cmd buffer for submit 7009 m_commandBuffer->begin(); 7010 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 7011 m_commandBuffer->EndRenderPass(); 7012 m_commandBuffer->end(); 7013 // Destroy image attached to framebuffer to invalidate cmd buffer 7014 vkDestroyImage(m_device->device(), image, NULL); 7015 // Now attempt to submit cmd buffer and verify error 7016 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Image "); 7017 m_commandBuffer->QueueCommandBuffer(false); 7018 m_errorMonitor->VerifyFound(); 7019 7020 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 7021 vkDestroyImageView(m_device->device(), view, nullptr); 7022 vkFreeMemory(m_device->device(), image_memory, nullptr); 7023 } 7024 7025 TEST_F(VkLayerTest, FramebufferInUseDestroyedSignaled) { 7026 TEST_DESCRIPTION("Delete in-use framebuffer."); 7027 ASSERT_NO_FATAL_FAILURE(Init()); 7028 VkFormatProperties format_properties; 7029 VkResult err = VK_SUCCESS; 7030 vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties); 7031 7032 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7033 7034 VkImageObj image(m_device); 7035 image.Init(256, 256, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 7036 ASSERT_TRUE(image.initialized()); 7037 VkImageView view = image.targetView(VK_FORMAT_B8G8R8A8_UNORM); 7038 7039 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 256, 256, 1}; 7040 VkFramebuffer fb; 7041 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); 7042 ASSERT_VK_SUCCESS(err); 7043 7044 // Just use default renderpass with our framebuffer 7045 m_renderPassBeginInfo.framebuffer = fb; 7046 // Create Null cmd buffer for submit 7047 m_commandBuffer->begin(); 7048 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 7049 m_commandBuffer->EndRenderPass(); 7050 m_commandBuffer->end(); 7051 // Submit cmd buffer to put it in-flight 7052 VkSubmitInfo submit_info = {}; 7053 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 7054 submit_info.commandBufferCount = 1; 7055 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 7056 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 7057 // Destroy framebuffer while in-flight 7058 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_250006f8); 7059 vkDestroyFramebuffer(m_device->device(), fb, NULL); 7060 m_errorMonitor->VerifyFound(); 7061 // Wait for queue to complete so we can safely destroy everything 7062 vkQueueWaitIdle(m_device->m_queue); 7063 m_errorMonitor->SetUnexpectedError("If framebuffer is not VK_NULL_HANDLE, framebuffer must be a valid VkFramebuffer handle"); 7064 m_errorMonitor->SetUnexpectedError("Unable to remove Framebuffer obj"); 7065 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 7066 } 7067 7068 TEST_F(VkLayerTest, FramebufferImageInUseDestroyedSignaled) { 7069 TEST_DESCRIPTION("Delete in-use image that's child of framebuffer."); 7070 ASSERT_NO_FATAL_FAILURE(Init()); 7071 VkFormatProperties format_properties; 7072 VkResult err = VK_SUCCESS; 7073 vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties); 7074 7075 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7076 7077 VkImageCreateInfo image_ci = {}; 7078 image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 7079 image_ci.pNext = NULL; 7080 image_ci.imageType = VK_IMAGE_TYPE_2D; 7081 image_ci.format = VK_FORMAT_B8G8R8A8_UNORM; 7082 image_ci.extent.width = 256; 7083 image_ci.extent.height = 256; 7084 image_ci.extent.depth = 1; 7085 image_ci.mipLevels = 1; 7086 image_ci.arrayLayers = 1; 7087 image_ci.samples = VK_SAMPLE_COUNT_1_BIT; 7088 image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; 7089 image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 7090 image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 7091 image_ci.flags = 0; 7092 VkImage image; 7093 ASSERT_VK_SUCCESS(vkCreateImage(m_device->handle(), &image_ci, NULL, &image)); 7094 7095 VkMemoryRequirements memory_reqs; 7096 VkDeviceMemory image_memory; 7097 bool pass; 7098 VkMemoryAllocateInfo memory_info = {}; 7099 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 7100 memory_info.pNext = NULL; 7101 memory_info.allocationSize = 0; 7102 memory_info.memoryTypeIndex = 0; 7103 vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs); 7104 memory_info.allocationSize = memory_reqs.size; 7105 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 7106 ASSERT_TRUE(pass); 7107 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory); 7108 ASSERT_VK_SUCCESS(err); 7109 err = vkBindImageMemory(m_device->device(), image, image_memory, 0); 7110 ASSERT_VK_SUCCESS(err); 7111 7112 VkImageViewCreateInfo ivci = { 7113 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 7114 nullptr, 7115 0, 7116 image, 7117 VK_IMAGE_VIEW_TYPE_2D, 7118 VK_FORMAT_B8G8R8A8_UNORM, 7119 {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A}, 7120 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}, 7121 }; 7122 VkImageView view; 7123 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view); 7124 ASSERT_VK_SUCCESS(err); 7125 7126 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 256, 256, 1}; 7127 VkFramebuffer fb; 7128 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); 7129 ASSERT_VK_SUCCESS(err); 7130 7131 // Just use default renderpass with our framebuffer 7132 m_renderPassBeginInfo.framebuffer = fb; 7133 // Create Null cmd buffer for submit 7134 m_commandBuffer->begin(); 7135 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 7136 m_commandBuffer->EndRenderPass(); 7137 m_commandBuffer->end(); 7138 // Submit cmd buffer to put it (and attached imageView) in-flight 7139 VkSubmitInfo submit_info = {}; 7140 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 7141 submit_info.commandBufferCount = 1; 7142 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 7143 // Submit cmd buffer to put framebuffer and children in-flight 7144 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 7145 // Destroy image attached to framebuffer while in-flight 7146 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_252007d0); 7147 vkDestroyImage(m_device->device(), image, NULL); 7148 m_errorMonitor->VerifyFound(); 7149 // Wait for queue to complete so we can safely destroy image and other objects 7150 vkQueueWaitIdle(m_device->m_queue); 7151 m_errorMonitor->SetUnexpectedError("If image is not VK_NULL_HANDLE, image must be a valid VkImage handle"); 7152 m_errorMonitor->SetUnexpectedError("Unable to remove Image obj"); 7153 vkDestroyImage(m_device->device(), image, NULL); 7154 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 7155 vkDestroyImageView(m_device->device(), view, nullptr); 7156 vkFreeMemory(m_device->device(), image_memory, nullptr); 7157 } 7158 7159 TEST_F(VkLayerTest, RenderPassInUseDestroyedSignaled) { 7160 TEST_DESCRIPTION("Delete in-use renderPass."); 7161 7162 ASSERT_NO_FATAL_FAILURE(Init()); 7163 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7164 7165 // Create simple renderpass 7166 VkAttachmentReference attach = {}; 7167 attach.layout = VK_IMAGE_LAYOUT_GENERAL; 7168 VkSubpassDescription subpass = {}; 7169 subpass.colorAttachmentCount = 1; 7170 subpass.pColorAttachments = &attach; 7171 VkRenderPassCreateInfo rpci = {}; 7172 rpci.subpassCount = 1; 7173 rpci.pSubpasses = &subpass; 7174 rpci.attachmentCount = 1; 7175 VkAttachmentDescription attach_desc = {}; 7176 attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM; 7177 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; 7178 attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; 7179 rpci.pAttachments = &attach_desc; 7180 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 7181 VkRenderPass rp; 7182 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 7183 ASSERT_VK_SUCCESS(err); 7184 7185 m_errorMonitor->ExpectSuccess(); 7186 7187 m_commandBuffer->begin(); 7188 VkRenderPassBeginInfo rpbi = {}; 7189 rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; 7190 rpbi.framebuffer = m_framebuffer; 7191 rpbi.renderPass = rp; 7192 m_commandBuffer->BeginRenderPass(rpbi); 7193 m_commandBuffer->EndRenderPass(); 7194 m_commandBuffer->end(); 7195 7196 VkSubmitInfo submit_info = {}; 7197 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 7198 submit_info.commandBufferCount = 1; 7199 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 7200 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 7201 m_errorMonitor->VerifyNotFound(); 7202 7203 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_264006d2); 7204 vkDestroyRenderPass(m_device->device(), rp, nullptr); 7205 m_errorMonitor->VerifyFound(); 7206 7207 // Wait for queue to complete so we can safely destroy rp 7208 vkQueueWaitIdle(m_device->m_queue); 7209 m_errorMonitor->SetUnexpectedError("If renderPass is not VK_NULL_HANDLE, renderPass must be a valid VkRenderPass handle"); 7210 m_errorMonitor->SetUnexpectedError("Was it created? Has it already been destroyed?"); 7211 vkDestroyRenderPass(m_device->device(), rp, nullptr); 7212 } 7213 7214 TEST_F(VkLayerTest, ImageMemoryNotBound) { 7215 TEST_DESCRIPTION("Attempt to draw with an image which has not had memory bound to it."); 7216 ASSERT_NO_FATAL_FAILURE(Init()); 7217 7218 VkImage image; 7219 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 7220 VkImageCreateInfo image_create_info = {}; 7221 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 7222 image_create_info.pNext = NULL; 7223 image_create_info.imageType = VK_IMAGE_TYPE_2D; 7224 image_create_info.format = tex_format; 7225 image_create_info.extent.width = 32; 7226 image_create_info.extent.height = 32; 7227 image_create_info.extent.depth = 1; 7228 image_create_info.mipLevels = 1; 7229 image_create_info.arrayLayers = 1; 7230 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 7231 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 7232 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 7233 image_create_info.flags = 0; 7234 VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 7235 ASSERT_VK_SUCCESS(err); 7236 // Have to bind memory to image before recording cmd in cmd buffer using it 7237 VkMemoryRequirements mem_reqs; 7238 VkDeviceMemory image_mem; 7239 bool pass; 7240 VkMemoryAllocateInfo mem_alloc = {}; 7241 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 7242 mem_alloc.pNext = NULL; 7243 mem_alloc.memoryTypeIndex = 0; 7244 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs); 7245 mem_alloc.allocationSize = mem_reqs.size; 7246 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0); 7247 ASSERT_TRUE(pass); 7248 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem); 7249 ASSERT_VK_SUCCESS(err); 7250 7251 // Introduce error, do not call vkBindImageMemory(m_device->device(), image, image_mem, 0); 7252 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 7253 " used with no memory bound. Memory should be bound by calling vkBindImageMemory()."); 7254 7255 m_commandBuffer->begin(); 7256 VkClearColorValue ccv; 7257 ccv.float32[0] = 1.0f; 7258 ccv.float32[1] = 1.0f; 7259 ccv.float32[2] = 1.0f; 7260 ccv.float32[3] = 1.0f; 7261 VkImageSubresourceRange isr = {}; 7262 isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 7263 isr.baseArrayLayer = 0; 7264 isr.baseMipLevel = 0; 7265 isr.layerCount = 1; 7266 isr.levelCount = 1; 7267 vkCmdClearColorImage(m_commandBuffer->handle(), image, VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &isr); 7268 m_commandBuffer->end(); 7269 7270 m_errorMonitor->VerifyFound(); 7271 vkDestroyImage(m_device->device(), image, NULL); 7272 vkFreeMemory(m_device->device(), image_mem, nullptr); 7273 } 7274 7275 TEST_F(VkLayerTest, BufferMemoryNotBound) { 7276 TEST_DESCRIPTION("Attempt to copy from a buffer which has not had memory bound to it."); 7277 ASSERT_NO_FATAL_FAILURE(Init()); 7278 7279 VkImageObj image(m_device); 7280 image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 7281 VK_IMAGE_TILING_OPTIMAL, 0); 7282 ASSERT_TRUE(image.initialized()); 7283 7284 VkBuffer buffer; 7285 VkDeviceMemory mem; 7286 VkMemoryRequirements mem_reqs; 7287 7288 VkBufferCreateInfo buf_info = {}; 7289 buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 7290 buf_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; 7291 buf_info.size = 1024; 7292 buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 7293 VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer); 7294 ASSERT_VK_SUCCESS(err); 7295 7296 vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs); 7297 7298 VkMemoryAllocateInfo alloc_info = {}; 7299 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 7300 alloc_info.allocationSize = 1024; 7301 bool pass = false; 7302 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); 7303 if (!pass) { 7304 vkDestroyBuffer(m_device->device(), buffer, NULL); 7305 return; 7306 } 7307 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem); 7308 ASSERT_VK_SUCCESS(err); 7309 7310 // Introduce failure by not calling vkBindBufferMemory(m_device->device(), buffer, mem, 0); 7311 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 7312 " used with no memory bound. Memory should be bound by calling vkBindBufferMemory()."); 7313 VkBufferImageCopy region = {}; 7314 region.bufferRowLength = 16; 7315 region.bufferImageHeight = 16; 7316 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 7317 7318 region.imageSubresource.layerCount = 1; 7319 region.imageExtent.height = 4; 7320 region.imageExtent.width = 4; 7321 region.imageExtent.depth = 1; 7322 m_commandBuffer->begin(); 7323 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer, image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); 7324 m_commandBuffer->end(); 7325 7326 m_errorMonitor->VerifyFound(); 7327 7328 vkDestroyBuffer(m_device->device(), buffer, NULL); 7329 vkFreeMemory(m_device->handle(), mem, NULL); 7330 } 7331 7332 TEST_F(VkLayerTest, InvalidCmdBufferEventDestroyed) { 7333 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid due to an event dependency being destroyed."); 7334 ASSERT_NO_FATAL_FAILURE(Init()); 7335 7336 VkEvent event; 7337 VkEventCreateInfo evci = {}; 7338 evci.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 7339 VkResult result = vkCreateEvent(m_device->device(), &evci, NULL, &event); 7340 ASSERT_VK_SUCCESS(result); 7341 7342 m_commandBuffer->begin(); 7343 vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); 7344 m_commandBuffer->end(); 7345 7346 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Event "); 7347 // Destroy event dependency prior to submit to cause ERROR 7348 vkDestroyEvent(m_device->device(), event, NULL); 7349 7350 VkSubmitInfo submit_info = {}; 7351 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 7352 submit_info.commandBufferCount = 1; 7353 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 7354 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 7355 7356 m_errorMonitor->VerifyFound(); 7357 } 7358 7359 TEST_F(VkLayerTest, InvalidCmdBufferQueryPoolDestroyed) { 7360 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid due to a query pool dependency being destroyed."); 7361 ASSERT_NO_FATAL_FAILURE(Init()); 7362 7363 VkQueryPool query_pool; 7364 VkQueryPoolCreateInfo qpci{}; 7365 qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; 7366 qpci.queryType = VK_QUERY_TYPE_TIMESTAMP; 7367 qpci.queryCount = 1; 7368 VkResult result = vkCreateQueryPool(m_device->device(), &qpci, nullptr, &query_pool); 7369 ASSERT_VK_SUCCESS(result); 7370 7371 m_commandBuffer->begin(); 7372 vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1); 7373 m_commandBuffer->end(); 7374 7375 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound QueryPool "); 7376 // Destroy query pool dependency prior to submit to cause ERROR 7377 vkDestroyQueryPool(m_device->device(), query_pool, NULL); 7378 7379 VkSubmitInfo submit_info = {}; 7380 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 7381 submit_info.commandBufferCount = 1; 7382 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 7383 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 7384 7385 m_errorMonitor->VerifyFound(); 7386 } 7387 7388 TEST_F(VkLayerTest, InvalidCmdBufferPipelineDestroyed) { 7389 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid due to a pipeline dependency being destroyed."); 7390 ASSERT_NO_FATAL_FAILURE(Init()); 7391 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7392 7393 { 7394 // Use helper to create graphics pipeline 7395 CreatePipelineHelper helper(*this); 7396 helper.InitInfo(); 7397 helper.InitState(); 7398 helper.CreateGraphicsPipeline(); 7399 7400 // Bind helper pipeline to command buffer 7401 m_commandBuffer->begin(); 7402 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, helper.pipeline_); 7403 m_commandBuffer->end(); 7404 7405 // pipeline will be destroyed when helper goes out of scope 7406 } 7407 7408 // Cause error by submitting command buffer that references destroyed pipeline 7409 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Pipeline "); 7410 m_commandBuffer->QueueCommandBuffer(false); 7411 m_errorMonitor->VerifyFound(); 7412 } 7413 7414 TEST_F(VkPositiveLayerTest, DestroyPipelineRenderPass) { 7415 TEST_DESCRIPTION("Draw using a pipeline whose create renderPass has been destroyed."); 7416 m_errorMonitor->ExpectSuccess(); 7417 ASSERT_NO_FATAL_FAILURE(Init()); 7418 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7419 7420 VkResult err; 7421 7422 // Create a renderPass that's compatible with Draw-time renderPass 7423 VkAttachmentDescription att = {}; 7424 att.format = m_render_target_fmt; 7425 att.samples = VK_SAMPLE_COUNT_1_BIT; 7426 att.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 7427 att.storeOp = VK_ATTACHMENT_STORE_OP_STORE; 7428 att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; 7429 att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; 7430 att.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 7431 att.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 7432 7433 VkAttachmentReference ref = {}; 7434 ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 7435 ref.attachment = 0; 7436 7437 m_renderPassClearValues.clear(); 7438 VkClearValue clear = {}; 7439 clear.color = m_clear_color; 7440 7441 VkSubpassDescription subpass = {}; 7442 subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; 7443 subpass.flags = 0; 7444 subpass.inputAttachmentCount = 0; 7445 subpass.pInputAttachments = NULL; 7446 subpass.colorAttachmentCount = 1; 7447 subpass.pColorAttachments = &ref; 7448 subpass.pResolveAttachments = NULL; 7449 7450 subpass.pDepthStencilAttachment = NULL; 7451 subpass.preserveAttachmentCount = 0; 7452 subpass.pPreserveAttachments = NULL; 7453 7454 VkRenderPassCreateInfo rp_info = {}; 7455 rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 7456 rp_info.attachmentCount = 1; 7457 rp_info.pAttachments = &att; 7458 rp_info.subpassCount = 1; 7459 rp_info.pSubpasses = &subpass; 7460 7461 VkRenderPass rp; 7462 err = vkCreateRenderPass(device(), &rp_info, NULL, &rp); 7463 ASSERT_VK_SUCCESS(err); 7464 7465 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 7466 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 7467 7468 VkPipelineObj pipe(m_device); 7469 pipe.AddDefaultColorAttachment(); 7470 pipe.AddShader(&vs); 7471 pipe.AddShader(&fs); 7472 VkViewport view_port = {}; 7473 m_viewports.push_back(view_port); 7474 pipe.SetViewport(m_viewports); 7475 VkRect2D rect = {}; 7476 m_scissors.push_back(rect); 7477 pipe.SetScissor(m_scissors); 7478 7479 const VkPipelineLayoutObj pl(m_device); 7480 pipe.CreateVKPipeline(pl.handle(), rp); 7481 7482 m_commandBuffer->begin(); 7483 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 7484 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 7485 // Destroy renderPass before pipeline is used in Draw 7486 // We delay until after CmdBindPipeline to verify that invalid binding isn't 7487 // created between CB & renderPass, which we used to do. 7488 vkDestroyRenderPass(m_device->device(), rp, nullptr); 7489 vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); 7490 vkCmdEndRenderPass(m_commandBuffer->handle()); 7491 m_commandBuffer->end(); 7492 7493 VkSubmitInfo submit_info = {}; 7494 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 7495 submit_info.commandBufferCount = 1; 7496 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 7497 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 7498 m_errorMonitor->VerifyNotFound(); 7499 vkQueueWaitIdle(m_device->m_queue); 7500 } 7501 7502 TEST_F(VkLayerTest, InvalidCmdBufferDescriptorSetBufferDestroyed) { 7503 TEST_DESCRIPTION( 7504 "Attempt to draw with a command buffer that is invalid due to a bound descriptor set with a buffer dependency being " 7505 "destroyed."); 7506 ASSERT_NO_FATAL_FAILURE(Init()); 7507 ASSERT_NO_FATAL_FAILURE(InitViewport()); 7508 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7509 7510 VkDescriptorPoolSize ds_type_count = {}; 7511 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 7512 ds_type_count.descriptorCount = 1; 7513 7514 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 7515 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 7516 ds_pool_ci.pNext = NULL; 7517 ds_pool_ci.maxSets = 1; 7518 ds_pool_ci.poolSizeCount = 1; 7519 ds_pool_ci.pPoolSizes = &ds_type_count; 7520 7521 VkDescriptorPool ds_pool; 7522 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 7523 ASSERT_VK_SUCCESS(err); 7524 7525 VkDescriptorSetLayoutBinding dsl_binding = {}; 7526 dsl_binding.binding = 0; 7527 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 7528 dsl_binding.descriptorCount = 1; 7529 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 7530 dsl_binding.pImmutableSamplers = NULL; 7531 7532 const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding}); 7533 7534 VkDescriptorSet descriptorSet; 7535 VkDescriptorSetAllocateInfo alloc_info = {}; 7536 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 7537 alloc_info.descriptorSetCount = 1; 7538 alloc_info.descriptorPool = ds_pool; 7539 alloc_info.pSetLayouts = &ds_layout.handle(); 7540 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 7541 ASSERT_VK_SUCCESS(err); 7542 7543 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout}); 7544 7545 // Create a buffer to update the descriptor with 7546 uint32_t qfi = 0; 7547 VkBufferCreateInfo buffCI = {}; 7548 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 7549 buffCI.size = 1024; 7550 buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 7551 buffCI.queueFamilyIndexCount = 1; 7552 buffCI.pQueueFamilyIndices = &qfi; 7553 7554 VkBuffer buffer; 7555 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &buffer); 7556 ASSERT_VK_SUCCESS(err); 7557 // Allocate memory and bind to buffer so we can make it to the appropriate 7558 // error 7559 VkMemoryRequirements memReqs; 7560 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs); 7561 VkMemoryAllocateInfo mem_alloc = {}; 7562 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 7563 mem_alloc.pNext = NULL; 7564 mem_alloc.allocationSize = memReqs.size; 7565 mem_alloc.memoryTypeIndex = 0; 7566 bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0); 7567 if (!pass) { 7568 vkDestroyBuffer(m_device->device(), buffer, NULL); 7569 return; 7570 } 7571 7572 VkDeviceMemory mem; 7573 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem); 7574 ASSERT_VK_SUCCESS(err); 7575 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0); 7576 ASSERT_VK_SUCCESS(err); 7577 // Correctly update descriptor to avoid "NOT_UPDATED" error 7578 VkDescriptorBufferInfo buffInfo = {}; 7579 buffInfo.buffer = buffer; 7580 buffInfo.offset = 0; 7581 buffInfo.range = 1024; 7582 7583 VkWriteDescriptorSet descriptor_write; 7584 memset(&descriptor_write, 0, sizeof(descriptor_write)); 7585 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 7586 descriptor_write.dstSet = descriptorSet; 7587 descriptor_write.dstBinding = 0; 7588 descriptor_write.descriptorCount = 1; 7589 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 7590 descriptor_write.pBufferInfo = &buffInfo; 7591 7592 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 7593 7594 // Create PSO to be used for draw-time errors below 7595 char const *vsSource = 7596 "#version 450\n" 7597 "\n" 7598 "void main(){\n" 7599 " gl_Position = vec4(1);\n" 7600 "}\n"; 7601 char const *fsSource = 7602 "#version 450\n" 7603 "\n" 7604 "layout(location=0) out vec4 x;\n" 7605 "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n" 7606 "void main(){\n" 7607 " x = vec4(bar.y);\n" 7608 "}\n"; 7609 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 7610 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 7611 VkPipelineObj pipe(m_device); 7612 pipe.AddShader(&vs); 7613 pipe.AddShader(&fs); 7614 pipe.AddDefaultColorAttachment(); 7615 pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 7616 7617 m_commandBuffer->begin(); 7618 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 7619 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 7620 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, 7621 &descriptorSet, 0, NULL); 7622 7623 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &m_viewports[0]); 7624 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &m_scissors[0]); 7625 7626 m_commandBuffer->Draw(1, 0, 0, 0); 7627 m_commandBuffer->EndRenderPass(); 7628 m_commandBuffer->end(); 7629 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Buffer "); 7630 // Destroy buffer should invalidate the cmd buffer, causing error on submit 7631 vkDestroyBuffer(m_device->device(), buffer, NULL); 7632 // Attempt to submit cmd buffer 7633 VkSubmitInfo submit_info = {}; 7634 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 7635 submit_info.commandBufferCount = 1; 7636 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 7637 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 7638 m_errorMonitor->VerifyFound(); 7639 // Cleanup 7640 vkFreeMemory(m_device->device(), mem, NULL); 7641 7642 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 7643 } 7644 7645 TEST_F(VkLayerTest, InvalidCmdBufferDescriptorSetImageSamplerDestroyed) { 7646 TEST_DESCRIPTION( 7647 "Attempt to draw with a command buffer that is invalid due to a bound descriptor sets with a combined image sampler having " 7648 "their image, sampler, and descriptor set each respectively destroyed and then attempting to submit associated cmd " 7649 "buffers. Attempt to destroy a DescriptorSet that is in use."); 7650 ASSERT_NO_FATAL_FAILURE(Init(nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)); 7651 ASSERT_NO_FATAL_FAILURE(InitViewport()); 7652 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7653 7654 VkDescriptorPoolSize ds_type_count = {}; 7655 ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 7656 ds_type_count.descriptorCount = 1; 7657 7658 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 7659 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 7660 ds_pool_ci.pNext = NULL; 7661 ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; 7662 ds_pool_ci.maxSets = 1; 7663 ds_pool_ci.poolSizeCount = 1; 7664 ds_pool_ci.pPoolSizes = &ds_type_count; 7665 7666 VkDescriptorPool ds_pool; 7667 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 7668 ASSERT_VK_SUCCESS(err); 7669 7670 VkDescriptorSetLayoutBinding dsl_binding = {}; 7671 dsl_binding.binding = 0; 7672 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 7673 dsl_binding.descriptorCount = 1; 7674 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 7675 dsl_binding.pImmutableSamplers = NULL; 7676 7677 const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding}); 7678 7679 VkDescriptorSet descriptorSet; 7680 VkDescriptorSetAllocateInfo alloc_info = {}; 7681 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 7682 alloc_info.descriptorSetCount = 1; 7683 alloc_info.descriptorPool = ds_pool; 7684 alloc_info.pSetLayouts = &ds_layout.handle(); 7685 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 7686 ASSERT_VK_SUCCESS(err); 7687 7688 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout}); 7689 7690 // Create images to update the descriptor with 7691 VkImage image; 7692 VkImage image2; 7693 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 7694 const int32_t tex_width = 32; 7695 const int32_t tex_height = 32; 7696 VkImageCreateInfo image_create_info = {}; 7697 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 7698 image_create_info.pNext = NULL; 7699 image_create_info.imageType = VK_IMAGE_TYPE_2D; 7700 image_create_info.format = tex_format; 7701 image_create_info.extent.width = tex_width; 7702 image_create_info.extent.height = tex_height; 7703 image_create_info.extent.depth = 1; 7704 image_create_info.mipLevels = 1; 7705 image_create_info.arrayLayers = 1; 7706 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 7707 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 7708 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 7709 image_create_info.flags = 0; 7710 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 7711 ASSERT_VK_SUCCESS(err); 7712 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image2); 7713 ASSERT_VK_SUCCESS(err); 7714 7715 VkMemoryRequirements memory_reqs; 7716 VkDeviceMemory image_memory; 7717 bool pass; 7718 VkMemoryAllocateInfo memory_info = {}; 7719 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 7720 memory_info.pNext = NULL; 7721 memory_info.allocationSize = 0; 7722 memory_info.memoryTypeIndex = 0; 7723 vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs); 7724 // Allocate enough memory for both images 7725 memory_info.allocationSize = memory_reqs.size * 2; 7726 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 7727 ASSERT_TRUE(pass); 7728 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory); 7729 ASSERT_VK_SUCCESS(err); 7730 err = vkBindImageMemory(m_device->device(), image, image_memory, 0); 7731 ASSERT_VK_SUCCESS(err); 7732 // Bind second image to memory right after first image 7733 err = vkBindImageMemory(m_device->device(), image2, image_memory, memory_reqs.size); 7734 ASSERT_VK_SUCCESS(err); 7735 7736 VkImageViewCreateInfo image_view_create_info = {}; 7737 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 7738 image_view_create_info.image = image; 7739 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; 7740 image_view_create_info.format = tex_format; 7741 image_view_create_info.subresourceRange.layerCount = 1; 7742 image_view_create_info.subresourceRange.baseMipLevel = 0; 7743 image_view_create_info.subresourceRange.levelCount = 1; 7744 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 7745 7746 VkImageView tmp_view; // First test deletes this view 7747 VkImageView view; 7748 VkImageView view2; 7749 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &tmp_view); 7750 ASSERT_VK_SUCCESS(err); 7751 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view); 7752 ASSERT_VK_SUCCESS(err); 7753 image_view_create_info.image = image2; 7754 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view2); 7755 ASSERT_VK_SUCCESS(err); 7756 // Create Samplers 7757 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo(); 7758 VkSampler sampler; 7759 VkSampler sampler2; 7760 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 7761 ASSERT_VK_SUCCESS(err); 7762 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler2); 7763 ASSERT_VK_SUCCESS(err); 7764 // Update descriptor with image and sampler 7765 VkDescriptorImageInfo img_info = {}; 7766 img_info.sampler = sampler; 7767 img_info.imageView = tmp_view; 7768 img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 7769 7770 VkWriteDescriptorSet descriptor_write; 7771 memset(&descriptor_write, 0, sizeof(descriptor_write)); 7772 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 7773 descriptor_write.dstSet = descriptorSet; 7774 descriptor_write.dstBinding = 0; 7775 descriptor_write.descriptorCount = 1; 7776 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 7777 descriptor_write.pImageInfo = &img_info; 7778 7779 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 7780 7781 // Create PSO to be used for draw-time errors below 7782 char const *vsSource = 7783 "#version 450\n" 7784 "\n" 7785 "void main(){\n" 7786 " gl_Position = vec4(1);\n" 7787 "}\n"; 7788 char const *fsSource = 7789 "#version 450\n" 7790 "\n" 7791 "layout(set=0, binding=0) uniform sampler2D s;\n" 7792 "layout(location=0) out vec4 x;\n" 7793 "void main(){\n" 7794 " x = texture(s, vec2(1));\n" 7795 "}\n"; 7796 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 7797 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 7798 VkPipelineObj pipe(m_device); 7799 pipe.AddShader(&vs); 7800 pipe.AddShader(&fs); 7801 pipe.AddDefaultColorAttachment(); 7802 pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 7803 7804 // First error case is destroying sampler prior to cmd buffer submission 7805 m_commandBuffer->begin(); 7806 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 7807 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 7808 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, 7809 &descriptorSet, 0, NULL); 7810 VkViewport viewport = {0, 0, 16, 16, 0, 1}; 7811 VkRect2D scissor = {{0, 0}, {16, 16}}; 7812 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 7813 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 7814 m_commandBuffer->Draw(1, 0, 0, 0); 7815 m_commandBuffer->EndRenderPass(); 7816 m_commandBuffer->end(); 7817 VkSubmitInfo submit_info = {}; 7818 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 7819 submit_info.commandBufferCount = 1; 7820 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 7821 // This first submit should be successful 7822 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 7823 vkQueueWaitIdle(m_device->m_queue); 7824 7825 // Now destroy imageview and reset cmdBuffer 7826 vkDestroyImageView(m_device->device(), tmp_view, NULL); 7827 m_commandBuffer->reset(0); 7828 m_commandBuffer->begin(); 7829 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 7830 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 7831 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, 7832 &descriptorSet, 0, NULL); 7833 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 7834 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 7835 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that has been destroyed."); 7836 m_commandBuffer->Draw(1, 0, 0, 0); 7837 m_errorMonitor->VerifyFound(); 7838 m_commandBuffer->reset(0); 7839 7840 // Re-update descriptor with new view 7841 img_info.imageView = view; 7842 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 7843 // Now test destroying sampler prior to cmd buffer submission 7844 m_commandBuffer->begin(); 7845 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 7846 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 7847 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, 7848 &descriptorSet, 0, NULL); 7849 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 7850 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 7851 m_commandBuffer->Draw(1, 0, 0, 0); 7852 m_commandBuffer->EndRenderPass(); 7853 m_commandBuffer->end(); 7854 // Destroy sampler invalidates the cmd buffer, causing error on submit 7855 vkDestroySampler(m_device->device(), sampler, NULL); 7856 // Attempt to submit cmd buffer 7857 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is invalid because bound Sampler"); 7858 submit_info = {}; 7859 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 7860 submit_info.commandBufferCount = 1; 7861 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 7862 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 7863 m_errorMonitor->VerifyFound(); 7864 7865 // Now re-update descriptor with valid sampler and delete image 7866 img_info.sampler = sampler2; 7867 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 7868 7869 VkCommandBufferBeginInfo info = {}; 7870 info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 7871 info.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; 7872 7873 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound Image "); 7874 m_commandBuffer->begin(&info); 7875 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 7876 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 7877 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, 7878 &descriptorSet, 0, NULL); 7879 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 7880 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 7881 m_commandBuffer->Draw(1, 0, 0, 0); 7882 m_commandBuffer->EndRenderPass(); 7883 m_commandBuffer->end(); 7884 // Destroy image invalidates the cmd buffer, causing error on submit 7885 vkDestroyImage(m_device->device(), image, NULL); 7886 // Attempt to submit cmd buffer 7887 submit_info = {}; 7888 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 7889 submit_info.commandBufferCount = 1; 7890 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 7891 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 7892 m_errorMonitor->VerifyFound(); 7893 // Now update descriptor to be valid, but then free descriptor 7894 img_info.imageView = view2; 7895 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 7896 m_commandBuffer->begin(&info); 7897 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 7898 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 7899 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, 7900 &descriptorSet, 0, NULL); 7901 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 7902 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 7903 m_commandBuffer->Draw(1, 0, 0, 0); 7904 m_commandBuffer->EndRenderPass(); 7905 m_commandBuffer->end(); 7906 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 7907 7908 // Immediately try to destroy the descriptor set in the active command buffer - failure expected 7909 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot call vkFreeDescriptorSets() on descriptor set 0x"); 7910 vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptorSet); 7911 m_errorMonitor->VerifyFound(); 7912 7913 // Try again once the queue is idle - should succeed w/o error 7914 // TODO - though the particular error above doesn't re-occur, there are other 'unexpecteds' still to clean up 7915 vkQueueWaitIdle(m_device->m_queue); 7916 m_errorMonitor->SetUnexpectedError( 7917 "pDescriptorSets must be a valid pointer to an array of descriptorSetCount VkDescriptorSet handles, each element of which " 7918 "must either be a valid handle or VK_NULL_HANDLE"); 7919 m_errorMonitor->SetUnexpectedError("Unable to remove DescriptorSet obj"); 7920 vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptorSet); 7921 7922 // Attempt to submit cmd buffer containing the freed descriptor set 7923 submit_info = {}; 7924 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 7925 submit_info.commandBufferCount = 1; 7926 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 7927 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound DescriptorSet "); 7928 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 7929 m_errorMonitor->VerifyFound(); 7930 7931 // Cleanup 7932 vkFreeMemory(m_device->device(), image_memory, NULL); 7933 vkDestroySampler(m_device->device(), sampler2, NULL); 7934 vkDestroyImage(m_device->device(), image2, NULL); 7935 vkDestroyImageView(m_device->device(), view, NULL); 7936 vkDestroyImageView(m_device->device(), view2, NULL); 7937 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 7938 } 7939 7940 TEST_F(VkLayerTest, ImageDescriptorLayoutMismatch) { 7941 TEST_DESCRIPTION("Update an image sampler with a layout that doesn't match the actual image layout at the image is used."); 7942 ASSERT_NO_FATAL_FAILURE(Init(nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)); 7943 ASSERT_NO_FATAL_FAILURE(InitViewport()); 7944 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7945 7946 VkDescriptorPoolSize ds_type_count = {}; 7947 ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 7948 ds_type_count.descriptorCount = 1; 7949 7950 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 7951 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 7952 ds_pool_ci.pNext = NULL; 7953 ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; 7954 ds_pool_ci.maxSets = 1; 7955 ds_pool_ci.poolSizeCount = 1; 7956 ds_pool_ci.pPoolSizes = &ds_type_count; 7957 7958 VkDescriptorPool ds_pool; 7959 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 7960 ASSERT_VK_SUCCESS(err); 7961 7962 VkDescriptorSetLayoutBinding dsl_binding = {}; 7963 dsl_binding.binding = 0; 7964 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 7965 dsl_binding.descriptorCount = 1; 7966 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 7967 dsl_binding.pImmutableSamplers = NULL; 7968 7969 const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding}); 7970 7971 VkDescriptorSet descriptorSet; 7972 VkDescriptorSetAllocateInfo alloc_info = {}; 7973 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 7974 alloc_info.descriptorSetCount = 1; 7975 alloc_info.descriptorPool = ds_pool; 7976 alloc_info.pSetLayouts = &ds_layout.handle(); 7977 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 7978 ASSERT_VK_SUCCESS(err); 7979 7980 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout}); 7981 7982 // Create images to update the descriptor with 7983 const VkFormat format = VK_FORMAT_B8G8R8A8_UNORM; 7984 VkImageObj image(m_device); 7985 image.Init(32, 32, 1, format, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_TILING_OPTIMAL, 7986 0); 7987 ASSERT_TRUE(image.initialized()); 7988 7989 VkImageViewCreateInfo image_view_create_info = {}; 7990 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 7991 image_view_create_info.image = image.handle(); 7992 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; 7993 image_view_create_info.format = format; 7994 image_view_create_info.subresourceRange.layerCount = 1; 7995 image_view_create_info.subresourceRange.baseMipLevel = 0; 7996 image_view_create_info.subresourceRange.levelCount = 1; 7997 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 7998 7999 VkImageView view; 8000 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view); 8001 ASSERT_VK_SUCCESS(err); 8002 // Create Sampler 8003 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo(); 8004 VkSampler sampler; 8005 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 8006 ASSERT_VK_SUCCESS(err); 8007 // Update descriptor with image and sampler 8008 VkDescriptorImageInfo img_info = {}; 8009 img_info.sampler = sampler; 8010 img_info.imageView = view; 8011 // This should cause a mis-match. Actual layout at use time is SHADER_RO 8012 img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 8013 8014 VkWriteDescriptorSet descriptor_write; 8015 memset(&descriptor_write, 0, sizeof(descriptor_write)); 8016 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 8017 descriptor_write.dstSet = descriptorSet; 8018 descriptor_write.dstBinding = 0; 8019 descriptor_write.descriptorCount = 1; 8020 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 8021 descriptor_write.pImageInfo = &img_info; 8022 8023 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 8024 8025 // Create PSO to be used for draw-time errors below 8026 char const *vsSource = 8027 "#version 450\n" 8028 "\n" 8029 "void main(){\n" 8030 " gl_Position = vec4(1);\n" 8031 "}\n"; 8032 char const *fsSource = 8033 "#version 450\n" 8034 "\n" 8035 "layout(set=0, binding=0) uniform sampler2D s;\n" 8036 "layout(location=0) out vec4 x;\n" 8037 "void main(){\n" 8038 " x = texture(s, vec2(1));\n" 8039 "}\n"; 8040 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 8041 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 8042 VkPipelineObj pipe(m_device); 8043 pipe.AddShader(&vs); 8044 pipe.AddShader(&fs); 8045 pipe.AddDefaultColorAttachment(); 8046 pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 8047 8048 VkCommandBufferObj cmd_buf(m_device, m_commandPool); 8049 cmd_buf.begin(); 8050 // record layout different than actual descriptor layout of SHADER_RO 8051 image.SetLayout(&cmd_buf, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); 8052 cmd_buf.BeginRenderPass(m_renderPassBeginInfo); 8053 vkCmdBindPipeline(cmd_buf.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 8054 vkCmdBindDescriptorSets(cmd_buf.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &descriptorSet, 0, 8055 NULL); 8056 VkViewport viewport = {0, 0, 16, 16, 0, 1}; 8057 VkRect2D scissor = {{0, 0}, {16, 16}}; 8058 vkCmdSetViewport(cmd_buf.handle(), 0, 1, &viewport); 8059 vkCmdSetScissor(cmd_buf.handle(), 0, 1, &scissor); 8060 // At draw time the update layout will mis-match the actual layout 8061 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 8062 " with specific layout VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL that doesn't match the " 8063 "actual current layout VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL."); 8064 m_errorMonitor->SetDesiredFailureMsg( 8065 VK_DEBUG_REPORT_ERROR_BIT_EXT, 8066 " Image layout specified at vkUpdateDescriptorSets() time doesn't match actual image layout at time descriptor is used."); 8067 cmd_buf.Draw(1, 0, 0, 0); 8068 m_errorMonitor->VerifyFound(); 8069 cmd_buf.EndRenderPass(); 8070 cmd_buf.end(); 8071 // Submit cmd buffer 8072 VkSubmitInfo submit_info = {}; 8073 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 8074 submit_info.commandBufferCount = 1; 8075 submit_info.pCommandBuffers = &cmd_buf.handle(); 8076 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 8077 vkQueueWaitIdle(m_device->m_queue); 8078 // Cleanup 8079 vkDestroySampler(m_device->device(), sampler, NULL); 8080 vkDestroyImageView(m_device->device(), view, NULL); 8081 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 8082 } 8083 8084 TEST_F(VkLayerTest, DescriptorPoolInUseDestroyedSignaled) { 8085 TEST_DESCRIPTION("Delete a DescriptorPool with a DescriptorSet that is in use."); 8086 ASSERT_NO_FATAL_FAILURE(Init()); 8087 ASSERT_NO_FATAL_FAILURE(InitViewport()); 8088 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 8089 8090 VkDescriptorPoolSize ds_type_count = {}; 8091 ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 8092 ds_type_count.descriptorCount = 1; 8093 8094 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 8095 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 8096 ds_pool_ci.pNext = NULL; 8097 ds_pool_ci.maxSets = 1; 8098 ds_pool_ci.poolSizeCount = 1; 8099 ds_pool_ci.pPoolSizes = &ds_type_count; 8100 8101 VkDescriptorPool ds_pool; 8102 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 8103 ASSERT_VK_SUCCESS(err); 8104 8105 VkDescriptorSetLayoutBinding dsl_binding = {}; 8106 dsl_binding.binding = 0; 8107 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 8108 dsl_binding.descriptorCount = 1; 8109 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 8110 dsl_binding.pImmutableSamplers = NULL; 8111 8112 const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding}); 8113 8114 VkDescriptorSet descriptor_set; 8115 VkDescriptorSetAllocateInfo alloc_info = {}; 8116 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 8117 alloc_info.descriptorSetCount = 1; 8118 alloc_info.descriptorPool = ds_pool; 8119 alloc_info.pSetLayouts = &ds_layout.handle(); 8120 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set); 8121 ASSERT_VK_SUCCESS(err); 8122 8123 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout}); 8124 8125 // Create image to update the descriptor with 8126 VkImageObj image(m_device); 8127 image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 8128 ASSERT_TRUE(image.initialized()); 8129 8130 VkImageView view = image.targetView(VK_FORMAT_B8G8R8A8_UNORM); 8131 // Create Sampler 8132 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo(); 8133 VkSampler sampler; 8134 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 8135 ASSERT_VK_SUCCESS(err); 8136 // Update descriptor with image and sampler 8137 VkDescriptorImageInfo img_info = {}; 8138 img_info.sampler = sampler; 8139 img_info.imageView = view; 8140 img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 8141 8142 VkWriteDescriptorSet descriptor_write; 8143 memset(&descriptor_write, 0, sizeof(descriptor_write)); 8144 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 8145 descriptor_write.dstSet = descriptor_set; 8146 descriptor_write.dstBinding = 0; 8147 descriptor_write.descriptorCount = 1; 8148 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 8149 descriptor_write.pImageInfo = &img_info; 8150 8151 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 8152 8153 // Create PSO to be used for draw-time errors below 8154 char const *vsSource = 8155 "#version 450\n" 8156 "\n" 8157 "void main(){\n" 8158 " gl_Position = vec4(1);\n" 8159 "}\n"; 8160 char const *fsSource = 8161 "#version 450\n" 8162 "\n" 8163 "layout(set=0, binding=0) uniform sampler2D s;\n" 8164 "layout(location=0) out vec4 x;\n" 8165 "void main(){\n" 8166 " x = texture(s, vec2(1));\n" 8167 "}\n"; 8168 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 8169 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 8170 VkPipelineObj pipe(m_device); 8171 pipe.AddShader(&vs); 8172 pipe.AddShader(&fs); 8173 pipe.AddDefaultColorAttachment(); 8174 pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 8175 8176 m_commandBuffer->begin(); 8177 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 8178 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 8179 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, 8180 &descriptor_set, 0, NULL); 8181 8182 VkViewport viewport = {0, 0, 16, 16, 0, 1}; 8183 VkRect2D scissor = {{0, 0}, {16, 16}}; 8184 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 8185 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 8186 8187 m_commandBuffer->Draw(1, 0, 0, 0); 8188 m_commandBuffer->EndRenderPass(); 8189 m_commandBuffer->end(); 8190 // Submit cmd buffer to put pool in-flight 8191 VkSubmitInfo submit_info = {}; 8192 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 8193 submit_info.commandBufferCount = 1; 8194 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 8195 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 8196 // Destroy pool while in-flight, causing error 8197 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_2440025e); 8198 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 8199 m_errorMonitor->VerifyFound(); 8200 vkQueueWaitIdle(m_device->m_queue); 8201 // Cleanup 8202 vkDestroySampler(m_device->device(), sampler, NULL); 8203 m_errorMonitor->SetUnexpectedError( 8204 "If descriptorPool is not VK_NULL_HANDLE, descriptorPool must be a valid VkDescriptorPool handle"); 8205 m_errorMonitor->SetUnexpectedError("Unable to remove DescriptorPool obj"); 8206 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 8207 // TODO : It seems Validation layers think ds_pool was already destroyed, even though it wasn't? 8208 } 8209 8210 TEST_F(VkLayerTest, DescriptorImageUpdateNoMemoryBound) { 8211 TEST_DESCRIPTION("Attempt an image descriptor set update where image's bound memory has been freed."); 8212 ASSERT_NO_FATAL_FAILURE(Init()); 8213 ASSERT_NO_FATAL_FAILURE(InitViewport()); 8214 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 8215 8216 VkDescriptorPoolSize ds_type_count = {}; 8217 ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 8218 ds_type_count.descriptorCount = 1; 8219 8220 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 8221 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 8222 ds_pool_ci.pNext = NULL; 8223 ds_pool_ci.maxSets = 1; 8224 ds_pool_ci.poolSizeCount = 1; 8225 ds_pool_ci.pPoolSizes = &ds_type_count; 8226 8227 VkDescriptorPool ds_pool; 8228 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 8229 ASSERT_VK_SUCCESS(err); 8230 8231 VkDescriptorSetLayoutBinding dsl_binding = {}; 8232 dsl_binding.binding = 0; 8233 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 8234 dsl_binding.descriptorCount = 1; 8235 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 8236 dsl_binding.pImmutableSamplers = NULL; 8237 8238 const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding}); 8239 8240 VkDescriptorSet descriptorSet; 8241 VkDescriptorSetAllocateInfo alloc_info = {}; 8242 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 8243 alloc_info.descriptorSetCount = 1; 8244 alloc_info.descriptorPool = ds_pool; 8245 alloc_info.pSetLayouts = &ds_layout.handle(); 8246 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 8247 ASSERT_VK_SUCCESS(err); 8248 8249 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout}); 8250 8251 // Create images to update the descriptor with 8252 VkImage image; 8253 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 8254 const int32_t tex_width = 32; 8255 const int32_t tex_height = 32; 8256 VkImageCreateInfo image_create_info = {}; 8257 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 8258 image_create_info.pNext = NULL; 8259 image_create_info.imageType = VK_IMAGE_TYPE_2D; 8260 image_create_info.format = tex_format; 8261 image_create_info.extent.width = tex_width; 8262 image_create_info.extent.height = tex_height; 8263 image_create_info.extent.depth = 1; 8264 image_create_info.mipLevels = 1; 8265 image_create_info.arrayLayers = 1; 8266 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 8267 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 8268 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 8269 image_create_info.flags = 0; 8270 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 8271 ASSERT_VK_SUCCESS(err); 8272 // Initially bind memory to avoid error at bind view time. We'll break binding before update. 8273 VkMemoryRequirements memory_reqs; 8274 VkDeviceMemory image_memory; 8275 bool pass; 8276 VkMemoryAllocateInfo memory_info = {}; 8277 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 8278 memory_info.pNext = NULL; 8279 memory_info.allocationSize = 0; 8280 memory_info.memoryTypeIndex = 0; 8281 vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs); 8282 // Allocate enough memory for image 8283 memory_info.allocationSize = memory_reqs.size; 8284 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 8285 ASSERT_TRUE(pass); 8286 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory); 8287 ASSERT_VK_SUCCESS(err); 8288 err = vkBindImageMemory(m_device->device(), image, image_memory, 0); 8289 ASSERT_VK_SUCCESS(err); 8290 8291 VkImageViewCreateInfo image_view_create_info = {}; 8292 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 8293 image_view_create_info.image = image; 8294 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; 8295 image_view_create_info.format = tex_format; 8296 image_view_create_info.subresourceRange.layerCount = 1; 8297 image_view_create_info.subresourceRange.baseMipLevel = 0; 8298 image_view_create_info.subresourceRange.levelCount = 1; 8299 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 8300 8301 VkImageView view; 8302 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view); 8303 ASSERT_VK_SUCCESS(err); 8304 // Create Samplers 8305 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo(); 8306 VkSampler sampler; 8307 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 8308 ASSERT_VK_SUCCESS(err); 8309 // Update descriptor with image and sampler 8310 VkDescriptorImageInfo img_info = {}; 8311 img_info.sampler = sampler; 8312 img_info.imageView = view; 8313 img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 8314 8315 VkWriteDescriptorSet descriptor_write; 8316 memset(&descriptor_write, 0, sizeof(descriptor_write)); 8317 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 8318 descriptor_write.dstSet = descriptorSet; 8319 descriptor_write.dstBinding = 0; 8320 descriptor_write.descriptorCount = 1; 8321 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 8322 descriptor_write.pImageInfo = &img_info; 8323 // Break memory binding and attempt update 8324 vkFreeMemory(m_device->device(), image_memory, nullptr); 8325 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 8326 " previously bound memory was freed. Memory must not be freed prior to this operation."); 8327 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 8328 "vkUpdateDescriptorSets() failed write update validation for Descriptor Set 0x"); 8329 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 8330 m_errorMonitor->VerifyFound(); 8331 // Cleanup 8332 vkDestroyImage(m_device->device(), image, NULL); 8333 vkDestroySampler(m_device->device(), sampler, NULL); 8334 vkDestroyImageView(m_device->device(), view, NULL); 8335 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 8336 } 8337 8338 TEST_F(VkLayerTest, InvalidPipeline) { 8339 // Attempt to bind an invalid Pipeline to a valid Command Buffer 8340 // ObjectTracker should catch this. 8341 // Create a valid cmd buffer 8342 // call vkCmdBindPipeline w/ false Pipeline 8343 uint64_t fake_pipeline_handle = 0xbaad6001; 8344 VkPipeline bad_pipeline = reinterpret_cast<VkPipeline &>(fake_pipeline_handle); 8345 ASSERT_NO_FATAL_FAILURE(Init()); 8346 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 8347 8348 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18027c01); 8349 m_commandBuffer->begin(); 8350 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 8351 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, bad_pipeline); 8352 m_errorMonitor->VerifyFound(); 8353 8354 // Now issue a draw call with no pipeline bound 8355 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "At Draw/Dispatch time no valid VkPipeline is bound!"); 8356 m_commandBuffer->Draw(1, 0, 0, 0); 8357 m_errorMonitor->VerifyFound(); 8358 8359 // Finally same check once more but with Dispatch/Compute 8360 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "At Draw/Dispatch time no valid VkPipeline is bound!"); 8361 vkCmdEndRenderPass(m_commandBuffer->handle()); // must be outside renderpass 8362 vkCmdDispatch(m_commandBuffer->handle(), 0, 0, 0); 8363 m_errorMonitor->VerifyFound(); 8364 } 8365 8366 TEST_F(VkLayerTest, CmdDispatchExceedLimits) { 8367 TEST_DESCRIPTION("Compute dispatch with dimensions that exceed device limits"); 8368 8369 // Enable KHX device group extensions, if available 8370 if (InstanceExtensionSupported(VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME)) { 8371 m_instance_extension_names.push_back(VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME); 8372 } 8373 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 8374 bool khx_dg_ext_available = false; 8375 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHX_DEVICE_GROUP_EXTENSION_NAME)) { 8376 m_device_extension_names.push_back(VK_KHX_DEVICE_GROUP_EXTENSION_NAME); 8377 khx_dg_ext_available = true; 8378 } 8379 ASSERT_NO_FATAL_FAILURE(InitState()); 8380 8381 uint32_t x_limit = m_device->props.limits.maxComputeWorkGroupCount[0]; 8382 uint32_t y_limit = m_device->props.limits.maxComputeWorkGroupCount[1]; 8383 uint32_t z_limit = m_device->props.limits.maxComputeWorkGroupCount[2]; 8384 if (std::max({x_limit, y_limit, z_limit}) == UINT32_MAX) { 8385 printf(" device maxComputeWorkGroupCount limit reports UINT32_MAX, test not possible, skipping.\n"); 8386 return; 8387 } 8388 8389 // Create a minimal compute pipeline 8390 std::string cs_text = "#version 450\nvoid main() {}\n"; // minimal no-op shader 8391 VkShaderObj cs_obj(m_device, cs_text.c_str(), VK_SHADER_STAGE_COMPUTE_BIT, this); 8392 8393 VkPipelineLayoutCreateInfo info = {}; 8394 info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 8395 info.pNext = nullptr; 8396 VkPipelineLayout pipe_layout; 8397 vkCreatePipelineLayout(device(), &info, nullptr, &pipe_layout); 8398 8399 VkComputePipelineCreateInfo pipeline_info = {}; 8400 pipeline_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; 8401 pipeline_info.pNext = nullptr; 8402 pipeline_info.flags = khx_dg_ext_available ? VK_PIPELINE_CREATE_DISPATCH_BASE_KHX : 0; 8403 pipeline_info.layout = pipe_layout; 8404 pipeline_info.basePipelineHandle = VK_NULL_HANDLE; 8405 pipeline_info.basePipelineIndex = -1; 8406 pipeline_info.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 8407 pipeline_info.stage.pNext = nullptr; 8408 pipeline_info.stage.flags = 0; 8409 pipeline_info.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT; 8410 pipeline_info.stage.module = cs_obj.handle(); 8411 pipeline_info.stage.pName = "main"; 8412 pipeline_info.stage.pSpecializationInfo = nullptr; 8413 VkPipeline cs_pipeline; 8414 vkCreateComputePipelines(device(), VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &cs_pipeline); 8415 8416 // Bind pipeline to command buffer 8417 m_commandBuffer->begin(); 8418 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, cs_pipeline); 8419 8420 // Dispatch counts that exceed device limits 8421 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19c00304); 8422 vkCmdDispatch(m_commandBuffer->handle(), x_limit + 1, y_limit, z_limit); 8423 m_errorMonitor->VerifyFound(); 8424 8425 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19c00306); 8426 vkCmdDispatch(m_commandBuffer->handle(), x_limit, y_limit + 1, z_limit); 8427 m_errorMonitor->VerifyFound(); 8428 8429 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19c00308); 8430 vkCmdDispatch(m_commandBuffer->handle(), x_limit, y_limit, z_limit + 1); 8431 m_errorMonitor->VerifyFound(); 8432 8433 if (khx_dg_ext_available) { 8434 PFN_vkCmdDispatchBaseKHX fp_vkCmdDispatchBaseKHX = 8435 (PFN_vkCmdDispatchBaseKHX)vkGetInstanceProcAddr(instance(), "vkCmdDispatchBaseKHX"); 8436 8437 // Base equals or exceeds limit 8438 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19e0034a); 8439 fp_vkCmdDispatchBaseKHX(m_commandBuffer->handle(), x_limit, y_limit - 1, z_limit - 1, 0, 0, 0); 8440 m_errorMonitor->VerifyFound(); 8441 8442 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19e0034c); 8443 fp_vkCmdDispatchBaseKHX(m_commandBuffer->handle(), x_limit - 1, y_limit, z_limit - 1, 0, 0, 0); 8444 m_errorMonitor->VerifyFound(); 8445 8446 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19e0034e); 8447 fp_vkCmdDispatchBaseKHX(m_commandBuffer->handle(), x_limit - 1, y_limit - 1, z_limit, 0, 0, 0); 8448 m_errorMonitor->VerifyFound(); 8449 8450 // (Base + count) exceeds limit 8451 uint32_t x_base = x_limit / 2; 8452 uint32_t y_base = y_limit / 2; 8453 uint32_t z_base = z_limit / 2; 8454 x_limit -= x_base; 8455 y_limit -= y_base; 8456 z_limit -= z_base; 8457 8458 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19e00350); 8459 fp_vkCmdDispatchBaseKHX(m_commandBuffer->handle(), x_base, y_base, z_base, x_limit + 1, y_limit, z_limit); 8460 m_errorMonitor->VerifyFound(); 8461 8462 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19e00352); 8463 fp_vkCmdDispatchBaseKHX(m_commandBuffer->handle(), x_base, y_base, z_base, x_limit, y_limit + 1, z_limit); 8464 m_errorMonitor->VerifyFound(); 8465 8466 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19e00354); 8467 fp_vkCmdDispatchBaseKHX(m_commandBuffer->handle(), x_base, y_base, z_base, x_limit, y_limit, z_limit + 1); 8468 m_errorMonitor->VerifyFound(); 8469 } else { 8470 printf(" KHX_DEVICE_GROUP_* extensions not supported, skipping CmdDispatchBaseKHX() tests.\n"); 8471 } 8472 8473 // Clean up 8474 vkDestroyPipeline(device(), cs_pipeline, nullptr); 8475 vkDestroyPipelineLayout(device(), pipe_layout, nullptr); 8476 } 8477 8478 TEST_F(VkLayerTest, MultiplaneImageLayoutBadAspectFlags) { 8479 TEST_DESCRIPTION("Query layout of a multiplane image using illegal aspect flag masks"); 8480 8481 // Enable KHR multiplane req'd extensions 8482 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 8483 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION); 8484 if (mp_extensions) { 8485 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 8486 } 8487 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 8488 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME); 8489 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); 8490 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME); 8491 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME); 8492 if (mp_extensions) { 8493 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME); 8494 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); 8495 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME); 8496 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME); 8497 } else { 8498 printf(" test requires KHR multiplane extensions, not available. Skipping.\n"); 8499 return; 8500 } 8501 ASSERT_NO_FATAL_FAILURE(InitState()); 8502 8503 // Query format support 8504 PFN_vkGetPhysicalDeviceImageFormatProperties2KHR GetPDIFP2KHR = 8505 (PFN_vkGetPhysicalDeviceImageFormatProperties2KHR)vkGetInstanceProcAddr(instance(), 8506 "vkGetPhysicalDeviceImageFormatProperties2KHR"); 8507 VkPhysicalDeviceImageFormatInfo2KHR fmt_info = {}; 8508 fmt_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR; 8509 fmt_info.pNext = nullptr; 8510 fmt_info.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR; 8511 fmt_info.type = VK_IMAGE_TYPE_2D; 8512 fmt_info.tiling = VK_IMAGE_TILING_LINEAR; 8513 fmt_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 8514 fmt_info.flags = 0; 8515 8516 VkImageFormatProperties2KHR fmt_props = {}; 8517 fmt_props.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR; 8518 VkResult err_2 = GetPDIFP2KHR(gpu(), &fmt_info, &fmt_props); 8519 8520 fmt_info.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR; 8521 VkResult err_3 = GetPDIFP2KHR(gpu(), &fmt_info, &fmt_props); 8522 8523 if ((VK_SUCCESS != err_2) || (VK_SUCCESS != err_3)) { 8524 printf(" Multiplane image format not supported. Skipping test.\n"); 8525 return; // Assume there's low ROI on searching for different mp formats 8526 } 8527 8528 VkImageCreateInfo ci = {}; 8529 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 8530 ci.pNext = NULL; 8531 ci.flags = fmt_info.flags; 8532 ci.imageType = fmt_info.type; 8533 ci.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR; 8534 ci.extent = {128, 128, 1}; 8535 ci.mipLevels = 1; 8536 ci.arrayLayers = 1; 8537 ci.samples = VK_SAMPLE_COUNT_1_BIT; 8538 ci.tiling = fmt_info.tiling; 8539 ci.usage = fmt_info.usage; 8540 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 8541 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 8542 VkImage image_2plane; 8543 VkResult err = vkCreateImage(device(), &ci, NULL, &image_2plane); 8544 ASSERT_VK_SUCCESS(err); 8545 8546 ci.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR; 8547 VkImage image_3plane; 8548 err = vkCreateImage(device(), &ci, NULL, &image_3plane); 8549 ASSERT_VK_SUCCESS(err); 8550 8551 // Query layout of 3rd plane, for a 2-plane image 8552 VkImageSubresource subres = {}; 8553 subres.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR; 8554 subres.mipLevel = 0; 8555 subres.arrayLayer = 0; 8556 VkSubresourceLayout layout = {}; 8557 8558 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_2a600c5a); 8559 vkGetImageSubresourceLayout(device(), image_2plane, &subres, &layout); 8560 m_errorMonitor->VerifyFound(); 8561 8562 // Query layout using color aspect, for a 3-plane image 8563 subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 8564 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_2a600c5c); 8565 vkGetImageSubresourceLayout(device(), image_3plane, &subres, &layout); 8566 m_errorMonitor->VerifyFound(); 8567 8568 // Clean up 8569 vkDestroyImage(device(), image_2plane, NULL); 8570 vkDestroyImage(device(), image_3plane, NULL); 8571 } 8572 8573 TEST_F(VkPositiveLayerTest, MultiplaneGetImageSubresourceLayout) { 8574 TEST_DESCRIPTION("Positive test, query layout of a single plane of a multiplane image. (repro Github #2530)"); 8575 8576 // Enable KHR multiplane req'd extensions 8577 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 8578 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION); 8579 if (mp_extensions) { 8580 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 8581 } 8582 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 8583 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME); 8584 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); 8585 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME); 8586 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME); 8587 if (mp_extensions) { 8588 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME); 8589 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); 8590 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME); 8591 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME); 8592 } else { 8593 printf(" test requires KHR multiplane extensions, not available. Skipping.\n"); 8594 return; 8595 } 8596 ASSERT_NO_FATAL_FAILURE(InitState()); 8597 8598 // Query format support 8599 PFN_vkGetPhysicalDeviceImageFormatProperties2KHR GetPDIFP2KHR = 8600 (PFN_vkGetPhysicalDeviceImageFormatProperties2KHR)vkGetInstanceProcAddr(instance(), 8601 "vkGetPhysicalDeviceImageFormatProperties2KHR"); 8602 VkPhysicalDeviceImageFormatInfo2KHR fmt_info = {}; 8603 fmt_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR; 8604 fmt_info.pNext = nullptr; 8605 fmt_info.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR; 8606 fmt_info.type = VK_IMAGE_TYPE_2D; 8607 fmt_info.tiling = VK_IMAGE_TILING_LINEAR; 8608 fmt_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 8609 fmt_info.flags = 0; 8610 8611 m_errorMonitor->ExpectSuccess(); 8612 VkImageFormatProperties2KHR fmt_props = {}; 8613 fmt_props.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR; 8614 VkResult err = GetPDIFP2KHR(gpu(), &fmt_info, &fmt_props); 8615 m_errorMonitor->VerifyNotFound(); 8616 if (VK_SUCCESS != err) { 8617 printf(" Multiplane image format not supported. Skipping test.\n"); 8618 return; // Assume there's low ROI on searching for a different mp format 8619 } 8620 8621 VkImageCreateInfo ci = {}; 8622 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 8623 ci.pNext = NULL; 8624 ci.flags = fmt_info.flags; 8625 ci.imageType = fmt_info.type; 8626 ci.format = fmt_info.format; 8627 ci.extent = {128, 128, 1}; 8628 ci.mipLevels = 1; 8629 ci.arrayLayers = 1; 8630 ci.samples = VK_SAMPLE_COUNT_1_BIT; 8631 ci.tiling = fmt_info.tiling; 8632 ci.usage = fmt_info.usage; 8633 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 8634 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 8635 VkImage image; 8636 err = vkCreateImage(device(), &ci, NULL, &image); 8637 ASSERT_VK_SUCCESS(err); 8638 8639 // Query layout of 3rd plane 8640 VkImageSubresource subres = {}; 8641 subres.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR; 8642 subres.mipLevel = 0; 8643 subres.arrayLayer = 0; 8644 VkSubresourceLayout layout = {}; 8645 8646 m_errorMonitor->ExpectSuccess(); 8647 vkGetImageSubresourceLayout(device(), image, &subres, &layout); 8648 m_errorMonitor->VerifyNotFound(); 8649 8650 vkDestroyImage(device(), image, NULL); 8651 } 8652 8653 TEST_F(VkLayerTest, DescriptorSetNotUpdated) { 8654 TEST_DESCRIPTION("Bind a descriptor set that hasn't been updated."); 8655 VkResult err; 8656 8657 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, " bound but it was never updated. "); 8658 8659 ASSERT_NO_FATAL_FAILURE(Init()); 8660 ASSERT_NO_FATAL_FAILURE(InitViewport()); 8661 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 8662 VkDescriptorPoolSize ds_type_count = {}; 8663 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 8664 ds_type_count.descriptorCount = 1; 8665 8666 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 8667 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 8668 ds_pool_ci.pNext = NULL; 8669 ds_pool_ci.maxSets = 1; 8670 ds_pool_ci.poolSizeCount = 1; 8671 ds_pool_ci.pPoolSizes = &ds_type_count; 8672 8673 VkDescriptorPool ds_pool; 8674 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 8675 ASSERT_VK_SUCCESS(err); 8676 8677 VkDescriptorSetLayoutBinding dsl_binding = {}; 8678 dsl_binding.binding = 0; 8679 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 8680 dsl_binding.descriptorCount = 1; 8681 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 8682 dsl_binding.pImmutableSamplers = NULL; 8683 8684 const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding}); 8685 8686 VkDescriptorSet descriptorSet; 8687 VkDescriptorSetAllocateInfo alloc_info = {}; 8688 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 8689 alloc_info.descriptorSetCount = 1; 8690 alloc_info.descriptorPool = ds_pool; 8691 alloc_info.pSetLayouts = &ds_layout.handle(); 8692 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 8693 ASSERT_VK_SUCCESS(err); 8694 8695 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout}); 8696 8697 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 8698 // We shouldn't need a fragment shader but add it to be able to run 8699 // on more devices 8700 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 8701 8702 VkPipelineObj pipe(m_device); 8703 pipe.AddShader(&vs); 8704 pipe.AddShader(&fs); 8705 pipe.AddDefaultColorAttachment(); 8706 pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 8707 8708 m_commandBuffer->begin(); 8709 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 8710 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, 8711 &descriptorSet, 0, NULL); 8712 8713 m_errorMonitor->VerifyFound(); 8714 8715 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 8716 } 8717 8718 TEST_F(VkLayerTest, InvalidBufferViewObject) { 8719 // Create a single TEXEL_BUFFER descriptor and send it an invalid bufferView 8720 // First, cause the bufferView to be invalid due to underlying buffer being destroyed 8721 // Then destroy view itself and verify that same error is hit 8722 VkResult err; 8723 8724 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15c00286); 8725 8726 ASSERT_NO_FATAL_FAILURE(Init()); 8727 VkDescriptorPoolSize ds_type_count = {}; 8728 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; 8729 ds_type_count.descriptorCount = 1; 8730 8731 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 8732 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 8733 ds_pool_ci.pNext = NULL; 8734 ds_pool_ci.maxSets = 1; 8735 ds_pool_ci.poolSizeCount = 1; 8736 ds_pool_ci.pPoolSizes = &ds_type_count; 8737 8738 VkDescriptorPool ds_pool; 8739 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 8740 ASSERT_VK_SUCCESS(err); 8741 8742 VkDescriptorSetLayoutBinding dsl_binding = {}; 8743 dsl_binding.binding = 0; 8744 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; 8745 dsl_binding.descriptorCount = 1; 8746 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 8747 dsl_binding.pImmutableSamplers = NULL; 8748 8749 const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding}); 8750 8751 VkDescriptorSet descriptorSet; 8752 VkDescriptorSetAllocateInfo alloc_info = {}; 8753 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 8754 alloc_info.descriptorSetCount = 1; 8755 alloc_info.descriptorPool = ds_pool; 8756 alloc_info.pSetLayouts = &ds_layout.handle(); 8757 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 8758 ASSERT_VK_SUCCESS(err); 8759 8760 // Create a valid bufferView to start with 8761 VkBuffer buffer; 8762 uint32_t queue_family_index = 0; 8763 VkBufferCreateInfo buffer_create_info = {}; 8764 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 8765 buffer_create_info.size = 1024; 8766 buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; 8767 buffer_create_info.queueFamilyIndexCount = 1; 8768 buffer_create_info.pQueueFamilyIndices = &queue_family_index; 8769 8770 err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer); 8771 ASSERT_VK_SUCCESS(err); 8772 8773 VkMemoryRequirements memory_reqs; 8774 VkDeviceMemory buffer_memory; 8775 8776 VkMemoryAllocateInfo memory_info = {}; 8777 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 8778 memory_info.allocationSize = 0; 8779 memory_info.memoryTypeIndex = 0; 8780 8781 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs); 8782 memory_info.allocationSize = memory_reqs.size; 8783 bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 8784 ASSERT_TRUE(pass); 8785 8786 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory); 8787 ASSERT_VK_SUCCESS(err); 8788 err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0); 8789 ASSERT_VK_SUCCESS(err); 8790 8791 VkBufferView view; 8792 VkBufferViewCreateInfo bvci = {}; 8793 bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; 8794 bvci.buffer = buffer; 8795 bvci.format = VK_FORMAT_R32_SFLOAT; 8796 bvci.range = VK_WHOLE_SIZE; 8797 8798 err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view); 8799 ASSERT_VK_SUCCESS(err); 8800 8801 // First Destroy buffer underlying view which should hit error in CV 8802 vkDestroyBuffer(m_device->device(), buffer, NULL); 8803 8804 VkWriteDescriptorSet descriptor_write; 8805 memset(&descriptor_write, 0, sizeof(descriptor_write)); 8806 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 8807 descriptor_write.dstSet = descriptorSet; 8808 descriptor_write.dstBinding = 0; 8809 descriptor_write.descriptorCount = 1; 8810 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; 8811 descriptor_write.pTexelBufferView = &view; 8812 8813 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 8814 m_errorMonitor->VerifyFound(); 8815 8816 // Now destroy view itself and verify same error, which is hit in PV this time 8817 vkDestroyBufferView(m_device->device(), view, NULL); 8818 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15c00286); 8819 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 8820 m_errorMonitor->VerifyFound(); 8821 8822 vkFreeMemory(m_device->device(), buffer_memory, NULL); 8823 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 8824 } 8825 8826 TEST_F(VkLayerTest, CreateBufferViewNoMemoryBoundToBuffer) { 8827 TEST_DESCRIPTION("Attempt to create a buffer view with a buffer that has no memory bound to it."); 8828 8829 VkResult err; 8830 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 8831 " used with no memory bound. Memory should be bound by calling vkBindBufferMemory()."); 8832 8833 ASSERT_NO_FATAL_FAILURE(Init()); 8834 8835 // Create a buffer with no bound memory and then attempt to create 8836 // a buffer view. 8837 VkBufferCreateInfo buff_ci = {}; 8838 buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 8839 buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT; 8840 buff_ci.size = 256; 8841 buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 8842 VkBuffer buffer; 8843 err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer); 8844 ASSERT_VK_SUCCESS(err); 8845 8846 VkBufferViewCreateInfo buff_view_ci = {}; 8847 buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; 8848 buff_view_ci.buffer = buffer; 8849 buff_view_ci.format = VK_FORMAT_R8_UNORM; 8850 buff_view_ci.range = VK_WHOLE_SIZE; 8851 VkBufferView buff_view; 8852 err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buff_view); 8853 8854 m_errorMonitor->VerifyFound(); 8855 vkDestroyBuffer(m_device->device(), buffer, NULL); 8856 // If last error is success, it still created the view, so delete it. 8857 if (err == VK_SUCCESS) { 8858 vkDestroyBufferView(m_device->device(), buff_view, NULL); 8859 } 8860 } 8861 8862 TEST_F(VkLayerTest, InvalidDynamicOffsetCases) { 8863 // Create a descriptorSet w/ dynamic descriptor and then hit 3 offset error 8864 // cases: 8865 // 1. No dynamicOffset supplied 8866 // 2. Too many dynamicOffsets supplied 8867 // 3. Dynamic offset oversteps buffer being updated 8868 VkResult err; 8869 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 8870 " requires 1 dynamicOffsets, but only 0 dynamicOffsets are left in pDynamicOffsets "); 8871 8872 ASSERT_NO_FATAL_FAILURE(Init()); 8873 ASSERT_NO_FATAL_FAILURE(InitViewport()); 8874 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 8875 8876 VkDescriptorPoolSize ds_type_count = {}; 8877 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 8878 ds_type_count.descriptorCount = 1; 8879 8880 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 8881 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 8882 ds_pool_ci.pNext = NULL; 8883 ds_pool_ci.maxSets = 1; 8884 ds_pool_ci.poolSizeCount = 1; 8885 ds_pool_ci.pPoolSizes = &ds_type_count; 8886 8887 VkDescriptorPool ds_pool; 8888 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 8889 ASSERT_VK_SUCCESS(err); 8890 8891 VkDescriptorSetLayoutBinding dsl_binding = {}; 8892 dsl_binding.binding = 0; 8893 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 8894 dsl_binding.descriptorCount = 1; 8895 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 8896 dsl_binding.pImmutableSamplers = NULL; 8897 8898 const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding}); 8899 8900 VkDescriptorSet descriptorSet; 8901 VkDescriptorSetAllocateInfo alloc_info = {}; 8902 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 8903 alloc_info.descriptorSetCount = 1; 8904 alloc_info.descriptorPool = ds_pool; 8905 alloc_info.pSetLayouts = &ds_layout.handle(); 8906 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 8907 ASSERT_VK_SUCCESS(err); 8908 8909 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout}); 8910 8911 // Create a buffer to update the descriptor with 8912 uint32_t qfi = 0; 8913 VkBufferCreateInfo buffCI = {}; 8914 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 8915 buffCI.size = 1024; 8916 buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 8917 buffCI.queueFamilyIndexCount = 1; 8918 buffCI.pQueueFamilyIndices = &qfi; 8919 8920 VkBuffer dyub; 8921 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub); 8922 ASSERT_VK_SUCCESS(err); 8923 // Allocate memory and bind to buffer so we can make it to the appropriate error 8924 VkMemoryRequirements memReqs; 8925 vkGetBufferMemoryRequirements(m_device->device(), dyub, &memReqs); 8926 VkMemoryAllocateInfo mem_alloc = {}; 8927 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 8928 mem_alloc.pNext = NULL; 8929 mem_alloc.allocationSize = memReqs.size; 8930 mem_alloc.memoryTypeIndex = 0; 8931 bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0); 8932 if (!pass) { 8933 vkDestroyBuffer(m_device->device(), dyub, NULL); 8934 return; 8935 } 8936 8937 VkDeviceMemory mem; 8938 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem); 8939 ASSERT_VK_SUCCESS(err); 8940 err = vkBindBufferMemory(m_device->device(), dyub, mem, 0); 8941 ASSERT_VK_SUCCESS(err); 8942 // Correctly update descriptor to avoid "NOT_UPDATED" error 8943 VkDescriptorBufferInfo buffInfo = {}; 8944 buffInfo.buffer = dyub; 8945 buffInfo.offset = 0; 8946 buffInfo.range = 1024; 8947 8948 VkWriteDescriptorSet descriptor_write; 8949 memset(&descriptor_write, 0, sizeof(descriptor_write)); 8950 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 8951 descriptor_write.dstSet = descriptorSet; 8952 descriptor_write.dstBinding = 0; 8953 descriptor_write.descriptorCount = 1; 8954 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 8955 descriptor_write.pBufferInfo = &buffInfo; 8956 8957 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 8958 8959 m_commandBuffer->begin(); 8960 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 8961 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, 8962 &descriptorSet, 0, NULL); 8963 m_errorMonitor->VerifyFound(); 8964 uint32_t pDynOff[2] = {512, 756}; 8965 // Now cause error b/c too many dynOffsets in array for # of dyn descriptors 8966 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 8967 "Attempting to bind 1 descriptorSets with 1 dynamic descriptors, but "); 8968 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, 8969 &descriptorSet, 2, pDynOff); 8970 m_errorMonitor->VerifyFound(); 8971 // Finally cause error due to dynamicOffset being too big 8972 m_errorMonitor->SetDesiredFailureMsg( 8973 VK_DEBUG_REPORT_ERROR_BIT_EXT, 8974 " dynamic offset 512 combined with offset 0 and range 1024 that oversteps the buffer size of 1024"); 8975 // Create PSO to be used for draw-time errors below 8976 char const *vsSource = 8977 "#version 450\n" 8978 "\n" 8979 "void main(){\n" 8980 " gl_Position = vec4(1);\n" 8981 "}\n"; 8982 char const *fsSource = 8983 "#version 450\n" 8984 "\n" 8985 "layout(location=0) out vec4 x;\n" 8986 "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n" 8987 "void main(){\n" 8988 " x = vec4(bar.y);\n" 8989 "}\n"; 8990 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 8991 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 8992 VkPipelineObj pipe(m_device); 8993 pipe.AddShader(&vs); 8994 pipe.AddShader(&fs); 8995 pipe.AddDefaultColorAttachment(); 8996 pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 8997 8998 VkViewport viewport = {0, 0, 16, 16, 0, 1}; 8999 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 9000 VkRect2D scissor = {{0, 0}, {16, 16}}; 9001 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 9002 9003 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 9004 // This update should succeed, but offset size of 512 will overstep buffer 9005 // /w range 1024 & size 1024 9006 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, 9007 &descriptorSet, 1, pDynOff); 9008 m_commandBuffer->Draw(1, 0, 0, 0); 9009 m_errorMonitor->VerifyFound(); 9010 9011 vkDestroyBuffer(m_device->device(), dyub, NULL); 9012 vkFreeMemory(m_device->device(), mem, NULL); 9013 9014 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 9015 } 9016 9017 TEST_F(VkLayerTest, DescriptorBufferUpdateNoMemoryBound) { 9018 TEST_DESCRIPTION("Attempt to update a descriptor with a non-sparse buffer that doesn't have memory bound"); 9019 VkResult err; 9020 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 9021 " used with no memory bound. Memory should be bound by calling vkBindBufferMemory()."); 9022 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 9023 "vkUpdateDescriptorSets() failed write update validation for Descriptor Set 0x"); 9024 9025 ASSERT_NO_FATAL_FAILURE(Init()); 9026 ASSERT_NO_FATAL_FAILURE(InitViewport()); 9027 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 9028 9029 VkDescriptorPoolSize ds_type_count = {}; 9030 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 9031 ds_type_count.descriptorCount = 1; 9032 9033 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 9034 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 9035 ds_pool_ci.pNext = NULL; 9036 ds_pool_ci.maxSets = 1; 9037 ds_pool_ci.poolSizeCount = 1; 9038 ds_pool_ci.pPoolSizes = &ds_type_count; 9039 9040 VkDescriptorPool ds_pool; 9041 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 9042 ASSERT_VK_SUCCESS(err); 9043 9044 VkDescriptorSetLayoutBinding dsl_binding = {}; 9045 dsl_binding.binding = 0; 9046 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 9047 dsl_binding.descriptorCount = 1; 9048 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 9049 dsl_binding.pImmutableSamplers = NULL; 9050 9051 const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding}); 9052 9053 VkDescriptorSet descriptorSet; 9054 VkDescriptorSetAllocateInfo alloc_info = {}; 9055 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 9056 alloc_info.descriptorSetCount = 1; 9057 alloc_info.descriptorPool = ds_pool; 9058 alloc_info.pSetLayouts = &ds_layout.handle(); 9059 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 9060 ASSERT_VK_SUCCESS(err); 9061 9062 // Create a buffer to update the descriptor with 9063 uint32_t qfi = 0; 9064 VkBufferCreateInfo buffCI = {}; 9065 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 9066 buffCI.size = 1024; 9067 buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 9068 buffCI.queueFamilyIndexCount = 1; 9069 buffCI.pQueueFamilyIndices = &qfi; 9070 9071 VkBuffer dyub; 9072 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub); 9073 ASSERT_VK_SUCCESS(err); 9074 9075 // Attempt to update descriptor without binding memory to it 9076 VkDescriptorBufferInfo buffInfo = {}; 9077 buffInfo.buffer = dyub; 9078 buffInfo.offset = 0; 9079 buffInfo.range = 1024; 9080 9081 VkWriteDescriptorSet descriptor_write; 9082 memset(&descriptor_write, 0, sizeof(descriptor_write)); 9083 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 9084 descriptor_write.dstSet = descriptorSet; 9085 descriptor_write.dstBinding = 0; 9086 descriptor_write.descriptorCount = 1; 9087 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 9088 descriptor_write.pBufferInfo = &buffInfo; 9089 9090 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 9091 m_errorMonitor->VerifyFound(); 9092 9093 vkDestroyBuffer(m_device->device(), dyub, NULL); 9094 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 9095 } 9096 9097 TEST_F(VkLayerTest, InvalidPushConstants) { 9098 ASSERT_NO_FATAL_FAILURE(Init()); 9099 ASSERT_NO_FATAL_FAILURE(InitViewport()); 9100 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 9101 9102 VkPipelineLayout pipeline_layout; 9103 VkPushConstantRange pc_range = {}; 9104 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 9105 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 9106 pipeline_layout_ci.pushConstantRangeCount = 1; 9107 pipeline_layout_ci.pPushConstantRanges = &pc_range; 9108 9109 // 9110 // Check for invalid push constant ranges in pipeline layouts. 9111 // 9112 struct PipelineLayoutTestCase { 9113 VkPushConstantRange const range; 9114 char const *msg; 9115 }; 9116 9117 const uint32_t too_big = m_device->props.limits.maxPushConstantsSize + 0x4; 9118 const std::array<PipelineLayoutTestCase, 10> range_tests = {{ 9119 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 0}, "vkCreatePipelineLayout() call has push constants index 0 with size 0."}, 9120 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 1}, "vkCreatePipelineLayout() call has push constants index 0 with size 1."}, 9121 {{VK_SHADER_STAGE_VERTEX_BIT, 4, 1}, "vkCreatePipelineLayout() call has push constants index 0 with size 1."}, 9122 {{VK_SHADER_STAGE_VERTEX_BIT, 4, 0}, "vkCreatePipelineLayout() call has push constants index 0 with size 0."}, 9123 {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4}, "vkCreatePipelineLayout() call has push constants index 0 with offset 1. Offset must"}, 9124 {{VK_SHADER_STAGE_VERTEX_BIT, 0, too_big}, "vkCreatePipelineLayout() call has push constants index 0 with offset "}, 9125 {{VK_SHADER_STAGE_VERTEX_BIT, too_big, too_big}, "vkCreatePipelineLayout() call has push constants index 0 with offset "}, 9126 {{VK_SHADER_STAGE_VERTEX_BIT, too_big, 4}, "vkCreatePipelineLayout() call has push constants index 0 with offset "}, 9127 {{VK_SHADER_STAGE_VERTEX_BIT, 0xFFFFFFF0, 0x00000020}, 9128 "vkCreatePipelineLayout() call has push constants index 0 with offset "}, 9129 {{VK_SHADER_STAGE_VERTEX_BIT, 0x00000020, 0xFFFFFFF0}, 9130 "vkCreatePipelineLayout() call has push constants index 0 with offset "}, 9131 }}; 9132 9133 // Check for invalid offset and size 9134 for (const auto &iter : range_tests) { 9135 pc_range = iter.range; 9136 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg); 9137 vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 9138 m_errorMonitor->VerifyFound(); 9139 } 9140 9141 // Check for invalid stage flag 9142 pc_range.offset = 0; 9143 pc_range.size = 16; 9144 pc_range.stageFlags = 0; 9145 m_errorMonitor->SetDesiredFailureMsg( 9146 VK_DEBUG_REPORT_ERROR_BIT_EXT, 9147 "vkCreatePipelineLayout: value of pCreateInfo->pPushConstantRanges[0].stageFlags must not be 0"); 9148 vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 9149 m_errorMonitor->VerifyFound(); 9150 9151 // Check for duplicate stage flags in a list of push constant ranges. 9152 // A shader can only have one push constant block and that block is mapped 9153 // to the push constant range that has that shader's stage flag set. 9154 // The shader's stage flag can only appear once in all the ranges, so the 9155 // implementation can find the one and only range to map it to. 9156 const uint32_t ranges_per_test = 5; 9157 struct DuplicateStageFlagsTestCase { 9158 VkPushConstantRange const ranges[ranges_per_test]; 9159 std::vector<char const *> const msg; 9160 }; 9161 // Overlapping ranges are OK, but a stage flag can appear only once. 9162 const std::array<DuplicateStageFlagsTestCase, 3> duplicate_stageFlags_tests = { 9163 { 9164 {{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, 9165 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, 9166 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, 9167 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, 9168 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}}, 9169 { 9170 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 1.", 9171 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 2.", 9172 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 3.", 9173 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 4.", 9174 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 2.", 9175 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 3.", 9176 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 4.", 9177 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 2 and 3.", 9178 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 2 and 4.", 9179 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 3 and 4.", 9180 }}, 9181 {{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, 9182 {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 4}, 9183 {VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4}, 9184 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, 9185 {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 4}}, 9186 { 9187 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 3.", 9188 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 4.", 9189 }}, 9190 {{{VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4}, 9191 {VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0, 4}, 9192 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, 9193 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, 9194 {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 4}}, 9195 { 9196 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 2 and 3.", 9197 }}, 9198 }, 9199 }; 9200 9201 for (const auto &iter : duplicate_stageFlags_tests) { 9202 pipeline_layout_ci.pPushConstantRanges = iter.ranges; 9203 pipeline_layout_ci.pushConstantRangeCount = ranges_per_test; 9204 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg.begin(), iter.msg.end()); 9205 vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 9206 m_errorMonitor->VerifyFound(); 9207 } 9208 9209 // 9210 // CmdPushConstants tests 9211 // 9212 9213 // Setup a pipeline layout with ranges: [0,16) [64,80) 9214 const std::vector<VkPushConstantRange> pc_range2 = {{VK_SHADER_STAGE_VERTEX_BIT, 64, 16}, 9215 {VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16}}; 9216 const VkPipelineLayoutObj pipeline_layout_obj(m_device, {}, pc_range2); 9217 9218 const uint8_t dummy_values[100] = {}; 9219 9220 m_commandBuffer->begin(); 9221 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 9222 9223 // Check for invalid stage flag 9224 // Note that VU 00996 isn't reached due to parameter validation 9225 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdPushConstants: value of stageFlags must not be 0"); 9226 vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), 0, 0, 16, dummy_values); 9227 m_errorMonitor->VerifyFound(); 9228 9229 m_errorMonitor->ExpectSuccess(); 9230 vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16, dummy_values); 9231 m_errorMonitor->VerifyNotFound(); 9232 m_errorMonitor->ExpectSuccess(); 9233 vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_VERTEX_BIT, 64, 16, dummy_values); 9234 m_errorMonitor->VerifyNotFound(); 9235 const std::array<VkPushConstantRange, 6> cmd_range_tests = {{ 9236 {VK_SHADER_STAGE_FRAGMENT_BIT, 64, 16}, 9237 {VK_SHADER_STAGE_VERTEX_BIT, 0, 16}, 9238 {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 16}, 9239 {VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16}, 9240 {VK_SHADER_STAGE_VERTEX_BIT, 24, 16}, 9241 {VK_SHADER_STAGE_VERTEX_BIT, 8, 4}, 9242 }}; 9243 for (const auto &iter : cmd_range_tests) { 9244 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1bc002de); 9245 vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), iter.stageFlags, iter.offset, iter.size, 9246 dummy_values); 9247 m_errorMonitor->VerifyFound(); 9248 } 9249 9250 m_commandBuffer->EndRenderPass(); 9251 m_commandBuffer->end(); 9252 } 9253 9254 TEST_F(VkLayerTest, DescriptorSetCompatibility) { 9255 // Test various desriptorSet errors with bad binding combinations 9256 using std::vector; 9257 VkResult err; 9258 9259 ASSERT_NO_FATAL_FAILURE(Init()); 9260 ASSERT_NO_FATAL_FAILURE(InitViewport()); 9261 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 9262 9263 static const uint32_t NUM_DESCRIPTOR_TYPES = 5; 9264 VkDescriptorPoolSize ds_type_count[NUM_DESCRIPTOR_TYPES] = {}; 9265 ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 9266 ds_type_count[0].descriptorCount = 10; 9267 ds_type_count[1].type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; 9268 ds_type_count[1].descriptorCount = 2; 9269 ds_type_count[2].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; 9270 ds_type_count[2].descriptorCount = 2; 9271 ds_type_count[3].type = VK_DESCRIPTOR_TYPE_SAMPLER; 9272 ds_type_count[3].descriptorCount = 5; 9273 // TODO : LunarG ILO driver currently asserts in desc.c w/ INPUT_ATTACHMENT 9274 // type 9275 // ds_type_count[4].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; 9276 ds_type_count[4].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 9277 ds_type_count[4].descriptorCount = 2; 9278 9279 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 9280 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 9281 ds_pool_ci.pNext = NULL; 9282 ds_pool_ci.maxSets = 5; 9283 ds_pool_ci.poolSizeCount = NUM_DESCRIPTOR_TYPES; 9284 ds_pool_ci.pPoolSizes = ds_type_count; 9285 9286 VkDescriptorPool ds_pool; 9287 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 9288 ASSERT_VK_SUCCESS(err); 9289 9290 static const uint32_t MAX_DS_TYPES_IN_LAYOUT = 2; 9291 VkDescriptorSetLayoutBinding dsl_binding[MAX_DS_TYPES_IN_LAYOUT] = {}; 9292 dsl_binding[0].binding = 0; 9293 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 9294 dsl_binding[0].descriptorCount = 5; 9295 dsl_binding[0].stageFlags = VK_SHADER_STAGE_ALL; 9296 dsl_binding[0].pImmutableSamplers = NULL; 9297 9298 // Create layout identical to set0 layout but w/ different stageFlags 9299 VkDescriptorSetLayoutBinding dsl_fs_stage_only = {}; 9300 dsl_fs_stage_only.binding = 0; 9301 dsl_fs_stage_only.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 9302 dsl_fs_stage_only.descriptorCount = 5; 9303 dsl_fs_stage_only.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; // Different stageFlags to cause error at 9304 // bind time 9305 dsl_fs_stage_only.pImmutableSamplers = NULL; 9306 9307 vector<VkDescriptorSetLayoutObj> ds_layouts; 9308 // Create 4 unique layouts for full pipelineLayout, and 1 special fs-only 9309 // layout for error case 9310 ds_layouts.emplace_back(m_device, std::vector<VkDescriptorSetLayoutBinding>(1, dsl_binding[0])); 9311 9312 const VkDescriptorSetLayoutObj ds_layout_fs_only(m_device, {dsl_fs_stage_only}); 9313 9314 dsl_binding[0].binding = 0; 9315 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; 9316 dsl_binding[0].descriptorCount = 2; 9317 dsl_binding[1].binding = 1; 9318 dsl_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; 9319 dsl_binding[1].descriptorCount = 2; 9320 dsl_binding[1].stageFlags = VK_SHADER_STAGE_ALL; 9321 dsl_binding[1].pImmutableSamplers = NULL; 9322 ds_layouts.emplace_back(m_device, std::vector<VkDescriptorSetLayoutBinding>({dsl_binding[0], dsl_binding[1]})); 9323 9324 dsl_binding[0].binding = 0; 9325 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 9326 dsl_binding[0].descriptorCount = 5; 9327 ds_layouts.emplace_back(m_device, std::vector<VkDescriptorSetLayoutBinding>(1, dsl_binding[0])); 9328 9329 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 9330 dsl_binding[0].descriptorCount = 2; 9331 ds_layouts.emplace_back(m_device, std::vector<VkDescriptorSetLayoutBinding>(1, dsl_binding[0])); 9332 9333 const auto &ds_vk_layouts = MakeVkHandles<VkDescriptorSetLayout>(ds_layouts); 9334 9335 static const uint32_t NUM_SETS = 4; 9336 VkDescriptorSet descriptorSet[NUM_SETS] = {}; 9337 VkDescriptorSetAllocateInfo alloc_info = {}; 9338 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 9339 alloc_info.descriptorPool = ds_pool; 9340 alloc_info.descriptorSetCount = ds_vk_layouts.size(); 9341 alloc_info.pSetLayouts = ds_vk_layouts.data(); 9342 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, descriptorSet); 9343 ASSERT_VK_SUCCESS(err); 9344 VkDescriptorSet ds0_fs_only = {}; 9345 alloc_info.descriptorSetCount = 1; 9346 alloc_info.pSetLayouts = &ds_layout_fs_only.handle(); 9347 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &ds0_fs_only); 9348 ASSERT_VK_SUCCESS(err); 9349 9350 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layouts[0], &ds_layouts[1]}); 9351 // Create pipelineLayout with only one setLayout 9352 const VkPipelineLayoutObj single_pipe_layout(m_device, {&ds_layouts[0]}); 9353 // Create pipelineLayout with 2 descriptor setLayout at index 0 9354 const VkPipelineLayoutObj pipe_layout_one_desc(m_device, {&ds_layouts[3]}); 9355 // Create pipelineLayout with 5 SAMPLER descriptor setLayout at index 0 9356 const VkPipelineLayoutObj pipe_layout_five_samp(m_device, {&ds_layouts[2]}); 9357 // Create pipelineLayout with UB type, but stageFlags for FS only 9358 VkPipelineLayoutObj pipe_layout_fs_only(m_device, {&ds_layout_fs_only}); 9359 // Create pipelineLayout w/ incompatible set0 layout, but set1 is fine 9360 const VkPipelineLayoutObj pipe_layout_bad_set0(m_device, {&ds_layout_fs_only, &ds_layouts[1]}); 9361 9362 // Create PSO to be used for draw-time errors below 9363 char const *vsSource = 9364 "#version 450\n" 9365 "\n" 9366 "void main(){\n" 9367 " gl_Position = vec4(1);\n" 9368 "}\n"; 9369 char const *fsSource = 9370 "#version 450\n" 9371 "\n" 9372 "layout(location=0) out vec4 x;\n" 9373 "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n" 9374 "void main(){\n" 9375 " x = vec4(bar.y);\n" 9376 "}\n"; 9377 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 9378 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 9379 VkPipelineObj pipe(m_device); 9380 pipe.AddShader(&vs); 9381 pipe.AddShader(&fs); 9382 pipe.AddDefaultColorAttachment(); 9383 pipe.CreateVKPipeline(pipe_layout_fs_only.handle(), renderPass()); 9384 9385 m_commandBuffer->begin(); 9386 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 9387 9388 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 9389 // NOTE : I believe LunarG ilo driver has bug (LX#189) that requires binding 9390 // of PSO 9391 // here before binding DSs. Otherwise we assert in cmd_copy_dset_data() of 9392 // cmd_pipeline.c 9393 // due to the fact that cmd_alloc_dset_data() has not been called in 9394 // cmd_bind_graphics_pipeline() 9395 // TODO : Want to cause various binding incompatibility issues here to test 9396 // DrawState 9397 // First cause various verify_layout_compatibility() fails 9398 // Second disturb early and late sets and verify INFO msgs 9399 // verify_set_layout_compatibility fail cases: 9400 // 1. invalid VkPipelineLayout (layout) passed into vkCmdBindDescriptorSets 9401 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_17c0be01); 9402 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, (VkPipelineLayout)((size_t)0xbaadb1be), 0, 9403 1, &descriptorSet[0], 0, NULL); 9404 m_errorMonitor->VerifyFound(); 9405 9406 // 2. layoutIndex exceeds # of layouts in layout 9407 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " attempting to bind set to index 1"); 9408 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, single_pipe_layout.handle(), 0, 2, 9409 &descriptorSet[0], 0, NULL); 9410 m_errorMonitor->VerifyFound(); 9411 9412 // 3. Pipeline setLayout[0] has 2 descriptors, but set being bound has 5 9413 // descriptors 9414 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has 2 descriptors, but DescriptorSetLayout "); 9415 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_one_desc.handle(), 0, 1, 9416 &descriptorSet[0], 0, NULL); 9417 m_errorMonitor->VerifyFound(); 9418 9419 // 4. same # of descriptors but mismatch in type 9420 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is type 'VK_DESCRIPTOR_TYPE_SAMPLER' but binding "); 9421 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_five_samp.handle(), 0, 1, 9422 &descriptorSet[0], 0, NULL); 9423 m_errorMonitor->VerifyFound(); 9424 9425 // 5. same # of descriptors but mismatch in stageFlags 9426 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 9427 " has stageFlags 16 but binding 0 for DescriptorSetLayout "); 9428 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_fs_only.handle(), 0, 1, 9429 &descriptorSet[0], 0, NULL); 9430 m_errorMonitor->VerifyFound(); 9431 9432 // Now that we're done actively using the pipelineLayout that gfx pipeline 9433 // was created with, we should be able to delete it. Do that now to verify 9434 // that validation obeys pipelineLayout lifetime 9435 pipe_layout_fs_only.Reset(); 9436 9437 // Cause draw-time errors due to PSO incompatibilities 9438 // 1. Error due to not binding required set (we actually use same code as 9439 // above to disturb set0) 9440 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 2, 9441 &descriptorSet[0], 0, NULL); 9442 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_bad_set0.handle(), 1, 1, 9443 &descriptorSet[1], 0, NULL); 9444 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " uses set #0 but that set is not bound."); 9445 9446 VkViewport viewport = {0, 0, 16, 16, 0, 1}; 9447 VkRect2D scissor = {{0, 0}, {16, 16}}; 9448 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 9449 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 9450 9451 m_commandBuffer->Draw(1, 0, 0, 0); 9452 m_errorMonitor->VerifyFound(); 9453 9454 // 2. Error due to bound set not being compatible with PSO's 9455 // VkPipelineLayout (diff stageFlags in this case) 9456 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 2, 9457 &descriptorSet[0], 0, NULL); 9458 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " bound as set #0 is not compatible with "); 9459 m_commandBuffer->Draw(1, 0, 0, 0); 9460 m_errorMonitor->VerifyFound(); 9461 9462 // Remaining clean-up 9463 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 9464 } 9465 9466 TEST_F(VkLayerTest, NoBeginCommandBuffer) { 9467 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 9468 "You must call vkBeginCommandBuffer() before this call to "); 9469 9470 ASSERT_NO_FATAL_FAILURE(Init()); 9471 VkCommandBufferObj commandBuffer(m_device, m_commandPool); 9472 // Call EndCommandBuffer() w/o calling BeginCommandBuffer() 9473 vkEndCommandBuffer(commandBuffer.handle()); 9474 9475 m_errorMonitor->VerifyFound(); 9476 } 9477 9478 TEST_F(VkLayerTest, SecondaryCommandBufferNullRenderpass) { 9479 ASSERT_NO_FATAL_FAILURE(Init()); 9480 9481 VkCommandBufferObj cb(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); 9482 9483 // Force the failure by not setting the Renderpass and Framebuffer fields 9484 VkCommandBufferInheritanceInfo cmd_buf_hinfo = {}; 9485 cmd_buf_hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; 9486 9487 VkCommandBufferBeginInfo cmd_buf_info = {}; 9488 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 9489 cmd_buf_info.pNext = NULL; 9490 cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; 9491 cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo; 9492 9493 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0280006a); 9494 vkBeginCommandBuffer(cb.handle(), &cmd_buf_info); 9495 m_errorMonitor->VerifyFound(); 9496 } 9497 9498 TEST_F(VkLayerTest, SecondaryCommandBufferRerecordedExplicitReset) { 9499 ASSERT_NO_FATAL_FAILURE(Init()); 9500 9501 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was destroyed or rerecorded"); 9502 9503 // A pool we can reset in. 9504 VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); 9505 VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); 9506 9507 secondary.begin(); 9508 secondary.end(); 9509 9510 m_commandBuffer->begin(); 9511 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle()); 9512 9513 // rerecording of secondary 9514 secondary.reset(); // explicit reset here. 9515 secondary.begin(); 9516 secondary.end(); 9517 9518 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle()); 9519 m_errorMonitor->VerifyFound(); 9520 } 9521 9522 TEST_F(VkLayerTest, SecondaryCommandBufferRerecordedNoReset) { 9523 ASSERT_NO_FATAL_FAILURE(Init()); 9524 9525 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was destroyed or rerecorded"); 9526 9527 // A pool we can reset in. 9528 VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); 9529 VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); 9530 9531 secondary.begin(); 9532 secondary.end(); 9533 9534 m_commandBuffer->begin(); 9535 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle()); 9536 9537 // rerecording of secondary 9538 secondary.begin(); // implicit reset in begin 9539 secondary.end(); 9540 9541 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle()); 9542 m_errorMonitor->VerifyFound(); 9543 } 9544 9545 TEST_F(VkLayerTest, CascadedInvalidation) { 9546 ASSERT_NO_FATAL_FAILURE(Init()); 9547 9548 VkEventCreateInfo eci = {VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, nullptr, 0}; 9549 VkEvent event; 9550 vkCreateEvent(m_device->device(), &eci, nullptr, &event); 9551 9552 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); 9553 secondary.begin(); 9554 vkCmdSetEvent(secondary.handle(), event, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT); 9555 secondary.end(); 9556 9557 m_commandBuffer->begin(); 9558 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle()); 9559 m_commandBuffer->end(); 9560 9561 // destroying the event should invalidate both primary and secondary CB 9562 vkDestroyEvent(m_device->device(), event, nullptr); 9563 9564 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "invalid because bound Event"); 9565 m_commandBuffer->QueueCommandBuffer(false); 9566 m_errorMonitor->VerifyFound(); 9567 } 9568 9569 TEST_F(VkLayerTest, CommandBufferResetErrors) { 9570 // Cause error due to Begin while recording CB 9571 // Then cause 2 errors for attempting to reset CB w/o having 9572 // VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT set for the pool from 9573 // which CBs were allocated. Note that this bit is off by default. 9574 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot call Begin on command buffer"); 9575 9576 ASSERT_NO_FATAL_FAILURE(Init()); 9577 9578 // Calls AllocateCommandBuffers 9579 VkCommandBufferObj commandBuffer(m_device, m_commandPool); 9580 9581 // Force the failure by setting the Renderpass and Framebuffer fields with (fake) data 9582 VkCommandBufferInheritanceInfo cmd_buf_hinfo = {}; 9583 cmd_buf_hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; 9584 VkCommandBufferBeginInfo cmd_buf_info = {}; 9585 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 9586 cmd_buf_info.pNext = NULL; 9587 cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; 9588 cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo; 9589 9590 // Begin CB to transition to recording state 9591 vkBeginCommandBuffer(commandBuffer.handle(), &cmd_buf_info); 9592 // Can't re-begin. This should trigger error 9593 vkBeginCommandBuffer(commandBuffer.handle(), &cmd_buf_info); 9594 m_errorMonitor->VerifyFound(); 9595 9596 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_3260005c); 9597 VkCommandBufferResetFlags flags = 0; // Don't care about flags for this test 9598 // Reset attempt will trigger error due to incorrect CommandPool state 9599 vkResetCommandBuffer(commandBuffer.handle(), flags); 9600 m_errorMonitor->VerifyFound(); 9601 9602 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_16e00064); 9603 // Transition CB to RECORDED state 9604 vkEndCommandBuffer(commandBuffer.handle()); 9605 // Now attempting to Begin will implicitly reset, which triggers error 9606 vkBeginCommandBuffer(commandBuffer.handle(), &cmd_buf_info); 9607 m_errorMonitor->VerifyFound(); 9608 } 9609 9610 TEST_F(VkLayerTest, InvalidPipelineCreateState) { 9611 // Attempt to Create Gfx Pipeline w/o a VS 9612 VkResult err; 9613 9614 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 9615 "Invalid Pipeline CreateInfo State: Vertex Shader required"); 9616 9617 ASSERT_NO_FATAL_FAILURE(Init()); 9618 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 9619 9620 VkDescriptorPoolSize ds_type_count = {}; 9621 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 9622 ds_type_count.descriptorCount = 1; 9623 9624 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 9625 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 9626 ds_pool_ci.pNext = NULL; 9627 ds_pool_ci.maxSets = 1; 9628 ds_pool_ci.poolSizeCount = 1; 9629 ds_pool_ci.pPoolSizes = &ds_type_count; 9630 9631 VkDescriptorPool ds_pool; 9632 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 9633 ASSERT_VK_SUCCESS(err); 9634 9635 VkDescriptorSetLayoutBinding dsl_binding = {}; 9636 dsl_binding.binding = 0; 9637 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 9638 dsl_binding.descriptorCount = 1; 9639 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 9640 dsl_binding.pImmutableSamplers = NULL; 9641 9642 const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding}); 9643 9644 VkDescriptorSet descriptorSet; 9645 VkDescriptorSetAllocateInfo alloc_info = {}; 9646 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 9647 alloc_info.descriptorSetCount = 1; 9648 alloc_info.descriptorPool = ds_pool; 9649 alloc_info.pSetLayouts = &ds_layout.handle(); 9650 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 9651 ASSERT_VK_SUCCESS(err); 9652 9653 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout}); 9654 9655 VkPipelineRasterizationStateCreateInfo rs_state_ci = {}; 9656 rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 9657 rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL; 9658 rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT; 9659 rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; 9660 rs_state_ci.depthClampEnable = VK_FALSE; 9661 rs_state_ci.rasterizerDiscardEnable = VK_TRUE; 9662 rs_state_ci.depthBiasEnable = VK_FALSE; 9663 rs_state_ci.lineWidth = 1.0f; 9664 9665 VkPipelineVertexInputStateCreateInfo vi_ci = {}; 9666 vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 9667 vi_ci.pNext = nullptr; 9668 vi_ci.vertexBindingDescriptionCount = 0; 9669 vi_ci.pVertexBindingDescriptions = nullptr; 9670 vi_ci.vertexAttributeDescriptionCount = 0; 9671 vi_ci.pVertexAttributeDescriptions = nullptr; 9672 9673 VkPipelineInputAssemblyStateCreateInfo ia_ci = {}; 9674 ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 9675 ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 9676 9677 VkPipelineShaderStageCreateInfo shaderStages[2]; 9678 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo)); 9679 9680 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 9681 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 9682 shaderStages[0] = fs.GetStageCreateInfo(); // should be: vs.GetStageCreateInfo(); 9683 shaderStages[1] = fs.GetStageCreateInfo(); 9684 9685 VkGraphicsPipelineCreateInfo gp_ci = {}; 9686 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 9687 gp_ci.pViewportState = nullptr; // no viewport b/c rasterizer is disabled 9688 gp_ci.pRasterizationState = &rs_state_ci; 9689 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; 9690 gp_ci.layout = pipeline_layout.handle(); 9691 gp_ci.renderPass = renderPass(); 9692 gp_ci.pVertexInputState = &vi_ci; 9693 gp_ci.pInputAssemblyState = &ia_ci; 9694 9695 gp_ci.stageCount = 1; 9696 gp_ci.pStages = shaderStages; 9697 9698 VkPipelineCacheCreateInfo pc_ci = {}; 9699 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 9700 pc_ci.initialDataSize = 0; 9701 pc_ci.pInitialData = 0; 9702 9703 VkPipeline pipeline; 9704 VkPipelineCache pipelineCache; 9705 9706 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache); 9707 ASSERT_VK_SUCCESS(err); 9708 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline); 9709 m_errorMonitor->VerifyFound(); 9710 9711 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL); 9712 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 9713 } 9714 9715 TEST_F(VkLayerTest, InvalidPipelineSampleRateFeatureDisable) { 9716 // Enable sample shading in pipeline when the feature is disabled. 9717 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 9718 9719 // Disable sampleRateShading here 9720 VkPhysicalDeviceFeatures device_features = {}; 9721 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features)); 9722 device_features.sampleRateShading = VK_FALSE; 9723 9724 ASSERT_NO_FATAL_FAILURE(InitState(&device_features)); 9725 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 9726 9727 // Cause the error by enabling sample shading... 9728 auto set_shading_enable = [](CreatePipelineHelper &helper) { helper.pipe_ms_state_ci_.sampleShadingEnable = VK_TRUE; }; 9729 CreatePipelineHelper::OneshotTest(*this, set_shading_enable, VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_10000620); 9730 } 9731 9732 TEST_F(VkLayerTest, InvalidPipelineSampleRateFeatureEnable) { 9733 // Enable sample shading in pipeline when the feature is disabled. 9734 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 9735 9736 // Require sampleRateShading here 9737 VkPhysicalDeviceFeatures device_features = {}; 9738 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features)); 9739 if (device_features.sampleRateShading == VK_FALSE) { 9740 printf(" SampleRateShading feature is disabled -- skipping related checks.\n"); 9741 return; 9742 } 9743 9744 ASSERT_NO_FATAL_FAILURE(InitState(&device_features)); 9745 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 9746 9747 auto range_test = [this](float value, bool positive_test) { 9748 auto info_override = [value](CreatePipelineHelper &helper) { 9749 helper.pipe_ms_state_ci_.sampleShadingEnable = VK_TRUE; 9750 helper.pipe_ms_state_ci_.minSampleShading = value; 9751 }; 9752 CreatePipelineHelper::OneshotTest(*this, info_override, VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_10000624, 9753 positive_test); 9754 }; 9755 9756 range_test(NextAfterLess(0.0F), false); 9757 range_test(NextAfterGreater(1.0F), false); 9758 range_test(0.0, /* positive_test= */ true); 9759 range_test(1.0, /* positive_test= */ true); 9760 } 9761 9762 TEST_F(VkLayerTest, InvalidPipelineSamplePNext) { 9763 // Enable sample shading in pipeline when the feature is disabled. 9764 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 9765 9766 // Set up the extension structs 9767 auto sampleLocations = chain_util::Init<VkPipelineSampleLocationsStateCreateInfoEXT>(); 9768 auto coverageToColor = chain_util::Init<VkPipelineCoverageToColorStateCreateInfoNV>(); 9769 auto coverageModulation = chain_util::Init<VkPipelineCoverageModulationStateCreateInfoNV>(); 9770 auto discriminatrix = [this](const char *name) { return DeviceExtensionSupported(gpu(), nullptr, name); }; 9771 chain_util::ExtensionChain chain(discriminatrix, &m_device_extension_names); 9772 chain.Add(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME, sampleLocations); 9773 chain.Add(VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME, coverageToColor); 9774 chain.Add(VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME, coverageModulation); 9775 const void *extension_head = chain.Head(); 9776 9777 ASSERT_NO_FATAL_FAILURE(InitState()); 9778 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 9779 9780 if (extension_head) { 9781 auto good_chain = [extension_head](CreatePipelineHelper &helper) { helper.pipe_ms_state_ci_.pNext = extension_head; }; 9782 CreatePipelineHelper::OneshotTest(*this, good_chain, (VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT), 9783 "No error", true); 9784 } else { 9785 printf(" Required extension not present -- skipping positive checks.\n"); 9786 } 9787 9788 auto instance_ci = chain_util::Init<VkInstanceCreateInfo>(); 9789 auto bad_chain = [&instance_ci](CreatePipelineHelper &helper) { helper.pipe_ms_state_ci_.pNext = &instance_ci; }; 9790 CreatePipelineHelper::OneshotTest(*this, bad_chain, VK_DEBUG_REPORT_WARNING_BIT_EXT, VALIDATION_ERROR_1001c40d); 9791 } 9792 9793 /*// TODO : This test should be good, but needs Tess support in compiler to run 9794 TEST_F(VkLayerTest, InvalidPatchControlPoints) 9795 { 9796 // Attempt to Create Gfx Pipeline w/o a VS 9797 VkResult err; 9798 9799 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 9800 "Invalid Pipeline CreateInfo State: VK_PRIMITIVE_TOPOLOGY_PATCH 9801 primitive "); 9802 9803 ASSERT_NO_FATAL_FAILURE(Init()); 9804 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 9805 9806 VkDescriptorPoolSize ds_type_count = {}; 9807 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 9808 ds_type_count.descriptorCount = 1; 9809 9810 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 9811 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 9812 ds_pool_ci.pNext = NULL; 9813 ds_pool_ci.poolSizeCount = 1; 9814 ds_pool_ci.pPoolSizes = &ds_type_count; 9815 9816 VkDescriptorPool ds_pool; 9817 err = vkCreateDescriptorPool(m_device->device(), 9818 VK_DESCRIPTOR_POOL_USAGE_NON_FREE, 1, &ds_pool_ci, NULL, &ds_pool); 9819 ASSERT_VK_SUCCESS(err); 9820 9821 VkDescriptorSetLayoutBinding dsl_binding = {}; 9822 dsl_binding.binding = 0; 9823 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 9824 dsl_binding.descriptorCount = 1; 9825 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 9826 dsl_binding.pImmutableSamplers = NULL; 9827 9828 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 9829 ds_layout_ci.sType = 9830 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 9831 ds_layout_ci.pNext = NULL; 9832 ds_layout_ci.bindingCount = 1; 9833 ds_layout_ci.pBindings = &dsl_binding; 9834 9835 VkDescriptorSetLayout ds_layout; 9836 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, 9837 &ds_layout); 9838 ASSERT_VK_SUCCESS(err); 9839 9840 VkDescriptorSet descriptorSet; 9841 err = vkAllocateDescriptorSets(m_device->device(), ds_pool, 9842 VK_DESCRIPTOR_SET_USAGE_NON_FREE, 1, &ds_layout, &descriptorSet); 9843 ASSERT_VK_SUCCESS(err); 9844 9845 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 9846 pipeline_layout_ci.sType = 9847 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 9848 pipeline_layout_ci.pNext = NULL; 9849 pipeline_layout_ci.setLayoutCount = 1; 9850 pipeline_layout_ci.pSetLayouts = &ds_layout; 9851 9852 VkPipelineLayout pipeline_layout; 9853 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, 9854 &pipeline_layout); 9855 ASSERT_VK_SUCCESS(err); 9856 9857 VkPipelineShaderStageCreateInfo shaderStages[3]; 9858 memset(&shaderStages, 0, 3 * sizeof(VkPipelineShaderStageCreateInfo)); 9859 9860 VkShaderObj vs(m_device,bindStateVertShaderText,VK_SHADER_STAGE_VERTEX_BIT, 9861 this); 9862 // Just using VS txt for Tess shaders as we don't care about functionality 9863 VkShaderObj 9864 tc(m_device,bindStateVertShaderText,VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 9865 this); 9866 VkShaderObj 9867 te(m_device,bindStateVertShaderText,VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, 9868 this); 9869 9870 shaderStages[0].sType = 9871 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 9872 shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; 9873 shaderStages[0].shader = vs.handle(); 9874 shaderStages[1].sType = 9875 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 9876 shaderStages[1].stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; 9877 shaderStages[1].shader = tc.handle(); 9878 shaderStages[2].sType = 9879 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 9880 shaderStages[2].stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; 9881 shaderStages[2].shader = te.handle(); 9882 9883 VkPipelineInputAssemblyStateCreateInfo iaCI = {}; 9884 iaCI.sType = 9885 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 9886 iaCI.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; 9887 9888 VkPipelineTessellationStateCreateInfo tsCI = {}; 9889 tsCI.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; 9890 tsCI.patchControlPoints = 0; // This will cause an error 9891 9892 VkGraphicsPipelineCreateInfo gp_ci = {}; 9893 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 9894 gp_ci.pNext = NULL; 9895 gp_ci.stageCount = 3; 9896 gp_ci.pStages = shaderStages; 9897 gp_ci.pVertexInputState = NULL; 9898 gp_ci.pInputAssemblyState = &iaCI; 9899 gp_ci.pTessellationState = &tsCI; 9900 gp_ci.pViewportState = NULL; 9901 gp_ci.pRasterizationState = NULL; 9902 gp_ci.pMultisampleState = NULL; 9903 gp_ci.pDepthStencilState = NULL; 9904 gp_ci.pColorBlendState = NULL; 9905 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; 9906 gp_ci.layout = pipeline_layout; 9907 gp_ci.renderPass = renderPass(); 9908 9909 VkPipelineCacheCreateInfo pc_ci = {}; 9910 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 9911 pc_ci.pNext = NULL; 9912 pc_ci.initialSize = 0; 9913 pc_ci.initialData = 0; 9914 pc_ci.maxSize = 0; 9915 9916 VkPipeline pipeline; 9917 VkPipelineCache pipelineCache; 9918 9919 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, 9920 &pipelineCache); 9921 ASSERT_VK_SUCCESS(err); 9922 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, 9923 &gp_ci, NULL, &pipeline); 9924 9925 m_errorMonitor->VerifyFound(); 9926 9927 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL); 9928 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 9929 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 9930 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 9931 } 9932 */ 9933 9934 TEST_F(VkLayerTest, PSOViewportStateTests) { 9935 TEST_DESCRIPTION("Test VkPipelineViewportStateCreateInfo viewport and scissor count validation for non-multiViewport"); 9936 9937 VkPhysicalDeviceFeatures features{}; 9938 ASSERT_NO_FATAL_FAILURE(Init(&features)); 9939 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 9940 9941 const auto break_vp_state = [](CreatePipelineHelper &helper) { 9942 helper.rs_state_ci_.rasterizerDiscardEnable = VK_FALSE; 9943 helper.gp_ci_.pViewportState = nullptr; 9944 }; 9945 CreatePipelineHelper::OneshotTest(*this, break_vp_state, VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_096005dc); 9946 9947 VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f}; 9948 VkViewport viewports[] = {viewport, viewport}; 9949 VkRect2D scissor = {{0, 0}, {64, 64}}; 9950 VkRect2D scissors[] = {scissor, scissor}; 9951 9952 // test viewport and scissor arrays 9953 using std::vector; 9954 struct TestCase { 9955 uint32_t viewport_count; 9956 VkViewport *viewports; 9957 uint32_t scissor_count; 9958 VkRect2D *scissors; 9959 9960 vector<UNIQUE_VALIDATION_ERROR_CODE> vuids; 9961 }; 9962 9963 vector<TestCase> test_cases = { 9964 {0, viewports, 1, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00988}}, 9965 {2, viewports, 1, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00988}}, 9966 {1, viewports, 0, scissors, {VALIDATION_ERROR_10c00982, VALIDATION_ERROR_10c00988}}, 9967 {1, viewports, 2, scissors, {VALIDATION_ERROR_10c00982, VALIDATION_ERROR_10c00988}}, 9968 {0, viewports, 0, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982}}, 9969 {2, viewports, 2, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982}}, 9970 {0, viewports, 2, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982, VALIDATION_ERROR_10c00988}}, 9971 {2, viewports, 0, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982, VALIDATION_ERROR_10c00988}}, 9972 {1, nullptr, 1, scissors, {VALIDATION_ERROR_096005d6}}, 9973 {1, viewports, 1, nullptr, {VALIDATION_ERROR_096005d8}}, 9974 {1, nullptr, 1, nullptr, {VALIDATION_ERROR_096005d6, VALIDATION_ERROR_096005d8}}, 9975 {2, 9976 nullptr, 9977 3, 9978 nullptr, 9979 {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982, VALIDATION_ERROR_10c00988, VALIDATION_ERROR_096005d6, 9980 VALIDATION_ERROR_096005d8}}, 9981 {0, nullptr, 0, nullptr, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982}}, 9982 }; 9983 9984 for (const auto &test_case : test_cases) { 9985 const auto break_vp = [&test_case](CreatePipelineHelper &helper) { 9986 helper.vp_state_ci_.viewportCount = test_case.viewport_count; 9987 helper.vp_state_ci_.pViewports = test_case.viewports; 9988 helper.vp_state_ci_.scissorCount = test_case.scissor_count; 9989 helper.vp_state_ci_.pScissors = test_case.scissors; 9990 }; 9991 CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids); 9992 } 9993 9994 vector<TestCase> dyn_test_cases = { 9995 {0, viewports, 1, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00988}}, 9996 {2, viewports, 1, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00988}}, 9997 {1, viewports, 0, scissors, {VALIDATION_ERROR_10c00982, VALIDATION_ERROR_10c00988}}, 9998 {1, viewports, 2, scissors, {VALIDATION_ERROR_10c00982, VALIDATION_ERROR_10c00988}}, 9999 {0, viewports, 0, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982}}, 10000 {2, viewports, 2, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982}}, 10001 {0, viewports, 2, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982, VALIDATION_ERROR_10c00988}}, 10002 {2, viewports, 0, scissors, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982, VALIDATION_ERROR_10c00988}}, 10003 {2, nullptr, 3, nullptr, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982, VALIDATION_ERROR_10c00988}}, 10004 {0, nullptr, 0, nullptr, {VALIDATION_ERROR_10c00980, VALIDATION_ERROR_10c00982}}, 10005 }; 10006 10007 const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR}; 10008 10009 for (const auto &test_case : dyn_test_cases) { 10010 const auto break_vp = [&](CreatePipelineHelper &helper) { 10011 VkPipelineDynamicStateCreateInfo dyn_state_ci = {}; 10012 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; 10013 dyn_state_ci.dynamicStateCount = size(dyn_states); 10014 dyn_state_ci.pDynamicStates = dyn_states; 10015 helper.dyn_state_ci_ = dyn_state_ci; 10016 10017 helper.vp_state_ci_.viewportCount = test_case.viewport_count; 10018 helper.vp_state_ci_.pViewports = test_case.viewports; 10019 helper.vp_state_ci_.scissorCount = test_case.scissor_count; 10020 helper.vp_state_ci_.pScissors = test_case.scissors; 10021 }; 10022 CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids); 10023 } 10024 } 10025 10026 // Set Extension dynamic states without enabling the required Extensions. 10027 TEST_F(VkLayerTest, ExtensionDynamicStatesSetWOExtensionEnabled) { 10028 TEST_DESCRIPTION("Create a graphics pipeline with Extension dynamic states without enabling the required Extensions."); 10029 10030 ASSERT_NO_FATAL_FAILURE(Init()); 10031 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10032 10033 using std::vector; 10034 struct TestCase { 10035 uint32_t dynamic_state_count; 10036 VkDynamicState dynamic_state; 10037 10038 char const *errmsg; 10039 }; 10040 10041 vector<TestCase> dyn_test_cases = { 10042 {1, VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV, 10043 "contains VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV, but VK_NV_clip_space_w_scaling"}, 10044 {1, VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT, 10045 "contains VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT, but VK_EXT_discard_rectangles"}, 10046 {1, VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT, "contains VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT, but VK_EXT_sample_locations"}, 10047 }; 10048 10049 for (const auto &test_case : dyn_test_cases) { 10050 VkDynamicState state[1]; 10051 state[0] = test_case.dynamic_state; 10052 const auto break_vp = [&](CreatePipelineHelper &helper) { 10053 VkPipelineDynamicStateCreateInfo dyn_state_ci = {}; 10054 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; 10055 dyn_state_ci.dynamicStateCount = test_case.dynamic_state_count; 10056 dyn_state_ci.pDynamicStates = state; 10057 helper.dyn_state_ci_ = dyn_state_ci; 10058 }; 10059 CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.errmsg); 10060 } 10061 } 10062 10063 TEST_F(VkLayerTest, PSOViewportStateMultiViewportTests) { 10064 TEST_DESCRIPTION("Test VkPipelineViewportStateCreateInfo viewport and scissor count validation for multiViewport feature"); 10065 10066 ASSERT_NO_FATAL_FAILURE(Init()); // enables all supported features 10067 10068 if (!m_device->phy().features().multiViewport) { 10069 printf(" VkPhysicalDeviceFeatures::multiViewport is not supported -- skipping test.\n"); 10070 return; 10071 } 10072 // at least 16 viewports supported from here on 10073 10074 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10075 10076 VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f}; 10077 VkViewport viewports[] = {viewport, viewport}; 10078 VkRect2D scissor = {{0, 0}, {64, 64}}; 10079 VkRect2D scissors[] = {scissor, scissor}; 10080 10081 using std::vector; 10082 struct TestCase { 10083 uint32_t viewport_count; 10084 VkViewport *viewports; 10085 uint32_t scissor_count; 10086 VkRect2D *scissors; 10087 10088 vector<UNIQUE_VALIDATION_ERROR_CODE> vuids; 10089 }; 10090 10091 vector<TestCase> test_cases = { 10092 {0, viewports, 2, scissors, {VALIDATION_ERROR_10c30a1b, VALIDATION_ERROR_10c00988}}, 10093 {2, viewports, 0, scissors, {VALIDATION_ERROR_10c2b61b, VALIDATION_ERROR_10c00988}}, 10094 {0, viewports, 0, scissors, {VALIDATION_ERROR_10c30a1b, VALIDATION_ERROR_10c2b61b}}, 10095 {2, nullptr, 2, scissors, {VALIDATION_ERROR_096005d6}}, 10096 {2, viewports, 2, nullptr, {VALIDATION_ERROR_096005d8}}, 10097 {2, nullptr, 2, nullptr, {VALIDATION_ERROR_096005d6, VALIDATION_ERROR_096005d8}}, 10098 {0, nullptr, 0, nullptr, {VALIDATION_ERROR_10c30a1b, VALIDATION_ERROR_10c2b61b}}, 10099 }; 10100 10101 const auto max_viewports = m_device->phy().properties().limits.maxViewports; 10102 const bool max_viewports_maxxed = max_viewports == std::numeric_limits<decltype(max_viewports)>::max(); 10103 if (max_viewports_maxxed) { 10104 printf( 10105 " VkPhysicalDeviceLimits::maxViewports is UINT32_MAX -- skipping part of test requiring to exceed " 10106 "maxViewports.\n"); 10107 } else { 10108 const auto too_much_viewports = max_viewports + 1; 10109 // avoid potentially big allocations by using only nullptr 10110 test_cases.push_back({too_much_viewports, 10111 nullptr, 10112 2, 10113 scissors, 10114 {VALIDATION_ERROR_10c00984, VALIDATION_ERROR_10c00988, VALIDATION_ERROR_096005d6}}); 10115 test_cases.push_back({2, 10116 viewports, 10117 too_much_viewports, 10118 nullptr, 10119 {VALIDATION_ERROR_10c00986, VALIDATION_ERROR_10c00988, VALIDATION_ERROR_096005d8}}); 10120 test_cases.push_back( 10121 {too_much_viewports, 10122 nullptr, 10123 too_much_viewports, 10124 nullptr, 10125 {VALIDATION_ERROR_10c00984, VALIDATION_ERROR_10c00986, VALIDATION_ERROR_096005d6, VALIDATION_ERROR_096005d8}}); 10126 } 10127 10128 for (const auto &test_case : test_cases) { 10129 const auto break_vp = [&test_case](CreatePipelineHelper &helper) { 10130 helper.vp_state_ci_.viewportCount = test_case.viewport_count; 10131 helper.vp_state_ci_.pViewports = test_case.viewports; 10132 helper.vp_state_ci_.scissorCount = test_case.scissor_count; 10133 helper.vp_state_ci_.pScissors = test_case.scissors; 10134 }; 10135 CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids); 10136 } 10137 10138 vector<TestCase> dyn_test_cases = { 10139 {0, viewports, 2, scissors, {VALIDATION_ERROR_10c30a1b, VALIDATION_ERROR_10c00988}}, 10140 {2, viewports, 0, scissors, {VALIDATION_ERROR_10c2b61b, VALIDATION_ERROR_10c00988}}, 10141 {0, viewports, 0, scissors, {VALIDATION_ERROR_10c30a1b, VALIDATION_ERROR_10c2b61b}}, 10142 {0, nullptr, 0, nullptr, {VALIDATION_ERROR_10c30a1b, VALIDATION_ERROR_10c2b61b}}, 10143 }; 10144 10145 if (!max_viewports_maxxed) { 10146 const auto too_much_viewports = max_viewports + 1; 10147 // avoid potentially big allocations by using only nullptr 10148 dyn_test_cases.push_back( 10149 {too_much_viewports, nullptr, 2, scissors, {VALIDATION_ERROR_10c00984, VALIDATION_ERROR_10c00988}}); 10150 dyn_test_cases.push_back( 10151 {2, viewports, too_much_viewports, nullptr, {VALIDATION_ERROR_10c00986, VALIDATION_ERROR_10c00988}}); 10152 dyn_test_cases.push_back( 10153 {too_much_viewports, nullptr, too_much_viewports, nullptr, {VALIDATION_ERROR_10c00984, VALIDATION_ERROR_10c00986}}); 10154 } 10155 10156 const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR}; 10157 10158 for (const auto &test_case : dyn_test_cases) { 10159 const auto break_vp = [&](CreatePipelineHelper &helper) { 10160 VkPipelineDynamicStateCreateInfo dyn_state_ci = {}; 10161 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; 10162 dyn_state_ci.dynamicStateCount = size(dyn_states); 10163 dyn_state_ci.pDynamicStates = dyn_states; 10164 helper.dyn_state_ci_ = dyn_state_ci; 10165 10166 helper.vp_state_ci_.viewportCount = test_case.viewport_count; 10167 helper.vp_state_ci_.pViewports = test_case.viewports; 10168 helper.vp_state_ci_.scissorCount = test_case.scissor_count; 10169 helper.vp_state_ci_.pScissors = test_case.scissors; 10170 }; 10171 CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids); 10172 } 10173 } 10174 10175 TEST_F(VkLayerTest, DynViewportAndScissorUndefinedDrawState) { 10176 TEST_DESCRIPTION("Test viewport and scissor dynamic state that is not set before draw"); 10177 10178 ASSERT_NO_FATAL_FAILURE(Init()); 10179 10180 // TODO: should also test on !multiViewport 10181 if (!m_device->phy().features().multiViewport) { 10182 printf(" Device does not support multiple viewports/scissors; skipped.\n"); 10183 return; 10184 } 10185 10186 ASSERT_NO_FATAL_FAILURE(InitViewport()); 10187 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10188 10189 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 10190 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 10191 10192 const VkPipelineLayoutObj pipeline_layout(m_device); 10193 10194 VkPipelineObj pipeline_dyn_vp(m_device); 10195 pipeline_dyn_vp.AddShader(&vs); 10196 pipeline_dyn_vp.AddShader(&fs); 10197 pipeline_dyn_vp.AddDefaultColorAttachment(); 10198 pipeline_dyn_vp.MakeDynamic(VK_DYNAMIC_STATE_VIEWPORT); 10199 pipeline_dyn_vp.SetScissor(m_scissors); 10200 ASSERT_VK_SUCCESS(pipeline_dyn_vp.CreateVKPipeline(pipeline_layout.handle(), m_renderPass)); 10201 10202 VkPipelineObj pipeline_dyn_sc(m_device); 10203 pipeline_dyn_sc.AddShader(&vs); 10204 pipeline_dyn_sc.AddShader(&fs); 10205 pipeline_dyn_sc.AddDefaultColorAttachment(); 10206 pipeline_dyn_sc.SetViewport(m_viewports); 10207 pipeline_dyn_sc.MakeDynamic(VK_DYNAMIC_STATE_SCISSOR); 10208 ASSERT_VK_SUCCESS(pipeline_dyn_sc.CreateVKPipeline(pipeline_layout.handle(), m_renderPass)); 10209 10210 m_commandBuffer->begin(); 10211 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 10212 10213 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 10214 "Dynamic viewport(s) 0 are used by pipeline state object, "); 10215 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_dyn_vp.handle()); 10216 vkCmdSetViewport(m_commandBuffer->handle(), 1, 1, 10217 &m_viewports[0]); // Forgetting to set needed 0th viweport (PSO viewportCount == 1) 10218 m_commandBuffer->Draw(1, 0, 0, 0); 10219 m_errorMonitor->VerifyFound(); 10220 10221 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic scissor(s) 0 are used by pipeline state object, "); 10222 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_dyn_sc.handle()); 10223 vkCmdSetScissor(m_commandBuffer->handle(), 1, 1, 10224 &m_scissors[0]); // Forgetting to set needed 0th scissor (PSO scissorCount == 1) 10225 m_commandBuffer->Draw(1, 0, 0, 0); 10226 m_errorMonitor->VerifyFound(); 10227 } 10228 10229 TEST_F(VkLayerTest, PSOLineWidthInvalid) { 10230 TEST_DESCRIPTION("Test non-1.0 lineWidth errors when pipeline is created and in vkCmdSetLineWidth"); 10231 VkPhysicalDeviceFeatures features{}; 10232 ASSERT_NO_FATAL_FAILURE(Init(&features)); 10233 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10234 10235 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 10236 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 10237 VkPipelineShaderStageCreateInfo shader_state_cis[] = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()}; 10238 10239 VkPipelineVertexInputStateCreateInfo vi_state_ci = {}; 10240 vi_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 10241 10242 VkPipelineInputAssemblyStateCreateInfo ia_state_ci = {}; 10243 ia_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 10244 ia_state_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 10245 10246 VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f}; 10247 VkRect2D scissor = {{0, 0}, {64, 64}}; 10248 VkPipelineViewportStateCreateInfo vp_state_ci = {}; 10249 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 10250 vp_state_ci.viewportCount = 1; 10251 vp_state_ci.pViewports = &viewport; 10252 vp_state_ci.scissorCount = 1; 10253 vp_state_ci.pScissors = &scissor; 10254 10255 VkPipelineRasterizationStateCreateInfo rs_state_ci = {}; 10256 rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 10257 rs_state_ci.rasterizerDiscardEnable = VK_FALSE; 10258 // lineWidth to be set by checks 10259 10260 VkPipelineMultisampleStateCreateInfo ms_state_ci = {}; 10261 ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 10262 ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; // must match subpass att. 10263 10264 VkPipelineColorBlendAttachmentState cba_state = {}; 10265 10266 VkPipelineColorBlendStateCreateInfo cb_state_ci = {}; 10267 cb_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; 10268 cb_state_ci.attachmentCount = 1; // must match count in subpass 10269 cb_state_ci.pAttachments = &cba_state; 10270 10271 const VkPipelineLayoutObj pipeline_layout(m_device); 10272 10273 VkGraphicsPipelineCreateInfo gp_ci = {}; 10274 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 10275 gp_ci.stageCount = sizeof(shader_state_cis) / sizeof(VkPipelineShaderStageCreateInfo); 10276 gp_ci.pStages = shader_state_cis; 10277 gp_ci.pVertexInputState = &vi_state_ci; 10278 gp_ci.pInputAssemblyState = &ia_state_ci; 10279 gp_ci.pViewportState = &vp_state_ci; 10280 gp_ci.pRasterizationState = &rs_state_ci; 10281 gp_ci.pMultisampleState = &ms_state_ci; 10282 gp_ci.pColorBlendState = &cb_state_ci; 10283 gp_ci.layout = pipeline_layout.handle(); 10284 gp_ci.renderPass = renderPass(); 10285 gp_ci.subpass = 0; 10286 10287 const std::vector<float> test_cases = {-1.0f, 0.0f, nextafterf(1.0f, 0.0f), nextafterf(1.0f, 2.0f), NAN}; 10288 10289 // test VkPipelineRasterizationStateCreateInfo::lineWidth 10290 for (const auto test_case : test_cases) { 10291 rs_state_ci.lineWidth = test_case; 10292 10293 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_096005da); 10294 VkPipeline pipeline; 10295 vkCreateGraphicsPipelines(m_device->device(), VK_NULL_HANDLE, 1, &gp_ci, nullptr, &pipeline); 10296 m_errorMonitor->VerifyFound(); 10297 } 10298 10299 // test vkCmdSetLineWidth 10300 m_commandBuffer->begin(); 10301 10302 for (const auto test_case : test_cases) { 10303 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1d600628); 10304 vkCmdSetLineWidth(m_commandBuffer->handle(), test_case); 10305 m_errorMonitor->VerifyFound(); 10306 } 10307 } 10308 10309 TEST_F(VkLayerTest, VALIDATION_ERROR_14c004d4) { 10310 TEST_DESCRIPTION("Test VALIDATION_ERROR_14c004d4: binding must be less than VkPhysicalDeviceLimits::maxVertexInputBindings"); 10311 10312 ASSERT_NO_FATAL_FAILURE(Init()); 10313 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10314 10315 VkPipelineCache pipeline_cache; 10316 { 10317 VkPipelineCacheCreateInfo create_info{}; 10318 create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 10319 10320 VkResult err = vkCreatePipelineCache(m_device->device(), &create_info, nullptr, &pipeline_cache); 10321 ASSERT_VK_SUCCESS(err); 10322 } 10323 10324 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 10325 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 10326 10327 VkPipelineShaderStageCreateInfo stages[2]{{}}; 10328 stages[0] = vs.GetStageCreateInfo(); 10329 stages[1] = fs.GetStageCreateInfo(); 10330 10331 // Test when binding is greater than or equal to VkPhysicalDeviceLimits::maxVertexInputBindings. 10332 VkVertexInputBindingDescription vertex_input_binding_description{}; 10333 vertex_input_binding_description.binding = m_device->props.limits.maxVertexInputBindings; 10334 10335 VkPipelineVertexInputStateCreateInfo vertex_input_state{}; 10336 vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 10337 vertex_input_state.pNext = nullptr; 10338 vertex_input_state.vertexBindingDescriptionCount = 1; 10339 vertex_input_state.pVertexBindingDescriptions = &vertex_input_binding_description; 10340 vertex_input_state.vertexAttributeDescriptionCount = 0; 10341 vertex_input_state.pVertexAttributeDescriptions = nullptr; 10342 10343 VkPipelineInputAssemblyStateCreateInfo input_assembly_state{}; 10344 input_assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 10345 input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 10346 10347 VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f}; 10348 VkRect2D scissor = {{0, 0}, {64, 64}}; 10349 VkPipelineViewportStateCreateInfo viewport_state{}; 10350 viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 10351 viewport_state.viewportCount = 1; 10352 viewport_state.pViewports = &viewport; 10353 viewport_state.scissorCount = 1; 10354 viewport_state.pScissors = &scissor; 10355 10356 VkPipelineMultisampleStateCreateInfo multisample_state{}; 10357 multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 10358 multisample_state.pNext = nullptr; 10359 multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; 10360 multisample_state.sampleShadingEnable = 0; 10361 multisample_state.minSampleShading = 1.0; 10362 multisample_state.pSampleMask = nullptr; 10363 10364 VkPipelineRasterizationStateCreateInfo rasterization_state{}; 10365 rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 10366 rasterization_state.polygonMode = VK_POLYGON_MODE_FILL; 10367 rasterization_state.cullMode = VK_CULL_MODE_BACK_BIT; 10368 rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; 10369 rasterization_state.depthClampEnable = VK_FALSE; 10370 rasterization_state.rasterizerDiscardEnable = VK_FALSE; 10371 rasterization_state.depthBiasEnable = VK_FALSE; 10372 rasterization_state.lineWidth = 1.0f; 10373 10374 const VkPipelineLayoutObj pipeline_layout(m_device); 10375 10376 { 10377 VkGraphicsPipelineCreateInfo create_info{}; 10378 create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 10379 create_info.stageCount = 2; 10380 create_info.pStages = stages; 10381 create_info.pVertexInputState = &vertex_input_state; 10382 create_info.pInputAssemblyState = &input_assembly_state; 10383 create_info.pViewportState = &viewport_state; 10384 create_info.pMultisampleState = &multisample_state; 10385 create_info.pRasterizationState = &rasterization_state; 10386 create_info.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; 10387 create_info.layout = pipeline_layout.handle(); 10388 create_info.renderPass = renderPass(); 10389 10390 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_14c004d4); 10391 VkPipeline pipeline; 10392 vkCreateGraphicsPipelines(m_device->device(), pipeline_cache, 1, &create_info, nullptr, &pipeline); 10393 m_errorMonitor->VerifyFound(); 10394 } 10395 10396 vkDestroyPipelineCache(m_device->device(), pipeline_cache, nullptr); 10397 } 10398 10399 TEST_F(VkLayerTest, VALIDATION_ERROR_14c004d6) { 10400 TEST_DESCRIPTION( 10401 "Test VALIDATION_ERROR_14c004d6: stride must be less than or equal to VkPhysicalDeviceLimits::maxVertexInputBindingStride"); 10402 10403 ASSERT_NO_FATAL_FAILURE(Init()); 10404 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10405 10406 VkPipelineCache pipeline_cache; 10407 { 10408 VkPipelineCacheCreateInfo create_info{}; 10409 create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 10410 10411 VkResult err = vkCreatePipelineCache(m_device->device(), &create_info, nullptr, &pipeline_cache); 10412 ASSERT_VK_SUCCESS(err); 10413 } 10414 10415 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 10416 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 10417 10418 VkPipelineShaderStageCreateInfo stages[2]{{}}; 10419 stages[0] = vs.GetStageCreateInfo(); 10420 stages[1] = fs.GetStageCreateInfo(); 10421 10422 // Test when stride is greater than VkPhysicalDeviceLimits::maxVertexInputBindingStride. 10423 VkVertexInputBindingDescription vertex_input_binding_description{}; 10424 vertex_input_binding_description.stride = m_device->props.limits.maxVertexInputBindingStride + 1; 10425 10426 VkPipelineVertexInputStateCreateInfo vertex_input_state{}; 10427 vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 10428 vertex_input_state.pNext = nullptr; 10429 vertex_input_state.vertexBindingDescriptionCount = 1; 10430 vertex_input_state.pVertexBindingDescriptions = &vertex_input_binding_description; 10431 vertex_input_state.vertexAttributeDescriptionCount = 0; 10432 vertex_input_state.pVertexAttributeDescriptions = nullptr; 10433 10434 VkPipelineInputAssemblyStateCreateInfo input_assembly_state{}; 10435 input_assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 10436 input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 10437 10438 VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f}; 10439 VkRect2D scissor = {{0, 0}, {64, 64}}; 10440 VkPipelineViewportStateCreateInfo viewport_state{}; 10441 viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 10442 viewport_state.viewportCount = 1; 10443 viewport_state.pViewports = &viewport; 10444 viewport_state.scissorCount = 1; 10445 viewport_state.pScissors = &scissor; 10446 10447 VkPipelineMultisampleStateCreateInfo multisample_state{}; 10448 multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 10449 multisample_state.pNext = nullptr; 10450 multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; 10451 multisample_state.sampleShadingEnable = 0; 10452 multisample_state.minSampleShading = 1.0; 10453 multisample_state.pSampleMask = nullptr; 10454 10455 VkPipelineRasterizationStateCreateInfo rasterization_state{}; 10456 rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 10457 rasterization_state.polygonMode = VK_POLYGON_MODE_FILL; 10458 rasterization_state.cullMode = VK_CULL_MODE_BACK_BIT; 10459 rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; 10460 rasterization_state.depthClampEnable = VK_FALSE; 10461 rasterization_state.rasterizerDiscardEnable = VK_FALSE; 10462 rasterization_state.depthBiasEnable = VK_FALSE; 10463 rasterization_state.lineWidth = 1.0f; 10464 10465 const VkPipelineLayoutObj pipeline_layout(m_device); 10466 10467 { 10468 VkGraphicsPipelineCreateInfo create_info{}; 10469 create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 10470 create_info.stageCount = 2; 10471 create_info.pStages = stages; 10472 create_info.pVertexInputState = &vertex_input_state; 10473 create_info.pInputAssemblyState = &input_assembly_state; 10474 create_info.pViewportState = &viewport_state; 10475 create_info.pMultisampleState = &multisample_state; 10476 create_info.pRasterizationState = &rasterization_state; 10477 create_info.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; 10478 create_info.layout = pipeline_layout.handle(); 10479 create_info.renderPass = renderPass(); 10480 10481 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_14c004d6); 10482 VkPipeline pipeline; 10483 vkCreateGraphicsPipelines(m_device->device(), pipeline_cache, 1, &create_info, nullptr, &pipeline); 10484 m_errorMonitor->VerifyFound(); 10485 } 10486 10487 vkDestroyPipelineCache(m_device->device(), pipeline_cache, nullptr); 10488 } 10489 10490 TEST_F(VkLayerTest, VALIDATION_ERROR_14a004d8) { 10491 TEST_DESCRIPTION("Test VALIDATION_ERROR_14a004d8: location must be less than VkPhysicalDeviceLimits::maxVertexInputAttributes"); 10492 10493 ASSERT_NO_FATAL_FAILURE(Init()); 10494 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10495 10496 VkPipelineCache pipeline_cache; 10497 { 10498 VkPipelineCacheCreateInfo create_info{}; 10499 create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 10500 10501 VkResult err = vkCreatePipelineCache(m_device->device(), &create_info, nullptr, &pipeline_cache); 10502 ASSERT_VK_SUCCESS(err); 10503 } 10504 10505 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 10506 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 10507 10508 VkPipelineShaderStageCreateInfo stages[2]{{}}; 10509 stages[0] = vs.GetStageCreateInfo(); 10510 stages[1] = fs.GetStageCreateInfo(); 10511 10512 // Test when location is greater than or equal to VkPhysicalDeviceLimits::maxVertexInputAttributes. 10513 VkVertexInputAttributeDescription vertex_input_attribute_description{}; 10514 vertex_input_attribute_description.location = m_device->props.limits.maxVertexInputAttributes; 10515 10516 VkPipelineVertexInputStateCreateInfo vertex_input_state{}; 10517 vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 10518 vertex_input_state.pNext = nullptr; 10519 vertex_input_state.vertexBindingDescriptionCount = 0; 10520 vertex_input_state.pVertexBindingDescriptions = nullptr; 10521 vertex_input_state.vertexAttributeDescriptionCount = 1; 10522 vertex_input_state.pVertexAttributeDescriptions = &vertex_input_attribute_description; 10523 10524 VkPipelineInputAssemblyStateCreateInfo input_assembly_state{}; 10525 input_assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 10526 input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 10527 10528 VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f}; 10529 VkRect2D scissor = {{0, 0}, {64, 64}}; 10530 VkPipelineViewportStateCreateInfo viewport_state{}; 10531 viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 10532 viewport_state.viewportCount = 1; 10533 viewport_state.pViewports = &viewport; 10534 viewport_state.scissorCount = 1; 10535 viewport_state.pScissors = &scissor; 10536 10537 VkPipelineMultisampleStateCreateInfo multisample_state{}; 10538 multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 10539 multisample_state.pNext = nullptr; 10540 multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; 10541 multisample_state.sampleShadingEnable = 0; 10542 multisample_state.minSampleShading = 1.0; 10543 multisample_state.pSampleMask = nullptr; 10544 10545 VkPipelineRasterizationStateCreateInfo rasterization_state{}; 10546 rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 10547 rasterization_state.polygonMode = VK_POLYGON_MODE_FILL; 10548 rasterization_state.cullMode = VK_CULL_MODE_BACK_BIT; 10549 rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; 10550 rasterization_state.depthClampEnable = VK_FALSE; 10551 rasterization_state.rasterizerDiscardEnable = VK_FALSE; 10552 rasterization_state.depthBiasEnable = VK_FALSE; 10553 rasterization_state.lineWidth = 1.0f; 10554 10555 const VkPipelineLayoutObj pipeline_layout(m_device); 10556 10557 { 10558 VkGraphicsPipelineCreateInfo create_info{}; 10559 create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 10560 create_info.stageCount = 2; 10561 create_info.pStages = stages; 10562 create_info.pVertexInputState = &vertex_input_state; 10563 create_info.pInputAssemblyState = &input_assembly_state; 10564 create_info.pViewportState = &viewport_state; 10565 create_info.pMultisampleState = &multisample_state; 10566 create_info.pRasterizationState = &rasterization_state; 10567 create_info.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; 10568 create_info.layout = pipeline_layout.handle(); 10569 create_info.renderPass = renderPass(); 10570 10571 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_14a004d8); 10572 VkPipeline pipeline; 10573 vkCreateGraphicsPipelines(m_device->device(), pipeline_cache, 1, &create_info, nullptr, &pipeline); 10574 m_errorMonitor->VerifyFound(); 10575 } 10576 10577 vkDestroyPipelineCache(m_device->device(), pipeline_cache, nullptr); 10578 } 10579 10580 TEST_F(VkLayerTest, VALIDATION_ERROR_14a004da) { 10581 TEST_DESCRIPTION("Test VALIDATION_ERROR_14a004da: binding must be less than VkPhysicalDeviceLimits::maxVertexInputBindings"); 10582 10583 ASSERT_NO_FATAL_FAILURE(Init()); 10584 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10585 10586 VkPipelineCache pipeline_cache; 10587 { 10588 VkPipelineCacheCreateInfo create_info{}; 10589 create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 10590 10591 VkResult err = vkCreatePipelineCache(m_device->device(), &create_info, nullptr, &pipeline_cache); 10592 ASSERT_VK_SUCCESS(err); 10593 } 10594 10595 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 10596 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 10597 10598 VkPipelineShaderStageCreateInfo stages[2]{{}}; 10599 stages[0] = vs.GetStageCreateInfo(); 10600 stages[1] = fs.GetStageCreateInfo(); 10601 10602 // Test when binding is greater than or equal to VkPhysicalDeviceLimits::maxVertexInputBindings. 10603 VkVertexInputAttributeDescription vertex_input_attribute_description{}; 10604 vertex_input_attribute_description.binding = m_device->props.limits.maxVertexInputBindings; 10605 10606 VkPipelineVertexInputStateCreateInfo vertex_input_state{}; 10607 vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 10608 vertex_input_state.pNext = nullptr; 10609 vertex_input_state.vertexBindingDescriptionCount = 0; 10610 vertex_input_state.pVertexBindingDescriptions = nullptr; 10611 vertex_input_state.vertexAttributeDescriptionCount = 1; 10612 vertex_input_state.pVertexAttributeDescriptions = &vertex_input_attribute_description; 10613 10614 VkPipelineInputAssemblyStateCreateInfo input_assembly_state{}; 10615 input_assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 10616 input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 10617 10618 VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f}; 10619 VkRect2D scissor = {{0, 0}, {64, 64}}; 10620 VkPipelineViewportStateCreateInfo viewport_state{}; 10621 viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 10622 viewport_state.viewportCount = 1; 10623 viewport_state.pViewports = &viewport; 10624 viewport_state.scissorCount = 1; 10625 viewport_state.pScissors = &scissor; 10626 10627 VkPipelineMultisampleStateCreateInfo multisample_state{}; 10628 multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 10629 multisample_state.pNext = nullptr; 10630 multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; 10631 multisample_state.sampleShadingEnable = 0; 10632 multisample_state.minSampleShading = 1.0; 10633 multisample_state.pSampleMask = nullptr; 10634 10635 VkPipelineRasterizationStateCreateInfo rasterization_state{}; 10636 rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 10637 rasterization_state.polygonMode = VK_POLYGON_MODE_FILL; 10638 rasterization_state.cullMode = VK_CULL_MODE_BACK_BIT; 10639 rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; 10640 rasterization_state.depthClampEnable = VK_FALSE; 10641 rasterization_state.rasterizerDiscardEnable = VK_FALSE; 10642 rasterization_state.depthBiasEnable = VK_FALSE; 10643 rasterization_state.lineWidth = 1.0f; 10644 10645 const VkPipelineLayoutObj pipeline_layout(m_device); 10646 10647 { 10648 VkGraphicsPipelineCreateInfo create_info{}; 10649 create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 10650 create_info.stageCount = 2; 10651 create_info.pStages = stages; 10652 create_info.pVertexInputState = &vertex_input_state; 10653 create_info.pInputAssemblyState = &input_assembly_state; 10654 create_info.pViewportState = &viewport_state; 10655 create_info.pMultisampleState = &multisample_state; 10656 create_info.pRasterizationState = &rasterization_state; 10657 create_info.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; 10658 create_info.layout = pipeline_layout.handle(); 10659 create_info.renderPass = renderPass(); 10660 10661 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_14a004da); 10662 VkPipeline pipeline; 10663 vkCreateGraphicsPipelines(m_device->device(), pipeline_cache, 1, &create_info, nullptr, &pipeline); 10664 m_errorMonitor->VerifyFound(); 10665 } 10666 10667 vkDestroyPipelineCache(m_device->device(), pipeline_cache, nullptr); 10668 } 10669 10670 TEST_F(VkLayerTest, VALIDATION_ERROR_14a004dc) { 10671 TEST_DESCRIPTION( 10672 "Test VALIDATION_ERROR_14a004dc: offset must be less than or equal to " 10673 "VkPhysicalDeviceLimits::maxVertexInputAttributeOffset"); 10674 10675 EnableDeviceProfileLayer(); 10676 10677 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 10678 10679 uint32_t maxVertexInputAttributeOffset = 0; 10680 { 10681 VkPhysicalDeviceProperties device_props = {}; 10682 vkGetPhysicalDeviceProperties(gpu(), &device_props); 10683 maxVertexInputAttributeOffset = device_props.limits.maxVertexInputAttributeOffset; 10684 if (maxVertexInputAttributeOffset == 0xFFFFFFFF) { 10685 // Attempt to artificially lower maximum offset 10686 PFN_vkSetPhysicalDeviceLimitsEXT fpvkSetPhysicalDeviceLimitsEXT = 10687 (PFN_vkSetPhysicalDeviceLimitsEXT)vkGetInstanceProcAddr(instance(), "vkSetPhysicalDeviceLimitsEXT"); 10688 if (!fpvkSetPhysicalDeviceLimitsEXT) { 10689 printf(" All offsets are valid & device_profile_api not found; skipped.\n"); 10690 return; 10691 } 10692 device_props.limits.maxVertexInputAttributeOffset = device_props.limits.maxVertexInputBindingStride - 2; 10693 fpvkSetPhysicalDeviceLimitsEXT(gpu(), &device_props.limits); 10694 maxVertexInputAttributeOffset = device_props.limits.maxVertexInputAttributeOffset; 10695 } 10696 } 10697 ASSERT_NO_FATAL_FAILURE(InitState()); 10698 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10699 10700 VkPipelineCache pipeline_cache; 10701 { 10702 VkPipelineCacheCreateInfo create_info{}; 10703 create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 10704 10705 VkResult err = vkCreatePipelineCache(m_device->device(), &create_info, nullptr, &pipeline_cache); 10706 ASSERT_VK_SUCCESS(err); 10707 } 10708 10709 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 10710 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 10711 10712 VkPipelineShaderStageCreateInfo stages[2]{{}}; 10713 stages[0] = vs.GetStageCreateInfo(); 10714 stages[1] = fs.GetStageCreateInfo(); 10715 10716 VkVertexInputBindingDescription vertex_input_binding_description{}; 10717 vertex_input_binding_description.binding = 0; 10718 vertex_input_binding_description.stride = m_device->props.limits.maxVertexInputBindingStride; 10719 vertex_input_binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; 10720 // Test when offset is greater than maximum. 10721 VkVertexInputAttributeDescription vertex_input_attribute_description{}; 10722 vertex_input_attribute_description.format = VK_FORMAT_R8_UNORM; 10723 vertex_input_attribute_description.offset = maxVertexInputAttributeOffset + 1; 10724 10725 VkPipelineVertexInputStateCreateInfo vertex_input_state{}; 10726 vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 10727 vertex_input_state.pNext = nullptr; 10728 vertex_input_state.vertexBindingDescriptionCount = 1; 10729 vertex_input_state.pVertexBindingDescriptions = &vertex_input_binding_description; 10730 vertex_input_state.vertexAttributeDescriptionCount = 1; 10731 vertex_input_state.pVertexAttributeDescriptions = &vertex_input_attribute_description; 10732 10733 VkPipelineInputAssemblyStateCreateInfo input_assembly_state{}; 10734 input_assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 10735 input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 10736 10737 VkPipelineMultisampleStateCreateInfo multisample_state{}; 10738 multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 10739 multisample_state.pNext = nullptr; 10740 multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; 10741 multisample_state.sampleShadingEnable = 0; 10742 multisample_state.minSampleShading = 1.0; 10743 multisample_state.pSampleMask = nullptr; 10744 10745 VkPipelineRasterizationStateCreateInfo rasterization_state{}; 10746 rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 10747 rasterization_state.polygonMode = VK_POLYGON_MODE_FILL; 10748 rasterization_state.cullMode = VK_CULL_MODE_BACK_BIT; 10749 rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; 10750 rasterization_state.depthClampEnable = VK_FALSE; 10751 rasterization_state.rasterizerDiscardEnable = VK_TRUE; 10752 rasterization_state.depthBiasEnable = VK_FALSE; 10753 rasterization_state.lineWidth = 1.0f; 10754 10755 const VkPipelineLayoutObj pipeline_layout(m_device); 10756 10757 { 10758 VkGraphicsPipelineCreateInfo create_info{}; 10759 create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 10760 create_info.stageCount = 2; 10761 create_info.pStages = stages; 10762 create_info.pVertexInputState = &vertex_input_state; 10763 create_info.pInputAssemblyState = &input_assembly_state; 10764 create_info.pViewportState = nullptr; // no viewport b/c rasterizer is disabled 10765 create_info.pMultisampleState = &multisample_state; 10766 create_info.pRasterizationState = &rasterization_state; 10767 create_info.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; 10768 create_info.layout = pipeline_layout.handle(); 10769 create_info.renderPass = renderPass(); 10770 10771 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_14a004dc); 10772 VkPipeline pipeline; 10773 vkCreateGraphicsPipelines(m_device->device(), pipeline_cache, 1, &create_info, nullptr, &pipeline); 10774 m_errorMonitor->VerifyFound(); 10775 } 10776 10777 vkDestroyPipelineCache(m_device->device(), pipeline_cache, nullptr); 10778 } 10779 10780 TEST_F(VkLayerTest, NullRenderPass) { 10781 // Bind a NULL RenderPass 10782 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 10783 "vkCmdBeginRenderPass: required parameter pRenderPassBegin specified as NULL"); 10784 10785 ASSERT_NO_FATAL_FAILURE(Init()); 10786 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10787 10788 m_commandBuffer->begin(); 10789 // Don't care about RenderPass handle b/c error should be flagged before 10790 // that 10791 vkCmdBeginRenderPass(m_commandBuffer->handle(), NULL, VK_SUBPASS_CONTENTS_INLINE); 10792 10793 m_errorMonitor->VerifyFound(); 10794 } 10795 10796 TEST_F(VkLayerTest, RenderPassWithinRenderPass) { 10797 // Bind a BeginRenderPass within an active RenderPass 10798 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 10799 "It is invalid to issue this call inside an active render pass"); 10800 10801 ASSERT_NO_FATAL_FAILURE(Init()); 10802 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10803 10804 m_commandBuffer->begin(); 10805 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 10806 // Just create a dummy Renderpass that's non-NULL so we can get to the 10807 // proper error 10808 vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 10809 10810 m_errorMonitor->VerifyFound(); 10811 } 10812 10813 TEST_F(VkLayerTest, RenderPassClearOpMismatch) { 10814 TEST_DESCRIPTION( 10815 "Begin a renderPass where clearValueCount is less than the number of renderPass attachments that use " 10816 "loadOpVK_ATTACHMENT_LOAD_OP_CLEAR."); 10817 10818 ASSERT_NO_FATAL_FAILURE(Init()); 10819 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10820 10821 // Create a renderPass with a single attachment that uses loadOp CLEAR 10822 VkAttachmentReference attach = {}; 10823 attach.layout = VK_IMAGE_LAYOUT_GENERAL; 10824 VkSubpassDescription subpass = {}; 10825 subpass.colorAttachmentCount = 1; 10826 subpass.pColorAttachments = &attach; 10827 VkRenderPassCreateInfo rpci = {}; 10828 rpci.subpassCount = 1; 10829 rpci.pSubpasses = &subpass; 10830 rpci.attachmentCount = 1; 10831 VkAttachmentDescription attach_desc = {}; 10832 attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM; 10833 // Set loadOp to CLEAR 10834 attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 10835 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; 10836 attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; 10837 rpci.pAttachments = &attach_desc; 10838 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 10839 VkRenderPass rp; 10840 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 10841 10842 VkCommandBufferInheritanceInfo hinfo = {}; 10843 hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; 10844 hinfo.renderPass = VK_NULL_HANDLE; 10845 hinfo.subpass = 0; 10846 hinfo.framebuffer = VK_NULL_HANDLE; 10847 hinfo.occlusionQueryEnable = VK_FALSE; 10848 hinfo.queryFlags = 0; 10849 hinfo.pipelineStatistics = 0; 10850 VkCommandBufferBeginInfo info = {}; 10851 info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; 10852 info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 10853 info.pInheritanceInfo = &hinfo; 10854 10855 vkBeginCommandBuffer(m_commandBuffer->handle(), &info); 10856 VkRenderPassBeginInfo rp_begin = {}; 10857 rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; 10858 rp_begin.pNext = NULL; 10859 rp_begin.renderPass = renderPass(); 10860 rp_begin.framebuffer = framebuffer(); 10861 rp_begin.clearValueCount = 0; // Should be 1 10862 10863 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1200070c); 10864 10865 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rp_begin, VK_SUBPASS_CONTENTS_INLINE); 10866 10867 m_errorMonitor->VerifyFound(); 10868 10869 vkDestroyRenderPass(m_device->device(), rp, NULL); 10870 } 10871 10872 TEST_F(VkLayerTest, EndCommandBufferWithinRenderPass) { 10873 TEST_DESCRIPTION("End a command buffer with an active render pass"); 10874 10875 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 10876 "It is invalid to issue this call inside an active render pass"); 10877 10878 ASSERT_NO_FATAL_FAILURE(Init()); 10879 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10880 10881 m_commandBuffer->begin(); 10882 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 10883 vkEndCommandBuffer(m_commandBuffer->handle()); 10884 10885 m_errorMonitor->VerifyFound(); 10886 10887 // TODO: Add test for VK_COMMAND_BUFFER_LEVEL_SECONDARY 10888 // TODO: Add test for VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT 10889 } 10890 10891 TEST_F(VkLayerTest, FillBufferWithinRenderPass) { 10892 // Call CmdFillBuffer within an active renderpass 10893 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 10894 "It is invalid to issue this call inside an active render pass"); 10895 10896 ASSERT_NO_FATAL_FAILURE(Init()); 10897 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10898 10899 m_commandBuffer->begin(); 10900 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 10901 10902 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; 10903 vk_testing::Buffer dstBuffer; 10904 dstBuffer.init_as_dst(*m_device, (VkDeviceSize)1024, reqs); 10905 10906 m_commandBuffer->FillBuffer(dstBuffer.handle(), 0, 4, 0x11111111); 10907 10908 m_errorMonitor->VerifyFound(); 10909 } 10910 10911 TEST_F(VkLayerTest, UpdateBufferWithinRenderPass) { 10912 // Call CmdUpdateBuffer within an active renderpass 10913 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 10914 "It is invalid to issue this call inside an active render pass"); 10915 10916 ASSERT_NO_FATAL_FAILURE(Init()); 10917 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10918 10919 m_commandBuffer->begin(); 10920 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 10921 10922 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; 10923 vk_testing::Buffer dstBuffer; 10924 dstBuffer.init_as_dst(*m_device, (VkDeviceSize)1024, reqs); 10925 10926 VkDeviceSize dstOffset = 0; 10927 uint32_t Data[] = {1, 2, 3, 4, 5, 6, 7, 8}; 10928 VkDeviceSize dataSize = sizeof(Data) / sizeof(uint32_t); 10929 vkCmdUpdateBuffer(m_commandBuffer->handle(), dstBuffer.handle(), dstOffset, dataSize, &Data); 10930 10931 m_errorMonitor->VerifyFound(); 10932 } 10933 10934 TEST_F(VkLayerTest, ClearColorImageWithBadRange) { 10935 TEST_DESCRIPTION("Record clear color with an invalid VkImageSubresourceRange"); 10936 10937 ASSERT_NO_FATAL_FAILURE(Init()); 10938 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10939 10940 VkImageObj image(m_device); 10941 image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL); 10942 ASSERT_TRUE(image.create_info().arrayLayers == 1); 10943 ASSERT_TRUE(image.initialized()); 10944 image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); 10945 10946 const VkClearColorValue clear_color = {{0.0f, 0.0f, 0.0f, 1.0f}}; 10947 10948 m_commandBuffer->begin(); 10949 const auto cb_handle = m_commandBuffer->handle(); 10950 10951 // Try baseMipLevel >= image.mipLevels with VK_REMAINING_MIP_LEVELS 10952 { 10953 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800b7c); 10954 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, VK_REMAINING_MIP_LEVELS, 0, 1}; 10955 vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range); 10956 m_errorMonitor->VerifyFound(); 10957 } 10958 10959 // Try baseMipLevel >= image.mipLevels without VK_REMAINING_MIP_LEVELS 10960 { 10961 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800b7c); 10962 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800b7e); 10963 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 0, 1}; 10964 vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range); 10965 m_errorMonitor->VerifyFound(); 10966 } 10967 10968 // Try levelCount = 0 10969 { 10970 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800b7e); 10971 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 0, 1}; 10972 vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range); 10973 m_errorMonitor->VerifyFound(); 10974 } 10975 10976 // Try baseMipLevel + levelCount > image.mipLevels 10977 { 10978 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800b7e); 10979 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 2, 0, 1}; 10980 vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range); 10981 m_errorMonitor->VerifyFound(); 10982 } 10983 10984 // Try baseArrayLayer >= image.arrayLayers with VK_REMAINING_ARRAY_LAYERS 10985 { 10986 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800b80); 10987 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, VK_REMAINING_ARRAY_LAYERS}; 10988 vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range); 10989 m_errorMonitor->VerifyFound(); 10990 } 10991 10992 // Try baseArrayLayer >= image.arrayLayers without VK_REMAINING_ARRAY_LAYERS 10993 { 10994 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800b80); 10995 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800b82); 10996 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, 1}; 10997 vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range); 10998 m_errorMonitor->VerifyFound(); 10999 } 11000 11001 // Try layerCount = 0 11002 { 11003 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800b82); 11004 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 0}; 11005 vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range); 11006 m_errorMonitor->VerifyFound(); 11007 } 11008 11009 // Try baseArrayLayer + layerCount > image.arrayLayers 11010 { 11011 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800b82); 11012 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 2}; 11013 vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range); 11014 m_errorMonitor->VerifyFound(); 11015 } 11016 } 11017 11018 TEST_F(VkLayerTest, ClearDepthStencilWithBadRange) { 11019 TEST_DESCRIPTION("Record clear depth with an invalid VkImageSubresourceRange"); 11020 11021 ASSERT_NO_FATAL_FAILURE(Init()); 11022 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11023 11024 const auto depth_format = FindSupportedDepthStencilFormat(gpu()); 11025 if (!depth_format) { 11026 printf(" No Depth + Stencil format found. Skipped.\n"); 11027 return; 11028 } 11029 11030 VkImageObj image(m_device); 11031 image.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL); 11032 ASSERT_TRUE(image.create_info().arrayLayers == 1); 11033 ASSERT_TRUE(image.initialized()); 11034 const VkImageAspectFlags ds_aspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 11035 image.SetLayout(ds_aspect, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); 11036 11037 const VkClearDepthStencilValue clear_value = {}; 11038 11039 m_commandBuffer->begin(); 11040 const auto cb_handle = m_commandBuffer->handle(); 11041 11042 // Try baseMipLevel >= image.mipLevels with VK_REMAINING_MIP_LEVELS 11043 { 11044 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00b84); 11045 const VkImageSubresourceRange range = {ds_aspect, 1, VK_REMAINING_MIP_LEVELS, 0, 1}; 11046 vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range); 11047 m_errorMonitor->VerifyFound(); 11048 } 11049 11050 // Try baseMipLevel >= image.mipLevels without VK_REMAINING_MIP_LEVELS 11051 { 11052 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00b84); 11053 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00b86); 11054 const VkImageSubresourceRange range = {ds_aspect, 1, 1, 0, 1}; 11055 vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range); 11056 m_errorMonitor->VerifyFound(); 11057 } 11058 11059 // Try levelCount = 0 11060 { 11061 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00b86); 11062 const VkImageSubresourceRange range = {ds_aspect, 0, 0, 0, 1}; 11063 vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range); 11064 m_errorMonitor->VerifyFound(); 11065 } 11066 11067 // Try baseMipLevel + levelCount > image.mipLevels 11068 { 11069 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00b86); 11070 const VkImageSubresourceRange range = {ds_aspect, 0, 2, 0, 1}; 11071 vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range); 11072 m_errorMonitor->VerifyFound(); 11073 } 11074 11075 // Try baseArrayLayer >= image.arrayLayers with VK_REMAINING_ARRAY_LAYERS 11076 { 11077 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00b88); 11078 const VkImageSubresourceRange range = {ds_aspect, 0, 1, 1, VK_REMAINING_ARRAY_LAYERS}; 11079 vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range); 11080 m_errorMonitor->VerifyFound(); 11081 } 11082 11083 // Try baseArrayLayer >= image.arrayLayers without VK_REMAINING_ARRAY_LAYERS 11084 { 11085 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00b88); 11086 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00b8a); 11087 const VkImageSubresourceRange range = {ds_aspect, 0, 1, 1, 1}; 11088 vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range); 11089 m_errorMonitor->VerifyFound(); 11090 } 11091 11092 // Try layerCount = 0 11093 { 11094 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00b8a); 11095 const VkImageSubresourceRange range = {ds_aspect, 0, 1, 0, 0}; 11096 vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range); 11097 m_errorMonitor->VerifyFound(); 11098 } 11099 11100 // Try baseArrayLayer + layerCount > image.arrayLayers 11101 { 11102 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00b8a); 11103 const VkImageSubresourceRange range = {ds_aspect, 0, 1, 0, 2}; 11104 vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range); 11105 m_errorMonitor->VerifyFound(); 11106 } 11107 } 11108 11109 TEST_F(VkLayerTest, ClearColorImageWithinRenderPass) { 11110 // Call CmdClearColorImage within an active RenderPass 11111 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 11112 "It is invalid to issue this call inside an active render pass"); 11113 11114 ASSERT_NO_FATAL_FAILURE(Init()); 11115 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11116 11117 m_commandBuffer->begin(); 11118 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 11119 11120 VkClearColorValue clear_color; 11121 memset(clear_color.uint32, 0, sizeof(uint32_t) * 4); 11122 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; 11123 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 11124 const int32_t tex_width = 32; 11125 const int32_t tex_height = 32; 11126 VkImageCreateInfo image_create_info = {}; 11127 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 11128 image_create_info.pNext = NULL; 11129 image_create_info.imageType = VK_IMAGE_TYPE_2D; 11130 image_create_info.format = tex_format; 11131 image_create_info.extent.width = tex_width; 11132 image_create_info.extent.height = tex_height; 11133 image_create_info.extent.depth = 1; 11134 image_create_info.mipLevels = 1; 11135 image_create_info.arrayLayers = 1; 11136 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 11137 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 11138 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 11139 11140 vk_testing::Image dstImage; 11141 dstImage.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs); 11142 11143 const VkImageSubresourceRange range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT); 11144 11145 vkCmdClearColorImage(m_commandBuffer->handle(), dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &range); 11146 11147 m_errorMonitor->VerifyFound(); 11148 } 11149 11150 TEST_F(VkLayerTest, ClearDepthStencilImageErrors) { 11151 // Hit errors related to vkCmdClearDepthStencilImage() 11152 // 1. Use an image that doesn't have VK_IMAGE_USAGE_TRANSFER_DST_BIT set 11153 // 2. Call CmdClearDepthStencilImage within an active RenderPass 11154 11155 ASSERT_NO_FATAL_FAILURE(Init()); 11156 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11157 11158 auto depth_format = FindSupportedDepthStencilFormat(gpu()); 11159 if (!depth_format) { 11160 printf(" No Depth + Stencil format found. Skipped.\n"); 11161 return; 11162 } 11163 11164 VkClearDepthStencilValue clear_value = {0}; 11165 VkMemoryPropertyFlags reqs = 0; 11166 VkImageCreateInfo image_create_info = vk_testing::Image::create_info(); 11167 image_create_info.imageType = VK_IMAGE_TYPE_2D; 11168 image_create_info.format = depth_format; 11169 image_create_info.extent.width = 64; 11170 image_create_info.extent.height = 64; 11171 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 11172 // Error here is that VK_IMAGE_USAGE_TRANSFER_DST_BIT is excluded for DS image that we'll call Clear on below 11173 image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; 11174 11175 vk_testing::Image dst_image_bad_usage; 11176 dst_image_bad_usage.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs); 11177 const VkImageSubresourceRange range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT); 11178 11179 m_commandBuffer->begin(); 11180 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00012); 11181 vkCmdClearDepthStencilImage(m_commandBuffer->handle(), dst_image_bad_usage.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1, 11182 &range); 11183 m_errorMonitor->VerifyFound(); 11184 11185 // Fix usage for next test case 11186 image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 11187 vk_testing::Image dst_image; 11188 dst_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs); 11189 11190 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 11191 11192 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00017); 11193 vkCmdClearDepthStencilImage(m_commandBuffer->handle(), dst_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1, &range); 11194 m_errorMonitor->VerifyFound(); 11195 } 11196 11197 TEST_F(VkLayerTest, ClearColorAttachmentsOutsideRenderPass) { 11198 // Call CmdClearAttachmentss outside of an active RenderPass 11199 11200 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 11201 "vkCmdClearAttachments(): This call must be issued inside an active render pass"); 11202 11203 ASSERT_NO_FATAL_FAILURE(Init()); 11204 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11205 11206 // Start no RenderPass 11207 m_commandBuffer->begin(); 11208 11209 VkClearAttachment color_attachment; 11210 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 11211 color_attachment.clearValue.color.float32[0] = 0; 11212 color_attachment.clearValue.color.float32[1] = 0; 11213 color_attachment.clearValue.color.float32[2] = 0; 11214 color_attachment.clearValue.color.float32[3] = 0; 11215 color_attachment.colorAttachment = 0; 11216 VkClearRect clear_rect = {{{0, 0}, {32, 32}}}; 11217 vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect); 11218 11219 m_errorMonitor->VerifyFound(); 11220 } 11221 11222 TEST_F(VkLayerTest, RenderPassExcessiveNextSubpass) { 11223 TEST_DESCRIPTION("Test that an error is produced when CmdNextSubpass is called too many times in a renderpass instance"); 11224 11225 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 11226 "vkCmdNextSubpass(): Attempted to advance beyond final subpass"); 11227 11228 ASSERT_NO_FATAL_FAILURE(Init()); 11229 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11230 11231 m_commandBuffer->begin(); 11232 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 11233 11234 // error here. 11235 vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE); 11236 m_errorMonitor->VerifyFound(); 11237 11238 m_commandBuffer->EndRenderPass(); 11239 m_commandBuffer->end(); 11240 } 11241 11242 TEST_F(VkLayerTest, RenderPassEndedBeforeFinalSubpass) { 11243 TEST_DESCRIPTION("Test that an error is produced when CmdEndRenderPass is called before the final subpass has been reached"); 11244 11245 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 11246 "vkCmdEndRenderPass(): Called before reaching final subpass"); 11247 11248 ASSERT_NO_FATAL_FAILURE(Init()); 11249 VkSubpassDescription sd[2] = {{0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}, 11250 {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}}; 11251 11252 VkRenderPassCreateInfo rcpi = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 2, sd, 0, nullptr}; 11253 11254 VkRenderPass rp; 11255 VkResult err = vkCreateRenderPass(m_device->device(), &rcpi, nullptr, &rp); 11256 ASSERT_VK_SUCCESS(err); 11257 11258 VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 16, 16, 1}; 11259 11260 VkFramebuffer fb; 11261 err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb); 11262 ASSERT_VK_SUCCESS(err); 11263 11264 m_commandBuffer->begin(); // no implicit RP begin 11265 11266 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {16, 16}}, 0, nullptr}; 11267 11268 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); 11269 11270 // Error here. 11271 vkCmdEndRenderPass(m_commandBuffer->handle()); 11272 m_errorMonitor->VerifyFound(); 11273 11274 // Clean up. 11275 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 11276 vkDestroyRenderPass(m_device->device(), rp, nullptr); 11277 } 11278 11279 TEST_F(VkLayerTest, BufferMemoryBarrierNoBuffer) { 11280 // Try to add a buffer memory barrier with no buffer. 11281 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 11282 "required parameter pBufferMemoryBarriers[0].buffer specified as VK_NULL_HANDLE"); 11283 11284 ASSERT_NO_FATAL_FAILURE(Init()); 11285 m_commandBuffer->begin(); 11286 11287 VkBufferMemoryBarrier buf_barrier = {}; 11288 buf_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; 11289 buf_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; 11290 buf_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 11291 buf_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 11292 buf_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 11293 buf_barrier.buffer = VK_NULL_HANDLE; 11294 buf_barrier.offset = 0; 11295 buf_barrier.size = VK_WHOLE_SIZE; 11296 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 11297 1, &buf_barrier, 0, nullptr); 11298 11299 m_errorMonitor->VerifyFound(); 11300 } 11301 11302 TEST_F(VkLayerTest, InvalidBarriers) { 11303 TEST_DESCRIPTION("A variety of ways to get VK_INVALID_BARRIER "); 11304 11305 ASSERT_NO_FATAL_FAILURE(Init()); 11306 auto depth_format = FindSupportedDepthStencilFormat(gpu()); 11307 if (!depth_format) { 11308 printf(" No Depth + Stencil format found. Skipped.\n"); 11309 return; 11310 } 11311 // Add a token self-dependency for this test to avoid unexpected errors 11312 m_addRenderPassSelfDependency = true; 11313 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11314 11315 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image Layout cannot be transitioned to UNDEFINED"); 11316 VkImageObj image(m_device); 11317 image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 11318 ASSERT_TRUE(image.initialized()); 11319 VkImageMemoryBarrier img_barrier = {}; 11320 img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 11321 img_barrier.pNext = NULL; 11322 img_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 11323 img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 11324 img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; 11325 // New layout can't be UNDEFINED 11326 img_barrier.newLayout = VK_IMAGE_LAYOUT_UNDEFINED; 11327 img_barrier.image = m_renderTargets[0]->handle(); 11328 img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 11329 img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 11330 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 11331 img_barrier.subresourceRange.baseArrayLayer = 0; 11332 img_barrier.subresourceRange.baseMipLevel = 0; 11333 img_barrier.subresourceRange.layerCount = 1; 11334 img_barrier.subresourceRange.levelCount = 1; 11335 m_commandBuffer->begin(); 11336 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 11337 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 11338 &img_barrier); 11339 m_errorMonitor->VerifyFound(); 11340 11341 // Transition image to color attachment optimal 11342 img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 11343 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 11344 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 11345 &img_barrier); 11346 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 11347 11348 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 11349 11350 // Can't send buffer memory barrier during a render pass 11351 vkCmdEndRenderPass(m_commandBuffer->handle()); 11352 11353 vk_testing::Buffer buffer; 11354 VkMemoryPropertyFlags mem_reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; 11355 buffer.init_as_src_and_dst(*m_device, 256, mem_reqs); 11356 VkBufferMemoryBarrier buf_barrier = {}; 11357 buf_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; 11358 buf_barrier.pNext = NULL; 11359 buf_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 11360 buf_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 11361 buf_barrier.buffer = buffer.handle(); 11362 buf_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 11363 buf_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 11364 buf_barrier.offset = 0; 11365 buf_barrier.size = VK_WHOLE_SIZE; 11366 11367 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "which is not less than total size"); 11368 // Exceed the internal memory size 11369 buf_barrier.offset = buffer.memory_requirements().size + 1; 11370 // Offset greater than total size 11371 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 11372 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1, &buf_barrier, 0, 11373 nullptr); 11374 m_errorMonitor->VerifyFound(); 11375 buf_barrier.offset = 0; 11376 11377 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "whose sum is greater than total size"); 11378 buf_barrier.size = buffer.memory_requirements().size + 1; 11379 // Size greater than total size 11380 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 11381 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1, &buf_barrier, 0, 11382 nullptr); 11383 m_errorMonitor->VerifyFound(); 11384 11385 // Now exercise barrier aspect bit errors, first DS 11386 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a400c01); 11387 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a00096e); 11388 VkDepthStencilObj ds_image(m_device); 11389 ds_image.Init(m_device, 128, 128, depth_format); 11390 ASSERT_TRUE(ds_image.initialized()); 11391 img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 11392 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; 11393 img_barrier.image = ds_image.handle(); 11394 11395 // Not having DEPTH or STENCIL set is an error 11396 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT; 11397 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 11398 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 11399 &img_barrier); 11400 m_errorMonitor->VerifyFound(); 11401 11402 // Having only one of depth or stencil set for DS image is an error 11403 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a00096e); 11404 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; 11405 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 11406 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 11407 &img_barrier); 11408 m_errorMonitor->VerifyFound(); 11409 11410 // Having anything other than DEPTH and STENCIL is an error 11411 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a400c01); 11412 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_COLOR_BIT; 11413 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 11414 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 11415 &img_barrier); 11416 m_errorMonitor->VerifyFound(); 11417 11418 // Now test depth-only 11419 VkFormatProperties format_props; 11420 vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D16_UNORM, &format_props); 11421 if (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) { 11422 VkDepthStencilObj d_image(m_device); 11423 d_image.Init(m_device, 128, 128, VK_FORMAT_D16_UNORM); 11424 ASSERT_TRUE(d_image.initialized()); 11425 img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 11426 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; 11427 img_barrier.image = d_image.handle(); 11428 11429 // DEPTH bit must be set 11430 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 11431 "Depth-only image formats must have the VK_IMAGE_ASPECT_DEPTH_BIT set."); 11432 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT; 11433 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 11434 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 11435 &img_barrier); 11436 m_errorMonitor->VerifyFound(); 11437 11438 // No bits other than DEPTH may be set 11439 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 11440 "Depth-only image formats can have only the VK_IMAGE_ASPECT_DEPTH_BIT set."); 11441 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_COLOR_BIT; 11442 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 11443 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 11444 &img_barrier); 11445 m_errorMonitor->VerifyFound(); 11446 } 11447 11448 // Now test stencil-only 11449 vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_S8_UINT, &format_props); 11450 if (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) { 11451 VkDepthStencilObj s_image(m_device); 11452 s_image.Init(m_device, 128, 128, VK_FORMAT_S8_UINT); 11453 ASSERT_TRUE(s_image.initialized()); 11454 img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 11455 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; 11456 img_barrier.image = s_image.handle(); 11457 // Use of COLOR aspect on depth image is error 11458 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 11459 "Stencil-only image formats must have the VK_IMAGE_ASPECT_STENCIL_BIT set."); 11460 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 11461 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 11462 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 11463 &img_barrier); 11464 m_errorMonitor->VerifyFound(); 11465 } 11466 11467 // Finally test color 11468 VkImageObj c_image(m_device); 11469 c_image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 11470 ASSERT_TRUE(c_image.initialized()); 11471 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 11472 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; 11473 img_barrier.image = c_image.handle(); 11474 11475 // COLOR bit must be set 11476 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 11477 "Color image formats must have the VK_IMAGE_ASPECT_COLOR_BIT set."); 11478 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT; 11479 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 11480 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 11481 &img_barrier); 11482 m_errorMonitor->VerifyFound(); 11483 11484 // No bits other than COLOR may be set 11485 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 11486 "Color image formats must have ONLY the VK_IMAGE_ASPECT_COLOR_BIT set."); 11487 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT; 11488 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 11489 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 11490 &img_barrier); 11491 m_errorMonitor->VerifyFound(); 11492 11493 // A barrier's new and old VkImageLayout must be compatible with an image's VkImageUsageFlags. 11494 { 11495 VkImageObj img_color(m_device); 11496 img_color.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL); 11497 ASSERT_TRUE(img_color.initialized()); 11498 11499 VkImageObj img_ds(m_device); 11500 img_ds.Init(128, 128, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL); 11501 ASSERT_TRUE(img_ds.initialized()); 11502 11503 VkImageObj img_xfer_src(m_device); 11504 img_xfer_src.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL); 11505 ASSERT_TRUE(img_xfer_src.initialized()); 11506 11507 VkImageObj img_xfer_dst(m_device); 11508 img_xfer_dst.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL); 11509 ASSERT_TRUE(img_xfer_dst.initialized()); 11510 11511 VkImageObj img_sampled(m_device); 11512 img_sampled.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL); 11513 ASSERT_TRUE(img_sampled.initialized()); 11514 11515 VkImageObj img_input(m_device); 11516 img_input.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL); 11517 ASSERT_TRUE(img_input.initialized()); 11518 11519 const struct { 11520 VkImageObj &image_obj; 11521 VkImageLayout bad_layout; 11522 UNIQUE_VALIDATION_ERROR_CODE msg_code; 11523 } bad_buffer_layouts[] = { 11524 // clang-format off 11525 // images _without_ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT 11526 {img_ds, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VALIDATION_ERROR_0a000970}, 11527 {img_xfer_src, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VALIDATION_ERROR_0a000970}, 11528 {img_xfer_dst, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VALIDATION_ERROR_0a000970}, 11529 {img_sampled, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VALIDATION_ERROR_0a000970}, 11530 {img_input, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VALIDATION_ERROR_0a000970}, 11531 // images _without_ VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT 11532 {img_color, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VALIDATION_ERROR_0a000972}, 11533 {img_xfer_src, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VALIDATION_ERROR_0a000972}, 11534 {img_xfer_dst, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VALIDATION_ERROR_0a000972}, 11535 {img_sampled, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VALIDATION_ERROR_0a000972}, 11536 {img_input, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VALIDATION_ERROR_0a000972}, 11537 {img_color, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VALIDATION_ERROR_0a000974}, 11538 {img_xfer_src, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VALIDATION_ERROR_0a000974}, 11539 {img_xfer_dst, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VALIDATION_ERROR_0a000974}, 11540 {img_sampled, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VALIDATION_ERROR_0a000974}, 11541 {img_input, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VALIDATION_ERROR_0a000974}, 11542 // images _without_ VK_IMAGE_USAGE_SAMPLED_BIT or VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT 11543 {img_color, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VALIDATION_ERROR_0a000976}, 11544 {img_ds, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VALIDATION_ERROR_0a000976}, 11545 {img_xfer_src, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VALIDATION_ERROR_0a000976}, 11546 {img_xfer_dst, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VALIDATION_ERROR_0a000976}, 11547 // images _without_ VK_IMAGE_USAGE_TRANSFER_SRC_BIT 11548 {img_color, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VALIDATION_ERROR_0a000978}, 11549 {img_ds, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VALIDATION_ERROR_0a000978}, 11550 {img_xfer_dst, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VALIDATION_ERROR_0a000978}, 11551 {img_sampled, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VALIDATION_ERROR_0a000978}, 11552 {img_input, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VALIDATION_ERROR_0a000978}, 11553 // images _without_ VK_IMAGE_USAGE_TRANSFER_DST_BIT 11554 {img_color, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VALIDATION_ERROR_0a00097a}, 11555 {img_ds, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VALIDATION_ERROR_0a00097a}, 11556 {img_xfer_src, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VALIDATION_ERROR_0a00097a}, 11557 {img_sampled, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VALIDATION_ERROR_0a00097a}, 11558 {img_input, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VALIDATION_ERROR_0a00097a}, 11559 // clang-format on 11560 }; 11561 const uint32_t layout_count = sizeof(bad_buffer_layouts) / sizeof(bad_buffer_layouts[0]); 11562 11563 for (uint32_t i = 0; i < layout_count; ++i) { 11564 img_barrier.image = bad_buffer_layouts[i].image_obj.handle(); 11565 const VkImageUsageFlags usage = bad_buffer_layouts[i].image_obj.usage(); 11566 img_barrier.subresourceRange.aspectMask = (usage == VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) 11567 ? (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) 11568 : VK_IMAGE_ASPECT_COLOR_BIT; 11569 11570 img_barrier.oldLayout = bad_buffer_layouts[i].bad_layout; 11571 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; 11572 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, bad_buffer_layouts[i].msg_code); 11573 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 11574 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 11575 &img_barrier); 11576 m_errorMonitor->VerifyFound(); 11577 11578 img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL; 11579 img_barrier.newLayout = bad_buffer_layouts[i].bad_layout; 11580 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, bad_buffer_layouts[i].msg_code); 11581 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 11582 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 11583 &img_barrier); 11584 m_errorMonitor->VerifyFound(); 11585 } 11586 11587 img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL; 11588 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; 11589 } 11590 // Attempt barrier where srcAccessMask is not supported by srcStageMask 11591 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800940); 11592 // Have lower-order bit that's supported (shader write), but higher-order bit not supported to verify multi-bit validation 11593 buf_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_WRITE_BIT; 11594 buf_barrier.offset = 0; 11595 buf_barrier.size = VK_WHOLE_SIZE; 11596 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 11597 VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1, &buf_barrier, 0, nullptr); 11598 m_errorMonitor->VerifyFound(); 11599 // Attempt barrier where dsAccessMask is not supported by dstStageMask 11600 buf_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 11601 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b800942); 11602 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 11603 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1, &buf_barrier, 0, 11604 nullptr); 11605 m_errorMonitor->VerifyFound(); 11606 11607 // Attempt to mismatch barriers/waitEvents calls with incompatible queues 11608 // Create command pool with incompatible queueflags 11609 const std::vector<VkQueueFamilyProperties> queue_props = m_device->queue_props; 11610 uint32_t queue_family_index = m_device->QueueFamilyWithoutCapabilities(VK_QUEUE_COMPUTE_BIT); 11611 if (queue_family_index == UINT32_MAX) { 11612 printf(" No non-compute queue found; skipped.\n"); 11613 return; // NOTE: this exits the test function! 11614 } 11615 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b80093e); 11616 11617 VkCommandPoolObj command_pool(m_device, queue_family_index, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); 11618 VkCommandBufferObj bad_command_buffer(m_device, &command_pool); 11619 11620 bad_command_buffer.begin(); 11621 buf_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; 11622 // Set two bits that should both be supported as a bonus positive check 11623 buf_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT; 11624 vkCmdPipelineBarrier(bad_command_buffer.handle(), VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 11625 VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1, &buf_barrier, 0, nullptr); 11626 m_errorMonitor->VerifyFound(); 11627 11628 if ((queue_props[queue_family_index].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0) { 11629 printf(" The non-compute queue does not support graphics; skipped.\n"); 11630 return; // NOTE: this exits the test function! 11631 } 11632 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1e600918); 11633 VkEvent event; 11634 VkEventCreateInfo event_create_info{}; 11635 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 11636 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event); 11637 vkCmdWaitEvents(bad_command_buffer.handle(), 1, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 11638 nullptr, 0, nullptr, 0, nullptr); 11639 m_errorMonitor->VerifyFound(); 11640 bad_command_buffer.end(); 11641 } 11642 11643 class BarrierQueueFamilyTestHelper { 11644 public: 11645 BarrierQueueFamilyTestHelper(VkLayerTest &test) : layer_test_(test), image_(test.DeviceObj()) {} 11646 // Init with queue familes non-null for CONCURRENT sharing mode (which requires them) 11647 void Init(std::vector<uint32_t> *families) { 11648 VkDeviceObj *device_obj = layer_test_.DeviceObj(); 11649 image_.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0, families); 11650 ASSERT_TRUE(image_.initialized()); 11651 11652 image_barrier_ = 11653 image_.image_memory_barrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, image_.Layout(), 11654 image_.Layout(), image_.subresource_range(VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1)); 11655 11656 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; 11657 buffer_.init_as_src_and_dst(*device_obj, 256, mem_prop, families); 11658 ASSERT_TRUE(buffer_.initialized()); 11659 buffer_barrier_ = 11660 buffer_.buffer_memory_barrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, 0, VK_WHOLE_SIZE); 11661 } 11662 11663 void operator()(UNIQUE_VALIDATION_ERROR_CODE img_err, UNIQUE_VALIDATION_ERROR_CODE buf_err, uint32_t src, uint32_t dst, 11664 bool positive = false, VkQueue submit = VK_NULL_HANDLE) { 11665 auto monitor = layer_test_.Monitor(); 11666 monitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, img_err); 11667 monitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, buf_err); 11668 11669 layer_test_.CommandBuffer()->begin(); 11670 image_barrier_.srcQueueFamilyIndex = src; 11671 image_barrier_.dstQueueFamilyIndex = dst; 11672 buffer_barrier_.srcQueueFamilyIndex = src; 11673 buffer_barrier_.dstQueueFamilyIndex = dst; 11674 vkCmdPipelineBarrier(layer_test_.CommandBuffer()->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 11675 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 1, &buffer_barrier_, 1, 11676 &image_barrier_); 11677 layer_test_.CommandBuffer()->end(); 11678 11679 VkCommandBuffer cb_handle = layer_test_.CommandBuffer()->handle(); 11680 if (submit != VK_NULL_HANDLE) { 11681 VkSubmitInfo submit_info = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &cb_handle, 0, nullptr}; 11682 VkResult err = vkQueueSubmit(submit, 1, &submit_info, VK_NULL_HANDLE); 11683 if (positive) { 11684 ASSERT_TRUE(err == VK_SUCCESS); 11685 err = vkQueueWaitIdle(submit); 11686 } 11687 } 11688 vkResetCommandBuffer(cb_handle, 0); 11689 11690 if (positive) { 11691 monitor->VerifyNotFound(); 11692 } else { 11693 monitor->VerifyFound(); 11694 } 11695 }; 11696 11697 protected: 11698 VkLayerTest &layer_test_; 11699 VkImageObj image_; 11700 VkImageMemoryBarrier image_barrier_; 11701 vk_testing::Buffer buffer_; 11702 VkBufferMemoryBarrier buffer_barrier_; 11703 }; 11704 11705 TEST_F(VkLayerTest, InvalidBarrierQueueFamily) { 11706 TEST_DESCRIPTION("Create and submit barriers with invalid queue families"); 11707 ASSERT_NO_FATAL_FAILURE(Init(nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)); 11708 11709 // Find queues of two families 11710 const uint32_t submit_family = m_device->graphics_queue_node_index_; 11711 const uint32_t invalid = static_cast<uint32_t>(m_device->queue_props.size()); 11712 const uint32_t other_family = submit_family != 0 ? 0 : 1; 11713 const bool only_one_family = invalid == 1; 11714 11715 if (only_one_family) { 11716 printf(" Single queue family found -- VK_SHARING_MODE_CONCURRENT testcases skipped.\n"); 11717 } else { 11718 std::vector<uint32_t> families = {submit_family, other_family}; 11719 BarrierQueueFamilyTestHelper conc_test(*this); 11720 conc_test.Init(&families); 11721 // core_validation::barrier_queue_families::kSrcAndDestMustBeIgnore 11722 conc_test(VALIDATION_ERROR_0a00095e, VALIDATION_ERROR_0180094c, VK_QUEUE_FAMILY_IGNORED, submit_family); 11723 conc_test(VALIDATION_ERROR_0a00095e, VALIDATION_ERROR_0180094c, submit_family, VK_QUEUE_FAMILY_IGNORED); 11724 conc_test(VALIDATION_ERROR_0a00095e, VALIDATION_ERROR_0180094c, submit_family, submit_family); 11725 // true -> positive test 11726 conc_test(VALIDATION_ERROR_0a00095e, VALIDATION_ERROR_0180094c, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, true); 11727 } 11728 11729 BarrierQueueFamilyTestHelper excl_test(*this); 11730 excl_test.Init(nullptr); // no queue families means *exclusive* sharing mode. 11731 11732 // core_validation::barrier_queue_families::kBothIgnoreOrBothValid 11733 excl_test(VALIDATION_ERROR_0a000960, VALIDATION_ERROR_01800950, VK_QUEUE_FAMILY_IGNORED, submit_family); 11734 excl_test(VALIDATION_ERROR_0a000960, VALIDATION_ERROR_01800950, submit_family, VK_QUEUE_FAMILY_IGNORED); 11735 // true -> positive test 11736 excl_test(VALIDATION_ERROR_0a000960, VALIDATION_ERROR_01800950, submit_family, submit_family, true); 11737 excl_test(VALIDATION_ERROR_0a000960, VALIDATION_ERROR_01800950, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, true); 11738 11739 if (only_one_family) { 11740 printf(" Single queue family found -- VK_SHARING_MODE_EXCLUSIVE submit testcases skipped.\n"); 11741 } else { 11742 // core_validation::barrier_queue_families::kSubmitQueueMustMatchSrcOrDst 11743 excl_test(VALIDATION_ERROR_0a00096a, VALIDATION_ERROR_01800958, other_family, other_family, false, m_device->m_queue); 11744 // true -> positive test 11745 // Note: when we start tracking resource onwership, we'll need a way to reset the buffers s.t. this doesn't 11746 // trigger unexpected errors 11747 excl_test(VALIDATION_ERROR_0a00096a, VALIDATION_ERROR_01800958, submit_family, other_family, true, m_device->m_queue); 11748 excl_test(VALIDATION_ERROR_0a00096a, VALIDATION_ERROR_01800958, other_family, submit_family, true, m_device->m_queue); 11749 } 11750 } 11751 11752 TEST_F(VkLayerTest, InvalidBarrierQueueFamilyWithMemExt) { 11753 TEST_DESCRIPTION("Create and submit barriers with invalid queue families when memory extension is enabled "); 11754 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 11755 // Check for external memory device extensions 11756 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME)) { 11757 m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME); 11758 } else { 11759 printf(" External memory extension not supported, skipping test\n"); 11760 return; 11761 } 11762 11763 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)); 11764 11765 // Find queues of two families 11766 const uint32_t submit_family = m_device->graphics_queue_node_index_; 11767 const uint32_t invalid = static_cast<uint32_t>(m_device->queue_props.size()); 11768 const uint32_t other_family = submit_family != 0 ? 0 : 1; 11769 const bool only_one_family = invalid == 1; 11770 11771 if (only_one_family) { 11772 printf(" Single queue family found -- VK_SHARING_MODE_CONCURRENT testcases skipped.\n"); 11773 } else { 11774 std::vector<uint32_t> families = {submit_family, other_family}; 11775 BarrierQueueFamilyTestHelper conc_test(*this); 11776 11777 // core_validation::barrier_queue_families::kSrcOrDstMustBeIgnore 11778 conc_test.Init(&families); 11779 conc_test(VALIDATION_ERROR_0a000aca, VALIDATION_ERROR_0180094e, submit_family, submit_family); 11780 // true -> positive test 11781 conc_test(VALIDATION_ERROR_0a000aca, VALIDATION_ERROR_0180094e, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, true); 11782 conc_test(VALIDATION_ERROR_0a000aca, VALIDATION_ERROR_0180094e, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_EXTERNAL_KHR, 11783 true); 11784 conc_test(VALIDATION_ERROR_0a000aca, VALIDATION_ERROR_0180094e, VK_QUEUE_FAMILY_EXTERNAL_KHR, VK_QUEUE_FAMILY_IGNORED, 11785 true); 11786 11787 // core_validation::barrier_queue_families::kSpecialOrIgnoreOnly 11788 conc_test(VALIDATION_ERROR_0a000dcc, VALIDATION_ERROR_01800dc6, submit_family, VK_QUEUE_FAMILY_IGNORED); 11789 conc_test(VALIDATION_ERROR_0a000dcc, VALIDATION_ERROR_01800dc6, VK_QUEUE_FAMILY_IGNORED, submit_family); 11790 // This is to flag the errors that would be considered only "unexpected" in the parallel case above 11791 // true -> positive test 11792 conc_test(VALIDATION_ERROR_0a000dcc, VALIDATION_ERROR_01800dc6, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_EXTERNAL_KHR, 11793 true); 11794 conc_test(VALIDATION_ERROR_0a000dcc, VALIDATION_ERROR_01800dc6, VK_QUEUE_FAMILY_EXTERNAL_KHR, VK_QUEUE_FAMILY_IGNORED, 11795 true); 11796 } 11797 11798 BarrierQueueFamilyTestHelper excl_test(*this); 11799 excl_test.Init(nullptr); // no queue families means *exclusive* sharing mode. 11800 11801 // core_validation::barrier_queue_families::kSrcIgnoreRequiresDstIgnore 11802 excl_test(VALIDATION_ERROR_0a000962, VALIDATION_ERROR_01800952, VK_QUEUE_FAMILY_IGNORED, submit_family); 11803 excl_test(VALIDATION_ERROR_0a000962, VALIDATION_ERROR_01800952, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_EXTERNAL_KHR); 11804 // true -> positive test 11805 excl_test(VALIDATION_ERROR_0a000962, VALIDATION_ERROR_01800952, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, true); 11806 11807 // core_validation::barrier_queue_families::kDstValidOrSpecialIfNotIgnore 11808 excl_test(VALIDATION_ERROR_0a000dd0, VALIDATION_ERROR_01800dca, submit_family, invalid); 11809 // true -> positive test 11810 excl_test(VALIDATION_ERROR_0a000dd0, VALIDATION_ERROR_01800dca, submit_family, submit_family, true); 11811 excl_test(VALIDATION_ERROR_0a000dd0, VALIDATION_ERROR_01800dca, submit_family, VK_QUEUE_FAMILY_IGNORED, true); 11812 excl_test(VALIDATION_ERROR_0a000dd0, VALIDATION_ERROR_01800dca, submit_family, VK_QUEUE_FAMILY_EXTERNAL_KHR, true); 11813 11814 // core_validation::barrier_queue_families::kSrcValidOrSpecialIfNotIgnore 11815 excl_test(VALIDATION_ERROR_0a000dce, VALIDATION_ERROR_01800dc8, invalid, submit_family); 11816 // true -> positive test 11817 excl_test(VALIDATION_ERROR_0a000dce, VALIDATION_ERROR_01800dc8, submit_family, submit_family, true); 11818 excl_test(VALIDATION_ERROR_0a000dce, VALIDATION_ERROR_01800dc8, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, true); 11819 excl_test(VALIDATION_ERROR_0a000dce, VALIDATION_ERROR_01800dc8, VK_QUEUE_FAMILY_EXTERNAL_KHR, submit_family, true); 11820 } 11821 11822 TEST_F(VkLayerTest, ImageBarrierWithBadRange) { 11823 TEST_DESCRIPTION("VkImageMemoryBarrier with an invalid subresourceRange"); 11824 11825 ASSERT_NO_FATAL_FAILURE(Init()); 11826 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11827 11828 VkImageObj image(m_device); 11829 image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL); 11830 ASSERT_TRUE(image.create_info().arrayLayers == 1); 11831 ASSERT_TRUE(image.initialized()); 11832 11833 VkImageMemoryBarrier img_barrier_template = {}; 11834 img_barrier_template.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 11835 img_barrier_template.pNext = NULL; 11836 img_barrier_template.srcAccessMask = 0; 11837 img_barrier_template.dstAccessMask = 0; 11838 img_barrier_template.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; 11839 img_barrier_template.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 11840 img_barrier_template.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 11841 img_barrier_template.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 11842 img_barrier_template.image = image.handle(); 11843 // subresourceRange to be set later for the for the purposes of this test 11844 img_barrier_template.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 11845 img_barrier_template.subresourceRange.baseArrayLayer = 0; 11846 img_barrier_template.subresourceRange.baseMipLevel = 0; 11847 img_barrier_template.subresourceRange.layerCount = 0; 11848 img_barrier_template.subresourceRange.levelCount = 0; 11849 11850 m_commandBuffer->begin(); 11851 11852 // Nested scope here confuses clang-format, somehow 11853 // clang-format off 11854 11855 // try for vkCmdPipelineBarrier 11856 { 11857 // Try baseMipLevel >= image.mipLevels with VK_REMAINING_MIP_LEVELS 11858 { 11859 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000b9c); 11860 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, VK_REMAINING_MIP_LEVELS, 0, 1}; 11861 VkImageMemoryBarrier img_barrier = img_barrier_template; 11862 img_barrier.subresourceRange = range; 11863 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 11864 nullptr, 0, nullptr, 1, &img_barrier); 11865 m_errorMonitor->VerifyFound(); 11866 } 11867 11868 // Try baseMipLevel >= image.mipLevels without VK_REMAINING_MIP_LEVELS 11869 { 11870 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000b9c); 11871 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000b9e); 11872 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 0, 1}; 11873 VkImageMemoryBarrier img_barrier = img_barrier_template; 11874 img_barrier.subresourceRange = range; 11875 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 11876 nullptr, 0, nullptr, 1, &img_barrier); 11877 m_errorMonitor->VerifyFound(); 11878 } 11879 11880 // Try levelCount = 0 11881 { 11882 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000b9e); 11883 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 0, 1}; 11884 VkImageMemoryBarrier img_barrier = img_barrier_template; 11885 img_barrier.subresourceRange = range; 11886 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 11887 nullptr, 0, nullptr, 1, &img_barrier); 11888 m_errorMonitor->VerifyFound(); 11889 } 11890 11891 // Try baseMipLevel + levelCount > image.mipLevels 11892 { 11893 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000b9e); 11894 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 2, 0, 1}; 11895 VkImageMemoryBarrier img_barrier = img_barrier_template; 11896 img_barrier.subresourceRange = range; 11897 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 11898 nullptr, 0, nullptr, 1, &img_barrier); 11899 m_errorMonitor->VerifyFound(); 11900 } 11901 11902 // Try baseArrayLayer >= image.arrayLayers with VK_REMAINING_ARRAY_LAYERS 11903 { 11904 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000ba0); 11905 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, VK_REMAINING_ARRAY_LAYERS}; 11906 VkImageMemoryBarrier img_barrier = img_barrier_template; 11907 img_barrier.subresourceRange = range; 11908 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 11909 nullptr, 0, nullptr, 1, &img_barrier); 11910 m_errorMonitor->VerifyFound(); 11911 } 11912 11913 // Try baseArrayLayer >= image.arrayLayers without VK_REMAINING_ARRAY_LAYERS 11914 { 11915 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000ba0); 11916 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000ba2); 11917 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, 1}; 11918 VkImageMemoryBarrier img_barrier = img_barrier_template; 11919 img_barrier.subresourceRange = range; 11920 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 11921 nullptr, 0, nullptr, 1, &img_barrier); 11922 m_errorMonitor->VerifyFound(); 11923 } 11924 11925 // Try layerCount = 0 11926 { 11927 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000ba2); 11928 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 0}; 11929 VkImageMemoryBarrier img_barrier = img_barrier_template; 11930 img_barrier.subresourceRange = range; 11931 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 11932 nullptr, 0, nullptr, 1, &img_barrier); 11933 m_errorMonitor->VerifyFound(); 11934 } 11935 11936 // Try baseArrayLayer + layerCount > image.arrayLayers 11937 { 11938 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000ba2); 11939 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 2}; 11940 VkImageMemoryBarrier img_barrier = img_barrier_template; 11941 img_barrier.subresourceRange = range; 11942 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 11943 nullptr, 0, nullptr, 1, &img_barrier); 11944 m_errorMonitor->VerifyFound(); 11945 } 11946 } 11947 11948 // try for vkCmdWaitEvents 11949 { 11950 VkEvent event; 11951 VkEventCreateInfo eci{VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, NULL, 0}; 11952 VkResult err = vkCreateEvent(m_device->handle(), &eci, nullptr, &event); 11953 ASSERT_VK_SUCCESS(err); 11954 11955 // Try baseMipLevel >= image.mipLevels with VK_REMAINING_MIP_LEVELS 11956 { 11957 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000b9c); 11958 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, VK_REMAINING_MIP_LEVELS, 0, 1}; 11959 VkImageMemoryBarrier img_barrier = img_barrier_template; 11960 img_barrier.subresourceRange = range; 11961 vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 11962 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier); 11963 m_errorMonitor->VerifyFound(); 11964 } 11965 11966 // Try baseMipLevel >= image.mipLevels without VK_REMAINING_MIP_LEVELS 11967 { 11968 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000b9c); 11969 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000b9e); 11970 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 0, 1}; 11971 VkImageMemoryBarrier img_barrier = img_barrier_template; 11972 img_barrier.subresourceRange = range; 11973 vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 11974 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier); 11975 m_errorMonitor->VerifyFound(); 11976 } 11977 11978 // Try levelCount = 0 11979 { 11980 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000b9e); 11981 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 0, 1}; 11982 VkImageMemoryBarrier img_barrier = img_barrier_template; 11983 img_barrier.subresourceRange = range; 11984 vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 11985 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier); 11986 m_errorMonitor->VerifyFound(); 11987 } 11988 11989 // Try baseMipLevel + levelCount > image.mipLevels 11990 { 11991 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000b9e); 11992 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 2, 0, 1}; 11993 VkImageMemoryBarrier img_barrier = img_barrier_template; 11994 img_barrier.subresourceRange = range; 11995 vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 11996 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier); 11997 m_errorMonitor->VerifyFound(); 11998 } 11999 12000 // Try baseArrayLayer >= image.arrayLayers with VK_REMAINING_ARRAY_LAYERS 12001 { 12002 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000ba0); 12003 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, VK_REMAINING_ARRAY_LAYERS}; 12004 VkImageMemoryBarrier img_barrier = img_barrier_template; 12005 img_barrier.subresourceRange = range; 12006 vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 12007 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier); 12008 m_errorMonitor->VerifyFound(); 12009 } 12010 12011 // Try baseArrayLayer >= image.arrayLayers without VK_REMAINING_ARRAY_LAYERS 12012 { 12013 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000ba0); 12014 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000ba2); 12015 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, 1}; 12016 VkImageMemoryBarrier img_barrier = img_barrier_template; 12017 img_barrier.subresourceRange = range; 12018 vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 12019 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier); 12020 m_errorMonitor->VerifyFound(); 12021 } 12022 12023 // Try layerCount = 0 12024 { 12025 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000ba2); 12026 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 0}; 12027 VkImageMemoryBarrier img_barrier = img_barrier_template; 12028 img_barrier.subresourceRange = range; 12029 vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 12030 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier); 12031 m_errorMonitor->VerifyFound(); 12032 } 12033 12034 // Try baseArrayLayer + layerCount > image.arrayLayers 12035 { 12036 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000ba2); 12037 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 2}; 12038 VkImageMemoryBarrier img_barrier = img_barrier_template; 12039 img_barrier.subresourceRange = range; 12040 vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 12041 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier); 12042 m_errorMonitor->VerifyFound(); 12043 } 12044 12045 vkDestroyEvent(m_device->handle(), event, nullptr); 12046 } 12047 // clang-format on 12048 } 12049 12050 TEST_F(VkLayerTest, ValidationCacheTestBadMerge) { 12051 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 12052 if (DeviceExtensionSupported(gpu(), "VK_LAYER_LUNARG_core_validation", VK_EXT_VALIDATION_CACHE_EXTENSION_NAME)) { 12053 m_device_extension_names.push_back(VK_EXT_VALIDATION_CACHE_EXTENSION_NAME); 12054 } else { 12055 printf(" %s not supported, skipping test\n", VK_EXT_VALIDATION_CACHE_EXTENSION_NAME); 12056 return; 12057 } 12058 ASSERT_NO_FATAL_FAILURE(InitState()); 12059 12060 // Load extension functions 12061 auto fpCreateValidationCache = 12062 (PFN_vkCreateValidationCacheEXT)vkGetDeviceProcAddr(m_device->device(), "vkCreateValidationCacheEXT"); 12063 auto fpDestroyValidationCache = 12064 (PFN_vkDestroyValidationCacheEXT)vkGetDeviceProcAddr(m_device->device(), "vkDestroyValidationCacheEXT"); 12065 auto fpMergeValidationCaches = 12066 (PFN_vkMergeValidationCachesEXT)vkGetDeviceProcAddr(m_device->device(), "vkMergeValidationCachesEXT"); 12067 if (!fpCreateValidationCache || !fpDestroyValidationCache || !fpMergeValidationCaches) { 12068 printf(" Failed to load function pointers for %s\n", VK_EXT_VALIDATION_CACHE_EXTENSION_NAME); 12069 return; 12070 } 12071 12072 VkValidationCacheCreateInfoEXT validationCacheCreateInfo; 12073 validationCacheCreateInfo.sType = VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT; 12074 validationCacheCreateInfo.pNext = NULL; 12075 validationCacheCreateInfo.initialDataSize = 0; 12076 validationCacheCreateInfo.pInitialData = NULL; 12077 validationCacheCreateInfo.flags = 0; 12078 VkValidationCacheEXT validationCache = VK_NULL_HANDLE; 12079 VkResult res = fpCreateValidationCache(m_device->device(), &validationCacheCreateInfo, nullptr, &validationCache); 12080 ASSERT_VK_SUCCESS(res); 12081 12082 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_3e600c00); 12083 res = fpMergeValidationCaches(m_device->device(), validationCache, 1, &validationCache); 12084 m_errorMonitor->VerifyFound(); 12085 12086 fpDestroyValidationCache(m_device->device(), validationCache, nullptr); 12087 } 12088 12089 TEST_F(VkPositiveLayerTest, LayoutFromPresentWithoutAccessMemoryRead) { 12090 // Transition an image away from PRESENT_SRC_KHR without ACCESS_MEMORY_READ 12091 // in srcAccessMask. 12092 12093 // The required behavior here was a bit unclear in earlier versions of the 12094 // spec, but there is no memory dependency required here, so this should 12095 // work without warnings. 12096 12097 m_errorMonitor->ExpectSuccess(); 12098 ASSERT_NO_FATAL_FAILURE(Init()); 12099 VkImageObj image(m_device); 12100 image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT), 12101 VK_IMAGE_TILING_OPTIMAL, 0); 12102 ASSERT_TRUE(image.initialized()); 12103 12104 VkImageMemoryBarrier barrier = {}; 12105 VkImageSubresourceRange range; 12106 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 12107 barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 12108 barrier.dstAccessMask = 0; 12109 barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 12110 barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; 12111 barrier.image = image.handle(); 12112 range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 12113 range.baseMipLevel = 0; 12114 range.levelCount = 1; 12115 range.baseArrayLayer = 0; 12116 range.layerCount = 1; 12117 barrier.subresourceRange = range; 12118 VkCommandBufferObj cmdbuf(m_device, m_commandPool); 12119 cmdbuf.begin(); 12120 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, 12121 &barrier); 12122 barrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; 12123 barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 12124 barrier.srcAccessMask = 0; 12125 barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 12126 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, 12127 &barrier); 12128 12129 m_errorMonitor->VerifyNotFound(); 12130 } 12131 12132 TEST_F(VkLayerTest, IdxBufferAlignmentError) { 12133 // Bind a BeginRenderPass within an active RenderPass 12134 ASSERT_NO_FATAL_FAILURE(Init()); 12135 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12136 12137 uint32_t const indices[] = {0}; 12138 VkBufferCreateInfo buf_info = {}; 12139 buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 12140 buf_info.size = 1024; 12141 buf_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT; 12142 buf_info.queueFamilyIndexCount = 1; 12143 buf_info.pQueueFamilyIndices = indices; 12144 12145 VkBuffer buffer; 12146 VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer); 12147 ASSERT_VK_SUCCESS(err); 12148 12149 VkMemoryRequirements requirements; 12150 vkGetBufferMemoryRequirements(m_device->device(), buffer, &requirements); 12151 12152 VkMemoryAllocateInfo alloc_info{}; 12153 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 12154 alloc_info.pNext = NULL; 12155 alloc_info.memoryTypeIndex = 0; 12156 alloc_info.allocationSize = requirements.size; 12157 bool pass = m_device->phy().set_memory_type(requirements.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); 12158 ASSERT_TRUE(pass); 12159 12160 VkDeviceMemory memory; 12161 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &memory); 12162 ASSERT_VK_SUCCESS(err); 12163 12164 err = vkBindBufferMemory(m_device->device(), buffer, memory, 0); 12165 ASSERT_VK_SUCCESS(err); 12166 12167 m_commandBuffer->begin(); 12168 ASSERT_VK_SUCCESS(err); 12169 12170 // vkCmdBindPipeline(m_commandBuffer->handle(), 12171 // VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 12172 // Should error before calling to driver so don't care about actual data 12173 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdBindIndexBuffer() offset (0x7) does not fall on "); 12174 vkCmdBindIndexBuffer(m_commandBuffer->handle(), buffer, 7, VK_INDEX_TYPE_UINT16); 12175 m_errorMonitor->VerifyFound(); 12176 12177 vkFreeMemory(m_device->device(), memory, NULL); 12178 vkDestroyBuffer(m_device->device(), buffer, NULL); 12179 } 12180 12181 TEST_F(VkLayerTest, InvalidQueueFamilyIndex) { 12182 // Create an out-of-range queueFamilyIndex 12183 ASSERT_NO_FATAL_FAILURE(Init()); 12184 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12185 VkBufferCreateInfo buffCI = {}; 12186 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 12187 buffCI.size = 1024; 12188 buffCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT; 12189 buffCI.queueFamilyIndexCount = 2; 12190 // Introduce failure by specifying invalid queue_family_index 12191 uint32_t qfi[2]; 12192 qfi[0] = 777; 12193 qfi[1] = 0; 12194 12195 buffCI.pQueueFamilyIndices = qfi; 12196 buffCI.sharingMode = VK_SHARING_MODE_CONCURRENT; // qfi only matters in CONCURRENT mode 12197 12198 VkBuffer ib; 12199 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 12200 "vkCreateBuffer: pCreateInfo->pQueueFamilyIndices[0] (= 777) is not one of the queue " 12201 "families given via VkDeviceQueueCreateInfo structures when the device was created."); 12202 vkCreateBuffer(m_device->device(), &buffCI, NULL, &ib); 12203 m_errorMonitor->VerifyFound(); 12204 12205 if (m_device->queue_props.size() > 2) { 12206 VkBuffer ib2; 12207 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "which was not created allowing concurrent"); 12208 12209 // Create buffer shared to queue families 1 and 2, but submitted on queue family 0 12210 buffCI.queueFamilyIndexCount = 2; 12211 qfi[0] = 1; 12212 qfi[1] = 2; 12213 vkCreateBuffer(m_device->device(), &buffCI, NULL, &ib2); 12214 VkDeviceMemory mem; 12215 VkMemoryRequirements mem_reqs; 12216 vkGetBufferMemoryRequirements(m_device->device(), ib2, &mem_reqs); 12217 12218 VkMemoryAllocateInfo alloc_info = {}; 12219 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 12220 alloc_info.allocationSize = 1024; 12221 bool pass = false; 12222 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); 12223 if (!pass) { 12224 vkDestroyBuffer(m_device->device(), ib2, NULL); 12225 return; 12226 } 12227 vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem); 12228 vkBindBufferMemory(m_device->device(), ib2, mem, 0); 12229 12230 m_commandBuffer->begin(); 12231 vkCmdFillBuffer(m_commandBuffer->handle(), ib2, 0, 16, 5); 12232 m_commandBuffer->end(); 12233 m_commandBuffer->QueueCommandBuffer(false); 12234 m_errorMonitor->VerifyFound(); 12235 vkDestroyBuffer(m_device->device(), ib2, NULL); 12236 vkFreeMemory(m_device->device(), mem, NULL); 12237 } 12238 } 12239 12240 TEST_F(VkLayerTest, ExecuteCommandsPrimaryCB) { 12241 TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a primary command buffer (should only be secondary)"); 12242 12243 ASSERT_NO_FATAL_FAILURE(Init()); 12244 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12245 12246 // An empty primary command buffer 12247 VkCommandBufferObj cb(m_device, m_commandPool); 12248 cb.begin(); 12249 cb.end(); 12250 12251 m_commandBuffer->begin(); 12252 vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); 12253 VkCommandBuffer handle = cb.handle(); 12254 12255 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdExecuteCommands() called w/ Primary Cmd Buffer "); 12256 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &handle); 12257 m_errorMonitor->VerifyFound(); 12258 12259 m_errorMonitor->SetUnexpectedError("All elements of pCommandBuffers must not be in the pending state"); 12260 } 12261 12262 TEST_F(VkLayerTest, DSUsageBitsErrors) { 12263 TEST_DESCRIPTION("Attempt to update descriptor sets for images and buffers that do not have correct usage bits sets."); 12264 12265 ASSERT_NO_FATAL_FAILURE(Init()); 12266 std::array<VkDescriptorPoolSize, VK_DESCRIPTOR_TYPE_RANGE_SIZE> ds_type_count; 12267 for (uint32_t i = 0; i < ds_type_count.size(); ++i) { 12268 ds_type_count[i].type = VkDescriptorType(i); 12269 ds_type_count[i].descriptorCount = 1; 12270 } 12271 12272 vk_testing::DescriptorPool ds_pool; 12273 ds_pool.init(*m_device, vk_testing::DescriptorPool::create_info(0, VK_DESCRIPTOR_TYPE_RANGE_SIZE, ds_type_count)); 12274 ASSERT_TRUE(ds_pool.initialized()); 12275 12276 std::vector<VkDescriptorSetLayoutBinding> dsl_bindings(1); 12277 dsl_bindings[0].binding = 0; 12278 dsl_bindings[0].descriptorType = VkDescriptorType(0); 12279 dsl_bindings[0].descriptorCount = 1; 12280 dsl_bindings[0].stageFlags = VK_SHADER_STAGE_ALL; 12281 dsl_bindings[0].pImmutableSamplers = NULL; 12282 12283 // Create arrays of layout and descriptor objects 12284 using UpDescriptorSet = std::unique_ptr<vk_testing::DescriptorSet>; 12285 std::vector<UpDescriptorSet> descriptor_sets; 12286 using UpDescriptorSetLayout = std::unique_ptr<VkDescriptorSetLayoutObj>; 12287 std::vector<UpDescriptorSetLayout> ds_layouts; 12288 descriptor_sets.reserve(VK_DESCRIPTOR_TYPE_RANGE_SIZE); 12289 ds_layouts.reserve(VK_DESCRIPTOR_TYPE_RANGE_SIZE); 12290 for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) { 12291 dsl_bindings[0].descriptorType = VkDescriptorType(i); 12292 ds_layouts.push_back(UpDescriptorSetLayout(new VkDescriptorSetLayoutObj(m_device, dsl_bindings))); 12293 descriptor_sets.push_back(UpDescriptorSet(ds_pool.alloc_sets(*m_device, *ds_layouts.back()))); 12294 ASSERT_TRUE(descriptor_sets.back()->initialized()); 12295 } 12296 12297 // Create a buffer & bufferView to be used for invalid updates 12298 const VkDeviceSize buffer_size = 256; 12299 uint8_t data[buffer_size]; 12300 VkConstantBufferObj buffer(m_device, buffer_size, data, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT); 12301 VkConstantBufferObj storage_texel_buffer(m_device, buffer_size, data, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT); 12302 ASSERT_TRUE(buffer.initialized() && storage_texel_buffer.initialized()); 12303 12304 auto buff_view_ci = vk_testing::BufferView::createInfo(buffer.handle(), VK_FORMAT_R8_UNORM); 12305 vk_testing::BufferView buffer_view_obj, storage_texel_buffer_view_obj; 12306 buffer_view_obj.init(*m_device, buff_view_ci); 12307 buff_view_ci.buffer = storage_texel_buffer.handle(); 12308 storage_texel_buffer_view_obj.init(*m_device, buff_view_ci); 12309 ASSERT_TRUE(buffer_view_obj.initialized() && storage_texel_buffer_view_obj.initialized()); 12310 VkBufferView buffer_view = buffer_view_obj.handle(); 12311 VkBufferView storage_texel_buffer_view = storage_texel_buffer_view_obj.handle(); 12312 12313 // Create an image to be used for invalid updates 12314 VkImageObj image_obj(m_device); 12315 image_obj.InitNoLayout(64, 64, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 12316 ASSERT_TRUE(image_obj.initialized()); 12317 VkImageView image_view = image_obj.targetView(VK_FORMAT_R8G8B8A8_UNORM); 12318 12319 VkDescriptorBufferInfo buff_info = {}; 12320 buff_info.buffer = buffer.handle(); 12321 VkDescriptorImageInfo img_info = {}; 12322 img_info.imageView = image_view; 12323 VkWriteDescriptorSet descriptor_write = {}; 12324 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 12325 descriptor_write.dstBinding = 0; 12326 descriptor_write.descriptorCount = 1; 12327 descriptor_write.pTexelBufferView = &buffer_view; 12328 descriptor_write.pBufferInfo = &buff_info; 12329 descriptor_write.pImageInfo = &img_info; 12330 12331 // These error messages align with VkDescriptorType struct 12332 UNIQUE_VALIDATION_ERROR_CODE error_codes[] = { 12333 VALIDATION_ERROR_15c0028c, // placeholder, no error for SAMPLER descriptor 12334 VALIDATION_ERROR_15c0028c, // COMBINED_IMAGE_SAMPLER 12335 VALIDATION_ERROR_15c0028c, // SAMPLED_IMAGE 12336 VALIDATION_ERROR_15c0028c, // STORAGE_IMAGE 12337 VALIDATION_ERROR_15c0029c, // UNIFORM_TEXEL_BUFFER 12338 VALIDATION_ERROR_15c0029e, // STORAGE_TEXEL_BUFFER 12339 VALIDATION_ERROR_15c00292, // UNIFORM_BUFFER 12340 VALIDATION_ERROR_15c00296, // STORAGE_BUFFER 12341 VALIDATION_ERROR_15c00292, // UNIFORM_BUFFER_DYNAMIC 12342 VALIDATION_ERROR_15c00296, // STORAGE_BUFFER_DYNAMIC 12343 VALIDATION_ERROR_15c0028c // INPUT_ATTACHMENT 12344 }; 12345 // Start loop at 1 as SAMPLER desc type has no usage bit error 12346 for (uint32_t i = 1; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) { 12347 if (VkDescriptorType(i) == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) { 12348 // Now check for UNIFORM_TEXEL_BUFFER using storage_texel_buffer_view 12349 descriptor_write.pTexelBufferView = &storage_texel_buffer_view; 12350 } 12351 descriptor_write.descriptorType = VkDescriptorType(i); 12352 descriptor_write.dstSet = descriptor_sets[i]->handle(); 12353 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error_codes[i]); 12354 12355 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 12356 12357 m_errorMonitor->VerifyFound(); 12358 if (VkDescriptorType(i) == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) { 12359 descriptor_write.pTexelBufferView = &buffer_view; 12360 } 12361 } 12362 } 12363 12364 TEST_F(VkLayerTest, DSBufferInfoErrors) { 12365 TEST_DESCRIPTION( 12366 "Attempt to update buffer descriptor set that has incorrect parameters in VkDescriptorBufferInfo struct. This includes:\n" 12367 "1. offset value greater than or equal to buffer size\n" 12368 "2. range value of 0\n" 12369 "3. range value greater than buffer (size - offset)"); 12370 VkResult err; 12371 12372 ASSERT_NO_FATAL_FAILURE(Init()); 12373 OneOffDescriptorSet ds(m_device, { 12374 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, 12375 }); 12376 12377 // Create a buffer to be used for invalid updates 12378 VkBufferCreateInfo buff_ci = {}; 12379 buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 12380 buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 12381 buff_ci.size = m_device->props.limits.minUniformBufferOffsetAlignment; 12382 buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 12383 VkBuffer buffer; 12384 err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer); 12385 ASSERT_VK_SUCCESS(err); 12386 12387 // Have to bind memory to buffer before descriptor update 12388 VkMemoryRequirements mem_reqs; 12389 vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs); 12390 VkMemoryAllocateInfo mem_alloc = {}; 12391 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 12392 mem_alloc.pNext = NULL; 12393 mem_alloc.allocationSize = mem_reqs.size; 12394 mem_alloc.memoryTypeIndex = 0; 12395 bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0); 12396 if (!pass) { 12397 vkDestroyBuffer(m_device->device(), buffer, NULL); 12398 return; 12399 } 12400 12401 VkDeviceMemory mem; 12402 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem); 12403 ASSERT_VK_SUCCESS(err); 12404 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0); 12405 ASSERT_VK_SUCCESS(err); 12406 12407 VkDescriptorBufferInfo buff_info = {}; 12408 buff_info.buffer = buffer; 12409 // Cause error due to offset out of range 12410 buff_info.offset = buff_ci.size; 12411 buff_info.range = VK_WHOLE_SIZE; 12412 VkWriteDescriptorSet descriptor_write = {}; 12413 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 12414 descriptor_write.dstBinding = 0; 12415 descriptor_write.descriptorCount = 1; 12416 descriptor_write.pTexelBufferView = nullptr; 12417 descriptor_write.pBufferInfo = &buff_info; 12418 descriptor_write.pImageInfo = nullptr; 12419 12420 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 12421 descriptor_write.dstSet = ds.set_; 12422 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_044002a8); 12423 12424 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 12425 12426 m_errorMonitor->VerifyFound(); 12427 // Now cause error due to range of 0 12428 buff_info.offset = 0; 12429 buff_info.range = 0; 12430 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_044002aa); 12431 12432 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 12433 12434 m_errorMonitor->VerifyFound(); 12435 // Now cause error due to range exceeding buffer size - offset 12436 buff_info.offset = 0; 12437 buff_info.range = buff_ci.size + 1; 12438 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_044002ac); 12439 12440 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 12441 12442 m_errorMonitor->VerifyFound(); 12443 vkFreeMemory(m_device->device(), mem, NULL); 12444 vkDestroyBuffer(m_device->device(), buffer, NULL); 12445 } 12446 12447 TEST_F(VkLayerTest, DSBufferLimitErrors) { 12448 TEST_DESCRIPTION( 12449 "Attempt to update buffer descriptor set that has VkDescriptorBufferInfo values that violate device limits.\n" 12450 "Test cases include:\n" 12451 "1. range of uniform buffer update exceeds maxUniformBufferRange\n" 12452 "2. offset of uniform buffer update is not multiple of minUniformBufferOffsetAlignment\n" 12453 "3. range of storage buffer update exceeds maxStorageBufferRange\n" 12454 "4. offset of storage buffer update is not multiple of minStorageBufferOffsetAlignment"); 12455 VkResult err; 12456 12457 ASSERT_NO_FATAL_FAILURE(Init()); 12458 12459 struct TestCase { 12460 VkDescriptorType descriptor_type; 12461 VkBufferUsageFlagBits buffer_usage; 12462 VkDeviceSize max_range; 12463 UNIQUE_VALIDATION_ERROR_CODE max_range_vu; 12464 VkDeviceSize min_align; 12465 UNIQUE_VALIDATION_ERROR_CODE min_align_vu; 12466 }; 12467 12468 for (const auto &test_case : { 12469 TestCase({VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, 12470 m_device->props.limits.maxUniformBufferRange, VALIDATION_ERROR_15c00298, 12471 m_device->props.limits.minUniformBufferOffsetAlignment, VALIDATION_ERROR_15c0028e}), 12472 TestCase({VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 12473 m_device->props.limits.maxStorageBufferRange, VALIDATION_ERROR_15c0029a, 12474 m_device->props.limits.minStorageBufferOffsetAlignment, VALIDATION_ERROR_15c00290}), 12475 }) { 12476 // Create layout with single buffer 12477 OneOffDescriptorSet ds(m_device, { 12478 {0, test_case.descriptor_type, 1, VK_SHADER_STAGE_ALL, nullptr}, 12479 }); 12480 12481 // Create a buffer to be used for invalid updates 12482 VkBufferCreateInfo bci = {}; 12483 bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 12484 bci.usage = test_case.buffer_usage; 12485 bci.size = test_case.max_range + test_case.min_align; // Make buffer bigger than range limit 12486 bci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 12487 VkBuffer buffer; 12488 err = vkCreateBuffer(m_device->device(), &bci, NULL, &buffer); 12489 ASSERT_VK_SUCCESS(err); 12490 12491 // Have to bind memory to buffer before descriptor update 12492 VkMemoryRequirements mem_reqs; 12493 vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs); 12494 12495 VkMemoryAllocateInfo mem_alloc = {}; 12496 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 12497 mem_alloc.pNext = NULL; 12498 mem_alloc.allocationSize = mem_reqs.size; 12499 bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0); 12500 if (!pass) { 12501 printf(" Failed to allocate memory in DSBufferLimitErrors; skipped.\n"); 12502 vkDestroyBuffer(m_device->device(), buffer, NULL); 12503 continue; 12504 } 12505 12506 VkDeviceMemory mem; 12507 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem); 12508 if (VK_SUCCESS != err) { 12509 printf(" Failed to allocate memory in DSBufferLimitErrors; skipped.\n"); 12510 vkDestroyBuffer(m_device->device(), buffer, NULL); 12511 continue; 12512 } 12513 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0); 12514 ASSERT_VK_SUCCESS(err); 12515 12516 VkDescriptorBufferInfo buff_info = {}; 12517 buff_info.buffer = buffer; 12518 VkWriteDescriptorSet descriptor_write = {}; 12519 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 12520 descriptor_write.dstBinding = 0; 12521 descriptor_write.descriptorCount = 1; 12522 descriptor_write.pTexelBufferView = nullptr; 12523 descriptor_write.pBufferInfo = &buff_info; 12524 descriptor_write.pImageInfo = nullptr; 12525 descriptor_write.descriptorType = test_case.descriptor_type; 12526 descriptor_write.dstSet = ds.set_; 12527 12528 // Exceed range limit 12529 if (test_case.max_range != UINT32_MAX) { 12530 buff_info.range = test_case.max_range + 1; 12531 buff_info.offset = 0; 12532 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.max_range_vu); 12533 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 12534 m_errorMonitor->VerifyFound(); 12535 } 12536 12537 // Reduce size of range to acceptable limit and cause offset error 12538 if (test_case.min_align > 1) { 12539 buff_info.range = test_case.max_range; 12540 buff_info.offset = test_case.min_align - 1; 12541 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.min_align_vu); 12542 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 12543 m_errorMonitor->VerifyFound(); 12544 } 12545 12546 // Cleanup 12547 vkFreeMemory(m_device->device(), mem, NULL); 12548 vkDestroyBuffer(m_device->device(), buffer, NULL); 12549 } 12550 } 12551 12552 TEST_F(VkLayerTest, DSAspectBitsErrors) { 12553 // TODO : Initially only catching case where DEPTH & STENCIL aspect bits 12554 // are set, but could expand this test to hit more cases. 12555 TEST_DESCRIPTION("Attempt to update descriptor sets for images that do not have correct aspect bits sets."); 12556 VkResult err; 12557 12558 ASSERT_NO_FATAL_FAILURE(Init()); 12559 auto depth_format = FindSupportedDepthStencilFormat(gpu()); 12560 if (!depth_format) { 12561 printf(" No Depth + Stencil format found. Skipped.\n"); 12562 return; 12563 } 12564 12565 OneOffDescriptorSet ds(m_device, { 12566 {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_ALL, nullptr}, 12567 }); 12568 12569 // Create an image to be used for invalid updates 12570 VkImageCreateInfo image_ci = {}; 12571 image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 12572 image_ci.imageType = VK_IMAGE_TYPE_2D; 12573 image_ci.format = depth_format; 12574 image_ci.extent.width = 64; 12575 image_ci.extent.height = 64; 12576 image_ci.extent.depth = 1; 12577 image_ci.mipLevels = 1; 12578 image_ci.arrayLayers = 1; 12579 image_ci.samples = VK_SAMPLE_COUNT_1_BIT; 12580 image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; 12581 image_ci.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; 12582 image_ci.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 12583 image_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 12584 VkImage image; 12585 err = vkCreateImage(m_device->device(), &image_ci, NULL, &image); 12586 ASSERT_VK_SUCCESS(err); 12587 // Bind memory to image 12588 VkMemoryRequirements mem_reqs; 12589 VkDeviceMemory image_mem; 12590 bool pass; 12591 VkMemoryAllocateInfo mem_alloc = {}; 12592 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 12593 mem_alloc.pNext = NULL; 12594 mem_alloc.allocationSize = 0; 12595 mem_alloc.memoryTypeIndex = 0; 12596 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs); 12597 mem_alloc.allocationSize = mem_reqs.size; 12598 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0); 12599 ASSERT_TRUE(pass); 12600 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem); 12601 ASSERT_VK_SUCCESS(err); 12602 err = vkBindImageMemory(m_device->device(), image, image_mem, 0); 12603 ASSERT_VK_SUCCESS(err); 12604 // Now create view for image 12605 VkImageViewCreateInfo image_view_ci = {}; 12606 image_view_ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 12607 image_view_ci.image = image; 12608 image_view_ci.format = depth_format; 12609 image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D; 12610 image_view_ci.subresourceRange.layerCount = 1; 12611 image_view_ci.subresourceRange.baseArrayLayer = 0; 12612 image_view_ci.subresourceRange.levelCount = 1; 12613 // Setting both depth & stencil aspect bits is illegal for descriptor 12614 image_view_ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 12615 12616 VkImageView image_view; 12617 err = vkCreateImageView(m_device->device(), &image_view_ci, NULL, &image_view); 12618 ASSERT_VK_SUCCESS(err); 12619 12620 VkDescriptorImageInfo img_info = {}; 12621 img_info.imageView = image_view; 12622 VkWriteDescriptorSet descriptor_write = {}; 12623 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 12624 descriptor_write.dstBinding = 0; 12625 descriptor_write.descriptorCount = 1; 12626 descriptor_write.pTexelBufferView = NULL; 12627 descriptor_write.pBufferInfo = NULL; 12628 descriptor_write.pImageInfo = &img_info; 12629 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; 12630 descriptor_write.dstSet = ds.set_; 12631 const char *error_msg = " please only set either VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT "; 12632 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error_msg); 12633 12634 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 12635 12636 m_errorMonitor->VerifyFound(); 12637 vkDestroyImage(m_device->device(), image, NULL); 12638 vkFreeMemory(m_device->device(), image_mem, NULL); 12639 vkDestroyImageView(m_device->device(), image_view, NULL); 12640 } 12641 12642 TEST_F(VkLayerTest, DSTypeMismatch) { 12643 // Create DS w/ layout of one type and attempt Update w/ mis-matched type 12644 VkResult err; 12645 12646 m_errorMonitor->SetDesiredFailureMsg( 12647 VK_DEBUG_REPORT_ERROR_BIT_EXT, 12648 " binding #0 with type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER but update type is VK_DESCRIPTOR_TYPE_SAMPLER"); 12649 12650 ASSERT_NO_FATAL_FAILURE(Init()); 12651 OneOffDescriptorSet ds(m_device, { 12652 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, 12653 }); 12654 12655 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo(); 12656 VkSampler sampler; 12657 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 12658 ASSERT_VK_SUCCESS(err); 12659 12660 VkDescriptorImageInfo info = {}; 12661 info.sampler = sampler; 12662 12663 VkWriteDescriptorSet descriptor_write; 12664 memset(&descriptor_write, 0, sizeof(descriptor_write)); 12665 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 12666 descriptor_write.dstSet = ds.set_; 12667 descriptor_write.descriptorCount = 1; 12668 // This is a mismatched type for the layout which expects BUFFER 12669 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 12670 descriptor_write.pImageInfo = &info; 12671 12672 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 12673 12674 m_errorMonitor->VerifyFound(); 12675 12676 vkDestroySampler(m_device->device(), sampler, NULL); 12677 } 12678 12679 TEST_F(VkLayerTest, DSUpdateOutOfBounds) { 12680 // For overlapping Update, have arrayIndex exceed that of layout 12681 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15c00282); 12682 12683 ASSERT_NO_FATAL_FAILURE(Init()); 12684 OneOffDescriptorSet ds(m_device, { 12685 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, 12686 }); 12687 12688 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); 12689 if (!buffer_test.GetBufferCurrent()) { 12690 // Something prevented creation of buffer so abort 12691 printf(" Buffer creation failed, skipping test\n"); 12692 return; 12693 } 12694 12695 // Correctly update descriptor to avoid "NOT_UPDATED" error 12696 VkDescriptorBufferInfo buff_info = {}; 12697 buff_info.buffer = buffer_test.GetBuffer(); 12698 buff_info.offset = 0; 12699 buff_info.range = 1024; 12700 12701 VkWriteDescriptorSet descriptor_write; 12702 memset(&descriptor_write, 0, sizeof(descriptor_write)); 12703 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 12704 descriptor_write.dstSet = ds.set_; 12705 descriptor_write.dstArrayElement = 1; /* This index out of bounds for the update */ 12706 descriptor_write.descriptorCount = 1; 12707 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 12708 descriptor_write.pBufferInfo = &buff_info; 12709 12710 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 12711 12712 m_errorMonitor->VerifyFound(); 12713 } 12714 12715 TEST_F(VkLayerTest, InvalidDSUpdateIndex) { 12716 // Create layout w/ count of 1 and attempt update to that layout w/ binding index 2 12717 VkResult err; 12718 12719 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15c00276); 12720 12721 ASSERT_NO_FATAL_FAILURE(Init()); 12722 OneOffDescriptorSet ds(m_device, { 12723 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, 12724 }); 12725 12726 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo(); 12727 VkSampler sampler; 12728 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 12729 ASSERT_VK_SUCCESS(err); 12730 12731 VkDescriptorImageInfo info = {}; 12732 info.sampler = sampler; 12733 12734 VkWriteDescriptorSet descriptor_write; 12735 memset(&descriptor_write, 0, sizeof(descriptor_write)); 12736 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 12737 descriptor_write.dstSet = ds.set_; 12738 descriptor_write.dstBinding = 2; 12739 descriptor_write.descriptorCount = 1; 12740 // This is the wrong type, but out of bounds will be flagged first 12741 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 12742 descriptor_write.pImageInfo = &info; 12743 12744 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 12745 12746 m_errorMonitor->VerifyFound(); 12747 12748 vkDestroySampler(m_device->device(), sampler, NULL); 12749 } 12750 12751 TEST_F(VkLayerTest, DSUpdateEmptyBinding) { 12752 // Create layout w/ empty binding and attempt to update it 12753 VkResult err; 12754 12755 ASSERT_NO_FATAL_FAILURE(Init()); 12756 12757 OneOffDescriptorSet ds(m_device, { 12758 {0, VK_DESCRIPTOR_TYPE_SAMPLER, 0 /* !! */, VK_SHADER_STAGE_ALL, nullptr}, 12759 }); 12760 12761 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo(); 12762 VkSampler sampler; 12763 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 12764 ASSERT_VK_SUCCESS(err); 12765 12766 VkDescriptorImageInfo info = {}; 12767 info.sampler = sampler; 12768 12769 VkWriteDescriptorSet descriptor_write; 12770 memset(&descriptor_write, 0, sizeof(descriptor_write)); 12771 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 12772 descriptor_write.dstSet = ds.set_; 12773 descriptor_write.dstBinding = 0; 12774 descriptor_write.descriptorCount = 1; // Lie here to avoid parameter_validation error 12775 // This is the wrong type, but empty binding error will be flagged first 12776 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 12777 descriptor_write.pImageInfo = &info; 12778 12779 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15c00278); 12780 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 12781 m_errorMonitor->VerifyFound(); 12782 12783 vkDestroySampler(m_device->device(), sampler, NULL); 12784 } 12785 12786 TEST_F(VkLayerTest, InvalidDSUpdateStruct) { 12787 // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_* 12788 // types 12789 VkResult err; 12790 12791 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, ".sType must be VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET"); 12792 12793 ASSERT_NO_FATAL_FAILURE(Init()); 12794 12795 OneOffDescriptorSet ds(m_device, { 12796 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, 12797 }); 12798 12799 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo(); 12800 VkSampler sampler; 12801 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 12802 ASSERT_VK_SUCCESS(err); 12803 12804 VkDescriptorImageInfo info = {}; 12805 info.sampler = sampler; 12806 12807 VkWriteDescriptorSet descriptor_write; 12808 memset(&descriptor_write, 0, sizeof(descriptor_write)); 12809 descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */ 12810 descriptor_write.dstSet = ds.set_; 12811 descriptor_write.descriptorCount = 1; 12812 // This is the wrong type, but out of bounds will be flagged first 12813 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 12814 descriptor_write.pImageInfo = &info; 12815 12816 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 12817 12818 m_errorMonitor->VerifyFound(); 12819 12820 vkDestroySampler(m_device->device(), sampler, NULL); 12821 } 12822 12823 TEST_F(VkLayerTest, SampleDescriptorUpdateError) { 12824 // Create a single Sampler descriptor and send it an invalid Sampler 12825 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15c0028a); 12826 12827 ASSERT_NO_FATAL_FAILURE(Init()); 12828 OneOffDescriptorSet ds(m_device, { 12829 {0, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr}, 12830 }); 12831 12832 VkSampler sampler = (VkSampler)((size_t)0xbaadbeef); // Sampler with invalid handle 12833 12834 VkDescriptorImageInfo descriptor_info; 12835 memset(&descriptor_info, 0, sizeof(VkDescriptorImageInfo)); 12836 descriptor_info.sampler = sampler; 12837 12838 VkWriteDescriptorSet descriptor_write; 12839 memset(&descriptor_write, 0, sizeof(descriptor_write)); 12840 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 12841 descriptor_write.dstSet = ds.set_; 12842 descriptor_write.dstBinding = 0; 12843 descriptor_write.descriptorCount = 1; 12844 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 12845 descriptor_write.pImageInfo = &descriptor_info; 12846 12847 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 12848 12849 m_errorMonitor->VerifyFound(); 12850 } 12851 12852 TEST_F(VkLayerTest, ImageViewDescriptorUpdateError) { 12853 // Create a single combined Image/Sampler descriptor and send it an invalid 12854 // imageView 12855 VkResult err; 12856 12857 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15c0028c); 12858 12859 ASSERT_NO_FATAL_FAILURE(Init()); 12860 OneOffDescriptorSet ds(m_device, { 12861 {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr}, 12862 }); 12863 12864 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo(); 12865 VkSampler sampler; 12866 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 12867 ASSERT_VK_SUCCESS(err); 12868 12869 VkImageView view = (VkImageView)((size_t)0xbaadbeef); // invalid imageView object 12870 12871 VkDescriptorImageInfo descriptor_info; 12872 memset(&descriptor_info, 0, sizeof(VkDescriptorImageInfo)); 12873 descriptor_info.sampler = sampler; 12874 descriptor_info.imageView = view; 12875 12876 VkWriteDescriptorSet descriptor_write; 12877 memset(&descriptor_write, 0, sizeof(descriptor_write)); 12878 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 12879 descriptor_write.dstSet = ds.set_; 12880 descriptor_write.dstBinding = 0; 12881 descriptor_write.descriptorCount = 1; 12882 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 12883 descriptor_write.pImageInfo = &descriptor_info; 12884 12885 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 12886 12887 m_errorMonitor->VerifyFound(); 12888 12889 vkDestroySampler(m_device->device(), sampler, NULL); 12890 } 12891 12892 TEST_F(VkLayerTest, CopyDescriptorUpdateErrors) { 12893 // Create DS w/ layout of 2 types, write update 1 and attempt to copy-update 12894 // into the other 12895 VkResult err; 12896 12897 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 12898 " binding #1 with type VK_DESCRIPTOR_TYPE_SAMPLER. Types do not match."); 12899 12900 ASSERT_NO_FATAL_FAILURE(Init()); 12901 OneOffDescriptorSet ds(m_device, { 12902 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, 12903 {1, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr}, 12904 }); 12905 12906 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo(); 12907 VkSampler sampler; 12908 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 12909 ASSERT_VK_SUCCESS(err); 12910 12911 VkDescriptorImageInfo info = {}; 12912 info.sampler = sampler; 12913 12914 VkWriteDescriptorSet descriptor_write; 12915 memset(&descriptor_write, 0, sizeof(VkWriteDescriptorSet)); 12916 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 12917 descriptor_write.dstSet = ds.set_; 12918 descriptor_write.dstBinding = 1; // SAMPLER binding from layout above 12919 descriptor_write.descriptorCount = 1; 12920 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 12921 descriptor_write.pImageInfo = &info; 12922 // This write update should succeed 12923 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 12924 // Now perform a copy update that fails due to type mismatch 12925 VkCopyDescriptorSet copy_ds_update; 12926 memset(©_ds_update, 0, sizeof(VkCopyDescriptorSet)); 12927 copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET; 12928 copy_ds_update.srcSet = ds.set_; 12929 copy_ds_update.srcBinding = 1; // Copy from SAMPLER binding 12930 copy_ds_update.dstSet = ds.set_; 12931 copy_ds_update.dstBinding = 0; // ERROR : copy to UNIFORM binding 12932 copy_ds_update.descriptorCount = 1; // copy 1 descriptor 12933 vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, ©_ds_update); 12934 12935 m_errorMonitor->VerifyFound(); 12936 // Now perform a copy update that fails due to binding out of bounds 12937 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " does not have copy update src binding of 3."); 12938 memset(©_ds_update, 0, sizeof(VkCopyDescriptorSet)); 12939 copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET; 12940 copy_ds_update.srcSet = ds.set_; 12941 copy_ds_update.srcBinding = 3; // ERROR : Invalid binding for matching layout 12942 copy_ds_update.dstSet = ds.set_; 12943 copy_ds_update.dstBinding = 0; 12944 copy_ds_update.descriptorCount = 1; // Copy 1 descriptor 12945 vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, ©_ds_update); 12946 12947 m_errorMonitor->VerifyFound(); 12948 12949 // Now perform a copy update that fails due to binding out of bounds 12950 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 12951 " binding#1 with offset index of 1 plus update array offset of 0 and update of 5 " 12952 "descriptors oversteps total number of descriptors in set: 2."); 12953 12954 memset(©_ds_update, 0, sizeof(VkCopyDescriptorSet)); 12955 copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET; 12956 copy_ds_update.srcSet = ds.set_; 12957 copy_ds_update.srcBinding = 1; 12958 copy_ds_update.dstSet = ds.set_; 12959 copy_ds_update.dstBinding = 0; 12960 copy_ds_update.descriptorCount = 5; // ERROR copy 5 descriptors (out of bounds for layout) 12961 vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, ©_ds_update); 12962 12963 m_errorMonitor->VerifyFound(); 12964 12965 vkDestroySampler(m_device->device(), sampler, NULL); 12966 } 12967 12968 TEST_F(VkPositiveLayerTest, CopyNonupdatedDescriptors) { 12969 TEST_DESCRIPTION("Copy nonupdated descriptors"); 12970 unsigned int i; 12971 12972 ASSERT_NO_FATAL_FAILURE(Init()); 12973 OneOffDescriptorSet src_ds(m_device, { 12974 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, 12975 {1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr}, 12976 {2, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr}, 12977 }); 12978 OneOffDescriptorSet dst_ds(m_device, { 12979 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, 12980 {1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr}, 12981 }); 12982 12983 m_errorMonitor->ExpectSuccess(); 12984 12985 const unsigned int copy_size = 2; 12986 VkCopyDescriptorSet copy_ds_update[copy_size]; 12987 memset(copy_ds_update, 0, sizeof(copy_ds_update)); 12988 for (i = 0; i < copy_size; i++) { 12989 copy_ds_update[i].sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET; 12990 copy_ds_update[i].srcSet = src_ds.set_; 12991 copy_ds_update[i].srcBinding = i; 12992 copy_ds_update[i].dstSet = dst_ds.set_; 12993 copy_ds_update[i].dstBinding = i; 12994 copy_ds_update[i].descriptorCount = 1; 12995 } 12996 vkUpdateDescriptorSets(m_device->device(), 0, NULL, copy_size, copy_ds_update); 12997 12998 m_errorMonitor->VerifyNotFound(); 12999 } 13000 13001 TEST_F(VkLayerTest, NumSamplesMismatch) { 13002 // Create CommandBuffer where MSAA samples doesn't match RenderPass 13003 // sampleCount 13004 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Num samples mismatch! "); 13005 13006 ASSERT_NO_FATAL_FAILURE(Init()); 13007 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 13008 13009 OneOffDescriptorSet ds(m_device, { 13010 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, 13011 }); 13012 13013 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {}; 13014 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 13015 pipe_ms_state_ci.pNext = NULL; 13016 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT; 13017 pipe_ms_state_ci.sampleShadingEnable = 0; 13018 pipe_ms_state_ci.minSampleShading = 1.0; 13019 pipe_ms_state_ci.pSampleMask = NULL; 13020 13021 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_}); 13022 13023 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 13024 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader 13025 // but add it to be able to run on more devices 13026 VkPipelineObj pipe(m_device); 13027 pipe.AddShader(&vs); 13028 pipe.AddShader(&fs); 13029 pipe.AddDefaultColorAttachment(); 13030 pipe.SetMSAA(&pipe_ms_state_ci); 13031 pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 13032 13033 m_commandBuffer->begin(); 13034 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 13035 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 13036 13037 VkViewport viewport = {0, 0, 16, 16, 0, 1}; 13038 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 13039 VkRect2D scissor = {{0, 0}, {16, 16}}; 13040 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 13041 13042 // Render triangle (the error should trigger on the attempt to draw). 13043 m_commandBuffer->Draw(3, 1, 0, 0); 13044 13045 // Finalize recording of the command buffer 13046 m_commandBuffer->EndRenderPass(); 13047 m_commandBuffer->end(); 13048 13049 m_errorMonitor->VerifyFound(); 13050 } 13051 13052 TEST_F(VkLayerTest, RenderPassIncompatible) { 13053 TEST_DESCRIPTION( 13054 "Hit RenderPass incompatible cases. Initial case is drawing with an active renderpass that's not compatible with the bound " 13055 "pipeline state object's creation renderpass"); 13056 13057 ASSERT_NO_FATAL_FAILURE(Init()); 13058 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 13059 13060 OneOffDescriptorSet ds(m_device, { 13061 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, 13062 }); 13063 13064 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_}); 13065 13066 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 13067 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader 13068 // but add it to be able to run on more devices 13069 // Create a renderpass that will be incompatible with default renderpass 13070 VkAttachmentReference color_att = {}; 13071 color_att.layout = VK_IMAGE_LAYOUT_GENERAL; 13072 VkSubpassDescription subpass = {}; 13073 subpass.colorAttachmentCount = 1; 13074 subpass.pColorAttachments = &color_att; 13075 VkRenderPassCreateInfo rpci = {}; 13076 rpci.subpassCount = 1; 13077 rpci.pSubpasses = &subpass; 13078 rpci.attachmentCount = 1; 13079 VkAttachmentDescription attach_desc = {}; 13080 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; 13081 // Format incompatible with PSO RP color attach format B8G8R8A8_UNORM 13082 attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM; 13083 attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; 13084 rpci.pAttachments = &attach_desc; 13085 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 13086 VkRenderPass rp; 13087 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 13088 VkPipelineObj pipe(m_device); 13089 pipe.AddShader(&vs); 13090 pipe.AddShader(&fs); 13091 pipe.AddDefaultColorAttachment(); 13092 VkViewport view_port = {}; 13093 m_viewports.push_back(view_port); 13094 pipe.SetViewport(m_viewports); 13095 VkRect2D rect = {}; 13096 m_scissors.push_back(rect); 13097 pipe.SetScissor(m_scissors); 13098 pipe.CreateVKPipeline(pipeline_layout.handle(), rp); 13099 13100 VkCommandBufferInheritanceInfo cbii = {}; 13101 cbii.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; 13102 cbii.renderPass = rp; 13103 cbii.subpass = 0; 13104 VkCommandBufferBeginInfo cbbi = {}; 13105 cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 13106 cbbi.pInheritanceInfo = &cbii; 13107 vkBeginCommandBuffer(m_commandBuffer->handle(), &cbbi); 13108 vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 13109 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 13110 13111 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1a200366); 13112 // Render triangle (the error should trigger on the attempt to draw). 13113 m_commandBuffer->Draw(3, 1, 0, 0); 13114 13115 // Finalize recording of the command buffer 13116 m_commandBuffer->EndRenderPass(); 13117 m_commandBuffer->end(); 13118 13119 m_errorMonitor->VerifyFound(); 13120 13121 vkDestroyRenderPass(m_device->device(), rp, NULL); 13122 } 13123 13124 TEST_F(VkLayerTest, NumBlendAttachMismatch) { 13125 // Create Pipeline where the number of blend attachments doesn't match the 13126 // number of color attachments. In this case, we don't add any color 13127 // blend attachments even though we have a color attachment. 13128 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_096005d4); 13129 13130 ASSERT_NO_FATAL_FAILURE(Init()); 13131 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 13132 13133 OneOffDescriptorSet ds(m_device, { 13134 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, 13135 }); 13136 13137 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {}; 13138 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 13139 pipe_ms_state_ci.pNext = NULL; 13140 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; 13141 pipe_ms_state_ci.sampleShadingEnable = 0; 13142 pipe_ms_state_ci.minSampleShading = 1.0; 13143 pipe_ms_state_ci.pSampleMask = NULL; 13144 13145 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_}); 13146 13147 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 13148 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader 13149 // but add it to be able to run on more devices 13150 VkPipelineObj pipe(m_device); 13151 pipe.AddShader(&vs); 13152 pipe.AddShader(&fs); 13153 pipe.SetMSAA(&pipe_ms_state_ci); 13154 pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 13155 m_errorMonitor->VerifyFound(); 13156 } 13157 13158 TEST_F(VkLayerTest, Maint1BindingSliceOf3DImage) { 13159 TEST_DESCRIPTION( 13160 "Attempt to bind a slice of a 3D texture in a descriptor set. This is explicitly disallowed by KHR_maintenance1 to keep " 13161 "things simple for drivers."); 13162 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 13163 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) { 13164 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME); 13165 } else { 13166 printf(VK_KHR_MAINTENANCE1_EXTENSION_NAME " is not supported; skipping\n"); 13167 return; 13168 } 13169 ASSERT_NO_FATAL_FAILURE(InitState()); 13170 13171 VkResult err; 13172 13173 OneOffDescriptorSet set(m_device, { 13174 {0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}, 13175 }); 13176 13177 VkImageCreateInfo ici = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 13178 nullptr, 13179 VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR, 13180 VK_IMAGE_TYPE_3D, 13181 VK_FORMAT_R8G8B8A8_UNORM, 13182 {32, 32, 32}, 13183 1, 13184 1, 13185 VK_SAMPLE_COUNT_1_BIT, 13186 VK_IMAGE_TILING_OPTIMAL, 13187 VK_IMAGE_USAGE_SAMPLED_BIT, 13188 VK_SHARING_MODE_EXCLUSIVE, 13189 0, 13190 nullptr, 13191 VK_IMAGE_LAYOUT_UNDEFINED}; 13192 VkImageObj image(m_device); 13193 image.init(&ici); 13194 ASSERT_TRUE(image.initialized()); 13195 13196 VkImageViewCreateInfo ivci = { 13197 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 13198 nullptr, 13199 0, 13200 image.handle(), 13201 VK_IMAGE_VIEW_TYPE_2D, 13202 VK_FORMAT_R8G8B8A8_UNORM, 13203 {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, 13204 VK_COMPONENT_SWIZZLE_IDENTITY}, 13205 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}, 13206 }; 13207 VkImageView view; 13208 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view); 13209 ASSERT_VK_SUCCESS(err); 13210 13211 // Meat of the test. 13212 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_046002ae); 13213 13214 VkDescriptorImageInfo dii = {VK_NULL_HANDLE, view, VK_IMAGE_LAYOUT_GENERAL}; 13215 VkWriteDescriptorSet write = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, nullptr, set.set_, 0, 0, 1, 13216 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &dii, nullptr, nullptr}; 13217 vkUpdateDescriptorSets(m_device->device(), 1, &write, 0, nullptr); 13218 13219 m_errorMonitor->VerifyFound(); 13220 13221 vkDestroyImageView(m_device->device(), view, nullptr); 13222 } 13223 13224 TEST_F(VkLayerTest, MissingClearAttachment) { 13225 TEST_DESCRIPTION("Points to a wrong colorAttachment index in a VkClearAttachment structure passed to vkCmdClearAttachments"); 13226 ASSERT_NO_FATAL_FAILURE(Init()); 13227 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1860001e); 13228 13229 VKTriangleTest(BsoFailCmdClearAttachments); 13230 m_errorMonitor->VerifyFound(); 13231 } 13232 13233 TEST_F(VkPositiveLayerTest, ConfirmNoVLErrorWhenVkCmdClearAttachmentsCalledInSecondaryCB) { 13234 TEST_DESCRIPTION( 13235 "This test is to verify that when vkCmdClearAttachments is called by a secondary commandbuffer, the validation layers do " 13236 "not throw an error if the primary commandbuffer begins a renderpass before executing the secondary commandbuffer."); 13237 13238 ASSERT_NO_FATAL_FAILURE(Init()); 13239 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 13240 13241 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); 13242 13243 VkCommandBufferBeginInfo info = {}; 13244 VkCommandBufferInheritanceInfo hinfo = {}; 13245 info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; 13246 info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 13247 info.pInheritanceInfo = &hinfo; 13248 hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; 13249 hinfo.pNext = NULL; 13250 hinfo.renderPass = renderPass(); 13251 hinfo.subpass = 0; 13252 hinfo.framebuffer = m_framebuffer; 13253 hinfo.occlusionQueryEnable = VK_FALSE; 13254 hinfo.queryFlags = 0; 13255 hinfo.pipelineStatistics = 0; 13256 13257 secondary.begin(&info); 13258 VkClearAttachment color_attachment; 13259 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 13260 color_attachment.clearValue.color.float32[0] = 0.0; 13261 color_attachment.clearValue.color.float32[1] = 0.0; 13262 color_attachment.clearValue.color.float32[2] = 0.0; 13263 color_attachment.clearValue.color.float32[3] = 0.0; 13264 color_attachment.colorAttachment = 0; 13265 VkClearRect clear_rect = {{{0, 0}, {(uint32_t)m_width, (uint32_t)m_height}}, 0, 1}; 13266 vkCmdClearAttachments(secondary.handle(), 1, &color_attachment, 1, &clear_rect); 13267 m_errorMonitor->VerifyNotFound(); 13268 secondary.end(); 13269 13270 m_commandBuffer->begin(); 13271 vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); 13272 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle()); 13273 vkCmdEndRenderPass(m_commandBuffer->handle()); 13274 m_commandBuffer->end(); 13275 } 13276 13277 TEST_F(VkLayerTest, CmdClearAttachmentTests) { 13278 TEST_DESCRIPTION("Various tests for validating usage of vkCmdClearAttachments"); 13279 13280 ASSERT_NO_FATAL_FAILURE(Init()); 13281 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 13282 13283 OneOffDescriptorSet ds(m_device, { 13284 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, 13285 }); 13286 13287 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {}; 13288 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 13289 pipe_ms_state_ci.pNext = NULL; 13290 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT; 13291 pipe_ms_state_ci.sampleShadingEnable = 0; 13292 pipe_ms_state_ci.minSampleShading = 1.0; 13293 pipe_ms_state_ci.pSampleMask = NULL; 13294 13295 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_}); 13296 13297 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 13298 // We shouldn't need a fragment shader but add it to be able to run 13299 // on more devices 13300 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 13301 13302 VkPipelineObj pipe(m_device); 13303 pipe.AddShader(&vs); 13304 pipe.AddShader(&fs); 13305 pipe.AddDefaultColorAttachment(); 13306 pipe.SetMSAA(&pipe_ms_state_ci); 13307 pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 13308 13309 m_commandBuffer->begin(); 13310 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 13311 13312 // Main thing we care about for this test is that the VkImage obj we're 13313 // clearing matches Color Attachment of FB 13314 // Also pass down other dummy params to keep driver and paramchecker happy 13315 VkClearAttachment color_attachment; 13316 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 13317 color_attachment.clearValue.color.float32[0] = 1.0; 13318 color_attachment.clearValue.color.float32[1] = 1.0; 13319 color_attachment.clearValue.color.float32[2] = 1.0; 13320 color_attachment.clearValue.color.float32[3] = 1.0; 13321 color_attachment.colorAttachment = 0; 13322 VkClearRect clear_rect = {{{0, 0}, {(uint32_t)m_width, (uint32_t)m_height}}, 0, 1}; 13323 13324 // Call for full-sized FB Color attachment prior to issuing a Draw 13325 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 13326 "vkCmdClearAttachments() issued on command buffer object "); 13327 vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect); 13328 m_errorMonitor->VerifyFound(); 13329 13330 clear_rect.rect.extent.width = renderPassBeginInfo().renderArea.extent.width + 4; 13331 clear_rect.rect.extent.height = clear_rect.rect.extent.height / 2; 13332 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18600020); 13333 vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect); 13334 m_errorMonitor->VerifyFound(); 13335 13336 // baseLayer >= view layers 13337 clear_rect.rect.extent.width = (uint32_t)m_width; 13338 clear_rect.baseArrayLayer = 1; 13339 clear_rect.layerCount = 0; 13340 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18600022); 13341 vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect); 13342 m_errorMonitor->VerifyFound(); 13343 13344 // baseLayer + layerCount > view layers 13345 clear_rect.rect.extent.width = (uint32_t)m_width; 13346 clear_rect.baseArrayLayer = 0; 13347 clear_rect.layerCount = 2; 13348 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18600022); 13349 vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect); 13350 m_errorMonitor->VerifyFound(); 13351 } 13352 13353 TEST_F(VkLayerTest, VtxBufferBadIndex) { 13354 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 13355 "but no vertex buffers are attached to this Pipeline State Object"); 13356 13357 ASSERT_NO_FATAL_FAILURE(Init()); 13358 ASSERT_NO_FATAL_FAILURE(InitViewport()); 13359 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 13360 13361 OneOffDescriptorSet ds(m_device, { 13362 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, 13363 }); 13364 13365 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {}; 13366 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 13367 pipe_ms_state_ci.pNext = NULL; 13368 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; 13369 pipe_ms_state_ci.sampleShadingEnable = 0; 13370 pipe_ms_state_ci.minSampleShading = 1.0; 13371 pipe_ms_state_ci.pSampleMask = NULL; 13372 13373 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_}); 13374 13375 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 13376 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader 13377 // but add it to be able to run on more devices 13378 VkPipelineObj pipe(m_device); 13379 pipe.AddShader(&vs); 13380 pipe.AddShader(&fs); 13381 pipe.AddDefaultColorAttachment(); 13382 pipe.SetMSAA(&pipe_ms_state_ci); 13383 pipe.SetViewport(m_viewports); 13384 pipe.SetScissor(m_scissors); 13385 pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 13386 13387 m_commandBuffer->begin(); 13388 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 13389 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 13390 // Don't care about actual data, just need to get to draw to flag error 13391 static const float vbo_data[3] = {1.f, 0.f, 1.f}; 13392 VkConstantBufferObj vbo(m_device, sizeof(vbo_data), (const void *)&vbo_data, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); 13393 m_commandBuffer->BindVertexBuffer(&vbo, (VkDeviceSize)0, 1); // VBO idx 1, but no VBO in PSO 13394 m_commandBuffer->Draw(1, 0, 0, 0); 13395 13396 m_errorMonitor->VerifyFound(); 13397 } 13398 13399 TEST_F(VkLayerTest, MismatchCountQueueCreateRequestedFeature) { 13400 TEST_DESCRIPTION("Use an invalid count in a vkEnumeratePhysicalDevices call.Use invalid Queue Family Index in vkCreateDevice"); 13401 ASSERT_NO_FATAL_FAILURE(Init()); 13402 13403 // The following test fails with recent NVidia drivers. 13404 // By the time core_validation is reached, the NVidia 13405 // driver has sanitized the invalid condition and core_validation 13406 // is not introduced to the failure condition. This is not the case 13407 // with AMD and Mesa drivers. Futher investigation is required 13408 // uint32_t count = static_cast<uint32_t>(~0); 13409 // VkPhysicalDevice physical_device; 13410 // vkEnumeratePhysicalDevices(instance(), &count, &physical_device); 13411 // m_errorMonitor->VerifyFound(); 13412 13413 float queue_priority = 0.0; 13414 VkDeviceQueueCreateInfo queue_create_info = {}; 13415 queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 13416 queue_create_info.queueCount = 1; 13417 queue_create_info.pQueuePriorities = &queue_priority; 13418 queue_create_info.queueFamilyIndex = static_cast<uint32_t>(~0); 13419 13420 VkPhysicalDeviceFeatures features = m_device->phy().features(); 13421 VkDevice testDevice; 13422 VkDeviceCreateInfo device_create_info = {}; 13423 device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; 13424 device_create_info.queueCreateInfoCount = 1; 13425 device_create_info.pQueueCreateInfos = &queue_create_info; 13426 device_create_info.pEnabledFeatures = &features; 13427 13428 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_06c002fa); 13429 // The following unexpected error is coming from the LunarG loader. Do not make it a desired message because platforms that do 13430 // not use the LunarG loader (e.g. Android) will not see the message and the test will fail. 13431 m_errorMonitor->SetUnexpectedError("Failed to create device chain."); 13432 vkCreateDevice(gpu(), &device_create_info, nullptr, &testDevice); 13433 m_errorMonitor->VerifyFound(); 13434 13435 vk_testing::QueueCreateInfoArray queue_info_obj(m_device->queue_props); 13436 device_create_info.queueCreateInfoCount = queue_info_obj.size(); 13437 device_create_info.pQueueCreateInfos = queue_info_obj.data(); 13438 13439 unsigned feature_count = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32); 13440 VkBool32 *feature_array = reinterpret_cast<VkBool32 *>(&features); 13441 for (unsigned i = 0; i < feature_count; i++) { 13442 if (VK_FALSE == feature_array[i]) { 13443 feature_array[i] = VK_TRUE; 13444 device_create_info.pEnabledFeatures = &features; 13445 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 13446 "While calling vkCreateDevice(), requesting feature"); 13447 // The following unexpected error is coming from the LunarG loader. Do not make it a desired message because platforms 13448 // that do not use the LunarG loader (e.g. Android) will not see the message and the test will fail. 13449 m_errorMonitor->SetUnexpectedError("Failed to create device chain."); 13450 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 13451 "You requested features that are unavailable on this device. You should first " 13452 "query feature availability by calling vkGetPhysicalDeviceFeatures()."); 13453 vkCreateDevice(gpu(), &device_create_info, nullptr, &testDevice); 13454 m_errorMonitor->VerifyFound(); 13455 break; 13456 } 13457 } 13458 } 13459 13460 TEST_F(VkLayerTest, InvalidQueryPoolCreate) { 13461 TEST_DESCRIPTION("Attempt to create a query pool for PIPELINE_STATISTICS without enabling pipeline stats for the device."); 13462 13463 ASSERT_NO_FATAL_FAILURE(Init()); 13464 13465 vk_testing::QueueCreateInfoArray queue_info(m_device->queue_props); 13466 13467 VkDevice local_device; 13468 VkDeviceCreateInfo device_create_info = {}; 13469 auto features = m_device->phy().features(); 13470 // Intentionally disable pipeline stats 13471 features.pipelineStatisticsQuery = VK_FALSE; 13472 device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; 13473 device_create_info.pNext = NULL; 13474 device_create_info.queueCreateInfoCount = queue_info.size(); 13475 device_create_info.pQueueCreateInfos = queue_info.data(); 13476 device_create_info.enabledLayerCount = 0; 13477 device_create_info.ppEnabledLayerNames = NULL; 13478 device_create_info.pEnabledFeatures = &features; 13479 VkResult err = vkCreateDevice(gpu(), &device_create_info, nullptr, &local_device); 13480 ASSERT_VK_SUCCESS(err); 13481 13482 VkQueryPoolCreateInfo qpci{}; 13483 qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; 13484 qpci.queryType = VK_QUERY_TYPE_PIPELINE_STATISTICS; 13485 qpci.queryCount = 1; 13486 VkQueryPool query_pool; 13487 13488 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_11c0062e); 13489 vkCreateQueryPool(local_device, &qpci, nullptr, &query_pool); 13490 m_errorMonitor->VerifyFound(); 13491 13492 vkDestroyDevice(local_device, nullptr); 13493 } 13494 13495 TEST_F(VkLayerTest, UnclosedQuery) { 13496 TEST_DESCRIPTION("End a command buffer with a query still in progress."); 13497 13498 const char *invalid_query = "Ending command buffer with in progress query: queryPool 0x"; 13499 13500 ASSERT_NO_FATAL_FAILURE(Init()); 13501 13502 VkEvent event; 13503 VkEventCreateInfo event_create_info{}; 13504 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 13505 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event); 13506 13507 VkQueue queue = VK_NULL_HANDLE; 13508 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue); 13509 13510 m_commandBuffer->begin(); 13511 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_query); 13512 13513 VkQueryPool query_pool; 13514 VkQueryPoolCreateInfo query_pool_create_info = {}; 13515 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; 13516 query_pool_create_info.queryType = VK_QUERY_TYPE_OCCLUSION; 13517 query_pool_create_info.queryCount = 1; 13518 vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool); 13519 13520 vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0 /*startQuery*/, 1 /*queryCount*/); 13521 vkCmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0); 13522 13523 vkEndCommandBuffer(m_commandBuffer->handle()); 13524 m_errorMonitor->VerifyFound(); 13525 13526 vkDestroyQueryPool(m_device->device(), query_pool, nullptr); 13527 vkDestroyEvent(m_device->device(), event, nullptr); 13528 } 13529 13530 TEST_F(VkLayerTest, VertexBufferInvalid) { 13531 TEST_DESCRIPTION( 13532 "Submit a command buffer using deleted vertex buffer, delete a buffer twice, use an invalid offset for each buffer type, " 13533 "and attempt to bind a null buffer"); 13534 13535 const char *deleted_buffer_in_command_buffer = "Cannot submit cmd buffer using deleted buffer "; 13536 const char *invalid_offset_message = "vkBindBufferMemory(): memoryOffset is 0x"; 13537 const char *invalid_storage_buffer_offset_message = "vkBindBufferMemory(): storage memoryOffset is 0x"; 13538 const char *invalid_texel_buffer_offset_message = "vkBindBufferMemory(): texel memoryOffset is 0x"; 13539 const char *invalid_uniform_buffer_offset_message = "vkBindBufferMemory(): uniform memoryOffset is 0x"; 13540 13541 ASSERT_NO_FATAL_FAILURE(Init()); 13542 ASSERT_NO_FATAL_FAILURE(InitViewport()); 13543 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 13544 13545 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {}; 13546 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 13547 pipe_ms_state_ci.pNext = NULL; 13548 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; 13549 pipe_ms_state_ci.sampleShadingEnable = 0; 13550 pipe_ms_state_ci.minSampleShading = 1.0; 13551 pipe_ms_state_ci.pSampleMask = nullptr; 13552 13553 const VkPipelineLayoutObj pipeline_layout(m_device); 13554 13555 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 13556 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 13557 VkPipelineObj pipe(m_device); 13558 pipe.AddShader(&vs); 13559 pipe.AddShader(&fs); 13560 pipe.AddDefaultColorAttachment(); 13561 pipe.SetMSAA(&pipe_ms_state_ci); 13562 pipe.SetViewport(m_viewports); 13563 pipe.SetScissor(m_scissors); 13564 pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 13565 13566 m_commandBuffer->begin(); 13567 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 13568 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 13569 13570 { 13571 // Create and bind a vertex buffer in a reduced scope, which will cause 13572 // it to be deleted upon leaving this scope 13573 const float vbo_data[3] = {1.f, 0.f, 1.f}; 13574 VkVerticesObj draw_verticies(m_device, 1, 1, sizeof(vbo_data[0]), sizeof(vbo_data) / sizeof(vbo_data[0]), vbo_data); 13575 draw_verticies.BindVertexBuffers(m_commandBuffer->handle()); 13576 draw_verticies.AddVertexInputToPipe(pipe); 13577 } 13578 13579 m_commandBuffer->Draw(1, 0, 0, 0); 13580 13581 m_commandBuffer->EndRenderPass(); 13582 m_commandBuffer->end(); 13583 13584 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, deleted_buffer_in_command_buffer); 13585 m_commandBuffer->QueueCommandBuffer(false); 13586 m_errorMonitor->VerifyFound(); 13587 13588 { 13589 // Create and bind a vertex buffer in a reduced scope, and delete it 13590 // twice, the second through the destructor 13591 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eDoubleDelete); 13592 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_23c01a01); 13593 buffer_test.TestDoubleDestroy(); 13594 } 13595 m_errorMonitor->VerifyFound(); 13596 13597 m_errorMonitor->SetUnexpectedError("value of pCreateInfo->usage must not be 0"); 13598 if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidMemoryOffset)) { 13599 // Create and bind a memory buffer with an invalid offset. 13600 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_offset_message); 13601 m_errorMonitor->SetUnexpectedError( 13602 "If buffer was created with the VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT or VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, " 13603 "memoryOffset must be a multiple of VkPhysicalDeviceLimits::minTexelBufferOffsetAlignment"); 13604 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VkBufferTest::eInvalidMemoryOffset); 13605 (void)buffer_test; 13606 m_errorMonitor->VerifyFound(); 13607 } 13608 13609 if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset, 13610 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) { 13611 // Create and bind a memory buffer with an invalid offset again, 13612 // but look for a texel buffer message. 13613 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_texel_buffer_offset_message); 13614 m_errorMonitor->SetUnexpectedError( 13615 "memoryOffset must be an integer multiple of the alignment member of the VkMemoryRequirements structure returned from " 13616 "a call to vkGetBufferMemoryRequirements with buffer"); 13617 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset); 13618 (void)buffer_test; 13619 m_errorMonitor->VerifyFound(); 13620 } 13621 13622 if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)) { 13623 // Create and bind a memory buffer with an invalid offset again, but 13624 // look for a uniform buffer message. 13625 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_uniform_buffer_offset_message); 13626 m_errorMonitor->SetUnexpectedError( 13627 "memoryOffset must be an integer multiple of the alignment member of the VkMemoryRequirements structure returned from " 13628 "a call to vkGetBufferMemoryRequirements with buffer"); 13629 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset); 13630 (void)buffer_test; 13631 m_errorMonitor->VerifyFound(); 13632 } 13633 13634 if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) { 13635 // Create and bind a memory buffer with an invalid offset again, but 13636 // look for a storage buffer message. 13637 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_storage_buffer_offset_message); 13638 m_errorMonitor->SetUnexpectedError( 13639 "memoryOffset must be an integer multiple of the alignment member of the VkMemoryRequirements structure returned from " 13640 "a call to vkGetBufferMemoryRequirements with buffer"); 13641 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset); 13642 (void)buffer_test; 13643 m_errorMonitor->VerifyFound(); 13644 } 13645 13646 { 13647 // Attempt to bind a null buffer. 13648 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 13649 "vkBindBufferMemory: required parameter buffer specified as VK_NULL_HANDLE"); 13650 VkBufferTest buffer_test(m_device, 0, VkBufferTest::eBindNullBuffer); 13651 (void)buffer_test; 13652 m_errorMonitor->VerifyFound(); 13653 } 13654 13655 { 13656 // Attempt to bind a fake buffer. 13657 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_17001a01); 13658 VkBufferTest buffer_test(m_device, 0, VkBufferTest::eBindFakeBuffer); 13659 (void)buffer_test; 13660 m_errorMonitor->VerifyFound(); 13661 } 13662 13663 { 13664 // Attempt to use an invalid handle to delete a buffer. 13665 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_2880c601); 13666 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eFreeInvalidHandle); 13667 (void)buffer_test; 13668 } 13669 m_errorMonitor->VerifyFound(); 13670 } 13671 13672 TEST_F(VkLayerTest, BadVertexBufferOffset) { 13673 TEST_DESCRIPTION("Submit an offset past the end of a vertex buffer"); 13674 13675 ASSERT_NO_FATAL_FAILURE(Init()); 13676 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 13677 static const float vbo_data[3] = {1.f, 0.f, 1.f}; 13678 VkConstantBufferObj vbo(m_device, sizeof(vbo_data), (const void *)&vbo_data, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); 13679 m_commandBuffer->begin(); 13680 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 13681 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_182004e4); 13682 m_commandBuffer->BindVertexBuffer(&vbo, (VkDeviceSize)(3 * sizeof(float)), 1); // Offset at the end of the buffer 13683 m_errorMonitor->VerifyFound(); 13684 } 13685 13686 // INVALID_IMAGE_LAYOUT tests (one other case is hit by MapMemWithoutHostVisibleBit and not here) 13687 TEST_F(VkLayerTest, InvalidImageLayout) { 13688 TEST_DESCRIPTION( 13689 "Hit all possible validation checks associated with the DRAWSTATE_INVALID_IMAGE_LAYOUT enum. Generally these involve " 13690 "havingimages in the wrong layout when they're copied or transitioned."); 13691 // 3 in ValidateCmdBufImageLayouts 13692 // * -1 Attempt to submit cmd buf w/ deleted image 13693 // * -2 Cmd buf submit of image w/ layout not matching first use w/ subresource 13694 // * -3 Cmd buf submit of image w/ layout not matching first use w/o subresource 13695 13696 ASSERT_NO_FATAL_FAILURE(Init()); 13697 auto depth_format = FindSupportedDepthStencilFormat(gpu()); 13698 if (!depth_format) { 13699 printf(" No Depth + Stencil format found. Skipped.\n"); 13700 return; 13701 } 13702 // Create src & dst images to use for copy operations 13703 VkImage src_image; 13704 VkImage dst_image; 13705 VkImage depth_image; 13706 13707 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 13708 const int32_t tex_width = 32; 13709 const int32_t tex_height = 32; 13710 13711 VkImageCreateInfo image_create_info = {}; 13712 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 13713 image_create_info.pNext = NULL; 13714 image_create_info.imageType = VK_IMAGE_TYPE_2D; 13715 image_create_info.format = tex_format; 13716 image_create_info.extent.width = tex_width; 13717 image_create_info.extent.height = tex_height; 13718 image_create_info.extent.depth = 1; 13719 image_create_info.mipLevels = 1; 13720 image_create_info.arrayLayers = 4; 13721 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 13722 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 13723 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 13724 image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 13725 image_create_info.flags = 0; 13726 13727 VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &src_image); 13728 ASSERT_VK_SUCCESS(err); 13729 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; 13730 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dst_image); 13731 ASSERT_VK_SUCCESS(err); 13732 image_create_info.format = VK_FORMAT_D16_UNORM; 13733 image_create_info.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; 13734 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &depth_image); 13735 ASSERT_VK_SUCCESS(err); 13736 13737 // Allocate memory 13738 VkMemoryRequirements img_mem_reqs = {}; 13739 VkMemoryAllocateInfo mem_alloc = {}; 13740 VkDeviceMemory src_image_mem, dst_image_mem, depth_image_mem; 13741 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 13742 mem_alloc.pNext = NULL; 13743 mem_alloc.allocationSize = 0; 13744 mem_alloc.memoryTypeIndex = 0; 13745 13746 vkGetImageMemoryRequirements(m_device->device(), src_image, &img_mem_reqs); 13747 mem_alloc.allocationSize = img_mem_reqs.size; 13748 bool pass = m_device->phy().set_memory_type(img_mem_reqs.memoryTypeBits, &mem_alloc, 0); 13749 ASSERT_TRUE(pass); 13750 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &src_image_mem); 13751 ASSERT_VK_SUCCESS(err); 13752 13753 vkGetImageMemoryRequirements(m_device->device(), dst_image, &img_mem_reqs); 13754 mem_alloc.allocationSize = img_mem_reqs.size; 13755 pass = m_device->phy().set_memory_type(img_mem_reqs.memoryTypeBits, &mem_alloc, 0); 13756 ASSERT_VK_SUCCESS(err); 13757 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &dst_image_mem); 13758 ASSERT_VK_SUCCESS(err); 13759 13760 vkGetImageMemoryRequirements(m_device->device(), depth_image, &img_mem_reqs); 13761 mem_alloc.allocationSize = img_mem_reqs.size; 13762 pass = m_device->phy().set_memory_type(img_mem_reqs.memoryTypeBits, &mem_alloc, 0); 13763 ASSERT_VK_SUCCESS(err); 13764 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &depth_image_mem); 13765 ASSERT_VK_SUCCESS(err); 13766 13767 err = vkBindImageMemory(m_device->device(), src_image, src_image_mem, 0); 13768 ASSERT_VK_SUCCESS(err); 13769 err = vkBindImageMemory(m_device->device(), dst_image, dst_image_mem, 0); 13770 ASSERT_VK_SUCCESS(err); 13771 err = vkBindImageMemory(m_device->device(), depth_image, depth_image_mem, 0); 13772 ASSERT_VK_SUCCESS(err); 13773 13774 m_commandBuffer->begin(); 13775 VkImageCopy copy_region; 13776 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 13777 copy_region.srcSubresource.mipLevel = 0; 13778 copy_region.srcSubresource.baseArrayLayer = 0; 13779 copy_region.srcSubresource.layerCount = 1; 13780 copy_region.srcOffset.x = 0; 13781 copy_region.srcOffset.y = 0; 13782 copy_region.srcOffset.z = 0; 13783 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 13784 copy_region.dstSubresource.mipLevel = 0; 13785 copy_region.dstSubresource.baseArrayLayer = 0; 13786 copy_region.dstSubresource.layerCount = 1; 13787 copy_region.dstOffset.x = 0; 13788 copy_region.dstOffset.y = 0; 13789 copy_region.dstOffset.z = 0; 13790 copy_region.extent.width = 1; 13791 copy_region.extent.height = 1; 13792 copy_region.extent.depth = 1; 13793 13794 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 13795 "layout should be VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL instead of GENERAL."); 13796 m_errorMonitor->SetUnexpectedError("layout should be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL instead of GENERAL."); 13797 13798 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, ©_region); 13799 m_errorMonitor->VerifyFound(); 13800 // The first call hits the expected WARNING and skips the call down the chain, so call a second time to call down chain and 13801 // update layer state 13802 m_errorMonitor->SetUnexpectedError("layout should be VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL instead of GENERAL."); 13803 m_errorMonitor->SetUnexpectedError("layout should be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL instead of GENERAL."); 13804 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, ©_region); 13805 // Now cause error due to src image layout changing 13806 m_errorMonitor->SetDesiredFailureMsg( 13807 VK_DEBUG_REPORT_ERROR_BIT_EXT, 13808 "with specific layout VK_IMAGE_LAYOUT_UNDEFINED that doesn't match the actual current layout VK_IMAGE_LAYOUT_GENERAL."); 13809 m_errorMonitor->SetUnexpectedError("is VK_IMAGE_LAYOUT_UNDEFINED but can only be VK_IMAGE_LAYOUT"); 13810 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_UNDEFINED, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, ©_region); 13811 m_errorMonitor->VerifyFound(); 13812 // Final src error is due to bad layout type 13813 m_errorMonitor->SetDesiredFailureMsg( 13814 VK_DEBUG_REPORT_ERROR_BIT_EXT, 13815 "is VK_IMAGE_LAYOUT_UNDEFINED but can only be VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL."); 13816 m_errorMonitor->SetUnexpectedError( 13817 "with specific layout VK_IMAGE_LAYOUT_UNDEFINED that doesn't match the actual current layout VK_IMAGE_LAYOUT_GENERAL."); 13818 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_UNDEFINED, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, ©_region); 13819 m_errorMonitor->VerifyFound(); 13820 // Now verify same checks for dst 13821 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 13822 "layout should be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL instead of GENERAL."); 13823 m_errorMonitor->SetUnexpectedError("layout should be VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL instead of GENERAL."); 13824 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, ©_region); 13825 m_errorMonitor->VerifyFound(); 13826 // Now cause error due to src image layout changing 13827 m_errorMonitor->SetDesiredFailureMsg( 13828 VK_DEBUG_REPORT_ERROR_BIT_EXT, 13829 "with specific layout VK_IMAGE_LAYOUT_UNDEFINED that doesn't match the actual current layout VK_IMAGE_LAYOUT_GENERAL."); 13830 m_errorMonitor->SetUnexpectedError( 13831 "is VK_IMAGE_LAYOUT_UNDEFINED but can only be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL."); 13832 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_UNDEFINED, 1, ©_region); 13833 m_errorMonitor->VerifyFound(); 13834 m_errorMonitor->SetDesiredFailureMsg( 13835 VK_DEBUG_REPORT_ERROR_BIT_EXT, 13836 "is VK_IMAGE_LAYOUT_UNDEFINED but can only be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL."); 13837 m_errorMonitor->SetUnexpectedError( 13838 "with specific layout VK_IMAGE_LAYOUT_UNDEFINED that doesn't match the actual current layout VK_IMAGE_LAYOUT_GENERAL."); 13839 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_UNDEFINED, 1, ©_region); 13840 m_errorMonitor->VerifyFound(); 13841 13842 // Convert dst and depth images to TRANSFER_DST for subsequent tests 13843 VkImageMemoryBarrier transfer_dst_image_barrier[1] = {}; 13844 transfer_dst_image_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 13845 transfer_dst_image_barrier[0].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; 13846 transfer_dst_image_barrier[0].newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 13847 transfer_dst_image_barrier[0].srcAccessMask = 0; 13848 transfer_dst_image_barrier[0].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 13849 transfer_dst_image_barrier[0].image = dst_image; 13850 transfer_dst_image_barrier[0].subresourceRange.layerCount = image_create_info.arrayLayers; 13851 transfer_dst_image_barrier[0].subresourceRange.levelCount = image_create_info.mipLevels; 13852 transfer_dst_image_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 13853 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 13854 NULL, 0, NULL, 1, transfer_dst_image_barrier); 13855 transfer_dst_image_barrier[0].image = depth_image; 13856 transfer_dst_image_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 13857 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 13858 NULL, 0, NULL, 1, transfer_dst_image_barrier); 13859 13860 // Cause errors due to clearing with invalid image layouts 13861 VkClearColorValue color_clear_value = {}; 13862 VkImageSubresourceRange clear_range; 13863 clear_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 13864 clear_range.baseMipLevel = 0; 13865 clear_range.baseArrayLayer = 0; 13866 clear_range.layerCount = 1; 13867 clear_range.levelCount = 1; 13868 13869 // Fail due to explicitly prohibited layout for color clear (only GENERAL and TRANSFER_DST are permitted). 13870 // Since the image is currently not in UNDEFINED layout, this will emit two errors. 13871 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1880000a); 13872 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800008); 13873 m_commandBuffer->ClearColorImage(dst_image, VK_IMAGE_LAYOUT_UNDEFINED, &color_clear_value, 1, &clear_range); 13874 m_errorMonitor->VerifyFound(); 13875 // Fail due to provided layout not matching actual current layout for color clear. 13876 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18800008); 13877 m_commandBuffer->ClearColorImage(dst_image, VK_IMAGE_LAYOUT_GENERAL, &color_clear_value, 1, &clear_range); 13878 m_errorMonitor->VerifyFound(); 13879 13880 VkClearDepthStencilValue depth_clear_value = {}; 13881 clear_range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 13882 13883 // Fail due to explicitly prohibited layout for depth clear (only GENERAL and TRANSFER_DST are permitted). 13884 // Since the image is currently not in UNDEFINED layout, this will emit two errors. 13885 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00018); 13886 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00016); 13887 m_commandBuffer->ClearDepthStencilImage(depth_image, VK_IMAGE_LAYOUT_UNDEFINED, &depth_clear_value, 1, &clear_range); 13888 m_errorMonitor->VerifyFound(); 13889 // Fail due to provided layout not matching actual current layout for depth clear. 13890 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18a00016); 13891 m_commandBuffer->ClearDepthStencilImage(depth_image, VK_IMAGE_LAYOUT_GENERAL, &depth_clear_value, 1, &clear_range); 13892 m_errorMonitor->VerifyFound(); 13893 13894 // Now cause error due to bad image layout transition in PipelineBarrier 13895 VkImageMemoryBarrier image_barrier[1] = {}; 13896 image_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 13897 image_barrier[0].oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; 13898 image_barrier[0].newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 13899 image_barrier[0].image = src_image; 13900 image_barrier[0].subresourceRange.layerCount = image_create_info.arrayLayers; 13901 image_barrier[0].subresourceRange.levelCount = image_create_info.mipLevels; 13902 image_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 13903 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 13904 "you cannot transition the layout of aspect 1 from " 13905 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL when current layout is " 13906 "VK_IMAGE_LAYOUT_GENERAL."); 13907 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a000974); 13908 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 13909 NULL, 0, NULL, 1, image_barrier); 13910 m_errorMonitor->VerifyFound(); 13911 13912 // Finally some layout errors at RenderPass create time 13913 // Just hacking in specific state to get to the errors we want so don't copy this unless you know what you're doing. 13914 VkAttachmentReference attach = {}; 13915 // perf warning for GENERAL layout w/ non-DS input attachment 13916 attach.layout = VK_IMAGE_LAYOUT_GENERAL; 13917 VkSubpassDescription subpass = {}; 13918 subpass.inputAttachmentCount = 1; 13919 subpass.pInputAttachments = &attach; 13920 VkRenderPassCreateInfo rpci = {}; 13921 rpci.subpassCount = 1; 13922 rpci.pSubpasses = &subpass; 13923 rpci.attachmentCount = 1; 13924 VkAttachmentDescription attach_desc = {}; 13925 attach_desc.format = VK_FORMAT_UNDEFINED; 13926 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; 13927 attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; 13928 rpci.pAttachments = &attach_desc; 13929 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 13930 VkRenderPass rp; 13931 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 13932 "Layout for input attachment is GENERAL but should be READ_ONLY_OPTIMAL."); 13933 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 13934 m_errorMonitor->VerifyFound(); 13935 // error w/ non-general layout 13936 attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 13937 13938 m_errorMonitor->SetDesiredFailureMsg( 13939 VK_DEBUG_REPORT_ERROR_BIT_EXT, 13940 "Layout for input attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be READ_ONLY_OPTIMAL or GENERAL."); 13941 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 13942 m_errorMonitor->VerifyFound(); 13943 subpass.inputAttachmentCount = 0; 13944 subpass.colorAttachmentCount = 1; 13945 subpass.pColorAttachments = &attach; 13946 attach.layout = VK_IMAGE_LAYOUT_GENERAL; 13947 // perf warning for GENERAL layout on color attachment 13948 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 13949 "Layout for color attachment is GENERAL but should be COLOR_ATTACHMENT_OPTIMAL."); 13950 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 13951 m_errorMonitor->VerifyFound(); 13952 // error w/ non-color opt or GENERAL layout for color attachment 13953 attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 13954 m_errorMonitor->SetDesiredFailureMsg( 13955 VK_DEBUG_REPORT_ERROR_BIT_EXT, 13956 "Layout for color attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be COLOR_ATTACHMENT_OPTIMAL or GENERAL."); 13957 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 13958 m_errorMonitor->VerifyFound(); 13959 subpass.colorAttachmentCount = 0; 13960 subpass.pDepthStencilAttachment = &attach; 13961 attach.layout = VK_IMAGE_LAYOUT_GENERAL; 13962 // perf warning for GENERAL layout on DS attachment 13963 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 13964 "GENERAL layout for depth attachment may not give optimal performance."); 13965 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 13966 m_errorMonitor->VerifyFound(); 13967 // error w/ non-ds opt or GENERAL layout for color attachment 13968 attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 13969 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 13970 "Layout for depth attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be " 13971 "DEPTH_STENCIL_ATTACHMENT_OPTIMAL, DEPTH_STENCIL_READ_ONLY_OPTIMAL or GENERAL."); 13972 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 13973 m_errorMonitor->VerifyFound(); 13974 // For this error we need a valid renderpass so create default one 13975 attach.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; 13976 attach.attachment = 0; 13977 attach_desc.format = depth_format; 13978 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; 13979 attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; 13980 attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; 13981 attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; 13982 // Can't do a CLEAR load on READ_ONLY initialLayout 13983 attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 13984 attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; 13985 attach_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 13986 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 13987 "with invalid first layout VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL"); 13988 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 13989 m_errorMonitor->VerifyFound(); 13990 13991 vkFreeMemory(m_device->device(), src_image_mem, NULL); 13992 vkFreeMemory(m_device->device(), dst_image_mem, NULL); 13993 vkFreeMemory(m_device->device(), depth_image_mem, NULL); 13994 vkDestroyImage(m_device->device(), src_image, NULL); 13995 vkDestroyImage(m_device->device(), dst_image, NULL); 13996 vkDestroyImage(m_device->device(), depth_image, NULL); 13997 } 13998 13999 TEST_F(VkLayerTest, InvalidStorageImageLayout) { 14000 TEST_DESCRIPTION("Attempt to update a STORAGE_IMAGE descriptor w/o GENERAL layout."); 14001 14002 ASSERT_NO_FATAL_FAILURE(Init()); 14003 14004 const VkFormat tex_format = VK_FORMAT_R8G8B8A8_UNORM; 14005 VkImageTiling tiling; 14006 VkFormatProperties format_properties; 14007 vkGetPhysicalDeviceFormatProperties(gpu(), tex_format, &format_properties); 14008 if (format_properties.linearTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) { 14009 tiling = VK_IMAGE_TILING_LINEAR; 14010 } else if (format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) { 14011 tiling = VK_IMAGE_TILING_OPTIMAL; 14012 } else { 14013 printf(" Device does not support VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; skipped.\n"); 14014 return; 14015 } 14016 14017 OneOffDescriptorSet ds(m_device, { 14018 {0, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}, 14019 }); 14020 14021 VkImageObj image(m_device); 14022 image.Init(32, 32, 1, tex_format, VK_IMAGE_USAGE_STORAGE_BIT, tiling, 0); 14023 ASSERT_TRUE(image.initialized()); 14024 VkImageView view = image.targetView(tex_format); 14025 14026 VkDescriptorImageInfo image_info = {}; 14027 image_info.imageView = view; 14028 image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 14029 14030 VkWriteDescriptorSet descriptor_write = {}; 14031 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 14032 descriptor_write.dstSet = ds.set_; 14033 descriptor_write.dstBinding = 0; 14034 descriptor_write.descriptorCount = 1; 14035 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; 14036 descriptor_write.pImageInfo = &image_info; 14037 14038 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 14039 " of VK_DESCRIPTOR_TYPE_STORAGE_IMAGE type is being updated with layout " 14040 "VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL but according to spec "); 14041 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 14042 m_errorMonitor->VerifyFound(); 14043 } 14044 14045 TEST_F(VkLayerTest, NonSimultaneousSecondaryMarksPrimary) { 14046 ASSERT_NO_FATAL_FAILURE(Init()); 14047 const char *simultaneous_use_message = 14048 "does not have VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set and will cause primary command buffer"; 14049 14050 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); 14051 14052 secondary.begin(); 14053 secondary.end(); 14054 14055 VkCommandBufferBeginInfo cbbi = { 14056 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 14057 nullptr, 14058 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, 14059 nullptr, 14060 }; 14061 14062 m_commandBuffer->begin(&cbbi); 14063 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, simultaneous_use_message); 14064 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle()); 14065 m_errorMonitor->VerifyFound(); 14066 m_commandBuffer->end(); 14067 } 14068 14069 TEST_F(VkLayerTest, SimultaneousUseSecondaryTwoExecutes) { 14070 ASSERT_NO_FATAL_FAILURE(Init()); 14071 14072 const char *simultaneous_use_message = "without VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set!"; 14073 14074 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); 14075 14076 VkCommandBufferInheritanceInfo inh = { 14077 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 14078 nullptr, 14079 }; 14080 VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, &inh}; 14081 14082 secondary.begin(&cbbi); 14083 secondary.end(); 14084 14085 m_commandBuffer->begin(); 14086 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle()); 14087 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, simultaneous_use_message); 14088 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle()); 14089 m_errorMonitor->VerifyFound(); 14090 m_commandBuffer->end(); 14091 } 14092 14093 TEST_F(VkLayerTest, SimultaneousUseSecondarySingleExecute) { 14094 ASSERT_NO_FATAL_FAILURE(Init()); 14095 14096 // variation on previous test executing the same CB twice in the same 14097 // CmdExecuteCommands call 14098 14099 const char *simultaneous_use_message = "without VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set!"; 14100 14101 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); 14102 14103 VkCommandBufferInheritanceInfo inh = { 14104 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 14105 nullptr, 14106 }; 14107 VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, &inh}; 14108 14109 secondary.begin(&cbbi); 14110 secondary.end(); 14111 14112 m_commandBuffer->begin(); 14113 VkCommandBuffer cbs[] = {secondary.handle(), secondary.handle()}; 14114 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, simultaneous_use_message); 14115 vkCmdExecuteCommands(m_commandBuffer->handle(), 2, cbs); 14116 m_errorMonitor->VerifyFound(); 14117 m_commandBuffer->end(); 14118 } 14119 14120 TEST_F(VkLayerTest, SimultaneousUseOneShot) { 14121 TEST_DESCRIPTION("Submit the same command buffer twice in one submit looking for simultaneous use and one time submit errors"); 14122 const char *simultaneous_use_message = "is already in use and is not marked for simultaneous use"; 14123 const char *one_shot_message = "VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has been submitted"; 14124 ASSERT_NO_FATAL_FAILURE(Init()); 14125 14126 VkCommandBuffer cmd_bufs[2]; 14127 VkCommandBufferAllocateInfo alloc_info; 14128 alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 14129 alloc_info.pNext = NULL; 14130 alloc_info.commandBufferCount = 2; 14131 alloc_info.commandPool = m_commandPool->handle(); 14132 alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 14133 vkAllocateCommandBuffers(m_device->device(), &alloc_info, cmd_bufs); 14134 14135 VkCommandBufferBeginInfo cb_binfo; 14136 cb_binfo.pNext = NULL; 14137 cb_binfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 14138 cb_binfo.pInheritanceInfo = VK_NULL_HANDLE; 14139 cb_binfo.flags = 0; 14140 vkBeginCommandBuffer(cmd_bufs[0], &cb_binfo); 14141 VkViewport viewport = {0, 0, 16, 16, 0, 1}; 14142 vkCmdSetViewport(cmd_bufs[0], 0, 1, &viewport); 14143 vkEndCommandBuffer(cmd_bufs[0]); 14144 VkCommandBuffer duplicates[2] = {cmd_bufs[0], cmd_bufs[0]}; 14145 14146 VkSubmitInfo submit_info = {}; 14147 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 14148 submit_info.commandBufferCount = 2; 14149 submit_info.pCommandBuffers = duplicates; 14150 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, simultaneous_use_message); 14151 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 14152 m_errorMonitor->VerifyFound(); 14153 vkQueueWaitIdle(m_device->m_queue); 14154 14155 // Set one time use and now look for one time submit 14156 duplicates[0] = duplicates[1] = cmd_bufs[1]; 14157 cb_binfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT | VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; 14158 vkBeginCommandBuffer(cmd_bufs[1], &cb_binfo); 14159 vkCmdSetViewport(cmd_bufs[1], 0, 1, &viewport); 14160 vkEndCommandBuffer(cmd_bufs[1]); 14161 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, one_shot_message); 14162 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 14163 m_errorMonitor->VerifyFound(); 14164 vkQueueWaitIdle(m_device->m_queue); 14165 } 14166 14167 TEST_F(VkLayerTest, StageMaskGsTsEnabled) { 14168 TEST_DESCRIPTION( 14169 "Attempt to use a stageMask w/ geometry shader and tesselation shader bits enabled when those features are disabled on the " 14170 "device."); 14171 14172 ASSERT_NO_FATAL_FAILURE(Init()); 14173 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 14174 14175 std::vector<const char *> device_extension_names; 14176 auto features = m_device->phy().features(); 14177 // Make sure gs & ts are disabled 14178 features.geometryShader = false; 14179 features.tessellationShader = false; 14180 // The sacrificial device object 14181 VkDeviceObj test_device(0, gpu(), device_extension_names, &features); 14182 14183 VkCommandPoolCreateInfo pool_create_info{}; 14184 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 14185 pool_create_info.queueFamilyIndex = test_device.graphics_queue_node_index_; 14186 14187 VkCommandPool command_pool; 14188 vkCreateCommandPool(test_device.handle(), &pool_create_info, nullptr, &command_pool); 14189 14190 VkCommandBufferAllocateInfo cmd = {}; 14191 cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 14192 cmd.pNext = NULL; 14193 cmd.commandPool = command_pool; 14194 cmd.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 14195 cmd.commandBufferCount = 1; 14196 14197 VkCommandBuffer cmd_buffer; 14198 VkResult err = vkAllocateCommandBuffers(test_device.handle(), &cmd, &cmd_buffer); 14199 ASSERT_VK_SUCCESS(err); 14200 14201 VkEvent event; 14202 VkEventCreateInfo evci = {}; 14203 evci.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 14204 VkResult result = vkCreateEvent(test_device.handle(), &evci, NULL, &event); 14205 ASSERT_VK_SUCCESS(result); 14206 14207 VkCommandBufferBeginInfo cbbi = {}; 14208 cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 14209 vkBeginCommandBuffer(cmd_buffer, &cbbi); 14210 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1d4008fc); 14211 vkCmdSetEvent(cmd_buffer, event, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT); 14212 m_errorMonitor->VerifyFound(); 14213 14214 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1d4008fe); 14215 vkCmdSetEvent(cmd_buffer, event, VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT); 14216 m_errorMonitor->VerifyFound(); 14217 14218 vkDestroyEvent(test_device.handle(), event, NULL); 14219 vkDestroyCommandPool(test_device.handle(), command_pool, NULL); 14220 } 14221 14222 TEST_F(VkLayerTest, EventInUseDestroyedSignaled) { 14223 ASSERT_NO_FATAL_FAILURE(Init()); 14224 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 14225 14226 m_commandBuffer->begin(); 14227 14228 VkEvent event; 14229 VkEventCreateInfo event_create_info = {}; 14230 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 14231 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event); 14232 vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); 14233 14234 m_commandBuffer->end(); 14235 vkDestroyEvent(m_device->device(), event, nullptr); 14236 14237 VkSubmitInfo submit_info = {}; 14238 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 14239 submit_info.commandBufferCount = 1; 14240 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 14241 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is invalid because bound"); 14242 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 14243 m_errorMonitor->VerifyFound(); 14244 } 14245 14246 TEST_F(VkLayerTest, InUseDestroyedSignaled) { 14247 TEST_DESCRIPTION( 14248 "Use vkCmdExecuteCommands with invalid state in primary and secondary command buffers. Delete objects that are inuse. Call " 14249 "VkQueueSubmit with an event that has been deleted."); 14250 14251 ASSERT_NO_FATAL_FAILURE(Init()); 14252 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 14253 14254 m_errorMonitor->ExpectSuccess(); 14255 14256 VkSemaphoreCreateInfo semaphore_create_info = {}; 14257 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 14258 VkSemaphore semaphore; 14259 ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore)); 14260 VkFenceCreateInfo fence_create_info = {}; 14261 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 14262 VkFence fence; 14263 ASSERT_VK_SUCCESS(vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence)); 14264 14265 OneOffDescriptorSet ds(m_device, { 14266 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, 14267 }); 14268 14269 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); 14270 14271 VkDescriptorBufferInfo buffer_info = {}; 14272 buffer_info.buffer = buffer_test.GetBuffer(); 14273 buffer_info.offset = 0; 14274 buffer_info.range = 1024; 14275 14276 VkWriteDescriptorSet write_descriptor_set = {}; 14277 write_descriptor_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 14278 write_descriptor_set.dstSet = ds.set_; 14279 write_descriptor_set.descriptorCount = 1; 14280 write_descriptor_set.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 14281 write_descriptor_set.pBufferInfo = &buffer_info; 14282 14283 vkUpdateDescriptorSets(m_device->device(), 1, &write_descriptor_set, 0, nullptr); 14284 14285 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 14286 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 14287 14288 VkPipelineObj pipe(m_device); 14289 pipe.AddDefaultColorAttachment(); 14290 pipe.AddShader(&vs); 14291 pipe.AddShader(&fs); 14292 14293 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_}); 14294 14295 pipe.CreateVKPipeline(pipeline_layout.handle(), m_renderPass); 14296 14297 VkEvent event; 14298 VkEventCreateInfo event_create_info = {}; 14299 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 14300 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event); 14301 14302 m_commandBuffer->begin(); 14303 14304 vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); 14305 14306 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 14307 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &ds.set_, 0, 14308 NULL); 14309 14310 m_commandBuffer->end(); 14311 14312 VkSubmitInfo submit_info = {}; 14313 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 14314 submit_info.commandBufferCount = 1; 14315 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 14316 submit_info.signalSemaphoreCount = 1; 14317 submit_info.pSignalSemaphores = &semaphore; 14318 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence); 14319 m_errorMonitor->Reset(); // resume logmsg processing 14320 14321 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_24c008f2); 14322 vkDestroyEvent(m_device->device(), event, nullptr); 14323 m_errorMonitor->VerifyFound(); 14324 14325 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_268008e2); 14326 vkDestroySemaphore(m_device->device(), semaphore, nullptr); 14327 m_errorMonitor->VerifyFound(); 14328 14329 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Fence 0x"); 14330 vkDestroyFence(m_device->device(), fence, nullptr); 14331 m_errorMonitor->VerifyFound(); 14332 14333 vkQueueWaitIdle(m_device->m_queue); 14334 m_errorMonitor->SetUnexpectedError("If semaphore is not VK_NULL_HANDLE, semaphore must be a valid VkSemaphore handle"); 14335 m_errorMonitor->SetUnexpectedError("Unable to remove Semaphore obj"); 14336 vkDestroySemaphore(m_device->device(), semaphore, nullptr); 14337 m_errorMonitor->SetUnexpectedError("If fence is not VK_NULL_HANDLE, fence must be a valid VkFence handle"); 14338 m_errorMonitor->SetUnexpectedError("Unable to remove Fence obj"); 14339 vkDestroyFence(m_device->device(), fence, nullptr); 14340 m_errorMonitor->SetUnexpectedError("If event is not VK_NULL_HANDLE, event must be a valid VkEvent handle"); 14341 m_errorMonitor->SetUnexpectedError("Unable to remove Event obj"); 14342 vkDestroyEvent(m_device->device(), event, nullptr); 14343 } 14344 14345 TEST_F(VkLayerTest, QueryPoolInUseDestroyedSignaled) { 14346 TEST_DESCRIPTION("Delete in-use query pool."); 14347 14348 ASSERT_NO_FATAL_FAILURE(Init()); 14349 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 14350 14351 VkQueryPool query_pool; 14352 VkQueryPoolCreateInfo query_pool_ci{}; 14353 query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; 14354 query_pool_ci.queryType = VK_QUERY_TYPE_TIMESTAMP; 14355 query_pool_ci.queryCount = 1; 14356 vkCreateQueryPool(m_device->device(), &query_pool_ci, nullptr, &query_pool); 14357 m_commandBuffer->begin(); 14358 // Reset query pool to create binding with cmd buffer 14359 vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1); 14360 14361 m_commandBuffer->end(); 14362 14363 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_2fa00664); 14364 uint32_t data_space[16]; 14365 m_errorMonitor->SetUnexpectedError("Cannot get query results on queryPool"); 14366 vkGetQueryPoolResults(m_device->handle(), query_pool, 0, 1, sizeof(data_space), &data_space, sizeof(uint32_t), 14367 VK_QUERY_RESULT_PARTIAL_BIT); 14368 m_errorMonitor->VerifyFound(); 14369 14370 VkSubmitInfo submit_info = {}; 14371 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 14372 submit_info.commandBufferCount = 1; 14373 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 14374 // Submit cmd buffer and then destroy query pool while in-flight 14375 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 14376 14377 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_26200632); 14378 vkDestroyQueryPool(m_device->handle(), query_pool, NULL); 14379 m_errorMonitor->VerifyFound(); 14380 14381 vkQueueWaitIdle(m_device->m_queue); 14382 // Now that cmd buffer done we can safely destroy query_pool 14383 m_errorMonitor->SetUnexpectedError("If queryPool is not VK_NULL_HANDLE, queryPool must be a valid VkQueryPool handle"); 14384 m_errorMonitor->SetUnexpectedError("Unable to remove QueryPool obj"); 14385 vkDestroyQueryPool(m_device->handle(), query_pool, NULL); 14386 } 14387 14388 TEST_F(VkLayerTest, PipelineInUseDestroyedSignaled) { 14389 TEST_DESCRIPTION("Delete in-use pipeline."); 14390 14391 ASSERT_NO_FATAL_FAILURE(Init()); 14392 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 14393 14394 const VkPipelineLayoutObj pipeline_layout(m_device); 14395 14396 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_25c005fa); 14397 // Create PSO to be used for draw-time errors below 14398 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 14399 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 14400 // Store pipeline handle so we can actually delete it before test finishes 14401 VkPipeline delete_this_pipeline; 14402 { // Scope pipeline so it will be auto-deleted 14403 VkPipelineObj pipe(m_device); 14404 pipe.AddShader(&vs); 14405 pipe.AddShader(&fs); 14406 pipe.AddDefaultColorAttachment(); 14407 pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 14408 delete_this_pipeline = pipe.handle(); 14409 14410 m_commandBuffer->begin(); 14411 // Bind pipeline to cmd buffer 14412 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 14413 14414 m_commandBuffer->end(); 14415 14416 VkSubmitInfo submit_info = {}; 14417 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 14418 submit_info.commandBufferCount = 1; 14419 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 14420 // Submit cmd buffer and then pipeline destroyed while in-flight 14421 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 14422 } // Pipeline deletion triggered here 14423 m_errorMonitor->VerifyFound(); 14424 // Make sure queue finished and then actually delete pipeline 14425 vkQueueWaitIdle(m_device->m_queue); 14426 m_errorMonitor->SetUnexpectedError("If pipeline is not VK_NULL_HANDLE, pipeline must be a valid VkPipeline handle"); 14427 m_errorMonitor->SetUnexpectedError("Unable to remove Pipeline obj"); 14428 vkDestroyPipeline(m_device->handle(), delete_this_pipeline, nullptr); 14429 } 14430 14431 TEST_F(VkLayerTest, CreateImageViewBreaksParameterCompatibilityRequirements) { 14432 TEST_DESCRIPTION( 14433 "Attempts to create an Image View with a view type that does not match the image type it is being created from."); 14434 14435 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 14436 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) { 14437 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME); 14438 } 14439 ASSERT_NO_FATAL_FAILURE(InitState()); 14440 14441 VkPhysicalDeviceMemoryProperties memProps; 14442 vkGetPhysicalDeviceMemoryProperties(m_device->phy().handle(), &memProps); 14443 14444 // Test mismatch detection for image of type VK_IMAGE_TYPE_1D 14445 VkImageCreateInfo imgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 14446 nullptr, 14447 VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, 14448 VK_IMAGE_TYPE_1D, 14449 VK_FORMAT_R8G8B8A8_UNORM, 14450 {1, 1, 1}, 14451 1, 14452 1, 14453 VK_SAMPLE_COUNT_1_BIT, 14454 VK_IMAGE_TILING_OPTIMAL, 14455 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 14456 VK_SHARING_MODE_EXCLUSIVE, 14457 0, 14458 nullptr, 14459 VK_IMAGE_LAYOUT_UNDEFINED}; 14460 VkImageObj image1D(m_device); 14461 image1D.init(&imgInfo); 14462 ASSERT_TRUE(image1D.initialized()); 14463 14464 // Initialize VkImageViewCreateInfo with mismatched viewType 14465 VkImageView imageView; 14466 VkImageViewCreateInfo ivci = {}; 14467 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 14468 ivci.image = image1D.handle(); 14469 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; 14470 ivci.format = VK_FORMAT_R8G8B8A8_UNORM; 14471 ivci.subresourceRange.layerCount = 1; 14472 ivci.subresourceRange.baseMipLevel = 0; 14473 ivci.subresourceRange.levelCount = 1; 14474 ivci.subresourceRange.baseArrayLayer = 0; 14475 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14476 14477 // Test for error message 14478 m_errorMonitor->SetDesiredFailureMsg( 14479 VK_DEBUG_REPORT_ERROR_BIT_EXT, 14480 "vkCreateImageView(): pCreateInfo->viewType VK_IMAGE_VIEW_TYPE_2D is not compatible with image"); 14481 vkCreateImageView(m_device->device(), &ivci, NULL, &imageView); 14482 m_errorMonitor->VerifyFound(); 14483 14484 // Test mismatch detection for image of type VK_IMAGE_TYPE_2D 14485 imgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 14486 nullptr, 14487 VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, 14488 VK_IMAGE_TYPE_2D, 14489 VK_FORMAT_R8G8B8A8_UNORM, 14490 {1, 1, 1}, 14491 1, 14492 6, 14493 VK_SAMPLE_COUNT_1_BIT, 14494 VK_IMAGE_TILING_OPTIMAL, 14495 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 14496 VK_SHARING_MODE_EXCLUSIVE, 14497 0, 14498 nullptr, 14499 VK_IMAGE_LAYOUT_UNDEFINED}; 14500 VkImageObj image2D(m_device); 14501 image2D.init(&imgInfo); 14502 ASSERT_TRUE(image2D.initialized()); 14503 14504 // Initialize VkImageViewCreateInfo with mismatched viewType 14505 ivci = {}; 14506 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 14507 ivci.image = image2D.handle(); 14508 ivci.viewType = VK_IMAGE_VIEW_TYPE_3D; 14509 ivci.format = VK_FORMAT_R8G8B8A8_UNORM; 14510 ivci.subresourceRange.layerCount = 1; 14511 ivci.subresourceRange.baseMipLevel = 0; 14512 ivci.subresourceRange.levelCount = 1; 14513 ivci.subresourceRange.baseArrayLayer = 0; 14514 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14515 14516 // Test for error message 14517 m_errorMonitor->SetDesiredFailureMsg( 14518 VK_DEBUG_REPORT_ERROR_BIT_EXT, 14519 "vkCreateImageView(): pCreateInfo->viewType VK_IMAGE_VIEW_TYPE_3D is not compatible with image"); 14520 vkCreateImageView(m_device->device(), &ivci, NULL, &imageView); 14521 m_errorMonitor->VerifyFound(); 14522 14523 // Change VkImageViewCreateInfo to different mismatched viewType 14524 ivci.viewType = VK_IMAGE_VIEW_TYPE_CUBE; 14525 ivci.subresourceRange.layerCount = 6; 14526 14527 // Test for error message 14528 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac007d6); 14529 vkCreateImageView(m_device->device(), &ivci, NULL, &imageView); 14530 m_errorMonitor->VerifyFound(); 14531 14532 // Test mismatch detection for image of type VK_IMAGE_TYPE_3D 14533 imgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 14534 nullptr, 14535 VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, 14536 VK_IMAGE_TYPE_3D, 14537 VK_FORMAT_R8G8B8A8_UNORM, 14538 {1, 1, 1}, 14539 1, 14540 1, 14541 VK_SAMPLE_COUNT_1_BIT, 14542 VK_IMAGE_TILING_OPTIMAL, 14543 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 14544 VK_SHARING_MODE_EXCLUSIVE, 14545 0, 14546 nullptr, 14547 VK_IMAGE_LAYOUT_UNDEFINED}; 14548 VkImageObj image3D(m_device); 14549 image3D.init(&imgInfo); 14550 ASSERT_TRUE(image3D.initialized()); 14551 14552 // Initialize VkImageViewCreateInfo with mismatched viewType 14553 ivci = {}; 14554 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 14555 ivci.image = image3D.handle(); 14556 ivci.viewType = VK_IMAGE_VIEW_TYPE_1D; 14557 ivci.format = VK_FORMAT_R8G8B8A8_UNORM; 14558 ivci.subresourceRange.layerCount = 1; 14559 ivci.subresourceRange.baseMipLevel = 0; 14560 ivci.subresourceRange.levelCount = 1; 14561 ivci.subresourceRange.baseArrayLayer = 0; 14562 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14563 14564 // Test for error message 14565 m_errorMonitor->SetDesiredFailureMsg( 14566 VK_DEBUG_REPORT_ERROR_BIT_EXT, 14567 "vkCreateImageView(): pCreateInfo->viewType VK_IMAGE_VIEW_TYPE_1D is not compatible with image"); 14568 vkCreateImageView(m_device->device(), &ivci, NULL, &imageView); 14569 m_errorMonitor->VerifyFound(); 14570 14571 // Change VkImageViewCreateInfo to different mismatched viewType 14572 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; 14573 14574 // Test for error message 14575 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) { 14576 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac007da); 14577 } else { 14578 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac007fa); 14579 } 14580 14581 vkCreateImageView(m_device->device(), &ivci, NULL, &imageView); 14582 m_errorMonitor->VerifyFound(); 14583 14584 // Check if the device can make the image required for this test case. 14585 VkImageFormatProperties formProps = {{0, 0, 0}, 0, 0, 0, 0}; 14586 VkResult res = vkGetPhysicalDeviceImageFormatProperties( 14587 m_device->phy().handle(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_3D, VK_IMAGE_TILING_OPTIMAL, 14588 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 14589 VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR | VK_IMAGE_CREATE_SPARSE_BINDING_BIT, 14590 &formProps); 14591 14592 // If not, skip this part of the test. 14593 if (res || !m_device->phy().features().sparseBinding || 14594 !DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) { 14595 return; 14596 } 14597 14598 // Initialize VkImageCreateInfo with VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR and VK_IMAGE_CREATE_SPARSE_BINDING_BIT which 14599 // are incompatible create flags. 14600 imgInfo = { 14601 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 14602 nullptr, 14603 VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR | VK_IMAGE_CREATE_SPARSE_BINDING_BIT, 14604 VK_IMAGE_TYPE_3D, 14605 VK_FORMAT_R8G8B8A8_UNORM, 14606 {1, 1, 1}, 14607 1, 14608 1, 14609 VK_SAMPLE_COUNT_1_BIT, 14610 VK_IMAGE_TILING_OPTIMAL, 14611 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 14612 VK_SHARING_MODE_EXCLUSIVE, 14613 0, 14614 nullptr, 14615 VK_IMAGE_LAYOUT_UNDEFINED}; 14616 VkImage imageSparse; 14617 14618 // Creating a sparse image means we should not bind memory to it. 14619 res = vkCreateImage(m_device->device(), &imgInfo, NULL, &imageSparse); 14620 ASSERT_FALSE(res); 14621 14622 // Initialize VkImageViewCreateInfo to create a view that will attempt to utilize VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR. 14623 ivci = {}; 14624 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 14625 ivci.image = imageSparse; 14626 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; 14627 ivci.format = VK_FORMAT_R8G8B8A8_UNORM; 14628 ivci.subresourceRange.layerCount = 1; 14629 ivci.subresourceRange.baseMipLevel = 0; 14630 ivci.subresourceRange.levelCount = 1; 14631 ivci.subresourceRange.baseArrayLayer = 0; 14632 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14633 14634 // Test for error message 14635 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 14636 " when the VK_IMAGE_CREATE_SPARSE_BINDING_BIT, VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, or " 14637 "VK_IMAGE_CREATE_SPARSE_ALIASED_BIT flags are enabled."); 14638 vkCreateImageView(m_device->device(), &ivci, NULL, &imageView); 14639 m_errorMonitor->VerifyFound(); 14640 14641 // Clean up 14642 vkDestroyImage(m_device->device(), imageSparse, nullptr); 14643 } 14644 14645 TEST_F(VkLayerTest, CreateImageViewFormatFeatureMismatch) { 14646 TEST_DESCRIPTION("Create view with a format that does not have the same features as the image format."); 14647 14648 if (!EnableDeviceProfileLayer()) return; 14649 14650 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 14651 ASSERT_NO_FATAL_FAILURE(InitState()); 14652 14653 PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr; 14654 PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr; 14655 14656 // Load required functions 14657 if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) { 14658 return; 14659 } 14660 14661 // List of features to be tested 14662 VkFormatFeatureFlagBits features[] = {VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT, 14663 VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT}; 14664 uint32_t feature_count = 4; 14665 // List of usage cases for each feature test 14666 VkImageUsageFlags usages[] = {VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 14667 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT}; 14668 // List of errors that will be thrown in order of tests run 14669 UNIQUE_VALIDATION_ERROR_CODE optimal_error_codes[] = { 14670 VALIDATION_ERROR_0ac007ea, 14671 VALIDATION_ERROR_0ac007ec, 14672 VALIDATION_ERROR_0ac007ee, 14673 VALIDATION_ERROR_0ac007f0, 14674 }; 14675 14676 VkFormatProperties formatProps; 14677 14678 // First three tests 14679 uint32_t i = 0; 14680 for (i = 0; i < (feature_count - 1); i++) { 14681 // Modify formats to have mismatched features 14682 14683 // Format for image 14684 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32G32B32A32_UINT, &formatProps); 14685 formatProps.optimalTilingFeatures |= features[i]; 14686 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32G32B32A32_UINT, formatProps); 14687 14688 memset(&formatProps, 0, sizeof(formatProps)); 14689 14690 // Format for view 14691 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32G32B32A32_SINT, &formatProps); 14692 formatProps.optimalTilingFeatures = features[(i + 1) % feature_count]; 14693 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32G32B32A32_SINT, formatProps); 14694 14695 // Create image with modified format 14696 VkImageCreateInfo imgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 14697 nullptr, 14698 VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, 14699 VK_IMAGE_TYPE_2D, 14700 VK_FORMAT_R32G32B32A32_UINT, 14701 {1, 1, 1}, 14702 1, 14703 1, 14704 VK_SAMPLE_COUNT_1_BIT, 14705 VK_IMAGE_TILING_OPTIMAL, 14706 usages[i], 14707 VK_SHARING_MODE_EXCLUSIVE, 14708 0, 14709 nullptr, 14710 VK_IMAGE_LAYOUT_UNDEFINED}; 14711 VkImageObj image(m_device); 14712 image.init(&imgInfo); 14713 ASSERT_TRUE(image.initialized()); 14714 14715 VkImageView imageView; 14716 14717 // Initialize VkImageViewCreateInfo with modified format 14718 VkImageViewCreateInfo ivci = {}; 14719 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 14720 ivci.image = image.handle(); 14721 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; 14722 ivci.format = VK_FORMAT_R32G32B32A32_SINT; 14723 ivci.subresourceRange.layerCount = 1; 14724 ivci.subresourceRange.baseMipLevel = 0; 14725 ivci.subresourceRange.levelCount = 1; 14726 ivci.subresourceRange.baseArrayLayer = 0; 14727 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14728 14729 // Test for error message 14730 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, optimal_error_codes[i]); 14731 VkResult res = vkCreateImageView(m_device->device(), &ivci, NULL, &imageView); 14732 m_errorMonitor->VerifyFound(); 14733 14734 if (!res) { 14735 vkDestroyImageView(m_device->device(), imageView, nullptr); 14736 } 14737 } 14738 14739 // Test for VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT. Needs special formats 14740 14741 // Only run this test if format supported 14742 if (!ImageFormatIsSupported(gpu(), VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_TILING_OPTIMAL)) { 14743 printf(" VK_FORMAT_D24_UNORM_S8_UINT format not supported - skipped.\n"); 14744 return; 14745 } 14746 // Modify formats to have mismatched features 14747 14748 // Format for image 14749 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_D24_UNORM_S8_UINT, &formatProps); 14750 formatProps.optimalTilingFeatures |= features[i]; 14751 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_D24_UNORM_S8_UINT, formatProps); 14752 14753 memset(&formatProps, 0, sizeof(formatProps)); 14754 14755 // Format for view 14756 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_D32_SFLOAT_S8_UINT, &formatProps); 14757 formatProps.optimalTilingFeatures = features[(i + 1) % feature_count]; 14758 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_D32_SFLOAT_S8_UINT, formatProps); 14759 14760 // Create image with modified format 14761 VkImageCreateInfo imgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 14762 nullptr, 14763 VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, 14764 VK_IMAGE_TYPE_2D, 14765 VK_FORMAT_D24_UNORM_S8_UINT, 14766 {1, 1, 1}, 14767 1, 14768 1, 14769 VK_SAMPLE_COUNT_1_BIT, 14770 VK_IMAGE_TILING_OPTIMAL, 14771 usages[i], 14772 VK_SHARING_MODE_EXCLUSIVE, 14773 0, 14774 nullptr, 14775 VK_IMAGE_LAYOUT_UNDEFINED}; 14776 VkImageObj image(m_device); 14777 image.init(&imgInfo); 14778 ASSERT_TRUE(image.initialized()); 14779 14780 VkImageView imageView; 14781 14782 // Initialize VkImageViewCreateInfo with modified format 14783 VkImageViewCreateInfo ivci = {}; 14784 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 14785 ivci.image = image.handle(); 14786 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; 14787 ivci.format = VK_FORMAT_D32_SFLOAT_S8_UINT; 14788 ivci.subresourceRange.layerCount = 1; 14789 ivci.subresourceRange.baseMipLevel = 0; 14790 ivci.subresourceRange.levelCount = 1; 14791 ivci.subresourceRange.baseArrayLayer = 0; 14792 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; 14793 14794 // Test for error message 14795 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, optimal_error_codes[i]); 14796 VkResult res = vkCreateImageView(m_device->device(), &ivci, NULL, &imageView); 14797 m_errorMonitor->VerifyFound(); 14798 14799 if (!res) { 14800 vkDestroyImageView(m_device->device(), imageView, nullptr); 14801 } 14802 } 14803 14804 TEST_F(VkLayerTest, ImageViewInUseDestroyedSignaled) { 14805 TEST_DESCRIPTION("Delete in-use imageView."); 14806 14807 ASSERT_NO_FATAL_FAILURE(Init()); 14808 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 14809 14810 OneOffDescriptorSet ds(m_device, { 14811 {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}, 14812 }); 14813 14814 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo(); 14815 VkSampler sampler; 14816 14817 VkResult err; 14818 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 14819 ASSERT_VK_SUCCESS(err); 14820 14821 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_}); 14822 14823 VkImageObj image(m_device); 14824 image.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 14825 ASSERT_TRUE(image.initialized()); 14826 14827 VkImageView view; 14828 VkImageViewCreateInfo ivci = {}; 14829 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 14830 ivci.image = image.handle(); 14831 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; 14832 ivci.format = VK_FORMAT_R8G8B8A8_UNORM; 14833 ivci.subresourceRange.layerCount = 1; 14834 ivci.subresourceRange.baseMipLevel = 0; 14835 ivci.subresourceRange.levelCount = 1; 14836 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14837 14838 err = vkCreateImageView(m_device->device(), &ivci, NULL, &view); 14839 ASSERT_VK_SUCCESS(err); 14840 14841 VkDescriptorImageInfo image_info{}; 14842 image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 14843 image_info.imageView = view; 14844 image_info.sampler = sampler; 14845 14846 VkWriteDescriptorSet descriptor_write = {}; 14847 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 14848 descriptor_write.dstSet = ds.set_; 14849 descriptor_write.dstBinding = 0; 14850 descriptor_write.descriptorCount = 1; 14851 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 14852 descriptor_write.pImageInfo = &image_info; 14853 14854 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 14855 14856 // Create PSO to use the sampler 14857 char const *vsSource = 14858 "#version 450\n" 14859 "\n" 14860 "void main(){\n" 14861 " gl_Position = vec4(1);\n" 14862 "}\n"; 14863 char const *fsSource = 14864 "#version 450\n" 14865 "\n" 14866 "layout(set=0, binding=0) uniform sampler2D s;\n" 14867 "layout(location=0) out vec4 x;\n" 14868 "void main(){\n" 14869 " x = texture(s, vec2(1));\n" 14870 "}\n"; 14871 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 14872 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 14873 VkPipelineObj pipe(m_device); 14874 pipe.AddShader(&vs); 14875 pipe.AddShader(&fs); 14876 pipe.AddDefaultColorAttachment(); 14877 pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 14878 14879 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_25400804); 14880 14881 m_commandBuffer->begin(); 14882 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 14883 // Bind pipeline to cmd buffer 14884 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 14885 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &ds.set_, 0, 14886 nullptr); 14887 14888 VkViewport viewport = {0, 0, 16, 16, 0, 1}; 14889 VkRect2D scissor = {{0, 0}, {16, 16}}; 14890 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 14891 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 14892 14893 m_commandBuffer->Draw(1, 0, 0, 0); 14894 m_commandBuffer->EndRenderPass(); 14895 m_commandBuffer->end(); 14896 // Submit cmd buffer then destroy sampler 14897 VkSubmitInfo submit_info = {}; 14898 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 14899 submit_info.commandBufferCount = 1; 14900 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 14901 // Submit cmd buffer and then destroy imageView while in-flight 14902 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 14903 14904 vkDestroyImageView(m_device->device(), view, nullptr); 14905 m_errorMonitor->VerifyFound(); 14906 vkQueueWaitIdle(m_device->m_queue); 14907 // Now we can actually destroy imageView 14908 m_errorMonitor->SetUnexpectedError("If imageView is not VK_NULL_HANDLE, imageView must be a valid VkImageView handle"); 14909 m_errorMonitor->SetUnexpectedError("Unable to remove ImageView obj"); 14910 vkDestroyImageView(m_device->device(), view, NULL); 14911 vkDestroySampler(m_device->device(), sampler, nullptr); 14912 } 14913 14914 TEST_F(VkLayerTest, BufferViewInUseDestroyedSignaled) { 14915 TEST_DESCRIPTION("Delete in-use bufferView."); 14916 14917 ASSERT_NO_FATAL_FAILURE(Init()); 14918 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 14919 14920 OneOffDescriptorSet ds(m_device, { 14921 {0, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}, 14922 }); 14923 14924 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_}); 14925 14926 VkBuffer buffer; 14927 uint32_t queue_family_index = 0; 14928 VkBufferCreateInfo buffer_create_info = {}; 14929 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 14930 buffer_create_info.size = 1024; 14931 buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; 14932 buffer_create_info.queueFamilyIndexCount = 1; 14933 buffer_create_info.pQueueFamilyIndices = &queue_family_index; 14934 14935 VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer); 14936 ASSERT_VK_SUCCESS(err); 14937 14938 VkMemoryRequirements memory_reqs; 14939 VkDeviceMemory buffer_memory; 14940 14941 VkMemoryAllocateInfo memory_info = {}; 14942 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 14943 memory_info.allocationSize = 0; 14944 memory_info.memoryTypeIndex = 0; 14945 14946 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs); 14947 memory_info.allocationSize = memory_reqs.size; 14948 bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 14949 ASSERT_TRUE(pass); 14950 14951 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory); 14952 ASSERT_VK_SUCCESS(err); 14953 err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0); 14954 ASSERT_VK_SUCCESS(err); 14955 14956 VkBufferView view; 14957 VkBufferViewCreateInfo bvci = {}; 14958 bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; 14959 bvci.buffer = buffer; 14960 bvci.format = VK_FORMAT_R32_SFLOAT; 14961 bvci.range = VK_WHOLE_SIZE; 14962 14963 err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view); 14964 ASSERT_VK_SUCCESS(err); 14965 14966 VkWriteDescriptorSet descriptor_write = {}; 14967 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 14968 descriptor_write.dstSet = ds.set_; 14969 descriptor_write.dstBinding = 0; 14970 descriptor_write.descriptorCount = 1; 14971 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 14972 descriptor_write.pTexelBufferView = &view; 14973 14974 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 14975 14976 char const *vsSource = 14977 "#version 450\n" 14978 "\n" 14979 "void main(){\n" 14980 " gl_Position = vec4(1);\n" 14981 "}\n"; 14982 char const *fsSource = 14983 "#version 450\n" 14984 "\n" 14985 "layout(set=0, binding=0, r32f) uniform imageBuffer s;\n" 14986 "layout(location=0) out vec4 x;\n" 14987 "void main(){\n" 14988 " x = imageLoad(s, 0);\n" 14989 "}\n"; 14990 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 14991 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 14992 VkPipelineObj pipe(m_device); 14993 pipe.AddShader(&vs); 14994 pipe.AddShader(&fs); 14995 pipe.AddDefaultColorAttachment(); 14996 pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 14997 14998 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_23e00750); 14999 15000 m_commandBuffer->begin(); 15001 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 15002 VkViewport viewport = {0, 0, 16, 16, 0, 1}; 15003 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 15004 VkRect2D scissor = {{0, 0}, {16, 16}}; 15005 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 15006 // Bind pipeline to cmd buffer 15007 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 15008 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &ds.set_, 0, 15009 nullptr); 15010 m_commandBuffer->Draw(1, 0, 0, 0); 15011 m_commandBuffer->EndRenderPass(); 15012 m_commandBuffer->end(); 15013 15014 VkSubmitInfo submit_info = {}; 15015 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 15016 submit_info.commandBufferCount = 1; 15017 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 15018 // Submit cmd buffer and then destroy bufferView while in-flight 15019 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 15020 15021 vkDestroyBufferView(m_device->device(), view, nullptr); 15022 m_errorMonitor->VerifyFound(); 15023 vkQueueWaitIdle(m_device->m_queue); 15024 // Now we can actually destroy bufferView 15025 m_errorMonitor->SetUnexpectedError("If bufferView is not VK_NULL_HANDLE, bufferView must be a valid VkBufferView handle"); 15026 m_errorMonitor->SetUnexpectedError("Unable to remove BufferView obj"); 15027 vkDestroyBufferView(m_device->device(), view, NULL); 15028 vkDestroyBuffer(m_device->device(), buffer, NULL); 15029 vkFreeMemory(m_device->device(), buffer_memory, NULL); 15030 } 15031 15032 TEST_F(VkLayerTest, SamplerInUseDestroyedSignaled) { 15033 TEST_DESCRIPTION("Delete in-use sampler."); 15034 15035 ASSERT_NO_FATAL_FAILURE(Init()); 15036 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 15037 15038 OneOffDescriptorSet ds(m_device, { 15039 {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}, 15040 }); 15041 15042 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo(); 15043 VkSampler sampler; 15044 15045 VkResult err; 15046 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 15047 ASSERT_VK_SUCCESS(err); 15048 15049 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_}); 15050 15051 VkImageObj image(m_device); 15052 image.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 15053 ASSERT_TRUE(image.initialized()); 15054 15055 VkImageView view; 15056 VkImageViewCreateInfo ivci = {}; 15057 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 15058 ivci.image = image.handle(); 15059 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; 15060 ivci.format = VK_FORMAT_R8G8B8A8_UNORM; 15061 ivci.subresourceRange.layerCount = 1; 15062 ivci.subresourceRange.baseMipLevel = 0; 15063 ivci.subresourceRange.levelCount = 1; 15064 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 15065 15066 err = vkCreateImageView(m_device->device(), &ivci, NULL, &view); 15067 ASSERT_VK_SUCCESS(err); 15068 15069 VkDescriptorImageInfo image_info{}; 15070 image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 15071 image_info.imageView = view; 15072 image_info.sampler = sampler; 15073 15074 VkWriteDescriptorSet descriptor_write = {}; 15075 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 15076 descriptor_write.dstSet = ds.set_; 15077 descriptor_write.dstBinding = 0; 15078 descriptor_write.descriptorCount = 1; 15079 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 15080 descriptor_write.pImageInfo = &image_info; 15081 15082 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 15083 15084 // Create PSO to use the sampler 15085 char const *vsSource = 15086 "#version 450\n" 15087 "\n" 15088 "void main(){\n" 15089 " gl_Position = vec4(1);\n" 15090 "}\n"; 15091 char const *fsSource = 15092 "#version 450\n" 15093 "\n" 15094 "layout(set=0, binding=0) uniform sampler2D s;\n" 15095 "layout(location=0) out vec4 x;\n" 15096 "void main(){\n" 15097 " x = texture(s, vec2(1));\n" 15098 "}\n"; 15099 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 15100 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 15101 VkPipelineObj pipe(m_device); 15102 pipe.AddShader(&vs); 15103 pipe.AddShader(&fs); 15104 pipe.AddDefaultColorAttachment(); 15105 pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 15106 15107 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_26600874); 15108 15109 m_commandBuffer->begin(); 15110 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 15111 // Bind pipeline to cmd buffer 15112 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 15113 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &ds.set_, 0, 15114 nullptr); 15115 15116 VkViewport viewport = {0, 0, 16, 16, 0, 1}; 15117 VkRect2D scissor = {{0, 0}, {16, 16}}; 15118 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 15119 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 15120 15121 m_commandBuffer->Draw(1, 0, 0, 0); 15122 m_commandBuffer->EndRenderPass(); 15123 m_commandBuffer->end(); 15124 // Submit cmd buffer then destroy sampler 15125 VkSubmitInfo submit_info = {}; 15126 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 15127 submit_info.commandBufferCount = 1; 15128 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 15129 // Submit cmd buffer and then destroy sampler while in-flight 15130 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 15131 15132 vkDestroySampler(m_device->device(), sampler, nullptr); // Destroyed too soon 15133 m_errorMonitor->VerifyFound(); 15134 vkQueueWaitIdle(m_device->m_queue); 15135 15136 // Now we can actually destroy sampler 15137 m_errorMonitor->SetUnexpectedError("If sampler is not VK_NULL_HANDLE, sampler must be a valid VkSampler handle"); 15138 m_errorMonitor->SetUnexpectedError("Unable to remove Sampler obj"); 15139 vkDestroySampler(m_device->device(), sampler, NULL); // Destroyed for real 15140 vkDestroyImageView(m_device->device(), view, NULL); 15141 } 15142 15143 TEST_F(VkLayerTest, UpdateDestroyDescriptorSetLayout) { 15144 TEST_DESCRIPTION("Attempt updates to descriptor sets with destroyed descriptor set layouts"); 15145 // TODO: Update to match the descriptor set layout specific VUIDs/VALIDATION_ERROR_* when present 15146 const auto kWriteDestroyedLayout = VALIDATION_ERROR_15c00280; 15147 const auto kCopyDstDestroyedLayout = VALIDATION_ERROR_03207601; 15148 const auto kCopySrcDestroyedLayout = VALIDATION_ERROR_0322d201; 15149 15150 ASSERT_NO_FATAL_FAILURE(Init()); 15151 15152 // Set up the descriptor (resource) and write/copy operations to use. 15153 float data[16] = {}; 15154 VkConstantBufferObj buffer(m_device, sizeof(data), data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); 15155 ASSERT_TRUE(buffer.initialized()); 15156 15157 VkDescriptorBufferInfo info = {}; 15158 info.buffer = buffer.handle(); 15159 info.range = VK_WHOLE_SIZE; 15160 15161 VkWriteDescriptorSet write_descriptor = {}; 15162 write_descriptor.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 15163 write_descriptor.dstSet = VK_NULL_HANDLE; // must update this 15164 write_descriptor.dstBinding = 0; 15165 write_descriptor.descriptorCount = 1; 15166 write_descriptor.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 15167 write_descriptor.pBufferInfo = &info; 15168 15169 VkCopyDescriptorSet copy_descriptor = {}; 15170 copy_descriptor.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET; 15171 copy_descriptor.srcSet = VK_NULL_HANDLE; // must update 15172 copy_descriptor.srcBinding = 0; 15173 copy_descriptor.dstSet = VK_NULL_HANDLE; // must update 15174 copy_descriptor.dstBinding = 0; 15175 copy_descriptor.descriptorCount = 1; 15176 15177 // Create valid and invalid source and destination descriptor sets 15178 std::vector<VkDescriptorSetLayoutBinding> one_uniform_buffer = { 15179 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, 15180 }; 15181 OneOffDescriptorSet good_dst(m_device, one_uniform_buffer); 15182 ASSERT_TRUE(good_dst.Initialized()); 15183 15184 OneOffDescriptorSet bad_dst(m_device, one_uniform_buffer); 15185 // Must assert before invalidating it below 15186 ASSERT_TRUE(bad_dst.Initialized()); 15187 bad_dst.layout_ = VkDescriptorSetLayoutObj(); 15188 15189 OneOffDescriptorSet good_src(m_device, one_uniform_buffer); 15190 ASSERT_TRUE(good_src.Initialized()); 15191 15192 // Put valid data in the good and bad sources, simultaneously doing a postive test on write and copy operations 15193 m_errorMonitor->ExpectSuccess(); 15194 write_descriptor.dstSet = good_src.set_; 15195 vkUpdateDescriptorSets(m_device->device(), 1, &write_descriptor, 0, NULL); 15196 m_errorMonitor->VerifyNotFound(); 15197 15198 OneOffDescriptorSet bad_src(m_device, one_uniform_buffer); 15199 ASSERT_TRUE(bad_src.Initialized()); 15200 15201 // to complete our positive testing use copy, where above we used write. 15202 copy_descriptor.srcSet = good_src.set_; 15203 copy_descriptor.dstSet = bad_src.set_; 15204 vkUpdateDescriptorSets(m_device->device(), 0, nullptr, 1, ©_descriptor); 15205 bad_src.layout_ = VkDescriptorSetLayoutObj(); 15206 m_errorMonitor->VerifyNotFound(); 15207 15208 // Trigger the three invalid use errors 15209 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, kWriteDestroyedLayout); 15210 write_descriptor.dstSet = bad_dst.set_; 15211 vkUpdateDescriptorSets(m_device->device(), 1, &write_descriptor, 0, NULL); 15212 m_errorMonitor->VerifyFound(); 15213 15214 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, kCopyDstDestroyedLayout); 15215 copy_descriptor.dstSet = bad_dst.set_; 15216 vkUpdateDescriptorSets(m_device->device(), 0, nullptr, 1, ©_descriptor); 15217 m_errorMonitor->VerifyFound(); 15218 15219 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, kCopySrcDestroyedLayout); 15220 copy_descriptor.srcSet = bad_src.set_; 15221 copy_descriptor.dstSet = good_dst.set_; 15222 vkUpdateDescriptorSets(m_device->device(), 0, nullptr, 1, ©_descriptor); 15223 m_errorMonitor->VerifyFound(); 15224 } 15225 15226 TEST_F(VkLayerTest, QueueForwardProgressFenceWait) { 15227 TEST_DESCRIPTION( 15228 "Call VkQueueSubmit with a semaphore that is already signaled but not waited on by the queue. Wait on a fence that has not " 15229 "yet been submitted to a queue."); 15230 15231 ASSERT_NO_FATAL_FAILURE(Init()); 15232 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 15233 15234 const char *queue_forward_progress_message = " that has already been signaled but not waited on by queue 0x"; 15235 const char *invalid_fence_wait_message = " which has not been submitted on a Queue or during acquire next image."; 15236 15237 VkCommandBufferObj cb1(m_device, m_commandPool); 15238 cb1.begin(); 15239 cb1.end(); 15240 15241 VkSemaphoreCreateInfo semaphore_create_info = {}; 15242 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 15243 VkSemaphore semaphore; 15244 ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore)); 15245 VkSubmitInfo submit_info = {}; 15246 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 15247 submit_info.commandBufferCount = 1; 15248 submit_info.pCommandBuffers = &cb1.handle(); 15249 submit_info.signalSemaphoreCount = 1; 15250 submit_info.pSignalSemaphores = &semaphore; 15251 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 15252 15253 m_commandBuffer->begin(); 15254 m_commandBuffer->end(); 15255 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 15256 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, queue_forward_progress_message); 15257 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 15258 m_errorMonitor->VerifyFound(); 15259 15260 VkFenceCreateInfo fence_create_info = {}; 15261 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 15262 VkFence fence; 15263 ASSERT_VK_SUCCESS(vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence)); 15264 15265 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, invalid_fence_wait_message); 15266 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX); 15267 m_errorMonitor->VerifyFound(); 15268 15269 vkDeviceWaitIdle(m_device->device()); 15270 vkDestroyFence(m_device->device(), fence, nullptr); 15271 vkDestroySemaphore(m_device->device(), semaphore, nullptr); 15272 } 15273 15274 TEST_F(VkLayerTest, FramebufferIncompatible) { 15275 TEST_DESCRIPTION( 15276 "Bind a secondary command buffer with with a framebuffer that does not match the framebuffer for the active renderpass."); 15277 ASSERT_NO_FATAL_FAILURE(Init()); 15278 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 15279 15280 // A renderpass with one color attachment. 15281 VkAttachmentDescription attachment = {0, 15282 VK_FORMAT_B8G8R8A8_UNORM, 15283 VK_SAMPLE_COUNT_1_BIT, 15284 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 15285 VK_ATTACHMENT_STORE_OP_STORE, 15286 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 15287 VK_ATTACHMENT_STORE_OP_DONT_CARE, 15288 VK_IMAGE_LAYOUT_UNDEFINED, 15289 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; 15290 15291 VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; 15292 15293 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr}; 15294 15295 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr}; 15296 15297 VkRenderPass rp; 15298 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 15299 ASSERT_VK_SUCCESS(err); 15300 15301 // A compatible framebuffer. 15302 VkImageObj image(m_device); 15303 image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 15304 ASSERT_TRUE(image.initialized()); 15305 15306 VkImageViewCreateInfo ivci = { 15307 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 15308 nullptr, 15309 0, 15310 image.handle(), 15311 VK_IMAGE_VIEW_TYPE_2D, 15312 VK_FORMAT_B8G8R8A8_UNORM, 15313 {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, 15314 VK_COMPONENT_SWIZZLE_IDENTITY}, 15315 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}, 15316 }; 15317 VkImageView view; 15318 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view); 15319 ASSERT_VK_SUCCESS(err); 15320 15321 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1}; 15322 VkFramebuffer fb; 15323 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); 15324 ASSERT_VK_SUCCESS(err); 15325 15326 VkCommandBufferAllocateInfo cbai = {}; 15327 cbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 15328 cbai.commandPool = m_commandPool->handle(); 15329 cbai.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY; 15330 cbai.commandBufferCount = 1; 15331 15332 VkCommandBuffer sec_cb; 15333 err = vkAllocateCommandBuffers(m_device->device(), &cbai, &sec_cb); 15334 ASSERT_VK_SUCCESS(err); 15335 VkCommandBufferBeginInfo cbbi = {}; 15336 VkCommandBufferInheritanceInfo cbii = {}; 15337 cbii.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; 15338 cbii.renderPass = renderPass(); 15339 cbii.framebuffer = fb; 15340 cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 15341 cbbi.pNext = NULL; 15342 cbbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; 15343 cbbi.pInheritanceInfo = &cbii; 15344 vkBeginCommandBuffer(sec_cb, &cbbi); 15345 vkEndCommandBuffer(sec_cb); 15346 15347 VkCommandBufferBeginInfo cbbi2 = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, nullptr}; 15348 vkBeginCommandBuffer(m_commandBuffer->handle(), &cbbi2); 15349 vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); 15350 15351 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 15352 " that is not the same as the primary command buffer's current active framebuffer "); 15353 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &sec_cb); 15354 m_errorMonitor->VerifyFound(); 15355 // Cleanup 15356 vkDestroyImageView(m_device->device(), view, NULL); 15357 vkDestroyRenderPass(m_device->device(), rp, NULL); 15358 vkDestroyFramebuffer(m_device->device(), fb, NULL); 15359 } 15360 15361 TEST_F(VkLayerTest, ColorBlendInvalidLogicOp) { 15362 TEST_DESCRIPTION("Attempt to use invalid VkPipelineColorBlendStateCreateInfo::logicOp value."); 15363 15364 ASSERT_NO_FATAL_FAILURE(Init()); // enables all supported features 15365 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 15366 15367 if (!m_device->phy().features().logicOp) { 15368 printf(" Device does not support logicOp feature; skipped.\n"); 15369 return; 15370 } 15371 15372 const auto set_shading_enable = [](CreatePipelineHelper &helper) { 15373 helper.cb_ci_.logicOpEnable = VK_TRUE; 15374 helper.cb_ci_.logicOp = static_cast<VkLogicOp>(VK_LOGIC_OP_END_RANGE + 1); // invalid logicOp to be tested 15375 }; 15376 CreatePipelineHelper::OneshotTest(*this, set_shading_enable, VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0f4004be); 15377 } 15378 15379 TEST_F(VkLayerTest, ColorBlendUnsupportedLogicOp) { 15380 TEST_DESCRIPTION("Attempt enabling VkPipelineColorBlendStateCreateInfo::logicOpEnable when logicOp feature is disabled."); 15381 15382 VkPhysicalDeviceFeatures features{}; 15383 ASSERT_NO_FATAL_FAILURE(Init(&features)); 15384 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 15385 15386 const auto set_shading_enable = [](CreatePipelineHelper &helper) { helper.cb_ci_.logicOpEnable = VK_TRUE; }; 15387 CreatePipelineHelper::OneshotTest(*this, set_shading_enable, VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0f4004bc); 15388 } 15389 15390 #if GTEST_IS_THREADSAFE 15391 struct thread_data_struct { 15392 VkCommandBuffer commandBuffer; 15393 VkDevice device; 15394 VkEvent event; 15395 bool bailout; 15396 }; 15397 15398 extern "C" void *AddToCommandBuffer(void *arg) { 15399 struct thread_data_struct *data = (struct thread_data_struct *)arg; 15400 15401 for (int i = 0; i < 80000; i++) { 15402 vkCmdSetEvent(data->commandBuffer, data->event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); 15403 if (data->bailout) { 15404 break; 15405 } 15406 } 15407 return NULL; 15408 } 15409 15410 TEST_F(VkLayerTest, ThreadCommandBufferCollision) { 15411 test_platform_thread thread; 15412 15413 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "THREADING ERROR"); 15414 15415 ASSERT_NO_FATAL_FAILURE(Init()); 15416 ASSERT_NO_FATAL_FAILURE(InitViewport()); 15417 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 15418 15419 // Calls AllocateCommandBuffers 15420 VkCommandBufferObj commandBuffer(m_device, m_commandPool); 15421 15422 commandBuffer.begin(); 15423 15424 VkEventCreateInfo event_info; 15425 VkEvent event; 15426 VkResult err; 15427 15428 memset(&event_info, 0, sizeof(event_info)); 15429 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 15430 15431 err = vkCreateEvent(device(), &event_info, NULL, &event); 15432 ASSERT_VK_SUCCESS(err); 15433 15434 err = vkResetEvent(device(), event); 15435 ASSERT_VK_SUCCESS(err); 15436 15437 struct thread_data_struct data; 15438 data.commandBuffer = commandBuffer.handle(); 15439 data.event = event; 15440 data.bailout = false; 15441 m_errorMonitor->SetBailout(&data.bailout); 15442 15443 // First do some correct operations using multiple threads. 15444 // Add many entries to command buffer from another thread. 15445 test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data); 15446 // Make non-conflicting calls from this thread at the same time. 15447 for (int i = 0; i < 80000; i++) { 15448 uint32_t count; 15449 vkEnumeratePhysicalDevices(instance(), &count, NULL); 15450 } 15451 test_platform_thread_join(thread, NULL); 15452 15453 // Then do some incorrect operations using multiple threads. 15454 // Add many entries to command buffer from another thread. 15455 test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data); 15456 // Add many entries to command buffer from this thread at the same time. 15457 AddToCommandBuffer(&data); 15458 15459 test_platform_thread_join(thread, NULL); 15460 commandBuffer.end(); 15461 15462 m_errorMonitor->SetBailout(NULL); 15463 15464 m_errorMonitor->VerifyFound(); 15465 15466 vkDestroyEvent(device(), event, NULL); 15467 } 15468 #endif // GTEST_IS_THREADSAFE 15469 15470 TEST_F(VkLayerTest, InvalidSPIRVCodeSize) { 15471 TEST_DESCRIPTION("Test that errors are produced for a spirv modules with invalid code sizes"); 15472 15473 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid SPIR-V header"); 15474 15475 ASSERT_NO_FATAL_FAILURE(Init()); 15476 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 15477 15478 VkShaderModule module; 15479 VkShaderModuleCreateInfo moduleCreateInfo; 15480 struct icd_spv_header spv; 15481 15482 spv.magic = ICD_SPV_MAGIC; 15483 spv.version = ICD_SPV_VERSION; 15484 spv.gen_magic = 0; 15485 15486 moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; 15487 moduleCreateInfo.pNext = NULL; 15488 moduleCreateInfo.pCode = (const uint32_t *)&spv; 15489 moduleCreateInfo.codeSize = 4; 15490 moduleCreateInfo.flags = 0; 15491 vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module); 15492 15493 m_errorMonitor->VerifyFound(); 15494 15495 char const *vsSource = 15496 "#version 450\n" 15497 "\n" 15498 "layout(location=0) out float x;\n" 15499 "void main(){\n" 15500 " gl_Position = vec4(1);\n" 15501 " x = 0;\n" 15502 "}\n"; 15503 15504 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_12a00ac0); 15505 std::vector<unsigned int> shader; 15506 VkShaderModuleCreateInfo module_create_info; 15507 VkShaderModule shader_module; 15508 module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; 15509 module_create_info.pNext = NULL; 15510 this->GLSLtoSPV(VK_SHADER_STAGE_VERTEX_BIT, vsSource, shader); 15511 module_create_info.pCode = shader.data(); 15512 // Introduce failure by making codeSize a non-multiple of 4 15513 module_create_info.codeSize = shader.size() * sizeof(unsigned int) - 1; 15514 module_create_info.flags = 0; 15515 vkCreateShaderModule(m_device->handle(), &module_create_info, NULL, &shader_module); 15516 15517 m_errorMonitor->VerifyFound(); 15518 } 15519 15520 TEST_F(VkLayerTest, InvalidSPIRVMagic) { 15521 TEST_DESCRIPTION("Test that an error is produced for a spirv module with a bad magic number"); 15522 15523 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid SPIR-V magic number"); 15524 15525 ASSERT_NO_FATAL_FAILURE(Init()); 15526 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 15527 15528 VkShaderModule module; 15529 VkShaderModuleCreateInfo moduleCreateInfo; 15530 struct icd_spv_header spv; 15531 15532 spv.magic = (uint32_t)~ICD_SPV_MAGIC; 15533 spv.version = ICD_SPV_VERSION; 15534 spv.gen_magic = 0; 15535 15536 moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; 15537 moduleCreateInfo.pNext = NULL; 15538 moduleCreateInfo.pCode = (const uint32_t *)&spv; 15539 moduleCreateInfo.codeSize = sizeof(spv) + 16; 15540 moduleCreateInfo.flags = 0; 15541 vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module); 15542 15543 m_errorMonitor->VerifyFound(); 15544 } 15545 15546 TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed) { 15547 TEST_DESCRIPTION("Test that a warning is produced for a vertex output that is not consumed by the fragment stage"); 15548 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "not consumed by fragment shader"); 15549 15550 ASSERT_NO_FATAL_FAILURE(Init()); 15551 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 15552 15553 char const *vsSource = 15554 "#version 450\n" 15555 "\n" 15556 "layout(location=0) out float x;\n" 15557 "void main(){\n" 15558 " gl_Position = vec4(1);\n" 15559 " x = 0;\n" 15560 "}\n"; 15561 char const *fsSource = 15562 "#version 450\n" 15563 "\n" 15564 "layout(location=0) out vec4 color;\n" 15565 "void main(){\n" 15566 " color = vec4(1);\n" 15567 "}\n"; 15568 15569 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 15570 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 15571 15572 VkPipelineObj pipe(m_device); 15573 pipe.AddDefaultColorAttachment(); 15574 pipe.AddShader(&vs); 15575 pipe.AddShader(&fs); 15576 15577 VkDescriptorSetObj descriptorSet(m_device); 15578 descriptorSet.AppendDummy(); 15579 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 15580 15581 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 15582 15583 m_errorMonitor->VerifyFound(); 15584 } 15585 15586 TEST_F(VkPositiveLayerTest, CreatePipelineComplexTypes) { 15587 TEST_DESCRIPTION("Smoke test for complex types across VS/FS boundary"); 15588 ASSERT_NO_FATAL_FAILURE(Init()); 15589 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 15590 15591 if (!m_device->phy().features().tessellationShader) { 15592 printf(" Device does not support tessellation shaders; skipped.\n"); 15593 return; 15594 } 15595 15596 m_errorMonitor->ExpectSuccess(); 15597 15598 char const *vsSource = 15599 "#version 450\n" 15600 "void main() {}"; 15601 char const *tcsSource = 15602 "#version 450\n" 15603 "layout(vertices=3) out;\n" 15604 "struct S { int x; };\n" 15605 "layout(location=2) patch out B { S s; } b;\n" 15606 "void main() {\n" 15607 " gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n" 15608 " gl_TessLevelInner[0] = 1;\n" 15609 " b.s.x = 1;\n" 15610 "}\n"; 15611 15612 char const *tesSource = 15613 "#version 450\n" 15614 "layout(triangles, equal_spacing, cw) in;\n" 15615 "struct S { int x; };\n" 15616 "layout(location=2) patch in B { S s; } b;\n" 15617 "void main() { gl_Position = vec4(b.s.x); }\n"; 15618 15619 char const *fsSource = 15620 "#version 450\n" 15621 "layout(location=0) out vec4 c;\n" 15622 "void main() { c = vec4(1); }\n"; 15623 15624 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 15625 VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this); 15626 VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this); 15627 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 15628 15629 VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0, 15630 VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE}; 15631 15632 VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3}; 15633 15634 VkPipelineObj pipe(m_device); 15635 15636 pipe.AddDefaultColorAttachment(); 15637 pipe.AddShader(&vs); 15638 pipe.AddShader(&tcs); 15639 pipe.AddShader(&tes); 15640 pipe.AddShader(&fs); 15641 pipe.SetInputAssembly(&iasci); 15642 pipe.SetTessellation(&tsci); 15643 15644 VkDescriptorSetObj descriptorSet(m_device); 15645 descriptorSet.AppendDummy(); 15646 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 15647 15648 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 15649 15650 m_errorMonitor->VerifyNotFound(); 15651 } 15652 15653 TEST_F(VkLayerTest, CreatePipelineCheckShaderBadSpecialization) { 15654 TEST_DESCRIPTION("Challenge core_validation with shader validation issues related to vkCreateGraphicsPipelines."); 15655 15656 ASSERT_NO_FATAL_FAILURE(Init()); 15657 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 15658 15659 const char *bad_specialization_message = 15660 "Specialization entry 0 (for constant id 0) references memory outside provided specialization data "; 15661 15662 char const *vsSource = 15663 "#version 450\n" 15664 "\n" 15665 "void main(){\n" 15666 " gl_Position = vec4(1);\n" 15667 "}\n"; 15668 15669 char const *fsSource = 15670 "#version 450\n" 15671 "\n" 15672 "layout (constant_id = 0) const float r = 0.0f;\n" 15673 "layout(location = 0) out vec4 uFragColor;\n" 15674 "void main(){\n" 15675 " uFragColor = vec4(r,1,0,1);\n" 15676 "}\n"; 15677 15678 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 15679 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 15680 15681 const VkPipelineLayoutObj pipeline_layout(m_device); 15682 15683 VkPipelineViewportStateCreateInfo vp_state_create_info = {}; 15684 vp_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 15685 vp_state_create_info.viewportCount = 1; 15686 VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f}; 15687 vp_state_create_info.pViewports = &viewport; 15688 vp_state_create_info.scissorCount = 1; 15689 15690 VkDynamicState scissor_state = VK_DYNAMIC_STATE_SCISSOR; 15691 15692 VkPipelineDynamicStateCreateInfo pipeline_dynamic_state_create_info = {}; 15693 pipeline_dynamic_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; 15694 pipeline_dynamic_state_create_info.dynamicStateCount = 1; 15695 pipeline_dynamic_state_create_info.pDynamicStates = &scissor_state; 15696 15697 VkPipelineShaderStageCreateInfo shader_stage_create_info[2] = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()}; 15698 15699 VkPipelineVertexInputStateCreateInfo vertex_input_create_info = {}; 15700 vertex_input_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 15701 15702 VkPipelineInputAssemblyStateCreateInfo input_assembly_create_info = {}; 15703 input_assembly_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 15704 input_assembly_create_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 15705 15706 VkPipelineRasterizationStateCreateInfo rasterization_state_create_info = {}; 15707 rasterization_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 15708 rasterization_state_create_info.pNext = nullptr; 15709 rasterization_state_create_info.lineWidth = 1.0f; 15710 rasterization_state_create_info.rasterizerDiscardEnable = true; 15711 15712 VkPipelineColorBlendAttachmentState color_blend_attachment_state = {}; 15713 color_blend_attachment_state.blendEnable = VK_FALSE; 15714 color_blend_attachment_state.colorWriteMask = 0xf; 15715 15716 VkPipelineColorBlendStateCreateInfo color_blend_state_create_info = {}; 15717 color_blend_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; 15718 color_blend_state_create_info.attachmentCount = 1; 15719 color_blend_state_create_info.pAttachments = &color_blend_attachment_state; 15720 15721 VkGraphicsPipelineCreateInfo graphicspipe_create_info = {}; 15722 graphicspipe_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 15723 graphicspipe_create_info.stageCount = 2; 15724 graphicspipe_create_info.pStages = shader_stage_create_info; 15725 graphicspipe_create_info.pVertexInputState = &vertex_input_create_info; 15726 graphicspipe_create_info.pInputAssemblyState = &input_assembly_create_info; 15727 graphicspipe_create_info.pViewportState = &vp_state_create_info; 15728 graphicspipe_create_info.pRasterizationState = &rasterization_state_create_info; 15729 graphicspipe_create_info.pColorBlendState = &color_blend_state_create_info; 15730 graphicspipe_create_info.pDynamicState = &pipeline_dynamic_state_create_info; 15731 graphicspipe_create_info.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; 15732 graphicspipe_create_info.layout = pipeline_layout.handle(); 15733 graphicspipe_create_info.renderPass = renderPass(); 15734 15735 VkPipelineCacheCreateInfo pipeline_cache_create_info = {}; 15736 pipeline_cache_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 15737 15738 VkPipelineCache pipelineCache; 15739 ASSERT_VK_SUCCESS(vkCreatePipelineCache(m_device->device(), &pipeline_cache_create_info, nullptr, &pipelineCache)); 15740 15741 // This structure maps constant ids to data locations. 15742 const VkSpecializationMapEntry entry = 15743 // id, offset, size 15744 {0, 4, sizeof(uint32_t)}; // Challenge core validation by using a bogus offset. 15745 15746 uint32_t data = 1; 15747 15748 // Set up the info describing spec map and data 15749 const VkSpecializationInfo specialization_info = { 15750 1, 15751 &entry, 15752 1 * sizeof(float), 15753 &data, 15754 }; 15755 shader_stage_create_info[0].pSpecializationInfo = &specialization_info; 15756 15757 VkPipeline pipeline; 15758 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, bad_specialization_message); 15759 vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &graphicspipe_create_info, nullptr, &pipeline); 15760 m_errorMonitor->VerifyFound(); 15761 15762 vkDestroyPipelineCache(m_device->device(), pipelineCache, nullptr); 15763 } 15764 15765 TEST_F(VkLayerTest, CreatePipelineCheckShaderDescriptorTypeMismatch) { 15766 TEST_DESCRIPTION("Challenge core_validation with shader validation issues related to vkCreateGraphicsPipelines."); 15767 15768 ASSERT_NO_FATAL_FAILURE(Init()); 15769 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 15770 15771 const char *descriptor_type_mismatch_message = "Type mismatch on descriptor slot 0.0 (used as type "; 15772 15773 OneOffDescriptorSet ds(m_device, { 15774 {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, 15775 }); 15776 15777 char const *vsSource = 15778 "#version 450\n" 15779 "\n" 15780 "layout (std140, set = 0, binding = 0) uniform buf {\n" 15781 " mat4 mvp;\n" 15782 "} ubuf;\n" 15783 "void main(){\n" 15784 " gl_Position = ubuf.mvp * vec4(1);\n" 15785 "}\n"; 15786 15787 char const *fsSource = 15788 "#version 450\n" 15789 "\n" 15790 "layout(location = 0) out vec4 uFragColor;\n" 15791 "void main(){\n" 15792 " uFragColor = vec4(0,1,0,1);\n" 15793 "}\n"; 15794 15795 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 15796 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 15797 15798 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_}); 15799 15800 VkPipelineObj pipe(m_device); 15801 pipe.AddDefaultColorAttachment(); 15802 pipe.AddShader(&vs); 15803 pipe.AddShader(&fs); 15804 15805 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, descriptor_type_mismatch_message); 15806 pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 15807 m_errorMonitor->VerifyFound(); 15808 } 15809 15810 TEST_F(VkLayerTest, CreatePipelineCheckShaderDescriptorNotAccessible) { 15811 TEST_DESCRIPTION( 15812 "Create a pipeline in which a descriptor used by a shader stage does not include that stage in its stageFlags."); 15813 15814 ASSERT_NO_FATAL_FAILURE(Init()); 15815 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 15816 15817 const char *descriptor_not_accessible_message = "Shader uses descriptor slot 0.0 (used as type "; 15818 15819 OneOffDescriptorSet ds(m_device, { 15820 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT /*!*/, nullptr}, 15821 }); 15822 15823 char const *vsSource = 15824 "#version 450\n" 15825 "\n" 15826 "layout (std140, set = 0, binding = 0) uniform buf {\n" 15827 " mat4 mvp;\n" 15828 "} ubuf;\n" 15829 "void main(){\n" 15830 " gl_Position = ubuf.mvp * vec4(1);\n" 15831 "}\n"; 15832 15833 char const *fsSource = 15834 "#version 450\n" 15835 "\n" 15836 "layout(location = 0) out vec4 uFragColor;\n" 15837 "void main(){\n" 15838 " uFragColor = vec4(0,1,0,1);\n" 15839 "}\n"; 15840 15841 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 15842 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 15843 15844 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_}); 15845 15846 VkPipelineObj pipe(m_device); 15847 pipe.AddDefaultColorAttachment(); 15848 pipe.AddShader(&vs); 15849 pipe.AddShader(&fs); 15850 15851 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, descriptor_not_accessible_message); 15852 pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 15853 m_errorMonitor->VerifyFound(); 15854 } 15855 15856 TEST_F(VkLayerTest, CreatePipelineCheckShaderPushConstantNotAccessible) { 15857 TEST_DESCRIPTION( 15858 "Create a graphics pipleine in which a push constant range containing a push constant block member is not accessible from " 15859 "the current shader stage."); 15860 15861 ASSERT_NO_FATAL_FAILURE(Init()); 15862 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 15863 15864 const char *push_constant_not_accessible_message = 15865 "Push constant range covering variable starting at offset 0 not accessible from stage VK_SHADER_STAGE_VERTEX_BIT"; 15866 15867 char const *vsSource = 15868 "#version 450\n" 15869 "\n" 15870 "layout(push_constant, std430) uniform foo { float x; } consts;\n" 15871 "void main(){\n" 15872 " gl_Position = vec4(consts.x);\n" 15873 "}\n"; 15874 15875 char const *fsSource = 15876 "#version 450\n" 15877 "\n" 15878 "layout(location = 0) out vec4 uFragColor;\n" 15879 "void main(){\n" 15880 " uFragColor = vec4(0,1,0,1);\n" 15881 "}\n"; 15882 15883 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 15884 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 15885 15886 // Set up a push constant range 15887 VkPushConstantRange push_constant_range = {}; 15888 // Set to the wrong stage to challenge core_validation 15889 push_constant_range.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 15890 push_constant_range.size = 4; 15891 15892 const VkPipelineLayoutObj pipeline_layout(m_device, {}, {push_constant_range}); 15893 15894 VkPipelineObj pipe(m_device); 15895 pipe.AddDefaultColorAttachment(); 15896 pipe.AddShader(&vs); 15897 pipe.AddShader(&fs); 15898 15899 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, push_constant_not_accessible_message); 15900 pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 15901 m_errorMonitor->VerifyFound(); 15902 } 15903 15904 TEST_F(VkLayerTest, CreatePipelineCheckShaderNotEnabled) { 15905 TEST_DESCRIPTION( 15906 "Create a graphics pipeline in which a capability declared by the shader requires a feature not enabled on the device."); 15907 15908 ASSERT_NO_FATAL_FAILURE(Init()); 15909 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 15910 15911 const char *feature_not_enabled_message = 15912 "Shader requires VkPhysicalDeviceFeatures::shaderFloat64 but is not enabled on the device"; 15913 15914 // Some awkward steps are required to test with custom device features. 15915 std::vector<const char *> device_extension_names; 15916 auto features = m_device->phy().features(); 15917 // Disable support for 64 bit floats 15918 features.shaderFloat64 = false; 15919 // The sacrificial device object 15920 VkDeviceObj test_device(0, gpu(), device_extension_names, &features); 15921 15922 char const *vsSource = 15923 "#version 450\n" 15924 "\n" 15925 "void main(){\n" 15926 " gl_Position = vec4(1);\n" 15927 "}\n"; 15928 char const *fsSource = 15929 "#version 450\n" 15930 "\n" 15931 "layout(location=0) out vec4 color;\n" 15932 "void main(){\n" 15933 " dvec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n" 15934 " color = vec4(green);\n" 15935 "}\n"; 15936 15937 VkShaderObj vs(&test_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 15938 VkShaderObj fs(&test_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 15939 15940 VkRenderpassObj render_pass(&test_device); 15941 15942 VkPipelineObj pipe(&test_device); 15943 pipe.AddDefaultColorAttachment(); 15944 pipe.AddShader(&vs); 15945 pipe.AddShader(&fs); 15946 15947 const VkPipelineLayoutObj pipeline_layout(&test_device); 15948 15949 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, feature_not_enabled_message); 15950 pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle()); 15951 m_errorMonitor->VerifyFound(); 15952 } 15953 15954 TEST_F(VkLayerTest, CreateShaderModuleCheckBadCapability) { 15955 TEST_DESCRIPTION("Create a shader in which a capability declared by the shader is not supported."); 15956 // Note that this failure message comes from spirv-tools, specifically the validator. 15957 15958 ASSERT_NO_FATAL_FAILURE(Init()); 15959 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 15960 15961 char const *vsSource = 15962 "#version 450\n" 15963 "\n" 15964 "layout(xfb_buffer = 1) out;\n" 15965 "void main(){\n" 15966 " gl_Position = vec4(1);\n" 15967 "}\n"; 15968 15969 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Capability TransformFeedback is not allowed by Vulkan"); 15970 15971 std::vector<unsigned int> spv; 15972 VkShaderModuleCreateInfo module_create_info; 15973 VkShaderModule shader_module; 15974 module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; 15975 module_create_info.pNext = NULL; 15976 this->GLSLtoSPV(VK_SHADER_STAGE_VERTEX_BIT, vsSource, spv); 15977 module_create_info.pCode = spv.data(); 15978 module_create_info.codeSize = spv.size() * sizeof(unsigned int); 15979 module_create_info.flags = 0; 15980 15981 vkCreateShaderModule(m_device->handle(), &module_create_info, NULL, &shader_module); 15982 15983 m_errorMonitor->VerifyFound(); 15984 } 15985 15986 TEST_F(VkPositiveLayerTest, CreatePipelineCheckShaderCapabilityExtension1of2) { 15987 // This is a positive test, no errors expected 15988 // Verifies the ability to deal with a shader that declares a non-unique SPIRV capability ID 15989 TEST_DESCRIPTION("Create a shader in which uses a non-unique capability ID extension, 1 of 2"); 15990 15991 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 15992 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME)) { 15993 printf(" Extension %s not supported, skipping this pass. \n", 15994 VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME); 15995 return; 15996 } 15997 m_device_extension_names.push_back(VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME); 15998 ASSERT_NO_FATAL_FAILURE(InitState()); 15999 16000 // These tests require that the device support multiViewport 16001 if (!m_device->phy().features().multiViewport) { 16002 printf(" Device does not support multiViewport, test skipped.\n"); 16003 return; 16004 } 16005 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 16006 16007 // Vertex shader using viewport array capability 16008 char const *vsSource = 16009 "#version 450\n" 16010 "#extension GL_ARB_shader_viewport_layer_array : enable\n" 16011 "void main() {\n" 16012 " gl_ViewportIndex = 1;\n" 16013 "}\n"; 16014 16015 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 16016 16017 VkPipelineObj pipe(m_device); 16018 pipe.AddDefaultColorAttachment(); 16019 pipe.AddShader(&vs); 16020 16021 const VkPipelineLayoutObj pipe_layout(m_device, {}); 16022 16023 m_errorMonitor->ExpectSuccess(); 16024 pipe.CreateVKPipeline(pipe_layout.handle(), renderPass()); 16025 m_errorMonitor->VerifyNotFound(); 16026 } 16027 16028 TEST_F(VkPositiveLayerTest, CreatePipelineCheckShaderCapabilityExtension2of2) { 16029 // This is a positive test, no errors expected 16030 // Verifies the ability to deal with a shader that declares a non-unique SPIRV capability ID 16031 TEST_DESCRIPTION("Create a shader in which uses a non-unique capability ID extension, 2 of 2"); 16032 16033 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 16034 if (!DeviceExtensionSupported(gpu(), nullptr, VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME)) { 16035 printf(" Extension %s not supported, skipping this pass. \n", VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME); 16036 return; 16037 } 16038 m_device_extension_names.push_back(VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME); 16039 ASSERT_NO_FATAL_FAILURE(InitState()); 16040 16041 // These tests require that the device support multiViewport 16042 if (!m_device->phy().features().multiViewport) { 16043 printf(" Device does not support multiViewport, test skipped.\n"); 16044 return; 16045 } 16046 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 16047 16048 // Vertex shader using viewport array capability 16049 char const *vsSource = 16050 "#version 450\n" 16051 "#extension GL_ARB_shader_viewport_layer_array : enable\n" 16052 "void main() {\n" 16053 " gl_ViewportIndex = 1;\n" 16054 "}\n"; 16055 16056 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 16057 16058 VkPipelineObj pipe(m_device); 16059 pipe.AddDefaultColorAttachment(); 16060 pipe.AddShader(&vs); 16061 16062 const VkPipelineLayoutObj pipe_layout(m_device, {}); 16063 16064 m_errorMonitor->ExpectSuccess(); 16065 pipe.CreateVKPipeline(pipe_layout.handle(), renderPass()); 16066 m_errorMonitor->VerifyNotFound(); 16067 } 16068 16069 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided) { 16070 TEST_DESCRIPTION( 16071 "Test that an error is produced for a fragment shader input which is not present in the outputs of the previous stage"); 16072 16073 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not written by vertex shader"); 16074 16075 ASSERT_NO_FATAL_FAILURE(Init()); 16076 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 16077 16078 char const *vsSource = 16079 "#version 450\n" 16080 "\n" 16081 "void main(){\n" 16082 " gl_Position = vec4(1);\n" 16083 "}\n"; 16084 char const *fsSource = 16085 "#version 450\n" 16086 "\n" 16087 "layout(location=0) in float x;\n" 16088 "layout(location=0) out vec4 color;\n" 16089 "void main(){\n" 16090 " color = vec4(x);\n" 16091 "}\n"; 16092 16093 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 16094 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 16095 16096 VkPipelineObj pipe(m_device); 16097 pipe.AddDefaultColorAttachment(); 16098 pipe.AddShader(&vs); 16099 pipe.AddShader(&fs); 16100 16101 VkDescriptorSetObj descriptorSet(m_device); 16102 descriptorSet.AppendDummy(); 16103 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 16104 16105 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16106 16107 m_errorMonitor->VerifyFound(); 16108 } 16109 16110 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvidedInBlock) { 16111 TEST_DESCRIPTION( 16112 "Test that an error is produced for a fragment shader input within an interace block, which is not present in the outputs " 16113 "of the previous stage."); 16114 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not written by vertex shader"); 16115 16116 ASSERT_NO_FATAL_FAILURE(Init()); 16117 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 16118 16119 char const *vsSource = 16120 "#version 450\n" 16121 "\n" 16122 "void main(){\n" 16123 " gl_Position = vec4(1);\n" 16124 "}\n"; 16125 char const *fsSource = 16126 "#version 450\n" 16127 "\n" 16128 "in block { layout(location=0) float x; } ins;\n" 16129 "layout(location=0) out vec4 color;\n" 16130 "void main(){\n" 16131 " color = vec4(ins.x);\n" 16132 "}\n"; 16133 16134 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 16135 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 16136 16137 VkPipelineObj pipe(m_device); 16138 pipe.AddDefaultColorAttachment(); 16139 pipe.AddShader(&vs); 16140 pipe.AddShader(&fs); 16141 16142 VkDescriptorSetObj descriptorSet(m_device); 16143 descriptorSet.AppendDummy(); 16144 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 16145 16146 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16147 16148 m_errorMonitor->VerifyFound(); 16149 } 16150 16151 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchArraySize) { 16152 TEST_DESCRIPTION("Test that an error is produced for mismatched array sizes across the vertex->fragment shader interface"); 16153 m_errorMonitor->SetDesiredFailureMsg( 16154 VK_DEBUG_REPORT_ERROR_BIT_EXT, 16155 "Type mismatch on location 0.0: 'ptr to output arr[2] of float32' vs 'ptr to input arr[1] of float32'"); 16156 16157 ASSERT_NO_FATAL_FAILURE(Init()); 16158 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 16159 16160 char const *vsSource = 16161 "#version 450\n" 16162 "\n" 16163 "layout(location=0) out float x[2];\n" 16164 "void main(){\n" 16165 " x[0] = 0; x[1] = 0;\n" 16166 " gl_Position = vec4(1);\n" 16167 "}\n"; 16168 char const *fsSource = 16169 "#version 450\n" 16170 "\n" 16171 "layout(location=0) in float x[1];\n" 16172 "layout(location=0) out vec4 color;\n" 16173 "void main(){\n" 16174 " color = vec4(x[0]);\n" 16175 "}\n"; 16176 16177 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 16178 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 16179 16180 VkPipelineObj pipe(m_device); 16181 pipe.AddDefaultColorAttachment(); 16182 pipe.AddShader(&vs); 16183 pipe.AddShader(&fs); 16184 16185 VkDescriptorSetObj descriptorSet(m_device); 16186 descriptorSet.AppendDummy(); 16187 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 16188 16189 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16190 16191 m_errorMonitor->VerifyFound(); 16192 } 16193 16194 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch) { 16195 TEST_DESCRIPTION("Test that an error is produced for mismatched types across the vertex->fragment shader interface"); 16196 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0"); 16197 16198 ASSERT_NO_FATAL_FAILURE(Init()); 16199 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 16200 16201 char const *vsSource = 16202 "#version 450\n" 16203 "\n" 16204 "layout(location=0) out int x;\n" 16205 "void main(){\n" 16206 " x = 0;\n" 16207 " gl_Position = vec4(1);\n" 16208 "}\n"; 16209 char const *fsSource = 16210 "#version 450\n" 16211 "\n" 16212 "layout(location=0) in float x;\n" /* VS writes int */ 16213 "layout(location=0) out vec4 color;\n" 16214 "void main(){\n" 16215 " color = vec4(x);\n" 16216 "}\n"; 16217 16218 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 16219 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 16220 16221 VkPipelineObj pipe(m_device); 16222 pipe.AddDefaultColorAttachment(); 16223 pipe.AddShader(&vs); 16224 pipe.AddShader(&fs); 16225 16226 VkDescriptorSetObj descriptorSet(m_device); 16227 descriptorSet.AppendDummy(); 16228 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 16229 16230 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16231 16232 m_errorMonitor->VerifyFound(); 16233 } 16234 16235 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchInBlock) { 16236 TEST_DESCRIPTION( 16237 "Test that an error is produced for mismatched types across the vertex->fragment shader interface, when the variable is " 16238 "contained within an interface block"); 16239 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0"); 16240 16241 ASSERT_NO_FATAL_FAILURE(Init()); 16242 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 16243 16244 char const *vsSource = 16245 "#version 450\n" 16246 "\n" 16247 "out block { layout(location=0) int x; } outs;\n" 16248 "void main(){\n" 16249 " outs.x = 0;\n" 16250 " gl_Position = vec4(1);\n" 16251 "}\n"; 16252 char const *fsSource = 16253 "#version 450\n" 16254 "\n" 16255 "in block { layout(location=0) float x; } ins;\n" /* VS writes int */ 16256 "layout(location=0) out vec4 color;\n" 16257 "void main(){\n" 16258 " color = vec4(ins.x);\n" 16259 "}\n"; 16260 16261 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 16262 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 16263 16264 VkPipelineObj pipe(m_device); 16265 pipe.AddDefaultColorAttachment(); 16266 pipe.AddShader(&vs); 16267 pipe.AddShader(&fs); 16268 16269 VkDescriptorSetObj descriptorSet(m_device); 16270 descriptorSet.AppendDummy(); 16271 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 16272 16273 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16274 16275 m_errorMonitor->VerifyFound(); 16276 } 16277 16278 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByLocation) { 16279 TEST_DESCRIPTION( 16280 "Test that an error is produced for location mismatches across the vertex->fragment shader interface; This should manifest " 16281 "as a not-written/not-consumed pair, but flushes out broken walking of the interfaces"); 16282 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0.0 which is not written by vertex shader"); 16283 16284 ASSERT_NO_FATAL_FAILURE(Init()); 16285 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 16286 16287 char const *vsSource = 16288 "#version 450\n" 16289 "\n" 16290 "out block { layout(location=1) float x; } outs;\n" 16291 "void main(){\n" 16292 " outs.x = 0;\n" 16293 " gl_Position = vec4(1);\n" 16294 "}\n"; 16295 char const *fsSource = 16296 "#version 450\n" 16297 "\n" 16298 "in block { layout(location=0) float x; } ins;\n" 16299 "layout(location=0) out vec4 color;\n" 16300 "void main(){\n" 16301 " color = vec4(ins.x);\n" 16302 "}\n"; 16303 16304 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 16305 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 16306 16307 VkPipelineObj pipe(m_device); 16308 pipe.AddDefaultColorAttachment(); 16309 pipe.AddShader(&vs); 16310 pipe.AddShader(&fs); 16311 16312 VkDescriptorSetObj descriptorSet(m_device); 16313 descriptorSet.AppendDummy(); 16314 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 16315 16316 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16317 16318 m_errorMonitor->VerifyFound(); 16319 } 16320 16321 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByComponent) { 16322 TEST_DESCRIPTION( 16323 "Test that an error is produced for component mismatches across the vertex->fragment shader interface. It's not enough to " 16324 "have the same set of locations in use; matching is defined in terms of spirv variables."); 16325 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0.1 which is not written by vertex shader"); 16326 16327 ASSERT_NO_FATAL_FAILURE(Init()); 16328 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 16329 16330 char const *vsSource = 16331 "#version 450\n" 16332 "\n" 16333 "out block { layout(location=0, component=0) float x; } outs;\n" 16334 "void main(){\n" 16335 " outs.x = 0;\n" 16336 " gl_Position = vec4(1);\n" 16337 "}\n"; 16338 char const *fsSource = 16339 "#version 450\n" 16340 "\n" 16341 "in block { layout(location=0, component=1) float x; } ins;\n" 16342 "layout(location=0) out vec4 color;\n" 16343 "void main(){\n" 16344 " color = vec4(ins.x);\n" 16345 "}\n"; 16346 16347 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 16348 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 16349 16350 VkPipelineObj pipe(m_device); 16351 pipe.AddDefaultColorAttachment(); 16352 pipe.AddShader(&vs); 16353 pipe.AddShader(&fs); 16354 16355 VkDescriptorSetObj descriptorSet(m_device); 16356 descriptorSet.AppendDummy(); 16357 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 16358 16359 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16360 16361 m_errorMonitor->VerifyFound(); 16362 } 16363 16364 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByPrecision) { 16365 TEST_DESCRIPTION("Test that the RelaxedPrecision decoration is validated to match"); 16366 16367 ASSERT_NO_FATAL_FAILURE(Init()); 16368 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 16369 16370 char const *vsSource = 16371 "#version 450\n" 16372 "layout(location=0) out mediump float x;\n" 16373 "void main() { gl_Position = vec4(0); x = 1.0; }\n"; 16374 char const *fsSource = 16375 "#version 450\n" 16376 "layout(location=0) in highp float x;\n" 16377 "layout(location=0) out vec4 color;\n" 16378 "void main() { color = vec4(x); }\n"; 16379 16380 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 16381 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 16382 16383 VkPipelineObj pipe(m_device); 16384 pipe.AddDefaultColorAttachment(); 16385 pipe.AddShader(&vs); 16386 pipe.AddShader(&fs); 16387 16388 VkDescriptorSetObj descriptorSet(m_device); 16389 descriptorSet.AppendDummy(); 16390 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 16391 16392 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "differ in precision"); 16393 16394 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16395 16396 m_errorMonitor->VerifyFound(); 16397 } 16398 16399 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByPrecisionBlock) { 16400 TEST_DESCRIPTION("Test that the RelaxedPrecision decoration is validated to match"); 16401 16402 ASSERT_NO_FATAL_FAILURE(Init()); 16403 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 16404 16405 char const *vsSource = 16406 "#version 450\n" 16407 "out block { layout(location=0) mediump float x; };\n" 16408 "void main() { gl_Position = vec4(0); x = 1.0; }\n"; 16409 char const *fsSource = 16410 "#version 450\n" 16411 "in block { layout(location=0) highp float x; };\n" 16412 "layout(location=0) out vec4 color;\n" 16413 "void main() { color = vec4(x); }\n"; 16414 16415 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 16416 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 16417 16418 VkPipelineObj pipe(m_device); 16419 pipe.AddDefaultColorAttachment(); 16420 pipe.AddShader(&vs); 16421 pipe.AddShader(&fs); 16422 16423 VkDescriptorSetObj descriptorSet(m_device); 16424 descriptorSet.AppendDummy(); 16425 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 16426 16427 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "differ in precision"); 16428 16429 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16430 16431 m_errorMonitor->VerifyFound(); 16432 } 16433 16434 TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed) { 16435 TEST_DESCRIPTION("Test that a warning is produced for a vertex attribute which is not consumed by the vertex shader"); 16436 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by vertex shader"); 16437 16438 ASSERT_NO_FATAL_FAILURE(Init()); 16439 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 16440 16441 VkVertexInputBindingDescription input_binding; 16442 memset(&input_binding, 0, sizeof(input_binding)); 16443 16444 VkVertexInputAttributeDescription input_attrib; 16445 memset(&input_attrib, 0, sizeof(input_attrib)); 16446 input_attrib.format = VK_FORMAT_R32_SFLOAT; 16447 16448 char const *vsSource = 16449 "#version 450\n" 16450 "\n" 16451 "void main(){\n" 16452 " gl_Position = vec4(1);\n" 16453 "}\n"; 16454 char const *fsSource = 16455 "#version 450\n" 16456 "\n" 16457 "layout(location=0) out vec4 color;\n" 16458 "void main(){\n" 16459 " color = vec4(1);\n" 16460 "}\n"; 16461 16462 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 16463 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 16464 16465 VkPipelineObj pipe(m_device); 16466 pipe.AddDefaultColorAttachment(); 16467 pipe.AddShader(&vs); 16468 pipe.AddShader(&fs); 16469 16470 pipe.AddVertexInputBindings(&input_binding, 1); 16471 pipe.AddVertexInputAttribs(&input_attrib, 1); 16472 16473 VkDescriptorSetObj descriptorSet(m_device); 16474 descriptorSet.AppendDummy(); 16475 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 16476 16477 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16478 16479 m_errorMonitor->VerifyFound(); 16480 } 16481 16482 TEST_F(VkLayerTest, CreatePipelineAttribLocationMismatch) { 16483 TEST_DESCRIPTION( 16484 "Test that a warning is produced for a location mismatch on vertex attributes. This flushes out bad behavior in the " 16485 "interface walker"); 16486 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by vertex shader"); 16487 16488 ASSERT_NO_FATAL_FAILURE(Init()); 16489 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 16490 16491 VkVertexInputBindingDescription input_binding; 16492 memset(&input_binding, 0, sizeof(input_binding)); 16493 16494 VkVertexInputAttributeDescription input_attrib; 16495 memset(&input_attrib, 0, sizeof(input_attrib)); 16496 input_attrib.format = VK_FORMAT_R32_SFLOAT; 16497 16498 char const *vsSource = 16499 "#version 450\n" 16500 "\n" 16501 "layout(location=1) in float x;\n" 16502 "void main(){\n" 16503 " gl_Position = vec4(x);\n" 16504 "}\n"; 16505 char const *fsSource = 16506 "#version 450\n" 16507 "\n" 16508 "layout(location=0) out vec4 color;\n" 16509 "void main(){\n" 16510 " color = vec4(1);\n" 16511 "}\n"; 16512 16513 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 16514 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 16515 16516 VkPipelineObj pipe(m_device); 16517 pipe.AddDefaultColorAttachment(); 16518 pipe.AddShader(&vs); 16519 pipe.AddShader(&fs); 16520 16521 pipe.AddVertexInputBindings(&input_binding, 1); 16522 pipe.AddVertexInputAttribs(&input_attrib, 1); 16523 16524 VkDescriptorSetObj descriptorSet(m_device); 16525 descriptorSet.AppendDummy(); 16526 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 16527 16528 m_errorMonitor->SetUnexpectedError("Vertex shader consumes input at location 1 but not provided"); 16529 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16530 16531 m_errorMonitor->VerifyFound(); 16532 } 16533 16534 TEST_F(VkLayerTest, CreatePipelineAttribNotProvided) { 16535 TEST_DESCRIPTION("Test that an error is produced for a vertex shader input which is not provided by a vertex attribute"); 16536 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 16537 "Vertex shader consumes input at location 0 but not provided"); 16538 16539 ASSERT_NO_FATAL_FAILURE(Init()); 16540 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 16541 16542 char const *vsSource = 16543 "#version 450\n" 16544 "\n" 16545 "layout(location=0) in vec4 x;\n" /* not provided */ 16546 "void main(){\n" 16547 " gl_Position = x;\n" 16548 "}\n"; 16549 char const *fsSource = 16550 "#version 450\n" 16551 "\n" 16552 "layout(location=0) out vec4 color;\n" 16553 "void main(){\n" 16554 " color = vec4(1);\n" 16555 "}\n"; 16556 16557 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 16558 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 16559 16560 VkPipelineObj pipe(m_device); 16561 pipe.AddDefaultColorAttachment(); 16562 pipe.AddShader(&vs); 16563 pipe.AddShader(&fs); 16564 16565 VkDescriptorSetObj descriptorSet(m_device); 16566 descriptorSet.AppendDummy(); 16567 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 16568 16569 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16570 16571 m_errorMonitor->VerifyFound(); 16572 } 16573 16574 TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch) { 16575 TEST_DESCRIPTION( 16576 "Test that an error is produced for a mismatch between the fundamental type (float/int/uint) of an attribute and the " 16577 "vertex shader input that consumes it"); 16578 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0 does not match vertex shader input type"); 16579 16580 ASSERT_NO_FATAL_FAILURE(Init()); 16581 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 16582 16583 VkVertexInputBindingDescription input_binding; 16584 memset(&input_binding, 0, sizeof(input_binding)); 16585 16586 VkVertexInputAttributeDescription input_attrib; 16587 memset(&input_attrib, 0, sizeof(input_attrib)); 16588 input_attrib.format = VK_FORMAT_R32_SFLOAT; 16589 16590 char const *vsSource = 16591 "#version 450\n" 16592 "\n" 16593 "layout(location=0) in int x;\n" /* attrib provided float */ 16594 "void main(){\n" 16595 " gl_Position = vec4(x);\n" 16596 "}\n"; 16597 char const *fsSource = 16598 "#version 450\n" 16599 "\n" 16600 "layout(location=0) out vec4 color;\n" 16601 "void main(){\n" 16602 " color = vec4(1);\n" 16603 "}\n"; 16604 16605 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 16606 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 16607 16608 VkPipelineObj pipe(m_device); 16609 pipe.AddDefaultColorAttachment(); 16610 pipe.AddShader(&vs); 16611 pipe.AddShader(&fs); 16612 16613 pipe.AddVertexInputBindings(&input_binding, 1); 16614 pipe.AddVertexInputAttribs(&input_attrib, 1); 16615 16616 VkDescriptorSetObj descriptorSet(m_device); 16617 descriptorSet.AppendDummy(); 16618 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 16619 16620 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16621 16622 m_errorMonitor->VerifyFound(); 16623 } 16624 16625 TEST_F(VkLayerTest, CreatePipelineDuplicateStage) { 16626 TEST_DESCRIPTION("Test that an error is produced for a pipeline containing multiple shaders for the same stage"); 16627 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 16628 "Multiple shaders provided for stage VK_SHADER_STAGE_VERTEX_BIT"); 16629 16630 ASSERT_NO_FATAL_FAILURE(Init()); 16631 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 16632 16633 char const *vsSource = 16634 "#version 450\n" 16635 "\n" 16636 "void main(){\n" 16637 " gl_Position = vec4(1);\n" 16638 "}\n"; 16639 char const *fsSource = 16640 "#version 450\n" 16641 "\n" 16642 "layout(location=0) out vec4 color;\n" 16643 "void main(){\n" 16644 " color = vec4(1);\n" 16645 "}\n"; 16646 16647 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 16648 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 16649 16650 VkPipelineObj pipe(m_device); 16651 pipe.AddDefaultColorAttachment(); 16652 pipe.AddShader(&vs); 16653 pipe.AddShader(&vs); // intentionally duplicate vertex shader attachment 16654 pipe.AddShader(&fs); 16655 16656 VkDescriptorSetObj descriptorSet(m_device); 16657 descriptorSet.AppendDummy(); 16658 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 16659 16660 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16661 16662 m_errorMonitor->VerifyFound(); 16663 } 16664 16665 TEST_F(VkLayerTest, CreatePipelineMissingEntrypoint) { 16666 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "No entrypoint found named `foo`"); 16667 16668 ASSERT_NO_FATAL_FAILURE(Init()); 16669 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 16670 16671 char const *vsSource = 16672 "#version 450\n" 16673 "void main(){\n" 16674 " gl_Position = vec4(0);\n" 16675 "}\n"; 16676 char const *fsSource = 16677 "#version 450\n" 16678 "\n" 16679 "layout(location=0) out vec4 color;\n" 16680 "void main(){\n" 16681 " color = vec4(1);\n" 16682 "}\n"; 16683 16684 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 16685 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this, "foo"); 16686 16687 VkPipelineObj pipe(m_device); 16688 pipe.AddDefaultColorAttachment(); 16689 pipe.AddShader(&vs); 16690 pipe.AddShader(&fs); 16691 16692 VkDescriptorSetObj descriptorSet(m_device); 16693 descriptorSet.AppendDummy(); 16694 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 16695 16696 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16697 16698 m_errorMonitor->VerifyFound(); 16699 } 16700 16701 TEST_F(VkLayerTest, CreatePipelineDepthStencilRequired) { 16702 m_errorMonitor->SetDesiredFailureMsg( 16703 VK_DEBUG_REPORT_ERROR_BIT_EXT, 16704 "pDepthStencilState is NULL when rasterization is enabled and subpass uses a depth/stencil attachment"); 16705 16706 ASSERT_NO_FATAL_FAILURE(Init()); 16707 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 16708 16709 char const *vsSource = 16710 "#version 450\n" 16711 "void main(){ gl_Position = vec4(0); }\n"; 16712 char const *fsSource = 16713 "#version 450\n" 16714 "\n" 16715 "layout(location=0) out vec4 color;\n" 16716 "void main(){\n" 16717 " color = vec4(1);\n" 16718 "}\n"; 16719 16720 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 16721 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 16722 16723 VkPipelineObj pipe(m_device); 16724 pipe.AddDefaultColorAttachment(); 16725 pipe.AddShader(&vs); 16726 pipe.AddShader(&fs); 16727 16728 VkDescriptorSetObj descriptorSet(m_device); 16729 descriptorSet.AppendDummy(); 16730 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 16731 16732 VkAttachmentDescription attachments[] = { 16733 { 16734 0, 16735 VK_FORMAT_B8G8R8A8_UNORM, 16736 VK_SAMPLE_COUNT_1_BIT, 16737 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 16738 VK_ATTACHMENT_STORE_OP_DONT_CARE, 16739 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 16740 VK_ATTACHMENT_STORE_OP_DONT_CARE, 16741 VK_IMAGE_LAYOUT_UNDEFINED, 16742 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 16743 }, 16744 { 16745 0, 16746 VK_FORMAT_D16_UNORM, 16747 VK_SAMPLE_COUNT_1_BIT, 16748 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 16749 VK_ATTACHMENT_STORE_OP_DONT_CARE, 16750 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 16751 VK_ATTACHMENT_STORE_OP_DONT_CARE, 16752 VK_IMAGE_LAYOUT_UNDEFINED, 16753 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 16754 }, 16755 }; 16756 VkAttachmentReference refs[] = { 16757 {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 16758 {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}, 16759 }; 16760 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &refs[0], nullptr, &refs[1], 0, nullptr}; 16761 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr}; 16762 VkRenderPass rp; 16763 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 16764 ASSERT_VK_SUCCESS(err); 16765 16766 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), rp); 16767 16768 m_errorMonitor->VerifyFound(); 16769 16770 vkDestroyRenderPass(m_device->device(), rp, nullptr); 16771 } 16772 16773 TEST_F(VkLayerTest, CreatePipelineTessPatchDecorationMismatch) { 16774 TEST_DESCRIPTION( 16775 "Test that an error is produced for a variable output from the TCS without the patch decoration, but consumed in the TES " 16776 "with the decoration."); 16777 m_errorMonitor->SetDesiredFailureMsg( 16778 VK_DEBUG_REPORT_ERROR_BIT_EXT, 16779 "is per-vertex in tessellation control shader stage but per-patch in tessellation evaluation shader stage"); 16780 16781 ASSERT_NO_FATAL_FAILURE(Init()); 16782 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 16783 16784 if (!m_device->phy().features().tessellationShader) { 16785 printf(" Device does not support tessellation shaders; skipped.\n"); 16786 return; 16787 } 16788 16789 char const *vsSource = 16790 "#version 450\n" 16791 "void main(){}\n"; 16792 char const *tcsSource = 16793 "#version 450\n" 16794 "layout(location=0) out int x[];\n" 16795 "layout(vertices=3) out;\n" 16796 "void main(){\n" 16797 " gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n" 16798 " gl_TessLevelInner[0] = 1;\n" 16799 " x[gl_InvocationID] = gl_InvocationID;\n" 16800 "}\n"; 16801 char const *tesSource = 16802 "#version 450\n" 16803 "layout(triangles, equal_spacing, cw) in;\n" 16804 "layout(location=0) patch in int x;\n" 16805 "void main(){\n" 16806 " gl_Position.xyz = gl_TessCoord;\n" 16807 " gl_Position.w = x;\n" 16808 "}\n"; 16809 char const *fsSource = 16810 "#version 450\n" 16811 "layout(location=0) out vec4 color;\n" 16812 "void main(){\n" 16813 " color = vec4(1);\n" 16814 "}\n"; 16815 16816 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 16817 VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this); 16818 VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this); 16819 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 16820 16821 VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0, 16822 VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE}; 16823 16824 VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3}; 16825 16826 VkPipelineObj pipe(m_device); 16827 pipe.SetInputAssembly(&iasci); 16828 pipe.SetTessellation(&tsci); 16829 pipe.AddDefaultColorAttachment(); 16830 pipe.AddShader(&vs); 16831 pipe.AddShader(&tcs); 16832 pipe.AddShader(&tes); 16833 pipe.AddShader(&fs); 16834 16835 VkDescriptorSetObj descriptorSet(m_device); 16836 descriptorSet.AppendDummy(); 16837 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 16838 16839 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16840 16841 m_errorMonitor->VerifyFound(); 16842 } 16843 16844 TEST_F(VkLayerTest, CreatePipelineTessErrors) { 16845 TEST_DESCRIPTION("Test various errors when creating a graphics pipeline with tessellation stages active."); 16846 16847 ASSERT_NO_FATAL_FAILURE(Init()); 16848 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 16849 16850 if (!m_device->phy().features().tessellationShader) { 16851 printf(" Device does not support tessellation shaders; skipped.\n"); 16852 return; 16853 } 16854 16855 char const *vsSource = 16856 "#version 450\n" 16857 "void main(){}\n"; 16858 char const *tcsSource = 16859 "#version 450\n" 16860 "layout(vertices=3) out;\n" 16861 "void main(){\n" 16862 " gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n" 16863 " gl_TessLevelInner[0] = 1;\n" 16864 "}\n"; 16865 char const *tesSource = 16866 "#version 450\n" 16867 "layout(triangles, equal_spacing, cw) in;\n" 16868 "void main(){\n" 16869 " gl_Position.xyz = gl_TessCoord;\n" 16870 " gl_Position.w = 0;\n" 16871 "}\n"; 16872 char const *fsSource = 16873 "#version 450\n" 16874 "layout(location=0) out vec4 color;\n" 16875 "void main(){\n" 16876 " color = vec4(1);\n" 16877 "}\n"; 16878 16879 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 16880 VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this); 16881 VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this); 16882 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 16883 16884 VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0, 16885 VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE}; 16886 16887 VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3}; 16888 16889 VkDescriptorSetObj descriptorSet(m_device); 16890 descriptorSet.AppendDummy(); 16891 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 16892 16893 { 16894 VkPipelineObj pipe(m_device); 16895 VkPipelineInputAssemblyStateCreateInfo iasci_bad = iasci; 16896 iasci_bad.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; // otherwise we get a failure about invalid topology 16897 pipe.SetInputAssembly(&iasci_bad); 16898 pipe.AddDefaultColorAttachment(); 16899 pipe.AddShader(&vs); 16900 pipe.AddShader(&fs); 16901 16902 // Pass a tess control shader without a tess eval shader 16903 pipe.AddShader(&tcs); 16904 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_096005b2); 16905 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16906 m_errorMonitor->VerifyFound(); 16907 } 16908 16909 { 16910 VkPipelineObj pipe(m_device); 16911 VkPipelineInputAssemblyStateCreateInfo iasci_bad = iasci; 16912 iasci_bad.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; // otherwise we get a failure about invalid topology 16913 pipe.SetInputAssembly(&iasci_bad); 16914 pipe.AddDefaultColorAttachment(); 16915 pipe.AddShader(&vs); 16916 pipe.AddShader(&fs); 16917 16918 // Pass a tess eval shader without a tess control shader 16919 pipe.AddShader(&tes); 16920 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_096005b4); 16921 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16922 m_errorMonitor->VerifyFound(); 16923 } 16924 16925 { 16926 VkPipelineObj pipe(m_device); 16927 pipe.SetInputAssembly(&iasci); 16928 pipe.AddDefaultColorAttachment(); 16929 pipe.AddShader(&vs); 16930 pipe.AddShader(&fs); 16931 16932 // Pass patch topology without tessellation shaders 16933 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_096005c2); 16934 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16935 m_errorMonitor->VerifyFound(); 16936 16937 pipe.AddShader(&tcs); 16938 pipe.AddShader(&tes); 16939 // Pass a NULL pTessellationState (with active tessellation shader stages) 16940 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_096005b6); 16941 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16942 m_errorMonitor->VerifyFound(); 16943 16944 // Pass an invalid pTessellationState (bad sType) 16945 VkPipelineTessellationStateCreateInfo tsci_bad = tsci; 16946 tsci_bad.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 16947 pipe.SetTessellation(&tsci_bad); 16948 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1082b00b); 16949 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16950 m_errorMonitor->VerifyFound(); 16951 // Pass out-of-range patchControlPoints 16952 tsci_bad = tsci; 16953 tsci_bad.patchControlPoints = 0; 16954 pipe.SetTessellation(&tsci); 16955 pipe.SetTessellation(&tsci_bad); 16956 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1080097c); 16957 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16958 m_errorMonitor->VerifyFound(); 16959 tsci_bad.patchControlPoints = m_device->props.limits.maxTessellationPatchSize + 1; 16960 pipe.SetTessellation(&tsci_bad); 16961 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1080097c); 16962 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16963 m_errorMonitor->VerifyFound(); 16964 pipe.SetTessellation(&tsci); 16965 16966 // Pass an invalid primitive topology 16967 VkPipelineInputAssemblyStateCreateInfo iasci_bad = iasci; 16968 iasci_bad.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; 16969 pipe.SetInputAssembly(&iasci_bad); 16970 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_096005c0); 16971 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 16972 m_errorMonitor->VerifyFound(); 16973 pipe.SetInputAssembly(&iasci); 16974 } 16975 } 16976 16977 TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict) { 16978 TEST_DESCRIPTION( 16979 "Test that an error is produced for a vertex attribute setup where multiple bindings provide the same location"); 16980 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 16981 "Duplicate vertex input binding descriptions for binding 0"); 16982 16983 ASSERT_NO_FATAL_FAILURE(Init()); 16984 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 16985 16986 /* Two binding descriptions for binding 0 */ 16987 VkVertexInputBindingDescription input_bindings[2]; 16988 memset(input_bindings, 0, sizeof(input_bindings)); 16989 16990 VkVertexInputAttributeDescription input_attrib; 16991 memset(&input_attrib, 0, sizeof(input_attrib)); 16992 input_attrib.format = VK_FORMAT_R32_SFLOAT; 16993 16994 char const *vsSource = 16995 "#version 450\n" 16996 "\n" 16997 "layout(location=0) in float x;\n" /* attrib provided float */ 16998 "void main(){\n" 16999 " gl_Position = vec4(x);\n" 17000 "}\n"; 17001 char const *fsSource = 17002 "#version 450\n" 17003 "\n" 17004 "layout(location=0) out vec4 color;\n" 17005 "void main(){\n" 17006 " color = vec4(1);\n" 17007 "}\n"; 17008 17009 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 17010 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 17011 17012 VkPipelineObj pipe(m_device); 17013 pipe.AddDefaultColorAttachment(); 17014 pipe.AddShader(&vs); 17015 pipe.AddShader(&fs); 17016 17017 pipe.AddVertexInputBindings(input_bindings, 2); 17018 pipe.AddVertexInputAttribs(&input_attrib, 1); 17019 17020 VkDescriptorSetObj descriptorSet(m_device); 17021 descriptorSet.AppendDummy(); 17022 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 17023 17024 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 17025 17026 m_errorMonitor->VerifyFound(); 17027 } 17028 17029 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten) { 17030 TEST_DESCRIPTION( 17031 "Test that an error is produced for a fragment shader which does not provide an output for one of the pipeline's color " 17032 "attachments"); 17033 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attachment 0 not written by fragment shader"); 17034 17035 ASSERT_NO_FATAL_FAILURE(Init()); 17036 17037 char const *vsSource = 17038 "#version 450\n" 17039 "\n" 17040 "void main(){\n" 17041 " gl_Position = vec4(1);\n" 17042 "}\n"; 17043 char const *fsSource = 17044 "#version 450\n" 17045 "\n" 17046 "void main(){\n" 17047 "}\n"; 17048 17049 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 17050 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 17051 17052 VkPipelineObj pipe(m_device); 17053 pipe.AddShader(&vs); 17054 pipe.AddShader(&fs); 17055 17056 /* set up CB 0, not written */ 17057 pipe.AddDefaultColorAttachment(); 17058 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 17059 17060 VkDescriptorSetObj descriptorSet(m_device); 17061 descriptorSet.AppendDummy(); 17062 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 17063 17064 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 17065 17066 m_errorMonitor->VerifyFound(); 17067 } 17068 17069 TEST_F(VkPositiveLayerTest, CreatePipelineFragmentOutputNotWrittenButMasked) { 17070 TEST_DESCRIPTION( 17071 "Test that no error is produced when the fragment shader fails to declare an output, but the corresponding attachment's " 17072 "write mask is 0."); 17073 m_errorMonitor->ExpectSuccess(); 17074 17075 ASSERT_NO_FATAL_FAILURE(Init()); 17076 17077 char const *vsSource = 17078 "#version 450\n" 17079 "\n" 17080 "void main(){\n" 17081 " gl_Position = vec4(1);\n" 17082 "}\n"; 17083 char const *fsSource = 17084 "#version 450\n" 17085 "\n" 17086 "void main(){\n" 17087 "}\n"; 17088 17089 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 17090 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 17091 17092 VkPipelineObj pipe(m_device); 17093 pipe.AddShader(&vs); 17094 pipe.AddShader(&fs); 17095 17096 /* set up CB 0, not written, but also masked */ 17097 pipe.AddDefaultColorAttachment(0); 17098 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 17099 17100 VkDescriptorSetObj descriptorSet(m_device); 17101 descriptorSet.AppendDummy(); 17102 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 17103 17104 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 17105 17106 m_errorMonitor->VerifyNotFound(); 17107 } 17108 17109 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed) { 17110 TEST_DESCRIPTION( 17111 "Test that a warning is produced for a fragment shader which provides a spurious output with no matching attachment"); 17112 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, 17113 "fragment shader writes to output location 1 with no matching attachment"); 17114 17115 ASSERT_NO_FATAL_FAILURE(Init()); 17116 17117 char const *vsSource = 17118 "#version 450\n" 17119 "\n" 17120 "void main(){\n" 17121 " gl_Position = vec4(1);\n" 17122 "}\n"; 17123 char const *fsSource = 17124 "#version 450\n" 17125 "\n" 17126 "layout(location=0) out vec4 x;\n" 17127 "layout(location=1) out vec4 y;\n" /* no matching attachment for this */ 17128 "void main(){\n" 17129 " x = vec4(1);\n" 17130 " y = vec4(1);\n" 17131 "}\n"; 17132 17133 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 17134 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 17135 17136 VkPipelineObj pipe(m_device); 17137 pipe.AddShader(&vs); 17138 pipe.AddShader(&fs); 17139 17140 /* set up CB 0, not written */ 17141 pipe.AddDefaultColorAttachment(); 17142 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 17143 /* FS writes CB 1, but we don't configure it */ 17144 17145 VkDescriptorSetObj descriptorSet(m_device); 17146 descriptorSet.AppendDummy(); 17147 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 17148 17149 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 17150 17151 m_errorMonitor->VerifyFound(); 17152 } 17153 17154 TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch) { 17155 TEST_DESCRIPTION( 17156 "Test that an error is produced for a mismatch between the fundamental type of an fragment shader output variable, and the " 17157 "format of the corresponding attachment"); 17158 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "does not match fragment shader output type"); 17159 17160 ASSERT_NO_FATAL_FAILURE(Init()); 17161 17162 char const *vsSource = 17163 "#version 450\n" 17164 "\n" 17165 "void main(){\n" 17166 " gl_Position = vec4(1);\n" 17167 "}\n"; 17168 char const *fsSource = 17169 "#version 450\n" 17170 "\n" 17171 "layout(location=0) out ivec4 x;\n" /* not UNORM */ 17172 "void main(){\n" 17173 " x = ivec4(1);\n" 17174 "}\n"; 17175 17176 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 17177 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 17178 17179 VkPipelineObj pipe(m_device); 17180 pipe.AddShader(&vs); 17181 pipe.AddShader(&fs); 17182 17183 /* set up CB 0; type is UNORM by default */ 17184 pipe.AddDefaultColorAttachment(); 17185 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 17186 17187 VkDescriptorSetObj descriptorSet(m_device); 17188 descriptorSet.AppendDummy(); 17189 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 17190 17191 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 17192 17193 m_errorMonitor->VerifyFound(); 17194 } 17195 17196 TEST_F(VkLayerTest, CreatePipelineUniformBlockNotProvided) { 17197 TEST_DESCRIPTION( 17198 "Test that an error is produced for a shader consuming a uniform block which has no corresponding binding in the pipeline " 17199 "layout"); 17200 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not declared in pipeline layout"); 17201 17202 ASSERT_NO_FATAL_FAILURE(Init()); 17203 17204 char const *vsSource = 17205 "#version 450\n" 17206 "\n" 17207 "void main(){\n" 17208 " gl_Position = vec4(1);\n" 17209 "}\n"; 17210 char const *fsSource = 17211 "#version 450\n" 17212 "\n" 17213 "layout(location=0) out vec4 x;\n" 17214 "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n" 17215 "void main(){\n" 17216 " x = vec4(bar.y);\n" 17217 "}\n"; 17218 17219 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 17220 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 17221 17222 VkPipelineObj pipe(m_device); 17223 pipe.AddShader(&vs); 17224 pipe.AddShader(&fs); 17225 17226 /* set up CB 0; type is UNORM by default */ 17227 pipe.AddDefaultColorAttachment(); 17228 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 17229 17230 VkDescriptorSetObj descriptorSet(m_device); 17231 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 17232 17233 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 17234 17235 m_errorMonitor->VerifyFound(); 17236 } 17237 17238 TEST_F(VkLayerTest, CreatePipelinePushConstantsNotInLayout) { 17239 TEST_DESCRIPTION( 17240 "Test that an error is produced for a shader consuming push constants which are not provided in the pipeline layout"); 17241 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not declared in layout"); 17242 17243 ASSERT_NO_FATAL_FAILURE(Init()); 17244 17245 char const *vsSource = 17246 "#version 450\n" 17247 "\n" 17248 "layout(push_constant, std430) uniform foo { float x; } consts;\n" 17249 "void main(){\n" 17250 " gl_Position = vec4(consts.x);\n" 17251 "}\n"; 17252 char const *fsSource = 17253 "#version 450\n" 17254 "\n" 17255 "layout(location=0) out vec4 x;\n" 17256 "void main(){\n" 17257 " x = vec4(1);\n" 17258 "}\n"; 17259 17260 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 17261 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 17262 17263 VkPipelineObj pipe(m_device); 17264 pipe.AddShader(&vs); 17265 pipe.AddShader(&fs); 17266 17267 /* set up CB 0; type is UNORM by default */ 17268 pipe.AddDefaultColorAttachment(); 17269 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 17270 17271 VkDescriptorSetObj descriptorSet(m_device); 17272 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 17273 17274 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 17275 17276 /* should have generated an error -- no push constant ranges provided! */ 17277 m_errorMonitor->VerifyFound(); 17278 } 17279 17280 TEST_F(VkLayerTest, CreatePipelineInputAttachmentMissing) { 17281 TEST_DESCRIPTION( 17282 "Test that an error is produced for a shader consuming an input attachment which is not included in the subpass " 17283 "description"); 17284 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 17285 "consumes input attachment index 0 but not provided in subpass"); 17286 17287 ASSERT_NO_FATAL_FAILURE(Init()); 17288 17289 char const *vsSource = 17290 "#version 450\n" 17291 "\n" 17292 "void main(){\n" 17293 " gl_Position = vec4(1);\n" 17294 "}\n"; 17295 char const *fsSource = 17296 "#version 450\n" 17297 "\n" 17298 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n" 17299 "layout(location=0) out vec4 color;\n" 17300 "void main() {\n" 17301 " color = subpassLoad(x);\n" 17302 "}\n"; 17303 17304 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 17305 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 17306 17307 VkPipelineObj pipe(m_device); 17308 pipe.AddShader(&vs); 17309 pipe.AddShader(&fs); 17310 pipe.AddDefaultColorAttachment(); 17311 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 17312 17313 VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}; 17314 const VkDescriptorSetLayoutObj dsl(m_device, {dslb}); 17315 17316 const VkPipelineLayoutObj pl(m_device, {&dsl}); 17317 17318 // error here. 17319 pipe.CreateVKPipeline(pl.handle(), renderPass()); 17320 17321 m_errorMonitor->VerifyFound(); 17322 } 17323 17324 TEST_F(VkLayerTest, CreatePipelineInputAttachmentTypeMismatch) { 17325 TEST_DESCRIPTION( 17326 "Test that an error is produced for a shader consuming an input attachment with a format having a different fundamental " 17327 "type"); 17328 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 17329 "input attachment 0 format of VK_FORMAT_R8G8B8A8_UINT does not match"); 17330 17331 ASSERT_NO_FATAL_FAILURE(Init()); 17332 17333 char const *vsSource = 17334 "#version 450\n" 17335 "\n" 17336 "void main(){\n" 17337 " gl_Position = vec4(1);\n" 17338 "}\n"; 17339 char const *fsSource = 17340 "#version 450\n" 17341 "\n" 17342 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n" 17343 "layout(location=0) out vec4 color;\n" 17344 "void main() {\n" 17345 " color = subpassLoad(x);\n" 17346 "}\n"; 17347 17348 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 17349 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 17350 17351 VkPipelineObj pipe(m_device); 17352 pipe.AddShader(&vs); 17353 pipe.AddShader(&fs); 17354 pipe.AddDefaultColorAttachment(); 17355 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 17356 17357 VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}; 17358 const VkDescriptorSetLayoutObj dsl(m_device, {dslb}); 17359 17360 const VkPipelineLayoutObj pl(m_device, {&dsl}); 17361 17362 VkAttachmentDescription descs[2] = { 17363 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, 17364 VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 17365 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 17366 {0, VK_FORMAT_R8G8B8A8_UINT, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, 17367 VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL}, 17368 }; 17369 VkAttachmentReference color = { 17370 0, 17371 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 17372 }; 17373 VkAttachmentReference input = { 17374 1, 17375 VK_IMAGE_LAYOUT_GENERAL, 17376 }; 17377 17378 VkSubpassDescription sd = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr}; 17379 17380 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr}; 17381 VkRenderPass rp; 17382 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 17383 ASSERT_VK_SUCCESS(err); 17384 17385 // error here. 17386 pipe.CreateVKPipeline(pl.handle(), rp); 17387 17388 m_errorMonitor->VerifyFound(); 17389 17390 vkDestroyRenderPass(m_device->device(), rp, nullptr); 17391 } 17392 17393 TEST_F(VkLayerTest, CreatePipelineInputAttachmentMissingArray) { 17394 TEST_DESCRIPTION( 17395 "Test that an error is produced for a shader consuming an input attachment which is not included in the subpass " 17396 "description -- array case"); 17397 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 17398 "consumes input attachment index 0 but not provided in subpass"); 17399 17400 ASSERT_NO_FATAL_FAILURE(Init()); 17401 17402 char const *vsSource = 17403 "#version 450\n" 17404 "\n" 17405 "void main(){\n" 17406 " gl_Position = vec4(1);\n" 17407 "}\n"; 17408 char const *fsSource = 17409 "#version 450\n" 17410 "\n" 17411 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput xs[1];\n" 17412 "layout(location=0) out vec4 color;\n" 17413 "void main() {\n" 17414 " color = subpassLoad(xs[0]);\n" 17415 "}\n"; 17416 17417 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 17418 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 17419 17420 VkPipelineObj pipe(m_device); 17421 pipe.AddShader(&vs); 17422 pipe.AddShader(&fs); 17423 pipe.AddDefaultColorAttachment(); 17424 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 17425 17426 VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}; 17427 const VkDescriptorSetLayoutObj dsl(m_device, {dslb}); 17428 17429 const VkPipelineLayoutObj pl(m_device, {&dsl}); 17430 17431 // error here. 17432 pipe.CreateVKPipeline(pl.handle(), renderPass()); 17433 17434 m_errorMonitor->VerifyFound(); 17435 } 17436 17437 TEST_F(VkLayerTest, CreateComputePipelineMissingDescriptor) { 17438 TEST_DESCRIPTION( 17439 "Test that an error is produced for a compute pipeline consuming a descriptor which is not provided in the pipeline " 17440 "layout"); 17441 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Shader uses descriptor slot 0.0"); 17442 17443 ASSERT_NO_FATAL_FAILURE(Init()); 17444 17445 char const *csSource = 17446 "#version 450\n" 17447 "\n" 17448 "layout(local_size_x=1) in;\n" 17449 "layout(set=0, binding=0) buffer block { vec4 x; };\n" 17450 "void main(){\n" 17451 " x = vec4(1);\n" 17452 "}\n"; 17453 17454 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this); 17455 17456 VkDescriptorSetObj descriptorSet(m_device); 17457 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 17458 17459 VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, 17460 nullptr, 17461 0, 17462 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, 17463 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr}, 17464 descriptorSet.GetPipelineLayout(), 17465 VK_NULL_HANDLE, 17466 -1}; 17467 17468 VkPipeline pipe; 17469 VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe); 17470 17471 m_errorMonitor->VerifyFound(); 17472 17473 if (err == VK_SUCCESS) { 17474 vkDestroyPipeline(m_device->device(), pipe, nullptr); 17475 } 17476 } 17477 17478 TEST_F(VkLayerTest, CreateComputePipelineDescriptorTypeMismatch) { 17479 TEST_DESCRIPTION("Test that an error is produced for a pipeline consuming a descriptor-backed resource of a mismatched type"); 17480 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 17481 "but descriptor of type VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER"); 17482 17483 ASSERT_NO_FATAL_FAILURE(Init()); 17484 17485 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}; 17486 const VkDescriptorSetLayoutObj dsl(m_device, {binding}); 17487 17488 const VkPipelineLayoutObj pl(m_device, {&dsl}); 17489 17490 char const *csSource = 17491 "#version 450\n" 17492 "\n" 17493 "layout(local_size_x=1) in;\n" 17494 "layout(set=0, binding=0) buffer block { vec4 x; };\n" 17495 "void main() {\n" 17496 " x.x = 1.0f;\n" 17497 "}\n"; 17498 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this); 17499 17500 VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, 17501 nullptr, 17502 0, 17503 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, 17504 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr}, 17505 pl.handle(), 17506 VK_NULL_HANDLE, 17507 -1}; 17508 17509 VkPipeline pipe; 17510 VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe); 17511 17512 m_errorMonitor->VerifyFound(); 17513 17514 if (err == VK_SUCCESS) { 17515 vkDestroyPipeline(m_device->device(), pipe, nullptr); 17516 } 17517 } 17518 17519 TEST_F(VkLayerTest, DrawTimeImageViewTypeMismatchWithPipeline) { 17520 TEST_DESCRIPTION( 17521 "Test that an error is produced when an image view type does not match the dimensionality declared in the shader"); 17522 17523 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "requires an image view of type VK_IMAGE_VIEW_TYPE_3D"); 17524 17525 ASSERT_NO_FATAL_FAILURE(Init()); 17526 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 17527 17528 char const *vsSource = 17529 "#version 450\n" 17530 "\n" 17531 "void main() { gl_Position = vec4(0); }\n"; 17532 char const *fsSource = 17533 "#version 450\n" 17534 "\n" 17535 "layout(set=0, binding=0) uniform sampler3D s;\n" 17536 "layout(location=0) out vec4 color;\n" 17537 "void main() {\n" 17538 " color = texture(s, vec3(0));\n" 17539 "}\n"; 17540 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 17541 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 17542 17543 VkPipelineObj pipe(m_device); 17544 pipe.AddShader(&vs); 17545 pipe.AddShader(&fs); 17546 pipe.AddDefaultColorAttachment(); 17547 17548 VkTextureObj texture(m_device, nullptr); 17549 VkSamplerObj sampler(m_device); 17550 17551 VkDescriptorSetObj descriptorSet(m_device); 17552 descriptorSet.AppendSamplerTexture(&sampler, &texture); 17553 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 17554 17555 VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 17556 ASSERT_VK_SUCCESS(err); 17557 17558 m_commandBuffer->begin(); 17559 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 17560 17561 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 17562 m_commandBuffer->BindDescriptorSet(descriptorSet); 17563 17564 VkViewport viewport = {0, 0, 16, 16, 0, 1}; 17565 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 17566 VkRect2D scissor = {{0, 0}, {16, 16}}; 17567 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 17568 17569 // error produced here. 17570 vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); 17571 17572 m_errorMonitor->VerifyFound(); 17573 17574 m_commandBuffer->EndRenderPass(); 17575 m_commandBuffer->end(); 17576 } 17577 17578 TEST_F(VkLayerTest, DrawTimeImageMultisampleMismatchWithPipeline) { 17579 TEST_DESCRIPTION( 17580 "Test that an error is produced when a multisampled images are consumed via singlesample images types in the shader, or " 17581 "vice versa."); 17582 17583 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "requires bound image to have multiple samples"); 17584 17585 ASSERT_NO_FATAL_FAILURE(Init()); 17586 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 17587 17588 char const *vsSource = 17589 "#version 450\n" 17590 "\n" 17591 "void main() { gl_Position = vec4(0); }\n"; 17592 char const *fsSource = 17593 "#version 450\n" 17594 "\n" 17595 "layout(set=0, binding=0) uniform sampler2DMS s;\n" 17596 "layout(location=0) out vec4 color;\n" 17597 "void main() {\n" 17598 " color = texelFetch(s, ivec2(0), 0);\n" 17599 "}\n"; 17600 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 17601 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 17602 17603 VkPipelineObj pipe(m_device); 17604 pipe.AddShader(&vs); 17605 pipe.AddShader(&fs); 17606 pipe.AddDefaultColorAttachment(); 17607 17608 VkTextureObj texture(m_device, nullptr); // THIS LINE CAUSES CRASH ON MALI 17609 VkSamplerObj sampler(m_device); 17610 17611 VkDescriptorSetObj descriptorSet(m_device); 17612 descriptorSet.AppendSamplerTexture(&sampler, &texture); 17613 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 17614 17615 VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 17616 ASSERT_VK_SUCCESS(err); 17617 17618 m_commandBuffer->begin(); 17619 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 17620 17621 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 17622 m_commandBuffer->BindDescriptorSet(descriptorSet); 17623 17624 VkViewport viewport = {0, 0, 16, 16, 0, 1}; 17625 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 17626 VkRect2D scissor = {{0, 0}, {16, 16}}; 17627 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 17628 17629 // error produced here. 17630 vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); 17631 17632 m_errorMonitor->VerifyFound(); 17633 17634 m_commandBuffer->EndRenderPass(); 17635 m_commandBuffer->end(); 17636 } 17637 17638 TEST_F(VkLayerTest, CreateImageMinLimitsViolation) { 17639 TEST_DESCRIPTION("Create invalid image with invalid parameters of zero."); 17640 17641 ASSERT_NO_FATAL_FAILURE(Init()); 17642 17643 const VkFormat safe_format = VK_FORMAT_B8G8R8A8_UNORM; 17644 const VkImageUsageFlags safe_usage = VK_IMAGE_USAGE_SAMPLED_BIT; 17645 17646 VkImageCreateInfo info = {}; 17647 info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 17648 info.imageType = VK_IMAGE_TYPE_3D; 17649 info.format = safe_format; 17650 // extent to be set by tests 17651 info.mipLevels = 1; 17652 info.arrayLayers = 1; 17653 info.samples = VK_SAMPLE_COUNT_1_BIT; 17654 info.usage = safe_usage; 17655 17656 enum Dimension { kWidth = 0x1, kHeight = 0x2, kDepth = 0x4 }; 17657 17658 for (underlying_type<Dimension>::type bad_dimensions = 0x1; bad_dimensions < 0x8; ++bad_dimensions) { 17659 VkExtent3D extent = {1, 1, 1}; 17660 17661 if (bad_dimensions & kWidth) { 17662 extent.width = 0; 17663 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00760); 17664 } 17665 17666 if (bad_dimensions & kHeight) { 17667 extent.height = 0; 17668 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00762); 17669 } 17670 17671 if (bad_dimensions & kDepth) { 17672 extent.depth = 0; 17673 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00764); 17674 } 17675 17676 info.extent = extent; 17677 17678 VkImage image; 17679 vkCreateImage(m_device->device(), &info, NULL, &image); 17680 17681 m_errorMonitor->VerifyFound(); 17682 } 17683 17684 info.imageType = VK_IMAGE_TYPE_2D; 17685 info.extent = {64, 64, 1}; 17686 17687 { 17688 VkImageCreateInfo bad_info = info; 17689 bad_info.mipLevels = 0; 17690 17691 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00766); 17692 VkImage image; 17693 vkCreateImage(m_device->device(), &bad_info, NULL, &image); 17694 m_errorMonitor->VerifyFound(); 17695 } 17696 17697 { 17698 VkImageCreateInfo bad_info = info; 17699 bad_info.arrayLayers = 0; 17700 17701 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00768); 17702 VkImage image; 17703 vkCreateImage(m_device->device(), &bad_info, NULL, &image); 17704 m_errorMonitor->VerifyFound(); 17705 } 17706 } 17707 17708 TEST_F(VkLayerTest, AttachmentDescriptionUndefinedFormat) { 17709 TEST_DESCRIPTION("Create a render pass with an attachment description format set to VK_FORMAT_UNDEFINED"); 17710 17711 ASSERT_NO_FATAL_FAILURE(Init()); 17712 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 17713 17714 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "format is VK_FORMAT_UNDEFINED"); 17715 17716 VkAttachmentReference color_attach = {}; 17717 color_attach.layout = VK_IMAGE_LAYOUT_GENERAL; 17718 color_attach.attachment = 0; 17719 VkSubpassDescription subpass = {}; 17720 subpass.colorAttachmentCount = 1; 17721 subpass.pColorAttachments = &color_attach; 17722 17723 VkRenderPassCreateInfo rpci = {}; 17724 rpci.subpassCount = 1; 17725 rpci.pSubpasses = &subpass; 17726 rpci.attachmentCount = 1; 17727 VkAttachmentDescription attach_desc = {}; 17728 attach_desc.format = VK_FORMAT_UNDEFINED; 17729 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; 17730 attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; 17731 rpci.pAttachments = &attach_desc; 17732 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 17733 VkRenderPass rp; 17734 VkResult result = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 17735 17736 m_errorMonitor->VerifyFound(); 17737 17738 if (result == VK_SUCCESS) { 17739 vkDestroyRenderPass(m_device->device(), rp, NULL); 17740 } 17741 } 17742 17743 TEST_F(VkLayerTest, AttachmentDescriptionInvalidFinalLayout) { 17744 TEST_DESCRIPTION("VkAttachmentDescription's finalLayout must not be UNDEFINED or PREINITIALIZED"); 17745 17746 ASSERT_NO_FATAL_FAILURE(Init()); 17747 17748 VkAttachmentDescription attach_desc = {}; 17749 attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM; 17750 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; 17751 attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 17752 attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; 17753 attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; 17754 attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; 17755 attach_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 17756 attach_desc.finalLayout = VK_IMAGE_LAYOUT_UNDEFINED; 17757 VkAttachmentReference attach_ref = {}; 17758 attach_ref.attachment = 0; 17759 attach_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 17760 VkSubpassDescription subpass = {}; 17761 subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; 17762 subpass.colorAttachmentCount = 1; 17763 subpass.pColorAttachments = &attach_ref; 17764 VkRenderPassCreateInfo rpci = {}; 17765 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 17766 rpci.attachmentCount = 1; 17767 rpci.pAttachments = &attach_desc; 17768 rpci.subpassCount = 1; 17769 rpci.pSubpasses = &subpass; 17770 VkRenderPass rp = VK_NULL_HANDLE; 17771 17772 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_00800696); 17773 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 17774 m_errorMonitor->VerifyFound(); 17775 if (rp != VK_NULL_HANDLE) { 17776 vkDestroyRenderPass(m_device->device(), rp, NULL); 17777 } 17778 17779 attach_desc.finalLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; 17780 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_00800696); 17781 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 17782 m_errorMonitor->VerifyFound(); 17783 if (rp != VK_NULL_HANDLE) { 17784 vkDestroyRenderPass(m_device->device(), rp, NULL); 17785 } 17786 } 17787 17788 TEST_F(VkLayerTest, CreateImageViewNoMemoryBoundToImage) { 17789 VkResult err; 17790 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 17791 " used with no memory bound. Memory should be bound by calling vkBindImageMemory()."); 17792 17793 ASSERT_NO_FATAL_FAILURE(Init()); 17794 17795 // Create an image and try to create a view with no memory backing the image 17796 VkImage image; 17797 17798 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 17799 const int32_t tex_width = 32; 17800 const int32_t tex_height = 32; 17801 17802 VkImageCreateInfo image_create_info = {}; 17803 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 17804 image_create_info.pNext = NULL; 17805 image_create_info.imageType = VK_IMAGE_TYPE_2D; 17806 image_create_info.format = tex_format; 17807 image_create_info.extent.width = tex_width; 17808 image_create_info.extent.height = tex_height; 17809 image_create_info.extent.depth = 1; 17810 image_create_info.mipLevels = 1; 17811 image_create_info.arrayLayers = 1; 17812 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 17813 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 17814 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 17815 image_create_info.flags = 0; 17816 17817 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 17818 ASSERT_VK_SUCCESS(err); 17819 17820 VkImageViewCreateInfo image_view_create_info = {}; 17821 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 17822 image_view_create_info.image = image; 17823 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; 17824 image_view_create_info.format = tex_format; 17825 image_view_create_info.subresourceRange.layerCount = 1; 17826 image_view_create_info.subresourceRange.baseMipLevel = 0; 17827 image_view_create_info.subresourceRange.levelCount = 1; 17828 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 17829 17830 VkImageView view; 17831 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view); 17832 17833 m_errorMonitor->VerifyFound(); 17834 vkDestroyImage(m_device->device(), image, NULL); 17835 // If last error is success, it still created the view, so delete it. 17836 if (err == VK_SUCCESS) { 17837 vkDestroyImageView(m_device->device(), view, NULL); 17838 } 17839 } 17840 17841 TEST_F(VkLayerTest, InvalidImageViewAspect) { 17842 TEST_DESCRIPTION("Create an image and try to create a view with an invalid aspectMask"); 17843 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a400c01); 17844 17845 ASSERT_NO_FATAL_FAILURE(Init()); 17846 17847 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 17848 VkImageObj image(m_device); 17849 image.Init(32, 32, 1, tex_format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_LINEAR, 0); 17850 ASSERT_TRUE(image.initialized()); 17851 17852 VkImageViewCreateInfo image_view_create_info = {}; 17853 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 17854 image_view_create_info.image = image.handle(); 17855 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; 17856 image_view_create_info.format = tex_format; 17857 image_view_create_info.subresourceRange.baseMipLevel = 0; 17858 image_view_create_info.subresourceRange.levelCount = 1; 17859 image_view_create_info.subresourceRange.layerCount = 1; 17860 // Cause an error by setting an invalid image aspect 17861 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT; 17862 17863 VkImageView view; 17864 vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view); 17865 17866 m_errorMonitor->VerifyFound(); 17867 } 17868 17869 TEST_F(VkLayerTest, ExerciseGetImageSubresourceLayout) { 17870 TEST_DESCRIPTION("Test vkGetImageSubresourceLayout() valid usages"); 17871 17872 ASSERT_NO_FATAL_FAILURE(Init()); 17873 VkSubresourceLayout subres_layout = {}; 17874 17875 // VU 00732: image must have been created with tiling equal to VK_IMAGE_TILING_LINEAR 17876 { 17877 const VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL; // ERROR: violates VU 00732 17878 VkImageObj img(m_device); 17879 img.InitNoLayout(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, tiling); 17880 ASSERT_TRUE(img.initialized()); 17881 17882 VkImageSubresource subres = {}; 17883 subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 17884 subres.mipLevel = 0; 17885 subres.arrayLayer = 0; 17886 17887 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_2a6007c8); 17888 vkGetImageSubresourceLayout(m_device->device(), img.image(), &subres, &subres_layout); 17889 m_errorMonitor->VerifyFound(); 17890 } 17891 17892 // VU 00733: The aspectMask member of pSubresource must only have a single bit set 17893 { 17894 VkImageObj img(m_device); 17895 img.InitNoLayout(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT); 17896 ASSERT_TRUE(img.initialized()); 17897 17898 VkImageSubresource subres = {}; 17899 subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_METADATA_BIT; // ERROR: triggers VU 00733 17900 subres.mipLevel = 0; 17901 subres.arrayLayer = 0; 17902 17903 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_2a6007ca); 17904 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a400c01); 17905 vkGetImageSubresourceLayout(m_device->device(), img.image(), &subres, &subres_layout); 17906 m_errorMonitor->VerifyFound(); 17907 } 17908 17909 // 00739 mipLevel must be less than the mipLevels specified in VkImageCreateInfo when the image was created 17910 { 17911 VkImageObj img(m_device); 17912 img.InitNoLayout(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT); 17913 ASSERT_TRUE(img.initialized()); 17914 17915 VkImageSubresource subres = {}; 17916 subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 17917 subres.mipLevel = 1; // ERROR: triggers VU 00739 17918 subres.arrayLayer = 0; 17919 17920 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a4007cc); 17921 vkGetImageSubresourceLayout(m_device->device(), img.image(), &subres, &subres_layout); 17922 m_errorMonitor->VerifyFound(); 17923 } 17924 17925 // 00740 arrayLayer must be less than the arrayLayers specified in VkImageCreateInfo when the image was created 17926 { 17927 VkImageObj img(m_device); 17928 img.InitNoLayout(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT); 17929 ASSERT_TRUE(img.initialized()); 17930 17931 VkImageSubresource subres = {}; 17932 subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 17933 subres.mipLevel = 0; 17934 subres.arrayLayer = 1; // ERROR: triggers VU 00740 17935 17936 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a4007ce); 17937 vkGetImageSubresourceLayout(m_device->device(), img.image(), &subres, &subres_layout); 17938 m_errorMonitor->VerifyFound(); 17939 } 17940 } 17941 17942 TEST_F(VkLayerTest, CopyImageLayerCountMismatch) { 17943 VkResult err; 17944 bool pass; 17945 17946 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00118); 17947 17948 ASSERT_NO_FATAL_FAILURE(Init()); 17949 17950 // Create two images of different types and try to copy between them 17951 VkImage srcImage; 17952 VkImage dstImage; 17953 VkDeviceMemory srcMem; 17954 VkDeviceMemory destMem; 17955 VkMemoryRequirements memReqs; 17956 17957 VkImageCreateInfo image_create_info = {}; 17958 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 17959 image_create_info.pNext = NULL; 17960 image_create_info.imageType = VK_IMAGE_TYPE_2D; 17961 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; 17962 image_create_info.extent.width = 32; 17963 image_create_info.extent.height = 32; 17964 image_create_info.extent.depth = 1; 17965 image_create_info.mipLevels = 1; 17966 image_create_info.arrayLayers = 4; 17967 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 17968 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 17969 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 17970 image_create_info.flags = 0; 17971 17972 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage); 17973 ASSERT_VK_SUCCESS(err); 17974 17975 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; 17976 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage); 17977 ASSERT_VK_SUCCESS(err); 17978 17979 // Allocate memory 17980 VkMemoryAllocateInfo memAlloc = {}; 17981 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 17982 memAlloc.pNext = NULL; 17983 memAlloc.allocationSize = 0; 17984 memAlloc.memoryTypeIndex = 0; 17985 17986 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs); 17987 memAlloc.allocationSize = memReqs.size; 17988 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 17989 ASSERT_TRUE(pass); 17990 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem); 17991 ASSERT_VK_SUCCESS(err); 17992 17993 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs); 17994 memAlloc.allocationSize = memReqs.size; 17995 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 17996 ASSERT_VK_SUCCESS(err); 17997 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem); 17998 ASSERT_VK_SUCCESS(err); 17999 18000 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0); 18001 ASSERT_VK_SUCCESS(err); 18002 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0); 18003 ASSERT_VK_SUCCESS(err); 18004 18005 m_commandBuffer->begin(); 18006 VkImageCopy copyRegion; 18007 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 18008 copyRegion.srcSubresource.mipLevel = 0; 18009 copyRegion.srcSubresource.baseArrayLayer = 0; 18010 copyRegion.srcSubresource.layerCount = 1; 18011 copyRegion.srcOffset.x = 0; 18012 copyRegion.srcOffset.y = 0; 18013 copyRegion.srcOffset.z = 0; 18014 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 18015 copyRegion.dstSubresource.mipLevel = 0; 18016 copyRegion.dstSubresource.baseArrayLayer = 0; 18017 // Introduce failure by forcing the dst layerCount to differ from src 18018 copyRegion.dstSubresource.layerCount = 3; 18019 copyRegion.dstOffset.x = 0; 18020 copyRegion.dstOffset.y = 0; 18021 copyRegion.dstOffset.z = 0; 18022 copyRegion.extent.width = 1; 18023 copyRegion.extent.height = 1; 18024 copyRegion.extent.depth = 1; 18025 m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region); 18026 m_commandBuffer->end(); 18027 18028 m_errorMonitor->VerifyFound(); 18029 18030 vkDestroyImage(m_device->device(), srcImage, NULL); 18031 vkDestroyImage(m_device->device(), dstImage, NULL); 18032 vkFreeMemory(m_device->device(), srcMem, NULL); 18033 vkFreeMemory(m_device->device(), destMem, NULL); 18034 } 18035 18036 TEST_F(VkLayerTest, ImageLayerUnsupportedFormat) { 18037 TEST_DESCRIPTION("Creating images with unsuported formats "); 18038 18039 ASSERT_NO_FATAL_FAILURE(Init()); 18040 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 18041 18042 // Create image with unsupported format - Expect FORMAT_UNSUPPORTED 18043 VkImageCreateInfo image_create_info = {}; 18044 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 18045 image_create_info.imageType = VK_IMAGE_TYPE_2D; 18046 image_create_info.format = VK_FORMAT_UNDEFINED; 18047 image_create_info.extent.width = 32; 18048 image_create_info.extent.height = 32; 18049 image_create_info.extent.depth = 1; 18050 image_create_info.mipLevels = 1; 18051 image_create_info.arrayLayers = 1; 18052 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 18053 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 18054 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 18055 18056 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 18057 "vkCreateImage: VkFormat for image must not be VK_FORMAT_UNDEFINED"); 18058 18059 VkImage image; 18060 vkCreateImage(m_device->handle(), &image_create_info, NULL, &image); 18061 m_errorMonitor->VerifyFound(); 18062 18063 // Look for a format that is COMPLETELY unsupported with this hardware 18064 VkFormat unsupported = VK_FORMAT_UNDEFINED; 18065 for (int f = VK_FORMAT_BEGIN_RANGE; f <= VK_FORMAT_END_RANGE; f++) { 18066 VkFormat format = static_cast<VkFormat>(f); 18067 VkFormatProperties fProps = m_device->format_properties(format); 18068 if (format != VK_FORMAT_UNDEFINED && fProps.linearTilingFeatures == 0 && fProps.optimalTilingFeatures == 0) { 18069 unsupported = format; 18070 break; 18071 } 18072 } 18073 18074 if (unsupported != VK_FORMAT_UNDEFINED) { 18075 image_create_info.format = unsupported; 18076 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is an unsupported format"); 18077 18078 vkCreateImage(m_device->handle(), &image_create_info, NULL, &image); 18079 m_errorMonitor->VerifyFound(); 18080 } 18081 } 18082 18083 TEST_F(VkLayerTest, CreateImageViewFormatMismatchUnrelated) { 18084 TEST_DESCRIPTION("Create an image with a color format, then try to create a depth view of it"); 18085 18086 if (!EnableDeviceProfileLayer()) return; 18087 18088 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 18089 ASSERT_NO_FATAL_FAILURE(InitState()); 18090 18091 // Load required functions 18092 PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = 18093 (PFN_vkSetPhysicalDeviceFormatPropertiesEXT)vkGetInstanceProcAddr(instance(), "vkSetPhysicalDeviceFormatPropertiesEXT"); 18094 PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = 18095 (PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT)vkGetInstanceProcAddr(instance(), 18096 "vkGetOriginalPhysicalDeviceFormatPropertiesEXT"); 18097 18098 if (!(fpvkSetPhysicalDeviceFormatPropertiesEXT) || !(fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) { 18099 printf(" Can't find device_profile_api functions; skipped.\n"); 18100 return; 18101 } 18102 18103 auto depth_format = FindSupportedDepthStencilFormat(gpu()); 18104 if (!depth_format) { 18105 return; 18106 } 18107 18108 VkFormatProperties formatProps; 18109 18110 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), depth_format, &formatProps); 18111 formatProps.optimalTilingFeatures |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; 18112 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), depth_format, formatProps); 18113 18114 VkImageObj image(m_device); 18115 image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 18116 ASSERT_TRUE(image.initialized()); 18117 18118 VkImageView imgView; 18119 VkImageViewCreateInfo imgViewInfo = {}; 18120 imgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 18121 imgViewInfo.image = image.handle(); 18122 imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; 18123 imgViewInfo.format = depth_format; 18124 imgViewInfo.subresourceRange.layerCount = 1; 18125 imgViewInfo.subresourceRange.baseMipLevel = 0; 18126 imgViewInfo.subresourceRange.levelCount = 1; 18127 imgViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 18128 18129 // Can't use depth format for view into color image - Expect INVALID_FORMAT 18130 m_errorMonitor->SetDesiredFailureMsg( 18131 VK_DEBUG_REPORT_ERROR_BIT_EXT, 18132 "Formats MUST be IDENTICAL unless VK_IMAGE_CREATE_MUTABLE_FORMAT BIT was set on image creation."); 18133 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView); 18134 m_errorMonitor->VerifyFound(); 18135 } 18136 18137 TEST_F(VkLayerTest, CreateImageViewNoMutableFormatBit) { 18138 TEST_DESCRIPTION("Create an image view with a different format, when the image does not have MUTABLE_FORMAT bit"); 18139 18140 if (!EnableDeviceProfileLayer()) return; 18141 18142 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 18143 ASSERT_NO_FATAL_FAILURE(InitState()); 18144 18145 PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr; 18146 PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr; 18147 18148 // Load required functions 18149 if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) { 18150 return; 18151 } 18152 18153 VkImageObj image(m_device); 18154 image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 18155 ASSERT_TRUE(image.initialized()); 18156 18157 VkFormatProperties formatProps; 18158 18159 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_B8G8R8A8_UINT, &formatProps); 18160 formatProps.optimalTilingFeatures |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; 18161 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_B8G8R8A8_UINT, formatProps); 18162 18163 VkImageView imgView; 18164 VkImageViewCreateInfo imgViewInfo = {}; 18165 imgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 18166 imgViewInfo.image = image.handle(); 18167 imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; 18168 imgViewInfo.format = VK_FORMAT_B8G8R8A8_UINT; 18169 imgViewInfo.subresourceRange.layerCount = 1; 18170 imgViewInfo.subresourceRange.baseMipLevel = 0; 18171 imgViewInfo.subresourceRange.levelCount = 1; 18172 imgViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 18173 18174 // Same compatibility class but no MUTABLE_FORMAT bit - Expect 18175 // VIEW_CREATE_ERROR 18176 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac007f6); 18177 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView); 18178 m_errorMonitor->VerifyFound(); 18179 } 18180 18181 TEST_F(VkLayerTest, CreateImageViewDifferentClass) { 18182 TEST_DESCRIPTION("Passing bad parameters to CreateImageView"); 18183 18184 ASSERT_NO_FATAL_FAILURE(Init()); 18185 18186 if (!(m_device->format_properties(VK_FORMAT_R8_UINT).optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) { 18187 printf("Device does not support R8_UINT as color attachment; skipped"); 18188 return; 18189 } 18190 18191 VkImageCreateInfo mutImgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 18192 nullptr, 18193 VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, 18194 VK_IMAGE_TYPE_2D, 18195 VK_FORMAT_R8_UINT, 18196 {128, 128, 1}, 18197 1, 18198 1, 18199 VK_SAMPLE_COUNT_1_BIT, 18200 VK_IMAGE_TILING_OPTIMAL, 18201 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 18202 VK_SHARING_MODE_EXCLUSIVE, 18203 0, 18204 nullptr, 18205 VK_IMAGE_LAYOUT_UNDEFINED}; 18206 VkImageObj mutImage(m_device); 18207 mutImage.init(&mutImgInfo); 18208 ASSERT_TRUE(mutImage.initialized()); 18209 18210 VkImageView imgView; 18211 VkImageViewCreateInfo imgViewInfo = {}; 18212 imgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 18213 imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; 18214 imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM; 18215 imgViewInfo.subresourceRange.layerCount = 1; 18216 imgViewInfo.subresourceRange.baseMipLevel = 0; 18217 imgViewInfo.subresourceRange.levelCount = 1; 18218 imgViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 18219 imgViewInfo.image = mutImage.handle(); 18220 18221 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac007f4); 18222 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView); 18223 m_errorMonitor->VerifyFound(); 18224 } 18225 18226 TEST_F(VkLayerTest, CreateImageViewInvalidSubresourceRange) { 18227 TEST_DESCRIPTION("Passing bad image subrange to CreateImageView"); 18228 18229 ASSERT_NO_FATAL_FAILURE(Init()); 18230 18231 VkImageObj image(m_device); 18232 image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL); 18233 ASSERT_TRUE(image.create_info().arrayLayers == 1); 18234 ASSERT_TRUE(image.initialized()); 18235 18236 VkImageView img_view; 18237 VkImageViewCreateInfo img_view_info_template = {}; 18238 img_view_info_template.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 18239 img_view_info_template.image = image.handle(); 18240 img_view_info_template.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; 18241 img_view_info_template.format = image.format(); 18242 // subresourceRange to be filled later for the purposes of this test 18243 img_view_info_template.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 18244 img_view_info_template.subresourceRange.baseMipLevel = 0; 18245 img_view_info_template.subresourceRange.levelCount = 0; 18246 img_view_info_template.subresourceRange.baseArrayLayer = 0; 18247 img_view_info_template.subresourceRange.layerCount = 0; 18248 18249 // Try baseMipLevel >= image.mipLevels with VK_REMAINING_MIP_LEVELS 18250 { 18251 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac00b8c); 18252 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, VK_REMAINING_MIP_LEVELS, 0, 1}; 18253 VkImageViewCreateInfo img_view_info = img_view_info_template; 18254 img_view_info.subresourceRange = range; 18255 vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view); 18256 m_errorMonitor->VerifyFound(); 18257 } 18258 18259 // Try baseMipLevel >= image.mipLevels without VK_REMAINING_MIP_LEVELS 18260 { 18261 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac00b8c); 18262 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac00b8e); 18263 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 0, 1}; 18264 VkImageViewCreateInfo img_view_info = img_view_info_template; 18265 img_view_info.subresourceRange = range; 18266 vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view); 18267 m_errorMonitor->VerifyFound(); 18268 } 18269 18270 // Try levelCount = 0 18271 { 18272 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac00b8e); 18273 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 0, 1}; 18274 VkImageViewCreateInfo img_view_info = img_view_info_template; 18275 img_view_info.subresourceRange = range; 18276 vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view); 18277 m_errorMonitor->VerifyFound(); 18278 } 18279 18280 // Try baseMipLevel + levelCount > image.mipLevels 18281 { 18282 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac00b8e); 18283 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 2, 0, 1}; 18284 VkImageViewCreateInfo img_view_info = img_view_info_template; 18285 img_view_info.subresourceRange = range; 18286 vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view); 18287 m_errorMonitor->VerifyFound(); 18288 } 18289 18290 // Try baseArrayLayer >= image.arrayLayers with VK_REMAINING_ARRAY_LAYERS 18291 { 18292 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac00b90); 18293 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, VK_REMAINING_ARRAY_LAYERS}; 18294 VkImageViewCreateInfo img_view_info = img_view_info_template; 18295 img_view_info.subresourceRange = range; 18296 vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view); 18297 m_errorMonitor->VerifyFound(); 18298 } 18299 18300 // Try baseArrayLayer >= image.arrayLayers without VK_REMAINING_ARRAY_LAYERS 18301 { 18302 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac00b90); 18303 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac00b92); 18304 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, 1}; 18305 VkImageViewCreateInfo img_view_info = img_view_info_template; 18306 img_view_info.subresourceRange = range; 18307 vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view); 18308 m_errorMonitor->VerifyFound(); 18309 } 18310 18311 // Try layerCount = 0 18312 { 18313 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 18314 "vkCreateImageView: if pCreateInfo->viewType is VK_IMAGE_TYPE_2D_ARRAY, " 18315 "pCreateInfo->subresourceRange.layerCount must be >= 1"); 18316 // TODO: The test environment aborts the Vulkan call in parameter_validation layer before VALIDATION_ERROR_0ac00b92 test 18317 // m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac00b92); 18318 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 0}; 18319 VkImageViewCreateInfo img_view_info = img_view_info_template; 18320 img_view_info.subresourceRange = range; 18321 vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view); 18322 m_errorMonitor->VerifyFound(); 18323 } 18324 18325 // Try baseArrayLayer + layerCount > image.arrayLayers 18326 { 18327 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0ac00b92); 18328 const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 2}; 18329 VkImageViewCreateInfo img_view_info = img_view_info_template; 18330 img_view_info.subresourceRange = range; 18331 vkCreateImageView(m_device->handle(), &img_view_info, nullptr, &img_view); 18332 m_errorMonitor->VerifyFound(); 18333 } 18334 } 18335 18336 TEST_F(VkLayerTest, CompressedImageMipCopyTests) { 18337 TEST_DESCRIPTION("Image/Buffer copies for higher mip levels"); 18338 18339 ASSERT_NO_FATAL_FAILURE(Init()); 18340 18341 VkPhysicalDeviceFeatures device_features = {}; 18342 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features)); 18343 VkFormat compressed_format = VK_FORMAT_UNDEFINED; 18344 if (device_features.textureCompressionBC) { 18345 compressed_format = VK_FORMAT_BC3_SRGB_BLOCK; 18346 } else if (device_features.textureCompressionETC2) { 18347 compressed_format = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK; 18348 } else if (device_features.textureCompressionASTC_LDR) { 18349 compressed_format = VK_FORMAT_ASTC_4x4_UNORM_BLOCK; 18350 } else { 18351 printf(" No compressed formats supported - CompressedImageMipCopyTests skipped.\n"); 18352 return; 18353 } 18354 18355 VkImageCreateInfo ci; 18356 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 18357 ci.pNext = NULL; 18358 ci.flags = 0; 18359 ci.imageType = VK_IMAGE_TYPE_2D; 18360 ci.format = compressed_format; 18361 ci.extent = {32, 32, 1}; 18362 ci.mipLevels = 6; 18363 ci.arrayLayers = 1; 18364 ci.samples = VK_SAMPLE_COUNT_1_BIT; 18365 ci.tiling = VK_IMAGE_TILING_OPTIMAL; 18366 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 18367 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 18368 ci.queueFamilyIndexCount = 0; 18369 ci.pQueueFamilyIndices = NULL; 18370 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 18371 18372 VkImageObj image(m_device); 18373 image.init(&ci); 18374 ASSERT_TRUE(image.initialized()); 18375 18376 VkImageObj odd_image(m_device); 18377 ci.extent = {31, 32, 1}; // Mips are [31,32] [15,16] [7,8] [3,4], [1,2] [1,1] 18378 odd_image.init(&ci); 18379 ASSERT_TRUE(odd_image.initialized()); 18380 18381 // Allocate buffers 18382 VkMemoryPropertyFlags reqs = 0; 18383 vk_testing::Buffer buffer_1024, buffer_64, buffer_16, buffer_8; 18384 buffer_1024.init_as_src_and_dst(*m_device, 1024, reqs); 18385 buffer_64.init_as_src_and_dst(*m_device, 64, reqs); 18386 buffer_16.init_as_src_and_dst(*m_device, 16, reqs); 18387 buffer_8.init_as_src_and_dst(*m_device, 8, reqs); 18388 18389 VkBufferImageCopy region = {}; 18390 region.bufferRowLength = 0; 18391 region.bufferImageHeight = 0; 18392 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 18393 region.imageSubresource.layerCount = 1; 18394 region.imageOffset = {0, 0, 0}; 18395 region.bufferOffset = 0; 18396 18397 // start recording 18398 m_commandBuffer->begin(); 18399 18400 // Mip level copies that work - 5 levels 18401 m_errorMonitor->ExpectSuccess(); 18402 18403 // Mip 0 should fit in 1k buffer - 1k texels @ 1b each 18404 region.imageExtent = {32, 32, 1}; 18405 region.imageSubresource.mipLevel = 0; 18406 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_1024.handle(), 1, ®ion); 18407 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_1024.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); 18408 18409 // Mip 2 should fit in 64b buffer - 64 texels @ 1b each 18410 region.imageExtent = {8, 8, 1}; 18411 region.imageSubresource.mipLevel = 2; 18412 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64.handle(), 1, ®ion); 18413 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); 18414 18415 // Mip 3 should fit in 16b buffer - 16 texels @ 1b each 18416 region.imageExtent = {4, 4, 1}; 18417 region.imageSubresource.mipLevel = 3; 18418 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, ®ion); 18419 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); 18420 18421 // Mip 4&5 should fit in 16b buffer with no complaint - 4 & 1 texels @ 1b each 18422 region.imageExtent = {2, 2, 1}; 18423 region.imageSubresource.mipLevel = 4; 18424 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, ®ion); 18425 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); 18426 18427 region.imageExtent = {1, 1, 1}; 18428 region.imageSubresource.mipLevel = 5; 18429 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, ®ion); 18430 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); 18431 m_errorMonitor->VerifyNotFound(); 18432 18433 // Buffer must accomodate a full compressed block, regardless of texel count 18434 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1920016e); 18435 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_8.handle(), 1, ®ion); 18436 m_errorMonitor->VerifyFound(); 18437 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18e00156); 18438 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_8.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); 18439 m_errorMonitor->VerifyFound(); 18440 18441 // Copy width < compressed block size, but not the full mip width 18442 region.imageExtent = {1, 2, 1}; 18443 region.imageSubresource.mipLevel = 4; 18444 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0160019e); 18445 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, ®ion); 18446 m_errorMonitor->VerifyFound(); 18447 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0160019e); 18448 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); 18449 m_errorMonitor->VerifyFound(); 18450 18451 // Copy height < compressed block size but not the full mip height 18452 region.imageExtent = {2, 1, 1}; 18453 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_016001a0); 18454 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, ®ion); 18455 m_errorMonitor->VerifyFound(); 18456 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_016001a0); 18457 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); 18458 m_errorMonitor->VerifyFound(); 18459 18460 // Offsets must be multiple of compressed block size 18461 region.imageOffset = {1, 1, 0}; 18462 region.imageExtent = {1, 1, 1}; 18463 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0160019a); 18464 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, ®ion); 18465 m_errorMonitor->VerifyFound(); 18466 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0160019a); 18467 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); 18468 m_errorMonitor->VerifyFound(); 18469 18470 // Offset + extent width = mip width - should succeed 18471 region.imageOffset = {4, 4, 0}; 18472 region.imageExtent = {3, 4, 1}; 18473 region.imageSubresource.mipLevel = 2; 18474 m_errorMonitor->ExpectSuccess(); 18475 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, ®ion); 18476 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); 18477 m_errorMonitor->VerifyNotFound(); 18478 18479 // Offset + extent width > mip width, but still within the final compressed block - should succeed 18480 region.imageExtent = {4, 4, 1}; 18481 m_errorMonitor->ExpectSuccess(); 18482 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, ®ion); 18483 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); 18484 m_errorMonitor->VerifyNotFound(); 18485 18486 // Offset + extent width < mip width and not a multiple of block width - should fail 18487 region.imageExtent = {3, 3, 1}; 18488 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_016001a0); 18489 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, ®ion); 18490 m_errorMonitor->VerifyFound(); 18491 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_016001a0); 18492 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); 18493 m_errorMonitor->VerifyFound(); 18494 } 18495 18496 TEST_F(VkLayerTest, ImageBufferCopyTests) { 18497 TEST_DESCRIPTION("Image to buffer and buffer to image tests"); 18498 18499 ASSERT_NO_FATAL_FAILURE(Init()); 18500 VkFormatProperties format_props = m_device->format_properties(VK_FORMAT_D24_UNORM_S8_UINT); 18501 if (!(format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) { 18502 printf(" VK_FORMAT_D24_UNORM_S8_UINT not supported. Skipped.\n"); 18503 return; 18504 } 18505 18506 // Bail if any dimension of transfer granularity is 0. 18507 auto index = m_device->graphics_queue_node_index_; 18508 auto queue_family_properties = m_device->phy().queue_properties(); 18509 if ((queue_family_properties[index].minImageTransferGranularity.depth == 0) || 18510 (queue_family_properties[index].minImageTransferGranularity.width == 0) || 18511 (queue_family_properties[index].minImageTransferGranularity.height == 0)) { 18512 printf(" Subresource copies are disallowed when xfer granularity (x|y|z) is 0. Skipped.\n"); 18513 return; 18514 } 18515 18516 VkImageObj image_64k(m_device); // 128^2 texels, 64k 18517 VkImageObj image_16k(m_device); // 64^2 texels, 16k 18518 VkImageObj image_16k_depth(m_device); // 64^2 texels, depth, 16k 18519 VkImageObj ds_image_4D_1S(m_device); // 256^2 texels, 512kb (256k depth, 64k stencil, 192k pack) 18520 VkImageObj ds_image_3D_1S(m_device); // 256^2 texels, 256kb (192k depth, 64k stencil) 18521 VkImageObj ds_image_2D(m_device); // 256^2 texels, 128k (128k depth) 18522 VkImageObj ds_image_1S(m_device); // 256^2 texels, 64k (64k stencil) 18523 18524 image_64k.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UINT, 18525 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 18526 VK_IMAGE_TILING_OPTIMAL, 0); 18527 image_16k.Init(64, 64, 1, VK_FORMAT_R8G8B8A8_UINT, 18528 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 18529 VK_IMAGE_TILING_OPTIMAL, 0); 18530 image_16k_depth.Init(64, 64, 1, VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 18531 VK_IMAGE_TILING_OPTIMAL, 0); 18532 ASSERT_TRUE(image_64k.initialized()); 18533 ASSERT_TRUE(image_16k.initialized()); 18534 ASSERT_TRUE(image_16k_depth.initialized()); 18535 18536 // Verify all needed Depth/Stencil formats are supported 18537 bool missing_ds_support = false; 18538 VkFormatProperties props = {0, 0, 0}; 18539 vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D32_SFLOAT_S8_UINT, &props); 18540 missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0); 18541 vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D24_UNORM_S8_UINT, &props); 18542 missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0); 18543 vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D16_UNORM, &props); 18544 missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0); 18545 vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_S8_UINT, &props); 18546 missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0); 18547 18548 if (!missing_ds_support) { 18549 ds_image_4D_1S.Init( 18550 256, 256, 1, VK_FORMAT_D32_SFLOAT_S8_UINT, 18551 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 18552 VK_IMAGE_TILING_OPTIMAL, 0); 18553 ASSERT_TRUE(ds_image_4D_1S.initialized()); 18554 18555 ds_image_3D_1S.Init( 18556 256, 256, 1, VK_FORMAT_D24_UNORM_S8_UINT, 18557 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 18558 VK_IMAGE_TILING_OPTIMAL, 0); 18559 ASSERT_TRUE(ds_image_3D_1S.initialized()); 18560 18561 ds_image_2D.Init( 18562 256, 256, 1, VK_FORMAT_D16_UNORM, 18563 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 18564 VK_IMAGE_TILING_OPTIMAL, 0); 18565 ASSERT_TRUE(ds_image_2D.initialized()); 18566 18567 ds_image_1S.Init( 18568 256, 256, 1, VK_FORMAT_S8_UINT, 18569 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 18570 VK_IMAGE_TILING_OPTIMAL, 0); 18571 ASSERT_TRUE(ds_image_1S.initialized()); 18572 } 18573 18574 // Allocate buffers 18575 vk_testing::Buffer buffer_256k, buffer_128k, buffer_64k, buffer_16k; 18576 VkMemoryPropertyFlags reqs = 0; 18577 buffer_256k.init_as_src_and_dst(*m_device, 262144, reqs); // 256k 18578 buffer_128k.init_as_src_and_dst(*m_device, 131072, reqs); // 128k 18579 buffer_64k.init_as_src_and_dst(*m_device, 65536, reqs); // 64k 18580 buffer_16k.init_as_src_and_dst(*m_device, 16384, reqs); // 16k 18581 18582 VkBufferImageCopy region = {}; 18583 region.bufferRowLength = 0; 18584 region.bufferImageHeight = 0; 18585 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 18586 region.imageSubresource.layerCount = 1; 18587 region.imageOffset = {0, 0, 0}; 18588 region.imageExtent = {64, 64, 1}; 18589 region.bufferOffset = 0; 18590 18591 // attempt copies before putting command buffer in recording state 18592 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18e02413); 18593 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); 18594 m_errorMonitor->VerifyFound(); 18595 18596 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19202413); 18597 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1, ®ion); 18598 m_errorMonitor->VerifyFound(); 18599 18600 // start recording 18601 m_commandBuffer->begin(); 18602 18603 // successful copies 18604 m_errorMonitor->ExpectSuccess(); 18605 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, ®ion); 18606 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); 18607 region.imageOffset.x = 16; // 16k copy, offset requires larger image 18608 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, ®ion); 18609 region.imageExtent.height = 78; // > 16k copy requires larger buffer & image 18610 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); 18611 region.imageOffset.x = 0; 18612 region.imageExtent.height = 64; 18613 region.bufferOffset = 256; // 16k copy with buffer offset, requires larger buffer 18614 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1, ®ion); 18615 m_errorMonitor->VerifyNotFound(); 18616 18617 // image/buffer too small (extent too large) on copy to image 18618 region.imageExtent = {65, 64, 1}; 18619 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18e00156); // buffer too small 18620 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); 18621 m_errorMonitor->VerifyFound(); 18622 18623 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18e00158); // image too small 18624 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); 18625 m_errorMonitor->VerifyFound(); 18626 18627 // image/buffer too small (offset) on copy to image 18628 region.imageExtent = {64, 64, 1}; 18629 region.imageOffset = {0, 4, 0}; 18630 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18e00156); // buffer too small 18631 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); 18632 m_errorMonitor->VerifyFound(); 18633 18634 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18e00158); // image too small 18635 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); 18636 m_errorMonitor->VerifyFound(); 18637 18638 // image/buffer too small on copy to buffer 18639 region.imageExtent = {64, 64, 1}; 18640 region.imageOffset = {0, 0, 0}; 18641 region.bufferOffset = 4; 18642 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1920016e); // buffer too small 18643 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, ®ion); 18644 m_errorMonitor->VerifyFound(); 18645 18646 region.imageExtent = {64, 65, 1}; 18647 region.bufferOffset = 0; 18648 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1920016c); // image too small 18649 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1, ®ion); 18650 m_errorMonitor->VerifyFound(); 18651 18652 // buffer size ok but rowlength causes loose packing 18653 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1920016e); 18654 region.imageExtent = {64, 64, 1}; 18655 region.bufferRowLength = 68; 18656 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, ®ion); 18657 m_errorMonitor->VerifyFound(); 18658 18659 // An extent with zero area should produce a warning, but no error 18660 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_ERROR_BIT_EXT, "} has zero area"); 18661 region.imageExtent.width = 0; 18662 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, ®ion); 18663 m_errorMonitor->VerifyFound(); 18664 18665 // aspect bits 18666 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_016001a8); // more than 1 aspect bit set 18667 region.imageExtent = {64, 64, 1}; 18668 region.bufferRowLength = 0; 18669 region.bufferImageHeight = 0; 18670 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 18671 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_depth.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, 18672 ®ion); 18673 m_errorMonitor->VerifyFound(); 18674 18675 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_016001a6); // mis-matched aspect 18676 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 18677 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, ®ion); 18678 m_errorMonitor->VerifyFound(); 18679 18680 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_016001a6); // different mis-matched aspect 18681 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 18682 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_depth.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, 18683 ®ion); 18684 m_errorMonitor->VerifyFound(); 18685 18686 // Test Depth/Stencil copies 18687 if (missing_ds_support) { 18688 printf(" Depth / Stencil formats unsupported - skipping D/S tests.\n"); 18689 } else { 18690 VkBufferImageCopy ds_region = {}; 18691 ds_region.bufferOffset = 0; 18692 ds_region.bufferRowLength = 0; 18693 ds_region.bufferImageHeight = 0; 18694 ds_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 18695 ds_region.imageSubresource.mipLevel = 0; 18696 ds_region.imageSubresource.baseArrayLayer = 0; 18697 ds_region.imageSubresource.layerCount = 1; 18698 ds_region.imageOffset = {0, 0, 0}; 18699 ds_region.imageExtent = {256, 256, 1}; 18700 18701 // Depth copies that should succeed 18702 m_errorMonitor->ExpectSuccess(); // Extract 4b depth per texel, pack into 256k buffer 18703 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 18704 buffer_256k.handle(), 1, &ds_region); 18705 m_errorMonitor->VerifyNotFound(); 18706 18707 m_errorMonitor->ExpectSuccess(); // Extract 3b depth per texel, pack (loose) into 256k buffer 18708 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 18709 buffer_256k.handle(), 1, &ds_region); 18710 m_errorMonitor->VerifyNotFound(); 18711 18712 m_errorMonitor->ExpectSuccess(); // Copy 2b depth per texel, into 128k buffer 18713 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_2D.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 18714 buffer_128k.handle(), 1, &ds_region); 18715 m_errorMonitor->VerifyNotFound(); 18716 18717 // Depth copies that should fail 18718 ds_region.bufferOffset = 4; 18719 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 18720 VALIDATION_ERROR_1920016e); // Extract 4b depth per texel, pack into 256k buffer 18721 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 18722 buffer_256k.handle(), 1, &ds_region); 18723 m_errorMonitor->VerifyFound(); 18724 18725 m_errorMonitor->SetDesiredFailureMsg( 18726 VK_DEBUG_REPORT_ERROR_BIT_EXT, 18727 VALIDATION_ERROR_1920016e); // Extract 3b depth per texel, pack (loose) into 256k buffer 18728 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 18729 buffer_256k.handle(), 1, &ds_region); 18730 m_errorMonitor->VerifyFound(); 18731 18732 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 18733 VALIDATION_ERROR_1920016e); // Copy 2b depth per texel, into 128k buffer 18734 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_2D.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 18735 buffer_128k.handle(), 1, &ds_region); 18736 m_errorMonitor->VerifyFound(); 18737 18738 // Stencil copies that should succeed 18739 ds_region.bufferOffset = 0; 18740 ds_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; 18741 m_errorMonitor->ExpectSuccess(); // Extract 1b stencil per texel, pack into 64k buffer 18742 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 18743 buffer_64k.handle(), 1, &ds_region); 18744 m_errorMonitor->VerifyNotFound(); 18745 18746 m_errorMonitor->ExpectSuccess(); // Extract 1b stencil per texel, pack into 64k buffer 18747 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 18748 buffer_64k.handle(), 1, &ds_region); 18749 m_errorMonitor->VerifyNotFound(); 18750 18751 m_errorMonitor->ExpectSuccess(); // Copy 1b depth per texel, into 64k buffer 18752 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 18753 buffer_64k.handle(), 1, &ds_region); 18754 m_errorMonitor->VerifyNotFound(); 18755 18756 // Stencil copies that should fail 18757 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 18758 VALIDATION_ERROR_1920016e); // Extract 1b stencil per texel, pack into 64k buffer 18759 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 18760 buffer_16k.handle(), 1, &ds_region); 18761 m_errorMonitor->VerifyFound(); 18762 18763 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 18764 VALIDATION_ERROR_1920016e); // Extract 1b stencil per texel, pack into 64k buffer 18765 ds_region.bufferRowLength = 260; 18766 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 18767 buffer_64k.handle(), 1, &ds_region); 18768 m_errorMonitor->VerifyFound(); 18769 18770 ds_region.bufferRowLength = 0; 18771 ds_region.bufferOffset = 4; 18772 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 18773 VALIDATION_ERROR_1920016e); // Copy 1b depth per texel, into 64k buffer 18774 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 18775 buffer_64k.handle(), 1, &ds_region); 18776 m_errorMonitor->VerifyFound(); 18777 } 18778 18779 // Test compressed formats, if supported 18780 VkPhysicalDeviceFeatures device_features = {}; 18781 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features)); 18782 if (!(device_features.textureCompressionBC || device_features.textureCompressionETC2 || 18783 device_features.textureCompressionASTC_LDR)) { 18784 printf(" No compressed formats supported - block compression tests skipped.\n"); 18785 } else { 18786 VkImageObj image_16k_4x4comp(m_device); // 128^2 texels as 32^2 compressed (4x4) blocks, 16k 18787 VkImageObj image_NPOT_4x4comp(m_device); // 130^2 texels as 33^2 compressed (4x4) blocks 18788 if (device_features.textureCompressionBC) { 18789 image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_BC3_SRGB_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL, 18790 0); 18791 image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_BC3_SRGB_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL, 18792 0); 18793 } else if (device_features.textureCompressionETC2) { 18794 image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 18795 VK_IMAGE_TILING_OPTIMAL, 0); 18796 image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 18797 VK_IMAGE_TILING_OPTIMAL, 0); 18798 } else { 18799 image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 18800 VK_IMAGE_TILING_OPTIMAL, 0); 18801 image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 18802 VK_IMAGE_TILING_OPTIMAL, 0); 18803 } 18804 ASSERT_TRUE(image_16k_4x4comp.initialized()); 18805 18806 // Just fits 18807 m_errorMonitor->ExpectSuccess(); 18808 region.imageExtent = {128, 128, 1}; 18809 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 18810 1, ®ion); 18811 m_errorMonitor->VerifyNotFound(); 18812 18813 // with offset, too big for buffer 18814 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1920016e); 18815 region.bufferOffset = 16; 18816 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 18817 1, ®ion); 18818 m_errorMonitor->VerifyFound(); 18819 region.bufferOffset = 0; 18820 18821 // extents that are not a multiple of compressed block size 18822 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0160019e); 18823 region.imageExtent.width = 66; 18824 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 18825 1, ®ion); 18826 m_errorMonitor->VerifyFound(); 18827 region.imageExtent.width = 128; 18828 18829 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_016001a0); 18830 region.imageExtent.height = 2; 18831 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 18832 1, ®ion); 18833 m_errorMonitor->VerifyFound(); 18834 region.imageExtent.height = 128; 18835 18836 // TODO: All available compressed formats are 2D, with block depth of 1. Unable to provoke VU_01277. 18837 18838 // non-multiple extents are allowed if at the far edge of a non-block-multiple image - these should pass 18839 m_errorMonitor->ExpectSuccess(); 18840 region.imageExtent.width = 66; 18841 region.imageOffset.x = 64; 18842 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 18843 1, ®ion); 18844 region.imageExtent.width = 16; 18845 region.imageOffset.x = 0; 18846 region.imageExtent.height = 2; 18847 region.imageOffset.y = 128; 18848 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 18849 1, ®ion); 18850 m_errorMonitor->VerifyNotFound(); 18851 region.imageOffset = {0, 0, 0}; 18852 18853 // buffer offset must be a multiple of texel block size (16) 18854 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0160019c); 18855 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01600182); 18856 region.imageExtent = {64, 64, 1}; 18857 region.bufferOffset = 24; 18858 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 18859 1, ®ion); 18860 m_errorMonitor->VerifyFound(); 18861 18862 // rowlength not a multiple of block width (4) 18863 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01600196); 18864 region.bufferOffset = 0; 18865 region.bufferRowLength = 130; 18866 region.bufferImageHeight = 0; 18867 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 18868 1, ®ion); 18869 m_errorMonitor->VerifyFound(); 18870 18871 // imageheight not a multiple of block height (4) 18872 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01600198); 18873 region.bufferRowLength = 0; 18874 region.bufferImageHeight = 130; 18875 vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 18876 1, ®ion); 18877 m_errorMonitor->VerifyFound(); 18878 } 18879 } 18880 18881 TEST_F(VkLayerTest, MiscImageLayerTests) { 18882 TEST_DESCRIPTION("Image-related tests that don't belong elsewhere"); 18883 18884 ASSERT_NO_FATAL_FAILURE(Init()); 18885 18886 // TODO: Ideally we should check if a format is supported, before using it. 18887 VkImageObj image(m_device); 18888 image.Init(128, 128, 1, VK_FORMAT_R16G16B16A16_UINT, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0); // 64bpp 18889 ASSERT_TRUE(image.initialized()); 18890 vk_testing::Buffer buffer; 18891 VkMemoryPropertyFlags reqs = 0; 18892 buffer.init_as_src(*m_device, 128 * 128 * 8, reqs); 18893 VkBufferImageCopy region = {}; 18894 region.bufferRowLength = 128; 18895 region.bufferImageHeight = 128; 18896 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 18897 // layerCount can't be 0 - Expect MISMATCHED_IMAGE_ASPECT 18898 region.imageSubresource.layerCount = 1; 18899 region.imageExtent.height = 4; 18900 region.imageExtent.width = 4; 18901 region.imageExtent.depth = 1; 18902 18903 VkImageObj image2(m_device); 18904 image2.Init(128, 128, 1, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0); // 16bpp 18905 ASSERT_TRUE(image2.initialized()); 18906 vk_testing::Buffer buffer2; 18907 VkMemoryPropertyFlags reqs2 = 0; 18908 buffer2.init_as_src(*m_device, 128 * 128 * 2, reqs2); 18909 VkBufferImageCopy region2 = {}; 18910 region2.bufferRowLength = 128; 18911 region2.bufferImageHeight = 128; 18912 region2.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 18913 // layerCount can't be 0 - Expect MISMATCHED_IMAGE_ASPECT 18914 region2.imageSubresource.layerCount = 1; 18915 region2.imageExtent.height = 4; 18916 region2.imageExtent.width = 4; 18917 region2.imageExtent.depth = 1; 18918 m_commandBuffer->begin(); 18919 18920 // Image must have offset.z of 0 and extent.depth of 1 18921 // Introduce failure by setting imageExtent.depth to 0 18922 region.imageExtent.depth = 0; 18923 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01600192); 18924 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 18925 ®ion); 18926 m_errorMonitor->VerifyFound(); 18927 18928 region.imageExtent.depth = 1; 18929 18930 // Image must have offset.z of 0 and extent.depth of 1 18931 // Introduce failure by setting imageOffset.z to 4 18932 // Note: Also (unavoidably) triggers 'region exceeds image' #1228 18933 region.imageOffset.z = 4; 18934 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01600192); 18935 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_18e00158); 18936 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 18937 ®ion); 18938 m_errorMonitor->VerifyFound(); 18939 18940 region.imageOffset.z = 0; 18941 // BufferOffset must be a multiple of the calling command's VkImage parameter's texel size 18942 // Introduce failure by setting bufferOffset to 1 and 1/2 texels 18943 region.bufferOffset = 4; 18944 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01600182); 18945 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 18946 ®ion); 18947 m_errorMonitor->VerifyFound(); 18948 18949 // BufferOffset must be a multiple of 4 18950 // Introduce failure by setting bufferOffset to a value not divisible by 4 18951 region2.bufferOffset = 6; 18952 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01600184); 18953 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer2.handle(), image2.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 18954 ®ion2); 18955 m_errorMonitor->VerifyFound(); 18956 18957 // BufferRowLength must be 0, or greater than or equal to the width member of imageExtent 18958 region.bufferOffset = 0; 18959 region.imageExtent.height = 128; 18960 region.imageExtent.width = 128; 18961 // Introduce failure by setting bufferRowLength > 0 but less than width 18962 region.bufferRowLength = 64; 18963 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01600186); 18964 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 18965 ®ion); 18966 m_errorMonitor->VerifyFound(); 18967 18968 // BufferImageHeight must be 0, or greater than or equal to the height member of imageExtent 18969 region.bufferRowLength = 128; 18970 // Introduce failure by setting bufferRowHeight > 0 but less than height 18971 region.bufferImageHeight = 64; 18972 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01600188); 18973 vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 18974 ®ion); 18975 m_errorMonitor->VerifyFound(); 18976 18977 region.bufferImageHeight = 128; 18978 VkImageObj intImage1(m_device); 18979 intImage1.Init(128, 128, 1, VK_FORMAT_R8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 18980 intImage1.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL); 18981 VkImageObj intImage2(m_device); 18982 intImage2.Init(128, 128, 1, VK_FORMAT_R8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 18983 intImage2.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL); 18984 VkImageBlit blitRegion = {}; 18985 blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 18986 blitRegion.srcSubresource.baseArrayLayer = 0; 18987 blitRegion.srcSubresource.layerCount = 1; 18988 blitRegion.srcSubresource.mipLevel = 0; 18989 blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 18990 blitRegion.dstSubresource.baseArrayLayer = 0; 18991 blitRegion.dstSubresource.layerCount = 1; 18992 blitRegion.dstSubresource.mipLevel = 0; 18993 blitRegion.srcOffsets[0] = {128, 0, 0}; 18994 blitRegion.srcOffsets[1] = {128, 128, 1}; 18995 blitRegion.dstOffsets[0] = {0, 128, 0}; 18996 blitRegion.dstOffsets[1] = {128, 128, 1}; 18997 18998 // Look for NULL-blit warning 18999 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, 19000 "vkCmdBlitImage: pRegions[0].srcOffsets specify a zero-volume area."); 19001 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, 19002 "vkCmdBlitImage: pRegions[0].dstOffsets specify a zero-volume area."); 19003 vkCmdBlitImage(m_commandBuffer->handle(), intImage1.handle(), intImage1.Layout(), intImage2.handle(), intImage2.Layout(), 1, 19004 &blitRegion, VK_FILTER_LINEAR); 19005 m_errorMonitor->VerifyFound(); 19006 } 19007 19008 TEST_F(VkLayerTest, ImageFormatLimits) { 19009 TEST_DESCRIPTION("Exceed the limits of image format "); 19010 19011 ASSERT_NO_FATAL_FAILURE(Init()); 19012 19013 VkFormat const format = VK_FORMAT_B8G8R8A8_UNORM; 19014 { 19015 VkFormatProperties properties; 19016 vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), format, &properties); 19017 if (properties.linearTilingFeatures == 0) { 19018 printf(" Image format not supported; skipped.\n"); 19019 return; 19020 } 19021 } 19022 19023 VkImageCreateInfo image_create_info = {}; 19024 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 19025 image_create_info.pNext = NULL; 19026 image_create_info.imageType = VK_IMAGE_TYPE_2D; 19027 image_create_info.format = format; 19028 image_create_info.extent.width = 32; 19029 image_create_info.extent.height = 32; 19030 image_create_info.extent.depth = 1; 19031 image_create_info.mipLevels = 1; 19032 image_create_info.arrayLayers = 1; 19033 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 19034 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 19035 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 19036 image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 19037 image_create_info.flags = 0; 19038 19039 VkImage nullImg; 19040 VkImageFormatProperties imgFmtProps; 19041 VkResult err = vkGetPhysicalDeviceImageFormatProperties(gpu(), image_create_info.format, image_create_info.imageType, 19042 image_create_info.tiling, image_create_info.usage, 19043 image_create_info.flags, &imgFmtProps); 19044 if (VK_SUCCESS != err) { 19045 printf(" Image format not supported; skipped.\n"); 19046 return; 19047 } 19048 19049 VkPhysicalDeviceProperties device_props; 19050 vkGetPhysicalDeviceProperties(gpu(), &device_props); 19051 uint32_t max_width = std::max(imgFmtProps.maxExtent.width, device_props.limits.maxImageDimension2D); 19052 if (max_width < UINT32_MAX) { 19053 image_create_info.extent.width = max_width + 1; 19054 // Expect INVALID_FORMAT_LIMITS_VIOLATION 19055 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00770); 19056 vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg); 19057 m_errorMonitor->VerifyFound(); 19058 image_create_info.extent.width = 1; 19059 } 19060 19061 uint32_t maxDim = std::max({image_create_info.extent.width, image_create_info.extent.height, image_create_info.extent.depth}); 19062 // If max mip levels exceeds image extents, skip the max mip levels test 19063 if ((imgFmtProps.maxMipLevels + 1) <= (floor(log2(maxDim)) + 1)) { 19064 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e0077e); 19065 image_create_info.mipLevels = imgFmtProps.maxMipLevels + 1; 19066 // Expect INVALID_FORMAT_LIMITS_VIOLATION 19067 vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg); 19068 m_errorMonitor->VerifyFound(); 19069 image_create_info.mipLevels = 1; 19070 } 19071 19072 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00780); 19073 image_create_info.arrayLayers = imgFmtProps.maxArrayLayers + 1; 19074 // Expect INVALID_FORMAT_LIMITS_VIOLATION 19075 vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg); 19076 m_errorMonitor->VerifyFound(); 19077 image_create_info.arrayLayers = 1; 19078 19079 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 19080 vkGetPhysicalDeviceImageFormatProperties(gpu(), image_create_info.format, image_create_info.imageType, image_create_info.tiling, 19081 image_create_info.usage, image_create_info.flags, &imgFmtProps); 19082 if (0 == (imgFmtProps.sampleCounts & VK_SAMPLE_COUNT_64_BIT)) { 19083 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e0078e); 19084 image_create_info.samples = VK_SAMPLE_COUNT_64_BIT; 19085 // Expect INVALID_FORMAT_LIMITS_VIOLATION 19086 vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg); 19087 m_errorMonitor->VerifyFound(); 19088 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 19089 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 19090 } 19091 19092 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e0b801); 19093 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e007c2); 19094 image_create_info.initialLayout = VK_IMAGE_LAYOUT_MAX_ENUM; // Not a legal layout value 19095 vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg); 19096 m_errorMonitor->VerifyFound(); 19097 image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 19098 } 19099 19100 VkResult GPDIFPHelper(VkPhysicalDevice dev, VkImageCreateInfo *ci, VkImageFormatProperties *limits) { 19101 return vkGetPhysicalDeviceImageFormatProperties(dev, ci->format, ci->imageType, ci->tiling, ci->usage, ci->flags, limits); 19102 } 19103 19104 TEST_F(VkLayerTest, ImageCreateInfoStructErrors) { 19105 TEST_DESCRIPTION("Misc valid usage errors in vkImageCreateInfo struct"); 19106 19107 ASSERT_NO_FATAL_FAILURE(Init()); 19108 19109 VkFormat format = VK_FORMAT_B8G8R8A8_UNORM; 19110 VkFormatProperties fmt_props; 19111 vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), format, &fmt_props); 19112 if ((fmt_props.linearTilingFeatures == 0) || (fmt_props.optimalTilingFeatures == 0)) { 19113 format = VK_FORMAT_R8G8B8A8_UNORM; 19114 vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), format, &fmt_props); 19115 if ((fmt_props.linearTilingFeatures == 0) || (fmt_props.optimalTilingFeatures == 0)) { 19116 printf(" Image format not supported, test skipped.\n"); 19117 return; 19118 } 19119 } 19120 19121 VkImage image; 19122 VkImageCreateInfo image_ci = {}; 19123 image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 19124 image_ci.pNext = NULL; 19125 image_ci.flags = 0; 19126 image_ci.imageType = VK_IMAGE_TYPE_1D; 19127 image_ci.format = format; 19128 image_ci.extent = {64, 1, 1}; 19129 image_ci.mipLevels = 1; 19130 image_ci.arrayLayers = 1; 19131 image_ci.samples = VK_SAMPLE_COUNT_1_BIT; 19132 image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; 19133 image_ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 19134 image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 19135 19136 VkImageFormatProperties img_limits = {}; 19137 const VkPhysicalDeviceLimits dev_limits = m_device->props.limits; 19138 19139 // InitialLayout not VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREDEFINED 19140 image_ci.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 19141 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e007c2); 19142 vkCreateImage(m_device->handle(), &image_ci, NULL, &image); 19143 m_errorMonitor->VerifyFound(); 19144 image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 19145 19146 // 1D with CUBE_COMPATIBLE 19147 image_ci.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; 19148 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e0076a); 19149 vkCreateImage(m_device->handle(), &image_ci, NULL, &image); 19150 m_errorMonitor->VerifyFound(); 19151 image_ci.flags = 0; 19152 19153 // 1D width 19154 GPDIFPHelper(gpu(), &image_ci, &img_limits); 19155 image_ci.extent.width = std::max(img_limits.maxExtent.width, dev_limits.maxImageDimension1D) + 1; 19156 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e0076e); 19157 vkCreateImage(m_device->handle(), &image_ci, NULL, &image); 19158 m_errorMonitor->VerifyFound(); 19159 19160 // 2D CUBE_COMPATIBLE extents 19161 image_ci.imageType = VK_IMAGE_TYPE_2D; 19162 image_ci.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; 19163 GPDIFPHelper(gpu(), &image_ci, &img_limits); 19164 uint32_t dim = std::max({img_limits.maxExtent.width, img_limits.maxExtent.height, dev_limits.maxImageDimensionCube}) + 1; 19165 image_ci.extent = {dim, dim, 1}; 19166 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00772); 19167 vkCreateImage(m_device->handle(), &image_ci, NULL, &image); 19168 m_errorMonitor->VerifyFound(); 19169 image_ci.flags = 0; 19170 19171 // 3D extents 19172 image_ci.imageType = VK_IMAGE_TYPE_3D; 19173 GPDIFPHelper(gpu(), &image_ci, &img_limits); 19174 image_ci.extent = {(std::max(img_limits.maxExtent.width, dev_limits.maxImageDimension3D) + 1), 4, 4}; 19175 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00776); 19176 vkCreateImage(m_device->handle(), &image_ci, NULL, &image); 19177 m_errorMonitor->VerifyFound(); 19178 image_ci.extent = {4, (std::max(img_limits.maxExtent.height, dev_limits.maxImageDimension3D) + 1), 4}; 19179 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00776); 19180 vkCreateImage(m_device->handle(), &image_ci, NULL, &image); 19181 m_errorMonitor->VerifyFound(); 19182 image_ci.extent = {4, 4, (std::max(img_limits.maxExtent.depth, dev_limits.maxImageDimension3D) + 1)}; 19183 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00776); 19184 vkCreateImage(m_device->handle(), &image_ci, NULL, &image); 19185 m_errorMonitor->VerifyFound(); 19186 19187 // 3D arrayLayers 19188 image_ci.extent = {4, 4, 4}; 19189 image_ci.arrayLayers = 2; 19190 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00782); 19191 vkCreateImage(m_device->handle(), &image_ci, NULL, &image); 19192 m_errorMonitor->VerifyFound(); 19193 image_ci.arrayLayers = 1; 19194 19195 // Multi-sample 19196 image_ci.samples = VK_SAMPLE_COUNT_4_BIT; 19197 image_ci.imageType = VK_IMAGE_TYPE_3D; 19198 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00784); 19199 vkCreateImage(m_device->handle(), &image_ci, NULL, &image); 19200 m_errorMonitor->VerifyFound(); 19201 image_ci.imageType = VK_IMAGE_TYPE_2D; 19202 image_ci.extent = {64, 64, 1}; 19203 image_ci.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; 19204 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00784); 19205 vkCreateImage(m_device->handle(), &image_ci, NULL, &image); 19206 m_errorMonitor->VerifyFound(); 19207 image_ci.flags = 0; 19208 image_ci.tiling = VK_IMAGE_TILING_LINEAR; 19209 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00784); 19210 vkCreateImage(m_device->handle(), &image_ci, NULL, &image); 19211 m_errorMonitor->VerifyFound(); 19212 image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; 19213 image_ci.mipLevels = 7; 19214 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00784); 19215 vkCreateImage(m_device->handle(), &image_ci, NULL, &image); 19216 m_errorMonitor->VerifyFound(); 19217 image_ci.mipLevels = 1; 19218 image_ci.samples = VK_SAMPLE_COUNT_1_BIT; 19219 19220 // TRANSIENT with a non-attachment flag 19221 image_ci.usage = 19222 VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 19223 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00786); 19224 vkCreateImage(m_device->handle(), &image_ci, NULL, &image); 19225 m_errorMonitor->VerifyFound(); 19226 19227 // TRANSIENT without another attachment flag 19228 image_ci.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT; 19229 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e0078c); 19230 vkCreateImage(m_device->handle(), &image_ci, NULL, &image); 19231 m_errorMonitor->VerifyFound(); 19232 19233 // Frame buffer width 19234 image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; // (any attachment bit) 19235 GPDIFPHelper(gpu(), &image_ci, &img_limits); 19236 image_ci.extent.width = dev_limits.maxFramebufferWidth + 1; 19237 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00788); 19238 if (image_ci.extent.width > std::max(dev_limits.maxImageDimension2D, img_limits.maxExtent.width)) { 19239 // Image/device limits are <= framebuffer limit - will also trip 770 19240 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00770); 19241 } 19242 vkCreateImage(m_device->handle(), &image_ci, NULL, &image); 19243 m_errorMonitor->VerifyFound(); 19244 19245 // Frame buffer height 19246 image_ci.usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; // (any attachment bit) 19247 image_ci.extent.width = 64; 19248 image_ci.extent.height = dev_limits.maxFramebufferHeight + 1; 19249 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e0078a); 19250 if (image_ci.extent.height > std::max(dev_limits.maxImageDimension2D, img_limits.maxExtent.height)) { 19251 // Image/device limits are <= framebuffer limit - will also trip 770 19252 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00770); 19253 } 19254 vkCreateImage(m_device->handle(), &image_ci, NULL, &image); 19255 m_errorMonitor->VerifyFound(); 19256 19257 image_ci.format = VK_FORMAT_R8_SRGB; // pick an 'unlikely' format 19258 VkFormatProperties format_props; 19259 vkGetPhysicalDeviceFormatProperties(gpu(), image_ci.format, &format_props); 19260 19261 // Linear tiling with unsupported feature 19262 image_ci.tiling = VK_IMAGE_TILING_LINEAR; 19263 bool unsupported = (VK_ERROR_FORMAT_NOT_SUPPORTED == GPDIFPHelper(gpu(), &image_ci, &img_limits)); 19264 if (format_props.linearTilingFeatures && (0 == (format_props.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))) { 19265 image_ci.tiling = VK_IMAGE_TILING_LINEAR; 19266 image_ci.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 19267 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e007a4); 19268 if (unsupported) { 19269 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00758); 19270 } 19271 vkCreateImage(m_device->handle(), &image_ci, NULL, &image); 19272 m_errorMonitor->VerifyFound(); 19273 } 19274 if (format_props.linearTilingFeatures && (0 == (format_props.linearTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))) { 19275 image_ci.tiling = VK_IMAGE_TILING_LINEAR; 19276 image_ci.usage = VK_IMAGE_USAGE_STORAGE_BIT; 19277 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e007a6); 19278 if (unsupported) { 19279 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00758); 19280 } 19281 vkCreateImage(m_device->handle(), &image_ci, NULL, &image); 19282 m_errorMonitor->VerifyFound(); 19283 } 19284 19285 // Optimal tiling with unsupported feature 19286 image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; 19287 unsupported = (VK_ERROR_FORMAT_NOT_SUPPORTED == GPDIFPHelper(gpu(), &image_ci, &img_limits)); 19288 if (format_props.optimalTilingFeatures && (0 == (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))) { 19289 image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; 19290 image_ci.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 19291 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e007ae); 19292 if (unsupported) { 19293 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00758); 19294 } 19295 vkCreateImage(m_device->handle(), &image_ci, NULL, &image); 19296 m_errorMonitor->VerifyFound(); 19297 } 19298 if (format_props.optimalTilingFeatures && (0 == (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))) { 19299 image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; 19300 image_ci.usage = VK_IMAGE_USAGE_STORAGE_BIT; 19301 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e007b0); 19302 if (unsupported) { 19303 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09e00758); 19304 } 19305 vkCreateImage(m_device->handle(), &image_ci, NULL, &image); 19306 m_errorMonitor->VerifyFound(); 19307 } 19308 } 19309 19310 TEST_F(VkLayerTest, CopyImageTypeExtentMismatch) { 19311 // Image copy tests where format type and extents don't match 19312 ASSERT_NO_FATAL_FAILURE(Init()); 19313 19314 VkImageCreateInfo ci; 19315 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 19316 ci.pNext = NULL; 19317 ci.flags = 0; 19318 ci.imageType = VK_IMAGE_TYPE_1D; 19319 ci.format = VK_FORMAT_R8G8B8A8_UNORM; 19320 ci.extent = {32, 1, 1}; 19321 ci.mipLevels = 1; 19322 ci.arrayLayers = 1; 19323 ci.samples = VK_SAMPLE_COUNT_1_BIT; 19324 ci.tiling = VK_IMAGE_TILING_OPTIMAL; 19325 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 19326 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 19327 ci.queueFamilyIndexCount = 0; 19328 ci.pQueueFamilyIndices = NULL; 19329 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 19330 19331 // Create 1D image 19332 VkImageObj image_1D(m_device); 19333 image_1D.init(&ci); 19334 ASSERT_TRUE(image_1D.initialized()); 19335 19336 // 2D image 19337 ci.imageType = VK_IMAGE_TYPE_2D; 19338 ci.extent = {32, 32, 1}; 19339 VkImageObj image_2D(m_device); 19340 image_2D.init(&ci); 19341 ASSERT_TRUE(image_2D.initialized()); 19342 19343 // 3D image 19344 ci.imageType = VK_IMAGE_TYPE_3D; 19345 ci.extent = {32, 32, 8}; 19346 VkImageObj image_3D(m_device); 19347 image_3D.init(&ci); 19348 ASSERT_TRUE(image_3D.initialized()); 19349 19350 // 2D image array 19351 ci.imageType = VK_IMAGE_TYPE_2D; 19352 ci.extent = {32, 32, 1}; 19353 ci.arrayLayers = 8; 19354 VkImageObj image_2D_array(m_device); 19355 image_2D_array.init(&ci); 19356 ASSERT_TRUE(image_2D_array.initialized()); 19357 19358 m_commandBuffer->begin(); 19359 19360 VkImageCopy copy_region; 19361 copy_region.extent = {32, 1, 1}; 19362 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 19363 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 19364 copy_region.srcSubresource.mipLevel = 0; 19365 copy_region.dstSubresource.mipLevel = 0; 19366 copy_region.srcSubresource.baseArrayLayer = 0; 19367 copy_region.dstSubresource.baseArrayLayer = 0; 19368 copy_region.srcSubresource.layerCount = 1; 19369 copy_region.dstSubresource.layerCount = 1; 19370 copy_region.srcOffset = {0, 0, 0}; 19371 copy_region.dstOffset = {0, 0, 0}; 19372 19373 // Sanity check 19374 m_errorMonitor->ExpectSuccess(); 19375 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 19376 ©_region); 19377 m_errorMonitor->VerifyNotFound(); 19378 19379 // 1D texture w/ offset.y > 0. Source = VU 09c00124, dest = 09c00130 19380 copy_region.srcOffset.y = 1; 19381 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00124); 19382 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00122); // also y-dim overrun 19383 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 19384 ©_region); 19385 m_errorMonitor->VerifyFound(); 19386 copy_region.srcOffset.y = 0; 19387 copy_region.dstOffset.y = 1; 19388 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00130); 19389 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0012e); // also y-dim overrun 19390 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 19391 ©_region); 19392 m_errorMonitor->VerifyFound(); 19393 copy_region.dstOffset.y = 0; 19394 19395 // 1D texture w/ extent.height > 1. Source = VU 09c00124, dest = 09c00130 19396 copy_region.extent.height = 2; 19397 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00124); 19398 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00122); // also y-dim overrun 19399 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 19400 ©_region); 19401 m_errorMonitor->VerifyFound(); 19402 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00130); 19403 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0012e); // also y-dim overrun 19404 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 19405 ©_region); 19406 m_errorMonitor->VerifyFound(); 19407 copy_region.extent.height = 1; 19408 19409 // 2D texture w/ offset.z > 0. Source = VU 09c00128, dest = 09c00134 19410 copy_region.extent = {16, 16, 1}; 19411 copy_region.srcOffset.z = 4; 19412 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00128); 19413 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00126); // also z-dim overrun 19414 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 19415 ©_region); 19416 m_errorMonitor->VerifyFound(); 19417 copy_region.srcOffset.z = 0; 19418 copy_region.dstOffset.z = 1; 19419 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00134); 19420 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00132); // also z-dim overrun 19421 m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 19422 ©_region); 19423 m_errorMonitor->VerifyFound(); 19424 copy_region.dstOffset.z = 0; 19425 19426 // 2D texture w/ extent.depth > 1. Source = VU 09c00128, dest = 09c00134 19427 copy_region.extent.depth = 8; 19428 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00128); 19429 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00126); // also z-dim overrun 19430 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 19431 ©_region); 19432 m_errorMonitor->VerifyFound(); 19433 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00134); 19434 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00132); // also z-dim overrun 19435 m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 19436 ©_region); 19437 m_errorMonitor->VerifyFound(); 19438 copy_region.extent.depth = 1; 19439 19440 // 3D texture accessing an array layer other than 0. VU 09c0011a 19441 copy_region.extent = {4, 4, 1}; 19442 copy_region.srcSubresource.baseArrayLayer = 1; 19443 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0011a); 19444 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 19445 VALIDATION_ERROR_0a600154); // also triggers 'too many layers' 19446 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 19447 VALIDATION_ERROR_09c0012a); // and 'copy from layer not present' 19448 m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 19449 ©_region); 19450 m_errorMonitor->VerifyFound(); 19451 19452 m_commandBuffer->end(); 19453 } 19454 19455 TEST_F(VkLayerTest, CopyImageTypeExtentMismatchMaintenance1) { 19456 // Image copy tests where format type and extents don't match and the Maintenance1 extension is enabled 19457 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 19458 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) { 19459 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME); 19460 } else { 19461 printf(" Maintenance1 extension cannot be enabled, test skipped.\n"); 19462 return; 19463 } 19464 ASSERT_NO_FATAL_FAILURE(InitState()); 19465 19466 VkImageCreateInfo ci; 19467 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 19468 ci.pNext = NULL; 19469 ci.flags = 0; 19470 ci.imageType = VK_IMAGE_TYPE_1D; 19471 ci.format = VK_FORMAT_R8G8B8A8_UNORM; 19472 ci.extent = {32, 1, 1}; 19473 ci.mipLevels = 1; 19474 ci.arrayLayers = 1; 19475 ci.samples = VK_SAMPLE_COUNT_1_BIT; 19476 ci.tiling = VK_IMAGE_TILING_OPTIMAL; 19477 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 19478 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 19479 ci.queueFamilyIndexCount = 0; 19480 ci.pQueueFamilyIndices = NULL; 19481 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 19482 19483 // Create 1D image 19484 VkImageObj image_1D(m_device); 19485 image_1D.init(&ci); 19486 ASSERT_TRUE(image_1D.initialized()); 19487 19488 // 2D image 19489 ci.imageType = VK_IMAGE_TYPE_2D; 19490 ci.extent = {32, 32, 1}; 19491 VkImageObj image_2D(m_device); 19492 image_2D.init(&ci); 19493 ASSERT_TRUE(image_2D.initialized()); 19494 19495 // 3D image 19496 ci.imageType = VK_IMAGE_TYPE_3D; 19497 ci.extent = {32, 32, 8}; 19498 VkImageObj image_3D(m_device); 19499 image_3D.init(&ci); 19500 ASSERT_TRUE(image_3D.initialized()); 19501 19502 // 2D image array 19503 ci.imageType = VK_IMAGE_TYPE_2D; 19504 ci.extent = {32, 32, 1}; 19505 ci.arrayLayers = 8; 19506 VkImageObj image_2D_array(m_device); 19507 image_2D_array.init(&ci); 19508 ASSERT_TRUE(image_2D_array.initialized()); 19509 19510 m_commandBuffer->begin(); 19511 19512 VkImageCopy copy_region; 19513 copy_region.extent = {32, 1, 1}; 19514 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 19515 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 19516 copy_region.srcSubresource.mipLevel = 0; 19517 copy_region.dstSubresource.mipLevel = 0; 19518 copy_region.srcSubresource.baseArrayLayer = 0; 19519 copy_region.dstSubresource.baseArrayLayer = 0; 19520 copy_region.srcSubresource.layerCount = 1; 19521 copy_region.dstSubresource.layerCount = 1; 19522 copy_region.srcOffset = {0, 0, 0}; 19523 copy_region.dstOffset = {0, 0, 0}; 19524 19525 // Copy from layer not present - VU 09c0012a 19526 // TODO: this VU is redundant with VU 0a600154. Gitlab issue 812 submitted to have it removed. 19527 copy_region.srcSubresource.baseArrayLayer = 4; 19528 copy_region.srcSubresource.layerCount = 6; 19529 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0012a); 19530 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a600154); 19531 m_commandBuffer->CopyImage(image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 19532 ©_region); 19533 m_errorMonitor->VerifyFound(); 19534 copy_region.srcSubresource.baseArrayLayer = 0; 19535 copy_region.srcSubresource.layerCount = 1; 19536 19537 // Copy to layer not present - VU 09c00136 19538 // TODO: this VU is redundant with 0a600154. Gitlab issue 812 submitted to have it removed. 19539 copy_region.dstSubresource.baseArrayLayer = 1; 19540 copy_region.dstSubresource.layerCount = 8; 19541 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00136); 19542 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a600154); 19543 m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 19544 ©_region); 19545 m_errorMonitor->VerifyFound(); 19546 copy_region.dstSubresource.layerCount = 1; 19547 19548 m_commandBuffer->end(); 19549 } 19550 19551 TEST_F(VkLayerTest, CopyImageCompressedBlockAlignment) { 19552 // Image copy tests on compressed images with block alignment errors 19553 19554 ASSERT_NO_FATAL_FAILURE(Init()); 19555 19556 // Select a compressed format and verify support 19557 VkPhysicalDeviceFeatures device_features = {}; 19558 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features)); 19559 VkFormat compressed_format = VK_FORMAT_UNDEFINED; 19560 if (device_features.textureCompressionBC) { 19561 compressed_format = VK_FORMAT_BC3_SRGB_BLOCK; 19562 } else if (device_features.textureCompressionETC2) { 19563 compressed_format = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK; 19564 } else if (device_features.textureCompressionASTC_LDR) { 19565 compressed_format = VK_FORMAT_ASTC_4x4_UNORM_BLOCK; 19566 } 19567 19568 VkImageCreateInfo ci; 19569 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 19570 ci.pNext = NULL; 19571 ci.flags = 0; 19572 ci.imageType = VK_IMAGE_TYPE_2D; 19573 ci.format = compressed_format; 19574 ci.extent = {64, 64, 1}; 19575 ci.mipLevels = 1; 19576 ci.arrayLayers = 1; 19577 ci.samples = VK_SAMPLE_COUNT_1_BIT; 19578 ci.tiling = VK_IMAGE_TILING_OPTIMAL; 19579 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 19580 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 19581 ci.queueFamilyIndexCount = 0; 19582 ci.pQueueFamilyIndices = NULL; 19583 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 19584 19585 VkImageFormatProperties img_prop = {}; 19586 if (VK_SUCCESS != vkGetPhysicalDeviceImageFormatProperties(m_device->phy().handle(), ci.format, ci.imageType, ci.tiling, 19587 ci.usage, ci.flags, &img_prop)) { 19588 printf(" No compressed formats supported - CopyImageCompressedBlockAlignment skipped.\n"); 19589 return; 19590 } 19591 19592 // Create images 19593 VkImageObj image_1(m_device); 19594 image_1.init(&ci); 19595 ASSERT_TRUE(image_1.initialized()); 19596 19597 ci.extent = {62, 62, 1}; // slightly smaller and not divisible by block size 19598 VkImageObj image_2(m_device); 19599 image_2.init(&ci); 19600 ASSERT_TRUE(image_2.initialized()); 19601 19602 m_commandBuffer->begin(); 19603 19604 VkImageCopy copy_region; 19605 copy_region.extent = {48, 48, 1}; 19606 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 19607 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 19608 copy_region.srcSubresource.mipLevel = 0; 19609 copy_region.dstSubresource.mipLevel = 0; 19610 copy_region.srcSubresource.baseArrayLayer = 0; 19611 copy_region.dstSubresource.baseArrayLayer = 0; 19612 copy_region.srcSubresource.layerCount = 1; 19613 copy_region.dstSubresource.layerCount = 1; 19614 copy_region.srcOffset = {0, 0, 0}; 19615 copy_region.dstOffset = {0, 0, 0}; 19616 19617 // Sanity check 19618 m_errorMonitor->ExpectSuccess(); 19619 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, ©_region); 19620 m_errorMonitor->VerifyNotFound(); 19621 19622 // Src, Dest offsets must be multiples of compressed block sizes {4, 4, 1} 19623 // Image transfer granularity gets set to compressed block size, so an ITG error is also (unavoidably) triggered. 19624 copy_region.srcOffset = {2, 4, 0}; // source width 19625 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0013a); 19626 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 19627 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, ©_region); 19628 m_errorMonitor->VerifyFound(); 19629 copy_region.srcOffset = {12, 1, 0}; // source height 19630 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0013a); 19631 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 19632 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, ©_region); 19633 m_errorMonitor->VerifyFound(); 19634 copy_region.srcOffset = {0, 0, 0}; 19635 copy_region.dstOffset = {1, 0, 0}; // dest width 19636 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00144); 19637 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 19638 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, ©_region); 19639 m_errorMonitor->VerifyFound(); 19640 copy_region.dstOffset = {4, 1, 0}; // dest height 19641 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00144); 19642 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 19643 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, ©_region); 19644 m_errorMonitor->VerifyFound(); 19645 copy_region.dstOffset = {0, 0, 0}; 19646 19647 // Copy extent must be multiples of compressed block sizes {4, 4, 1} if not full width/height 19648 copy_region.extent = {62, 60, 1}; // source width 19649 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0013c); 19650 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 19651 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, ©_region); 19652 m_errorMonitor->VerifyFound(); 19653 copy_region.extent = {60, 62, 1}; // source height 19654 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0013e); 19655 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 19656 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, ©_region); 19657 m_errorMonitor->VerifyFound(); 19658 copy_region.extent = {62, 60, 1}; // dest width 19659 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00146); 19660 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 19661 m_commandBuffer->CopyImage(image_2.image(), VK_IMAGE_LAYOUT_GENERAL, image_1.image(), VK_IMAGE_LAYOUT_GENERAL, 1, ©_region); 19662 m_errorMonitor->VerifyFound(); 19663 copy_region.extent = {60, 62, 1}; // dest height 19664 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00148); 19665 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 19666 m_commandBuffer->CopyImage(image_2.image(), VK_IMAGE_LAYOUT_GENERAL, image_1.image(), VK_IMAGE_LAYOUT_GENERAL, 1, ©_region); 19667 m_errorMonitor->VerifyFound(); 19668 19669 // Note: VALIDATION_ERROR_09c00140 and VALIDATION_ERROR_09c0014a 19670 // VUs 01212 and 01217 should be tested here, if possible. There are currently no supported compressed formats with 19671 // a block depth other than 1, so impossible to create a 'not a multiple' condiditon for depth. 19672 19673 m_commandBuffer->end(); 19674 } 19675 19676 TEST_F(VkLayerTest, CopyImageSrcSizeExceeded) { 19677 // Image copy with source region specified greater than src image size 19678 ASSERT_NO_FATAL_FAILURE(Init()); 19679 19680 // Create images with full mip chain 19681 VkImageCreateInfo ci; 19682 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 19683 ci.pNext = NULL; 19684 ci.flags = 0; 19685 ci.imageType = VK_IMAGE_TYPE_3D; 19686 ci.format = VK_FORMAT_R8G8B8A8_UNORM; 19687 ci.extent = {32, 32, 8}; 19688 ci.mipLevels = 6; 19689 ci.arrayLayers = 1; 19690 ci.samples = VK_SAMPLE_COUNT_1_BIT; 19691 ci.tiling = VK_IMAGE_TILING_OPTIMAL; 19692 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 19693 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 19694 ci.queueFamilyIndexCount = 0; 19695 ci.pQueueFamilyIndices = NULL; 19696 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 19697 19698 VkImageObj src_image(m_device); 19699 src_image.init(&ci); 19700 ASSERT_TRUE(src_image.initialized()); 19701 19702 // Dest image with one more mip level 19703 ci.extent = {64, 64, 16}; 19704 ci.mipLevels = 7; 19705 ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; 19706 VkImageObj dst_image(m_device); 19707 dst_image.init(&ci); 19708 ASSERT_TRUE(dst_image.initialized()); 19709 19710 m_commandBuffer->begin(); 19711 19712 VkImageCopy copy_region; 19713 copy_region.extent = {32, 32, 8}; 19714 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 19715 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 19716 copy_region.srcSubresource.mipLevel = 0; 19717 copy_region.dstSubresource.mipLevel = 0; 19718 copy_region.srcSubresource.baseArrayLayer = 0; 19719 copy_region.dstSubresource.baseArrayLayer = 0; 19720 copy_region.srcSubresource.layerCount = 1; 19721 copy_region.dstSubresource.layerCount = 1; 19722 copy_region.srcOffset = {0, 0, 0}; 19723 copy_region.dstOffset = {0, 0, 0}; 19724 19725 m_errorMonitor->ExpectSuccess(); 19726 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 19727 ©_region); 19728 m_errorMonitor->VerifyNotFound(); 19729 19730 // Source exceeded in x-dim, VU 01202 19731 copy_region.srcOffset.x = 4; 19732 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 19733 VALIDATION_ERROR_190000f4); // General "contained within" VU 19734 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00120); 19735 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 19736 ©_region); 19737 m_errorMonitor->VerifyFound(); 19738 19739 // Source exceeded in y-dim, VU 01203 19740 copy_region.srcOffset.x = 0; 19741 copy_region.extent.height = 48; 19742 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_190000f4); 19743 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00122); 19744 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 19745 ©_region); 19746 m_errorMonitor->VerifyFound(); 19747 19748 // Source exceeded in z-dim, VU 01204 19749 copy_region.extent = {4, 4, 4}; 19750 copy_region.srcSubresource.mipLevel = 2; 19751 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_190000f4); 19752 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00126); 19753 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 19754 ©_region); 19755 m_errorMonitor->VerifyFound(); 19756 19757 m_commandBuffer->end(); 19758 } 19759 19760 TEST_F(VkLayerTest, CopyImageDstSizeExceeded) { 19761 // Image copy with dest region specified greater than dest image size 19762 ASSERT_NO_FATAL_FAILURE(Init()); 19763 19764 // Create images with full mip chain 19765 VkImageCreateInfo ci; 19766 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 19767 ci.pNext = NULL; 19768 ci.flags = 0; 19769 ci.imageType = VK_IMAGE_TYPE_3D; 19770 ci.format = VK_FORMAT_R8G8B8A8_UNORM; 19771 ci.extent = {32, 32, 8}; 19772 ci.mipLevels = 6; 19773 ci.arrayLayers = 1; 19774 ci.samples = VK_SAMPLE_COUNT_1_BIT; 19775 ci.tiling = VK_IMAGE_TILING_OPTIMAL; 19776 ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; 19777 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 19778 ci.queueFamilyIndexCount = 0; 19779 ci.pQueueFamilyIndices = NULL; 19780 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 19781 19782 VkImageObj dst_image(m_device); 19783 dst_image.init(&ci); 19784 ASSERT_TRUE(dst_image.initialized()); 19785 19786 // Src image with one more mip level 19787 ci.extent = {64, 64, 16}; 19788 ci.mipLevels = 7; 19789 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 19790 VkImageObj src_image(m_device); 19791 src_image.init(&ci); 19792 ASSERT_TRUE(src_image.initialized()); 19793 19794 m_commandBuffer->begin(); 19795 19796 VkImageCopy copy_region; 19797 copy_region.extent = {32, 32, 8}; 19798 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 19799 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 19800 copy_region.srcSubresource.mipLevel = 0; 19801 copy_region.dstSubresource.mipLevel = 0; 19802 copy_region.srcSubresource.baseArrayLayer = 0; 19803 copy_region.dstSubresource.baseArrayLayer = 0; 19804 copy_region.srcSubresource.layerCount = 1; 19805 copy_region.dstSubresource.layerCount = 1; 19806 copy_region.srcOffset = {0, 0, 0}; 19807 copy_region.dstOffset = {0, 0, 0}; 19808 19809 m_errorMonitor->ExpectSuccess(); 19810 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 19811 ©_region); 19812 m_errorMonitor->VerifyNotFound(); 19813 19814 // Dest exceeded in x-dim, VU 01205 19815 copy_region.dstOffset.x = 4; 19816 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 19817 VALIDATION_ERROR_190000f6); // General "contained within" VU 19818 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0012c); 19819 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 19820 ©_region); 19821 m_errorMonitor->VerifyFound(); 19822 19823 // Dest exceeded in y-dim, VU 01206 19824 copy_region.dstOffset.x = 0; 19825 copy_region.extent.height = 48; 19826 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_190000f6); 19827 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0012e); 19828 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 19829 ©_region); 19830 m_errorMonitor->VerifyFound(); 19831 19832 // Dest exceeded in z-dim, VU 01207 19833 copy_region.extent = {4, 4, 4}; 19834 copy_region.dstSubresource.mipLevel = 2; 19835 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_190000f6); 19836 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00132); 19837 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 19838 ©_region); 19839 m_errorMonitor->VerifyFound(); 19840 19841 m_commandBuffer->end(); 19842 } 19843 19844 TEST_F(VkLayerTest, CopyImageFormatSizeMismatch) { 19845 VkResult err; 19846 bool pass; 19847 19848 // Create color images with different format sizes and try to copy between them 19849 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1900010e); 19850 19851 ASSERT_NO_FATAL_FAILURE(Init()); 19852 19853 // Create two images of different types and try to copy between them 19854 VkImage srcImage; 19855 VkImage dstImage; 19856 VkDeviceMemory srcMem; 19857 VkDeviceMemory destMem; 19858 VkMemoryRequirements memReqs; 19859 19860 VkImageCreateInfo image_create_info = {}; 19861 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 19862 image_create_info.pNext = NULL; 19863 image_create_info.imageType = VK_IMAGE_TYPE_2D; 19864 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; 19865 image_create_info.extent.width = 32; 19866 image_create_info.extent.height = 32; 19867 image_create_info.extent.depth = 1; 19868 image_create_info.mipLevels = 1; 19869 image_create_info.arrayLayers = 1; 19870 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 19871 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 19872 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 19873 image_create_info.flags = 0; 19874 19875 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage); 19876 ASSERT_VK_SUCCESS(err); 19877 19878 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; 19879 // Introduce failure by creating second image with a different-sized format. 19880 image_create_info.format = VK_FORMAT_R5G5B5A1_UNORM_PACK16; 19881 VkFormatProperties properties; 19882 vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), image_create_info.format, &properties); 19883 if (properties.optimalTilingFeatures == 0) { 19884 vkDestroyImage(m_device->device(), srcImage, NULL); 19885 printf(" Image format not supported; skipped.\n"); 19886 return; 19887 } 19888 19889 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage); 19890 ASSERT_VK_SUCCESS(err); 19891 19892 // Allocate memory 19893 VkMemoryAllocateInfo memAlloc = {}; 19894 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 19895 memAlloc.pNext = NULL; 19896 memAlloc.allocationSize = 0; 19897 memAlloc.memoryTypeIndex = 0; 19898 19899 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs); 19900 memAlloc.allocationSize = memReqs.size; 19901 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 19902 ASSERT_TRUE(pass); 19903 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem); 19904 ASSERT_VK_SUCCESS(err); 19905 19906 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs); 19907 memAlloc.allocationSize = memReqs.size; 19908 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 19909 ASSERT_TRUE(pass); 19910 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem); 19911 ASSERT_VK_SUCCESS(err); 19912 19913 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0); 19914 ASSERT_VK_SUCCESS(err); 19915 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0); 19916 ASSERT_VK_SUCCESS(err); 19917 19918 m_commandBuffer->begin(); 19919 VkImageCopy copyRegion; 19920 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 19921 copyRegion.srcSubresource.mipLevel = 0; 19922 copyRegion.srcSubresource.baseArrayLayer = 0; 19923 copyRegion.srcSubresource.layerCount = 0; 19924 copyRegion.srcOffset.x = 0; 19925 copyRegion.srcOffset.y = 0; 19926 copyRegion.srcOffset.z = 0; 19927 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 19928 copyRegion.dstSubresource.mipLevel = 0; 19929 copyRegion.dstSubresource.baseArrayLayer = 0; 19930 copyRegion.dstSubresource.layerCount = 0; 19931 copyRegion.dstOffset.x = 0; 19932 copyRegion.dstOffset.y = 0; 19933 copyRegion.dstOffset.z = 0; 19934 copyRegion.extent.width = 1; 19935 copyRegion.extent.height = 1; 19936 copyRegion.extent.depth = 1; 19937 m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region); 19938 m_commandBuffer->end(); 19939 19940 m_errorMonitor->VerifyFound(); 19941 19942 vkDestroyImage(m_device->device(), srcImage, NULL); 19943 vkDestroyImage(m_device->device(), dstImage, NULL); 19944 vkFreeMemory(m_device->device(), srcMem, NULL); 19945 vkFreeMemory(m_device->device(), destMem, NULL); 19946 } 19947 19948 TEST_F(VkLayerTest, CopyImageDepthStencilFormatMismatch) { 19949 ASSERT_NO_FATAL_FAILURE(Init()); 19950 auto depth_format = FindSupportedDepthStencilFormat(gpu()); 19951 if (!depth_format) { 19952 return; 19953 } 19954 19955 VkFormatProperties properties; 19956 vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D32_SFLOAT, &properties); 19957 if (properties.optimalTilingFeatures == 0) { 19958 printf(" Image format not supported; skipped.\n"); 19959 return; 19960 } 19961 19962 VkImageObj srcImage(m_device); 19963 srcImage.Init(32, 32, 1, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL); 19964 ASSERT_TRUE(srcImage.initialized()); 19965 VkImageObj dstImage(m_device); 19966 dstImage.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL); 19967 ASSERT_TRUE(dstImage.initialized()); 19968 19969 // Create two images of different types and try to copy between them 19970 19971 m_commandBuffer->begin(); 19972 VkImageCopy copyRegion; 19973 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 19974 copyRegion.srcSubresource.mipLevel = 0; 19975 copyRegion.srcSubresource.baseArrayLayer = 0; 19976 copyRegion.srcSubresource.layerCount = 0; 19977 copyRegion.srcOffset.x = 0; 19978 copyRegion.srcOffset.y = 0; 19979 copyRegion.srcOffset.z = 0; 19980 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 19981 copyRegion.dstSubresource.mipLevel = 0; 19982 copyRegion.dstSubresource.baseArrayLayer = 0; 19983 copyRegion.dstSubresource.layerCount = 0; 19984 copyRegion.dstOffset.x = 0; 19985 copyRegion.dstOffset.y = 0; 19986 copyRegion.dstOffset.z = 0; 19987 copyRegion.extent.width = 1; 19988 copyRegion.extent.height = 1; 19989 copyRegion.extent.depth = 1; 19990 19991 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 19992 "vkCmdCopyImage called with unmatched source and dest image depth"); 19993 m_commandBuffer->CopyImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, 19994 ©Region); 19995 m_commandBuffer->end(); 19996 19997 m_errorMonitor->VerifyFound(); 19998 } 19999 20000 TEST_F(VkLayerTest, CopyImageSampleCountMismatch) { 20001 TEST_DESCRIPTION("Image copies with sample count mis-matches"); 20002 20003 ASSERT_NO_FATAL_FAILURE(Init()); 20004 20005 VkImageFormatProperties image_format_properties; 20006 vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, 20007 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0, 20008 &image_format_properties); 20009 20010 if ((0 == (VK_SAMPLE_COUNT_2_BIT & image_format_properties.sampleCounts)) || 20011 (0 == (VK_SAMPLE_COUNT_4_BIT & image_format_properties.sampleCounts))) { 20012 printf(" Image multi-sample support not found; skipped.\n"); 20013 return; 20014 } 20015 20016 VkImageCreateInfo ci; 20017 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 20018 ci.pNext = NULL; 20019 ci.flags = 0; 20020 ci.imageType = VK_IMAGE_TYPE_2D; 20021 ci.format = VK_FORMAT_R8G8B8A8_UNORM; 20022 ci.extent = {128, 128, 1}; 20023 ci.mipLevels = 1; 20024 ci.arrayLayers = 1; 20025 ci.samples = VK_SAMPLE_COUNT_1_BIT; 20026 ci.tiling = VK_IMAGE_TILING_OPTIMAL; 20027 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 20028 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 20029 ci.queueFamilyIndexCount = 0; 20030 ci.pQueueFamilyIndices = NULL; 20031 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 20032 20033 VkImageObj image1(m_device); 20034 image1.init(&ci); 20035 ASSERT_TRUE(image1.initialized()); 20036 20037 ci.samples = VK_SAMPLE_COUNT_2_BIT; 20038 VkImageObj image2(m_device); 20039 image2.init(&ci); 20040 ASSERT_TRUE(image2.initialized()); 20041 20042 ci.samples = VK_SAMPLE_COUNT_4_BIT; 20043 VkImageObj image4(m_device); 20044 image4.init(&ci); 20045 ASSERT_TRUE(image4.initialized()); 20046 20047 m_commandBuffer->begin(); 20048 20049 VkImageCopy copyRegion; 20050 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 20051 copyRegion.srcSubresource.mipLevel = 0; 20052 copyRegion.srcSubresource.baseArrayLayer = 0; 20053 copyRegion.srcSubresource.layerCount = 1; 20054 copyRegion.srcOffset = {0, 0, 0}; 20055 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 20056 copyRegion.dstSubresource.mipLevel = 0; 20057 copyRegion.dstSubresource.baseArrayLayer = 0; 20058 copyRegion.dstSubresource.layerCount = 1; 20059 copyRegion.dstOffset = {0, 0, 0}; 20060 copyRegion.extent = {128, 128, 1}; 20061 20062 // Copy a single sample image to/from a multi-sample image 20063 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19000110); 20064 vkCmdCopyImage(m_commandBuffer->handle(), image1.handle(), VK_IMAGE_LAYOUT_GENERAL, image4.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, 20065 ©Region); 20066 m_errorMonitor->VerifyFound(); 20067 20068 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19000110); 20069 vkCmdCopyImage(m_commandBuffer->handle(), image2.handle(), VK_IMAGE_LAYOUT_GENERAL, image1.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, 20070 ©Region); 20071 m_errorMonitor->VerifyFound(); 20072 20073 // Copy between multi-sample images with different sample counts 20074 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19000110); 20075 vkCmdCopyImage(m_commandBuffer->handle(), image2.handle(), VK_IMAGE_LAYOUT_GENERAL, image4.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, 20076 ©Region); 20077 m_errorMonitor->VerifyFound(); 20078 20079 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_19000110); 20080 vkCmdCopyImage(m_commandBuffer->handle(), image4.handle(), VK_IMAGE_LAYOUT_GENERAL, image2.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, 20081 ©Region); 20082 m_errorMonitor->VerifyFound(); 20083 20084 m_commandBuffer->end(); 20085 } 20086 20087 TEST_F(VkLayerTest, CopyImageAspectMismatch) { 20088 TEST_DESCRIPTION("Image copies with aspect mask errors"); 20089 ASSERT_NO_FATAL_FAILURE(Init()); 20090 auto ds_format = FindSupportedDepthStencilFormat(gpu()); 20091 if (!ds_format) { 20092 return; 20093 } 20094 20095 VkFormatProperties properties; 20096 vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D32_SFLOAT, &properties); 20097 if (properties.optimalTilingFeatures == 0) { 20098 printf(" Image format VK_FORMAT_D32_SFLOAT not supported; skipped.\n"); 20099 return; 20100 } 20101 VkImageObj color_image(m_device), ds_image(m_device), depth_image(m_device); 20102 color_image.Init(128, 128, 1, VK_FORMAT_R32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); 20103 depth_image.Init(128, 128, 1, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 20104 VK_IMAGE_TILING_OPTIMAL, 0); 20105 ds_image.Init(128, 128, 1, ds_format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 20106 VK_IMAGE_TILING_OPTIMAL, 0); 20107 ASSERT_TRUE(color_image.initialized()); 20108 ASSERT_TRUE(depth_image.initialized()); 20109 ASSERT_TRUE(ds_image.initialized()); 20110 20111 VkImageCopy copyRegion; 20112 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 20113 copyRegion.srcSubresource.mipLevel = 0; 20114 copyRegion.srcSubresource.baseArrayLayer = 0; 20115 copyRegion.srcSubresource.layerCount = 1; 20116 copyRegion.srcOffset = {0, 0, 0}; 20117 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 20118 copyRegion.dstSubresource.mipLevel = 0; 20119 copyRegion.dstSubresource.baseArrayLayer = 0; 20120 copyRegion.dstSubresource.layerCount = 1; 20121 copyRegion.dstOffset = {64, 0, 0}; 20122 copyRegion.extent = {64, 128, 1}; 20123 20124 // Submitting command before command buffer is in recording state 20125 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 20126 "You must call vkBeginCommandBuffer"); // VALIDATION_ERROR_19002413); 20127 vkCmdCopyImage(m_commandBuffer->handle(), depth_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(), 20128 VK_IMAGE_LAYOUT_GENERAL, 1, ©Region); 20129 m_errorMonitor->VerifyFound(); 20130 20131 m_commandBuffer->begin(); 20132 20133 // Src and dest aspect masks don't match 20134 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; 20135 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c00112); 20136 vkCmdCopyImage(m_commandBuffer->handle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, ds_image.handle(), 20137 VK_IMAGE_LAYOUT_GENERAL, 1, ©Region); 20138 m_errorMonitor->VerifyFound(); 20139 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 20140 20141 // Illegal combinations of aspect bits - VU 01221 20142 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT; // color must be alone 20143 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT; 20144 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a60014e); 20145 // These aspect/format mismatches are redundant but unavoidable here 20146 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0011c); 20147 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0011e); 20148 vkCmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(), 20149 VK_IMAGE_LAYOUT_GENERAL, 1, ©Region); 20150 m_errorMonitor->VerifyFound(); 20151 // Metadata aspect is illegal - VU 01222 20152 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT; 20153 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT; 20154 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0a600150); 20155 // These aspect/format mismatches are redundant but unavoidable here 20156 vkCmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(), 20157 VK_IMAGE_LAYOUT_GENERAL, 1, ©Region); 20158 m_errorMonitor->VerifyFound(); 20159 20160 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 20161 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 20162 20163 // Aspect mask doesn't match source image format - VU 01200 20164 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0011c); 20165 // Again redundant but unavoidable when provoking vu01200 w/o vu01201 20166 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "unmatched source and dest image depth/stencil formats"); 20167 vkCmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(), 20168 VK_IMAGE_LAYOUT_GENERAL, 1, ©Region); 20169 m_errorMonitor->VerifyFound(); 20170 20171 // Aspect mask doesn't match dest image format - VU 01201 20172 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 20173 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 20174 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09c0011e); 20175 // Again redundant but unavoidable when provoking vu01201 w/o vu01200 20176 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "unmatched source and dest image depth/stencil formats"); 20177 vkCmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(), 20178 VK_IMAGE_LAYOUT_GENERAL, 1, ©Region); 20179 m_errorMonitor->VerifyFound(); 20180 20181 m_commandBuffer->end(); 20182 } 20183 20184 TEST_F(VkLayerTest, ResolveImageLowSampleCount) { 20185 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 20186 "vkCmdResolveImage called with source sample count less than 2."); 20187 20188 ASSERT_NO_FATAL_FAILURE(Init()); 20189 20190 // Create two images of sample count 1 and try to Resolve between them 20191 20192 VkImageCreateInfo image_create_info = {}; 20193 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 20194 image_create_info.pNext = NULL; 20195 image_create_info.imageType = VK_IMAGE_TYPE_2D; 20196 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; 20197 image_create_info.extent.width = 32; 20198 image_create_info.extent.height = 1; 20199 image_create_info.extent.depth = 1; 20200 image_create_info.mipLevels = 1; 20201 image_create_info.arrayLayers = 1; 20202 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 20203 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 20204 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 20205 image_create_info.flags = 0; 20206 20207 VkImageObj srcImage(m_device); 20208 srcImage.init(&image_create_info); 20209 ASSERT_TRUE(srcImage.initialized()); 20210 20211 VkImageObj dstImage(m_device); 20212 dstImage.init(&image_create_info); 20213 ASSERT_TRUE(dstImage.initialized()); 20214 20215 m_commandBuffer->begin(); 20216 VkImageResolve resolveRegion; 20217 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 20218 resolveRegion.srcSubresource.mipLevel = 0; 20219 resolveRegion.srcSubresource.baseArrayLayer = 0; 20220 resolveRegion.srcSubresource.layerCount = 1; 20221 resolveRegion.srcOffset.x = 0; 20222 resolveRegion.srcOffset.y = 0; 20223 resolveRegion.srcOffset.z = 0; 20224 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 20225 resolveRegion.dstSubresource.mipLevel = 0; 20226 resolveRegion.dstSubresource.baseArrayLayer = 0; 20227 resolveRegion.dstSubresource.layerCount = 1; 20228 resolveRegion.dstOffset.x = 0; 20229 resolveRegion.dstOffset.y = 0; 20230 resolveRegion.dstOffset.z = 0; 20231 resolveRegion.extent.width = 1; 20232 resolveRegion.extent.height = 1; 20233 resolveRegion.extent.depth = 1; 20234 m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, 20235 &resolveRegion); 20236 m_commandBuffer->end(); 20237 20238 m_errorMonitor->VerifyFound(); 20239 } 20240 20241 TEST_F(VkLayerTest, ResolveImageHighSampleCount) { 20242 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 20243 "vkCmdResolveImage called with dest sample count greater than 1."); 20244 20245 ASSERT_NO_FATAL_FAILURE(Init()); 20246 20247 // Create two images of sample count 4 and try to Resolve between them 20248 20249 VkImageCreateInfo image_create_info = {}; 20250 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 20251 image_create_info.pNext = NULL; 20252 image_create_info.imageType = VK_IMAGE_TYPE_2D; 20253 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; 20254 image_create_info.extent.width = 32; 20255 image_create_info.extent.height = 1; 20256 image_create_info.extent.depth = 1; 20257 image_create_info.mipLevels = 1; 20258 image_create_info.arrayLayers = 1; 20259 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; 20260 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 20261 // Note: Some implementations expect color attachment usage for any 20262 // multisample surface 20263 image_create_info.usage = 20264 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 20265 image_create_info.flags = 0; 20266 20267 VkImageObj srcImage(m_device); 20268 srcImage.init(&image_create_info); 20269 ASSERT_TRUE(srcImage.initialized()); 20270 20271 VkImageObj dstImage(m_device); 20272 dstImage.init(&image_create_info); 20273 ASSERT_TRUE(dstImage.initialized()); 20274 20275 m_commandBuffer->begin(); 20276 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest? 20277 // VK_IMAGE_LAYOUT_UNDEFINED = 0, 20278 // VK_IMAGE_LAYOUT_GENERAL = 1, 20279 VkImageResolve resolveRegion; 20280 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 20281 resolveRegion.srcSubresource.mipLevel = 0; 20282 resolveRegion.srcSubresource.baseArrayLayer = 0; 20283 resolveRegion.srcSubresource.layerCount = 1; 20284 resolveRegion.srcOffset.x = 0; 20285 resolveRegion.srcOffset.y = 0; 20286 resolveRegion.srcOffset.z = 0; 20287 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 20288 resolveRegion.dstSubresource.mipLevel = 0; 20289 resolveRegion.dstSubresource.baseArrayLayer = 0; 20290 resolveRegion.dstSubresource.layerCount = 1; 20291 resolveRegion.dstOffset.x = 0; 20292 resolveRegion.dstOffset.y = 0; 20293 resolveRegion.dstOffset.z = 0; 20294 resolveRegion.extent.width = 1; 20295 resolveRegion.extent.height = 1; 20296 resolveRegion.extent.depth = 1; 20297 m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, 20298 &resolveRegion); 20299 m_commandBuffer->end(); 20300 20301 m_errorMonitor->VerifyFound(); 20302 } 20303 20304 TEST_F(VkLayerTest, ResolveImageFormatMismatch) { 20305 VkResult err; 20306 bool pass; 20307 20308 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, 20309 "vkCmdResolveImage called with unmatched source and dest formats."); 20310 20311 ASSERT_NO_FATAL_FAILURE(Init()); 20312 20313 // Create two images of different types and try to copy between them 20314 VkImage srcImage; 20315 VkImage dstImage; 20316 VkDeviceMemory srcMem; 20317 VkDeviceMemory destMem; 20318 VkMemoryRequirements memReqs; 20319 20320 VkImageCreateInfo image_create_info = {}; 20321 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 20322 image_create_info.pNext = NULL; 20323 image_create_info.imageType = VK_IMAGE_TYPE_2D; 20324 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; 20325 image_create_info.extent.width = 32; 20326 image_create_info.extent.height = 1; 20327 image_create_info.extent.depth = 1; 20328 image_create_info.mipLevels = 1; 20329 image_create_info.arrayLayers = 1; 20330 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT; 20331 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 20332 // Note: Some implementations expect color attachment usage for any 20333 // multisample surface 20334 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 20335 image_create_info.flags = 0; 20336 20337 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage); 20338 ASSERT_VK_SUCCESS(err); 20339 20340 // Set format to something other than source image 20341 image_create_info.format = VK_FORMAT_R32_SFLOAT; 20342 // Note: Some implementations expect color attachment usage for any 20343 // multisample surface 20344 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 20345 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 20346 20347 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage); 20348 ASSERT_VK_SUCCESS(err); 20349 20350 // Allocate memory 20351 VkMemoryAllocateInfo memAlloc = {}; 20352 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 20353 memAlloc.pNext = NULL; 20354 memAlloc.allocationSize = 0; 20355 memAlloc.memoryTypeIndex = 0; 20356 20357 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs); 20358 memAlloc.allocationSize = memReqs.size; 20359 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 20360 ASSERT_TRUE(pass); 20361 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem); 20362 ASSERT_VK_SUCCESS(err); 20363 20364 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs); 20365 memAlloc.allocationSize = memReqs.size; 20366 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 20367 ASSERT_TRUE(pass); 20368 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem); 20369 ASSERT_VK_SUCCESS(err); 20370 20371 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0); 20372 ASSERT_VK_SUCCESS(err); 20373 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0); 20374 ASSERT_VK_SUCCESS(err); 20375 20376 m_commandBuffer->begin(); 20377 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest? 20378 // VK_IMAGE_LAYOUT_UNDEFINED = 0, 20379 // VK_IMAGE_LAYOUT_GENERAL = 1, 20380 VkImageResolve resolveRegion; 20381 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 20382 resolveRegion.srcSubresource.mipLevel = 0; 20383 resolveRegion.srcSubresource.baseArrayLayer = 0; 20384 resolveRegion.srcSubresource.layerCount = 1; 20385 resolveRegion.srcOffset.x = 0; 20386 resolveRegion.srcOffset.y = 0; 20387 resolveRegion.srcOffset.z = 0; 20388 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 20389 resolveRegion.dstSubresource.mipLevel = 0; 20390 resolveRegion.dstSubresource.baseArrayLayer = 0; 20391 resolveRegion.dstSubresource.layerCount = 1; 20392 resolveRegion.dstOffset.x = 0; 20393 resolveRegion.dstOffset.y = 0; 20394 resolveRegion.dstOffset.z = 0; 20395 resolveRegion.extent.width = 1; 20396 resolveRegion.extent.height = 1; 20397 resolveRegion.extent.depth = 1; 20398 m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion); 20399 m_commandBuffer->end(); 20400 20401 m_errorMonitor->VerifyFound(); 20402 20403 vkDestroyImage(m_device->device(), srcImage, NULL); 20404 vkDestroyImage(m_device->device(), dstImage, NULL); 20405 vkFreeMemory(m_device->device(), srcMem, NULL); 20406 vkFreeMemory(m_device->device(), destMem, NULL); 20407 } 20408 20409 TEST_F(VkLayerTest, ResolveImageTypeMismatch) { 20410 VkResult err; 20411 bool pass; 20412 20413 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, 20414 "vkCmdResolveImage called with unmatched source and dest image types."); 20415 20416 ASSERT_NO_FATAL_FAILURE(Init()); 20417 20418 // Create two images of different types and try to copy between them 20419 VkImage srcImage; 20420 VkImage dstImage; 20421 VkDeviceMemory srcMem; 20422 VkDeviceMemory destMem; 20423 VkMemoryRequirements memReqs; 20424 20425 VkImageCreateInfo image_create_info = {}; 20426 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 20427 image_create_info.pNext = NULL; 20428 image_create_info.imageType = VK_IMAGE_TYPE_2D; 20429 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; 20430 image_create_info.extent.width = 32; 20431 image_create_info.extent.height = 1; 20432 image_create_info.extent.depth = 1; 20433 image_create_info.mipLevels = 1; 20434 image_create_info.arrayLayers = 1; 20435 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT; 20436 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 20437 // Note: Some implementations expect color attachment usage for any 20438 // multisample surface 20439 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 20440 image_create_info.flags = 0; 20441 20442 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage); 20443 ASSERT_VK_SUCCESS(err); 20444 20445 image_create_info.imageType = VK_IMAGE_TYPE_1D; 20446 // Note: Some implementations expect color attachment usage for any 20447 // multisample surface 20448 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 20449 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 20450 20451 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage); 20452 ASSERT_VK_SUCCESS(err); 20453 20454 // Allocate memory 20455 VkMemoryAllocateInfo memAlloc = {}; 20456 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 20457 memAlloc.pNext = NULL; 20458 memAlloc.allocationSize = 0; 20459 memAlloc.memoryTypeIndex = 0; 20460 20461 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs); 20462 memAlloc.allocationSize = memReqs.size; 20463 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 20464 ASSERT_TRUE(pass); 20465 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem); 20466 ASSERT_VK_SUCCESS(err); 20467 20468 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs); 20469 memAlloc.allocationSize = memReqs.size; 20470 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 20471 ASSERT_TRUE(pass); 20472 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem); 20473 ASSERT_VK_SUCCESS(err); 20474 20475 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0); 20476 ASSERT_VK_SUCCESS(err); 20477 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0); 20478 ASSERT_VK_SUCCESS(err); 20479 20480 m_commandBuffer->begin(); 20481 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest? 20482 // VK_IMAGE_LAYOUT_UNDEFINED = 0, 20483 // VK_IMAGE_LAYOUT_GENERAL = 1, 20484 VkImageResolve resolveRegion; 20485 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 20486 resolveRegion.srcSubresource.mipLevel = 0; 20487 resolveRegion.srcSubresource.baseArrayLayer = 0; 20488 resolveRegion.srcSubresource.layerCount = 1; 20489 resolveRegion.srcOffset.x = 0; 20490 resolveRegion.srcOffset.y = 0; 20491 resolveRegion.srcOffset.z = 0; 20492 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 20493 resolveRegion.dstSubresource.mipLevel = 0; 20494 resolveRegion.dstSubresource.baseArrayLayer = 0; 20495 resolveRegion.dstSubresource.layerCount = 1; 20496 resolveRegion.dstOffset.x = 0; 20497 resolveRegion.dstOffset.y = 0; 20498 resolveRegion.dstOffset.z = 0; 20499 resolveRegion.extent.width = 1; 20500 resolveRegion.extent.height = 1; 20501 resolveRegion.extent.depth = 1; 20502 m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion); 20503 m_commandBuffer->end(); 20504 20505 m_errorMonitor->VerifyFound(); 20506 20507 vkDestroyImage(m_device->device(), srcImage, NULL); 20508 vkDestroyImage(m_device->device(), dstImage, NULL); 20509 vkFreeMemory(m_device->device(), srcMem, NULL); 20510 vkFreeMemory(m_device->device(), destMem, NULL); 20511 } 20512 20513 TEST_F(VkLayerTest, DepthStencilImageViewWithColorAspectBitError) { 20514 // Create a single Image descriptor and cause it to first hit an error due 20515 // to using a DS format, then cause it to hit error due to COLOR_BIT not 20516 // set in aspect 20517 // The image format check comes 2nd in validation so we trigger it first, 20518 // then when we cause aspect fail next, bad format check will be preempted 20519 VkResult err; 20520 20521 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 20522 "Combination depth/stencil image formats can have only the "); 20523 20524 ASSERT_NO_FATAL_FAILURE(Init()); 20525 auto depth_format = FindSupportedDepthStencilFormat(gpu()); 20526 if (!depth_format) { 20527 return; 20528 } 20529 20530 VkDescriptorPoolSize ds_type_count = {}; 20531 ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; 20532 ds_type_count.descriptorCount = 1; 20533 20534 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 20535 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 20536 ds_pool_ci.pNext = NULL; 20537 ds_pool_ci.maxSets = 1; 20538 ds_pool_ci.poolSizeCount = 1; 20539 ds_pool_ci.pPoolSizes = &ds_type_count; 20540 20541 VkDescriptorPool ds_pool; 20542 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 20543 ASSERT_VK_SUCCESS(err); 20544 20545 VkDescriptorSetLayoutBinding dsl_binding = {}; 20546 dsl_binding.binding = 0; 20547 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; 20548 dsl_binding.descriptorCount = 1; 20549 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 20550 dsl_binding.pImmutableSamplers = NULL; 20551 20552 const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding}); 20553 20554 VkDescriptorSet descriptorSet; 20555 VkDescriptorSetAllocateInfo alloc_info = {}; 20556 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 20557 alloc_info.descriptorSetCount = 1; 20558 alloc_info.descriptorPool = ds_pool; 20559 alloc_info.pSetLayouts = &ds_layout.handle(); 20560 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 20561 ASSERT_VK_SUCCESS(err); 20562 20563 VkImage image_bad; 20564 VkImage image_good; 20565 // One bad format and one good format for Color attachment 20566 const VkFormat tex_format_bad = depth_format; 20567 const VkFormat tex_format_good = VK_FORMAT_B8G8R8A8_UNORM; 20568 const int32_t tex_width = 32; 20569 const int32_t tex_height = 32; 20570 20571 VkImageCreateInfo image_create_info = {}; 20572 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 20573 image_create_info.pNext = NULL; 20574 image_create_info.imageType = VK_IMAGE_TYPE_2D; 20575 image_create_info.format = tex_format_bad; 20576 image_create_info.extent.width = tex_width; 20577 image_create_info.extent.height = tex_height; 20578 image_create_info.extent.depth = 1; 20579 image_create_info.mipLevels = 1; 20580 image_create_info.arrayLayers = 1; 20581 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 20582 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 20583 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; 20584 image_create_info.flags = 0; 20585 20586 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image_bad); 20587 ASSERT_VK_SUCCESS(err); 20588 image_create_info.format = tex_format_good; 20589 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 20590 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image_good); 20591 ASSERT_VK_SUCCESS(err); 20592 20593 // ---Bind image memory--- 20594 VkMemoryRequirements img_mem_reqs; 20595 vkGetImageMemoryRequirements(m_device->device(), image_bad, &img_mem_reqs); 20596 VkMemoryAllocateInfo image_alloc_info = {}; 20597 image_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 20598 image_alloc_info.pNext = NULL; 20599 image_alloc_info.memoryTypeIndex = 0; 20600 image_alloc_info.allocationSize = img_mem_reqs.size; 20601 bool pass = 20602 m_device->phy().set_memory_type(img_mem_reqs.memoryTypeBits, &image_alloc_info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); 20603 ASSERT_TRUE(pass); 20604 VkDeviceMemory mem; 20605 err = vkAllocateMemory(m_device->device(), &image_alloc_info, NULL, &mem); 20606 ASSERT_VK_SUCCESS(err); 20607 err = vkBindImageMemory(m_device->device(), image_bad, mem, 0); 20608 ASSERT_VK_SUCCESS(err); 20609 // ----------------------- 20610 20611 VkImageViewCreateInfo image_view_create_info = {}; 20612 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 20613 image_view_create_info.image = image_bad; 20614 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; 20615 image_view_create_info.format = tex_format_bad; 20616 image_view_create_info.subresourceRange.baseArrayLayer = 0; 20617 image_view_create_info.subresourceRange.baseMipLevel = 0; 20618 image_view_create_info.subresourceRange.layerCount = 1; 20619 image_view_create_info.subresourceRange.levelCount = 1; 20620 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT; 20621 20622 VkImageView view; 20623 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view); 20624 20625 m_errorMonitor->VerifyFound(); 20626 20627 vkDestroyImage(m_device->device(), image_bad, NULL); 20628 vkDestroyImage(m_device->device(), image_good, NULL); 20629 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 20630 20631 vkFreeMemory(m_device->device(), mem, NULL); 20632 } 20633 20634 TEST_F(VkLayerTest, ClearImageErrors) { 20635 TEST_DESCRIPTION("Call ClearColorImage w/ a depth|stencil image and ClearDepthStencilImage with a color image."); 20636 20637 ASSERT_NO_FATAL_FAILURE(Init()); 20638 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 20639 20640 m_commandBuffer->begin(); 20641 20642 // Color image 20643 VkClearColorValue clear_color; 20644 memset(clear_color.uint32, 0, sizeof(uint32_t) * 4); 20645 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; 20646 const VkFormat color_format = VK_FORMAT_B8G8R8A8_UNORM; 20647 const int32_t img_width = 32; 20648 const int32_t img_height = 32; 20649 VkImageCreateInfo image_create_info = {}; 20650 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 20651 image_create_info.pNext = NULL; 20652 image_create_info.imageType = VK_IMAGE_TYPE_2D; 20653 image_create_info.format = color_format; 20654 image_create_info.extent.width = img_width; 20655 image_create_info.extent.height = img_height; 20656 image_create_info.extent.depth = 1; 20657 image_create_info.mipLevels = 1; 20658 image_create_info.arrayLayers = 1; 20659 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 20660 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 20661 20662 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 20663 vk_testing::Image color_image_no_transfer; 20664 color_image_no_transfer.init(*m_device, image_create_info, reqs); 20665 20666 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 20667 vk_testing::Image color_image; 20668 color_image.init(*m_device, image_create_info, reqs); 20669 20670 const VkImageSubresourceRange color_range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT); 20671 20672 // Depth/Stencil image 20673 VkClearDepthStencilValue clear_value = {0}; 20674 reqs = 0; // don't need HOST_VISIBLE DS image 20675 VkImageCreateInfo ds_image_create_info = vk_testing::Image::create_info(); 20676 ds_image_create_info.imageType = VK_IMAGE_TYPE_2D; 20677 ds_image_create_info.format = VK_FORMAT_D16_UNORM; 20678 ds_image_create_info.extent.width = 64; 20679 ds_image_create_info.extent.height = 64; 20680 ds_image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 20681 ds_image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 20682 20683 vk_testing::Image ds_image; 20684 ds_image.init(*m_device, ds_image_create_info, reqs); 20685 20686 const VkImageSubresourceRange ds_range = vk_testing::Image::subresource_range(ds_image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT); 20687 20688 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearColorImage called with depth/stencil image."); 20689 20690 vkCmdClearColorImage(m_commandBuffer->handle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &color_range); 20691 20692 m_errorMonitor->VerifyFound(); 20693 20694 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 20695 "vkCmdClearColorImage called with image created without VK_IMAGE_USAGE_TRANSFER_DST_BIT"); 20696 20697 vkCmdClearColorImage(m_commandBuffer->handle(), color_image_no_transfer.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, 20698 &color_range); 20699 20700 m_errorMonitor->VerifyFound(); 20701 20702 // Call CmdClearDepthStencilImage with color image 20703 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 20704 "vkCmdClearDepthStencilImage called without a depth/stencil image."); 20705 20706 vkCmdClearDepthStencilImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_value, 20707 1, &ds_range); 20708 20709 m_errorMonitor->VerifyFound(); 20710 } 20711 20712 TEST_F(VkLayerTest, CommandQueueFlags) { 20713 TEST_DESCRIPTION( 20714 "Allocate a command buffer on a queue that does not support graphics and try to issue a graphics-only command"); 20715 20716 ASSERT_NO_FATAL_FAILURE(Init()); 20717 20718 uint32_t queueFamilyIndex = m_device->QueueFamilyWithoutCapabilities(VK_QUEUE_GRAPHICS_BIT); 20719 if (queueFamilyIndex == UINT32_MAX) { 20720 printf(" Non-graphics queue family not found; skipped.\n"); 20721 return; 20722 } else { 20723 // Create command pool on a non-graphics queue 20724 VkCommandPoolObj command_pool(m_device, queueFamilyIndex); 20725 20726 // Setup command buffer on pool 20727 VkCommandBufferObj command_buffer(m_device, &command_pool); 20728 command_buffer.begin(); 20729 20730 // Issue a graphics only command 20731 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1e002415); 20732 VkViewport viewport = {0, 0, 16, 16, 0, 1}; 20733 command_buffer.SetViewport(0, 1, &viewport); 20734 m_errorMonitor->VerifyFound(); 20735 } 20736 } 20737 20738 TEST_F(VkLayerTest, ExecuteUnrecordedSecondaryCB) { 20739 TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a CB in the initial state"); 20740 ASSERT_NO_FATAL_FAILURE(Init()); 20741 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); 20742 // never record secondary 20743 20744 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1b2000b2); 20745 m_commandBuffer->begin(); 20746 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle()); 20747 m_errorMonitor->VerifyFound(); 20748 m_commandBuffer->end(); 20749 } 20750 20751 TEST_F(VkLayerTest, ExecuteUnrecordedPrimaryCB) { 20752 TEST_DESCRIPTION("Attempt vkQueueSubmit with a CB in the initial state"); 20753 ASSERT_NO_FATAL_FAILURE(Init()); 20754 // never record m_commandBuffer 20755 20756 VkSubmitInfo si = {}; 20757 si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 20758 si.commandBufferCount = 1; 20759 si.pCommandBuffers = &m_commandBuffer->handle(); 20760 20761 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_31a00090); 20762 vkQueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE); 20763 m_errorMonitor->VerifyFound(); 20764 } 20765 20766 TEST_F(VkLayerTest, ExtensionNotEnabled) { 20767 TEST_DESCRIPTION("Validate that using an API from an unenabled extension returns an error"); 20768 20769 // Do NOT enable VK_KHR_maintenance1 20770 ASSERT_NO_FATAL_FAILURE(Init()); 20771 // Find address of extension API 20772 PFN_vkTrimCommandPoolKHR vkTrimCommandPoolKHR = 20773 (PFN_vkTrimCommandPoolKHR)vkGetDeviceProcAddr(m_device->handle(), "vkTrimCommandPoolKHR"); 20774 if (vkTrimCommandPoolKHR == nullptr) { 20775 printf(" Maintenance1 not supported by device; skipped.\n"); 20776 return; 20777 } 20778 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 20779 "but its required extension VK_KHR_maintenance1 has not been enabled"); 20780 vkTrimCommandPoolKHR(m_device->handle(), m_commandPool->handle(), (VkCommandPoolTrimFlagsKHR)0); 20781 m_errorMonitor->VerifyFound(); 20782 } 20783 20784 TEST_F(VkLayerTest, Maintenance1AndNegativeViewport) { 20785 TEST_DESCRIPTION("Attempt to enable AMD_negative_viewport_height and Maintenance1_KHR extension simultaneously"); 20786 20787 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 20788 if (!((DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) && 20789 (DeviceExtensionSupported(gpu(), nullptr, VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME)))) { 20790 printf(" Maintenance1 and AMD_negative viewport height extensions not supported, skipping test\n"); 20791 return; 20792 } 20793 ASSERT_NO_FATAL_FAILURE(InitState()); 20794 20795 vk_testing::QueueCreateInfoArray queue_info(m_device->queue_props); 20796 const char *extension_names[2] = {"VK_KHR_maintenance1", "VK_AMD_negative_viewport_height"}; 20797 VkDevice testDevice; 20798 VkDeviceCreateInfo device_create_info = {}; 20799 auto features = m_device->phy().features(); 20800 device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; 20801 device_create_info.pNext = NULL; 20802 device_create_info.queueCreateInfoCount = queue_info.size(); 20803 device_create_info.pQueueCreateInfos = queue_info.data(); 20804 device_create_info.enabledLayerCount = 0; 20805 device_create_info.ppEnabledLayerNames = NULL; 20806 device_create_info.enabledExtensionCount = 2; 20807 device_create_info.ppEnabledExtensionNames = (const char *const *)extension_names; 20808 device_create_info.pEnabledFeatures = &features; 20809 20810 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_056002ec); 20811 // The following unexpected error is coming from the LunarG loader. Do not make it a desired message because platforms that do 20812 // not use the LunarG loader (e.g. Android) will not see the message and the test will fail. 20813 m_errorMonitor->SetUnexpectedError("Failed to create device chain."); 20814 vkCreateDevice(gpu(), &device_create_info, NULL, &testDevice); 20815 m_errorMonitor->VerifyFound(); 20816 } 20817 20818 TEST_F(VkLayerTest, InvalidCreateDescriptorPool) { 20819 TEST_DESCRIPTION("Attempt to create descriptor pool with invalid parameters"); 20820 20821 ASSERT_NO_FATAL_FAILURE(Init()); 20822 20823 const uint32_t default_descriptor_count = 1; 20824 const VkDescriptorPoolSize dp_size_template{VK_DESCRIPTOR_TYPE_SAMPLER, default_descriptor_count}; 20825 20826 const VkDescriptorPoolCreateInfo dp_ci_template{VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, 20827 nullptr, // pNext 20828 0, // flags 20829 1, // maxSets 20830 1, // poolSizeCount 20831 &dp_size_template}; 20832 20833 // try maxSets = 0 20834 { 20835 VkDescriptorPoolCreateInfo invalid_dp_ci = dp_ci_template; 20836 invalid_dp_ci.maxSets = 0; // invalid maxSets value 20837 20838 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0480025a); 20839 { 20840 VkDescriptorPool pool; 20841 vkCreateDescriptorPool(m_device->device(), &invalid_dp_ci, nullptr, &pool); 20842 } 20843 m_errorMonitor->VerifyFound(); 20844 } 20845 20846 // try descriptorCount = 0 20847 { 20848 VkDescriptorPoolSize invalid_dp_size = dp_size_template; 20849 invalid_dp_size.descriptorCount = 0; // invalid descriptorCount value 20850 20851 VkDescriptorPoolCreateInfo dp_ci = dp_ci_template; 20852 dp_ci.pPoolSizes = &invalid_dp_size; 20853 20854 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_04a0025c); 20855 { 20856 VkDescriptorPool pool; 20857 vkCreateDescriptorPool(m_device->device(), &dp_ci, nullptr, &pool); 20858 } 20859 m_errorMonitor->VerifyFound(); 20860 } 20861 } 20862 20863 TEST_F(VkLayerTest, InvalidCreateBufferSize) { 20864 TEST_DESCRIPTION("Attempt to create VkBuffer with size of zero"); 20865 20866 ASSERT_NO_FATAL_FAILURE(Init()); 20867 20868 VkBufferCreateInfo info = {}; 20869 info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 20870 info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; 20871 20872 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01400720); 20873 info.size = 0; 20874 VkBuffer buffer; 20875 vkCreateBuffer(m_device->device(), &info, nullptr, &buffer); 20876 m_errorMonitor->VerifyFound(); 20877 } 20878 20879 // 20880 // POSITIVE VALIDATION TESTS 20881 // 20882 // These tests do not expect to encounter ANY validation errors pass only if this is true 20883 20884 TEST_F(VkPositiveLayerTest, UncompressedToCompressedImageCopy) { 20885 TEST_DESCRIPTION("Image copies between compressed and uncompressed images"); 20886 ASSERT_NO_FATAL_FAILURE(Init()); 20887 20888 // Verify format support 20889 // Size-compatible (64-bit) formats. Uncompressed is 64 bits per texel, compressed is 64 bits per 4x4 block (or 4bpt). 20890 if (!ImageFormatAndFeaturesSupported(gpu(), VK_FORMAT_R16G16B16A16_UINT, VK_IMAGE_TILING_OPTIMAL, 20891 VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR | VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR) || 20892 !ImageFormatAndFeaturesSupported(gpu(), VK_FORMAT_BC1_RGBA_SRGB_BLOCK, VK_IMAGE_TILING_OPTIMAL, 20893 VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR | VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR)) { 20894 printf(" Required formats/features not supported - UncompressedToCompressedImageCopy skipped.\n"); 20895 return; 20896 } 20897 20898 VkImageObj uncomp_10x10t_image(m_device); // Size = 10 * 10 * 64 = 6400 20899 VkImageObj comp_10x10b_40x40t_image(m_device); // Size = 40 * 40 * 4 = 6400 20900 20901 uncomp_10x10t_image.Init(10, 10, 1, VK_FORMAT_R16G16B16A16_UINT, 20902 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL); 20903 comp_10x10b_40x40t_image.Init(40, 40, 1, VK_FORMAT_BC1_RGBA_SRGB_BLOCK, 20904 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL); 20905 20906 if (!uncomp_10x10t_image.initialized() || !comp_10x10b_40x40t_image.initialized()) { 20907 printf(" Unable to initialize surfaces - UncompressedToCompressedImageCopy skipped.\n"); 20908 return; 20909 } 20910 20911 // Both copies represent the same number of bytes. Bytes Per Texel = 1 for bc6, 16 for uncompressed 20912 // Copy compressed to uncompressed 20913 VkImageCopy copy_region = {}; 20914 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 20915 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 20916 copy_region.srcSubresource.mipLevel = 0; 20917 copy_region.dstSubresource.mipLevel = 0; 20918 copy_region.srcSubresource.baseArrayLayer = 0; 20919 copy_region.dstSubresource.baseArrayLayer = 0; 20920 copy_region.srcSubresource.layerCount = 1; 20921 copy_region.dstSubresource.layerCount = 1; 20922 copy_region.srcOffset = {0, 0, 0}; 20923 copy_region.dstOffset = {0, 0, 0}; 20924 20925 m_errorMonitor->ExpectSuccess(); 20926 m_commandBuffer->begin(); 20927 20928 // Copy from uncompressed to compressed 20929 copy_region.extent = {10, 10, 1}; // Dimensions in (uncompressed) texels 20930 vkCmdCopyImage(m_commandBuffer->handle(), uncomp_10x10t_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 20931 comp_10x10b_40x40t_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, ©_region); 20932 20933 // And from compressed to uncompressed 20934 copy_region.extent = {40, 40, 1}; // Dimensions in (compressed) texels 20935 vkCmdCopyImage(m_commandBuffer->handle(), comp_10x10b_40x40t_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 20936 uncomp_10x10t_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, ©_region); 20937 20938 m_errorMonitor->VerifyNotFound(); 20939 m_commandBuffer->end(); 20940 } 20941 20942 TEST_F(VkPositiveLayerTest, DeleteDescriptorSetLayoutsBeforeDescriptorSets) { 20943 TEST_DESCRIPTION("Create DSLayouts and DescriptorSets and then delete the DSLayouts before the DescriptorSets."); 20944 ASSERT_NO_FATAL_FAILURE(Init()); 20945 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 20946 VkResult err; 20947 20948 m_errorMonitor->ExpectSuccess(); 20949 20950 VkDescriptorPoolSize ds_type_count = {}; 20951 ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER; 20952 ds_type_count.descriptorCount = 1; 20953 20954 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 20955 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 20956 ds_pool_ci.pNext = NULL; 20957 ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; 20958 ds_pool_ci.maxSets = 1; 20959 ds_pool_ci.poolSizeCount = 1; 20960 ds_pool_ci.pPoolSizes = &ds_type_count; 20961 20962 VkDescriptorPool ds_pool_one; 20963 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool_one); 20964 ASSERT_VK_SUCCESS(err); 20965 20966 VkDescriptorSetLayoutBinding dsl_binding = {}; 20967 dsl_binding.binding = 0; 20968 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 20969 dsl_binding.descriptorCount = 1; 20970 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 20971 dsl_binding.pImmutableSamplers = NULL; 20972 20973 VkDescriptorSet descriptorSet; 20974 { 20975 const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding}); 20976 20977 VkDescriptorSetAllocateInfo alloc_info = {}; 20978 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 20979 alloc_info.descriptorSetCount = 1; 20980 alloc_info.descriptorPool = ds_pool_one; 20981 alloc_info.pSetLayouts = &ds_layout.handle(); 20982 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 20983 ASSERT_VK_SUCCESS(err); 20984 } // ds_layout destroyed 20985 err = vkFreeDescriptorSets(m_device->device(), ds_pool_one, 1, &descriptorSet); 20986 20987 vkDestroyDescriptorPool(m_device->device(), ds_pool_one, NULL); 20988 m_errorMonitor->VerifyNotFound(); 20989 } 20990 20991 TEST_F(VkPositiveLayerTest, CommandPoolDeleteWithReferences) { 20992 TEST_DESCRIPTION("Ensure the validation layers bookkeeping tracks the implicit command buffer frees."); 20993 ASSERT_NO_FATAL_FAILURE(Init()); 20994 20995 VkCommandPoolCreateInfo cmd_pool_info = {}; 20996 cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 20997 cmd_pool_info.pNext = NULL; 20998 cmd_pool_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 20999 cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 21000 cmd_pool_info.flags = 0; 21001 21002 VkCommandPool secondary_cmd_pool; 21003 VkResult res = vkCreateCommandPool(m_device->handle(), &cmd_pool_info, NULL, &secondary_cmd_pool); 21004 ASSERT_VK_SUCCESS(res); 21005 21006 VkCommandBufferAllocateInfo cmdalloc = vk_testing::CommandBuffer::create_info(secondary_cmd_pool); 21007 cmdalloc.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY; 21008 21009 VkCommandBuffer secondary_cmds; 21010 res = vkAllocateCommandBuffers(m_device->handle(), &cmdalloc, &secondary_cmds); 21011 21012 VkCommandBufferInheritanceInfo cmd_buf_inheritance_info = {}; 21013 cmd_buf_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; 21014 cmd_buf_inheritance_info.pNext = NULL; 21015 cmd_buf_inheritance_info.renderPass = VK_NULL_HANDLE; 21016 cmd_buf_inheritance_info.subpass = 0; 21017 cmd_buf_inheritance_info.framebuffer = VK_NULL_HANDLE; 21018 cmd_buf_inheritance_info.occlusionQueryEnable = VK_FALSE; 21019 cmd_buf_inheritance_info.queryFlags = 0; 21020 cmd_buf_inheritance_info.pipelineStatistics = 0; 21021 21022 VkCommandBufferBeginInfo secondary_begin = {}; 21023 secondary_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 21024 secondary_begin.pNext = NULL; 21025 secondary_begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; 21026 secondary_begin.pInheritanceInfo = &cmd_buf_inheritance_info; 21027 21028 res = vkBeginCommandBuffer(secondary_cmds, &secondary_begin); 21029 ASSERT_VK_SUCCESS(res); 21030 vkEndCommandBuffer(secondary_cmds); 21031 21032 m_commandBuffer->begin(); 21033 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_cmds); 21034 m_commandBuffer->end(); 21035 21036 // DestroyCommandPool *implicitly* frees the command buffers allocated from it 21037 vkDestroyCommandPool(m_device->handle(), secondary_cmd_pool, NULL); 21038 // If bookkeeping has been lax, validating the reset will attempt to touch deleted data 21039 res = vkResetCommandPool(m_device->handle(), m_commandPool->handle(), 0); 21040 ASSERT_VK_SUCCESS(res); 21041 } 21042 21043 TEST_F(VkPositiveLayerTest, SecondaryCommandBufferClearColorAttachments) { 21044 TEST_DESCRIPTION("Create a secondary command buffer and record a CmdClearAttachments call into it"); 21045 ASSERT_NO_FATAL_FAILURE(Init()); 21046 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 21047 21048 VkCommandBufferAllocateInfo command_buffer_allocate_info = {}; 21049 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 21050 command_buffer_allocate_info.commandPool = m_commandPool->handle(); 21051 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY; 21052 command_buffer_allocate_info.commandBufferCount = 1; 21053 21054 VkCommandBuffer secondary_command_buffer; 21055 ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer)); 21056 VkCommandBufferBeginInfo command_buffer_begin_info = {}; 21057 VkCommandBufferInheritanceInfo command_buffer_inheritance_info = {}; 21058 command_buffer_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; 21059 command_buffer_inheritance_info.renderPass = m_renderPass; 21060 command_buffer_inheritance_info.framebuffer = m_framebuffer; 21061 21062 command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 21063 command_buffer_begin_info.flags = 21064 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; 21065 command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info; 21066 21067 vkBeginCommandBuffer(secondary_command_buffer, &command_buffer_begin_info); 21068 VkClearAttachment color_attachment; 21069 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 21070 color_attachment.clearValue.color.float32[0] = 0; 21071 color_attachment.clearValue.color.float32[1] = 0; 21072 color_attachment.clearValue.color.float32[2] = 0; 21073 color_attachment.clearValue.color.float32[3] = 0; 21074 color_attachment.colorAttachment = 0; 21075 VkClearRect clear_rect = {{{0, 0}, {32, 32}}}; 21076 vkCmdClearAttachments(secondary_command_buffer, 1, &color_attachment, 1, &clear_rect); 21077 } 21078 21079 TEST_F(VkPositiveLayerTest, SecondaryCommandBufferImageLayoutTransitions) { 21080 TEST_DESCRIPTION("Perform an image layout transition in a secondary command buffer followed by a transition in the primary."); 21081 VkResult err; 21082 m_errorMonitor->ExpectSuccess(); 21083 ASSERT_NO_FATAL_FAILURE(Init()); 21084 auto depth_format = FindSupportedDepthStencilFormat(gpu()); 21085 if (!depth_format) { 21086 return; 21087 } 21088 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 21089 // Allocate a secondary and primary cmd buffer 21090 VkCommandBufferAllocateInfo command_buffer_allocate_info = {}; 21091 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 21092 command_buffer_allocate_info.commandPool = m_commandPool->handle(); 21093 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY; 21094 command_buffer_allocate_info.commandBufferCount = 1; 21095 21096 VkCommandBuffer secondary_command_buffer; 21097 ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer)); 21098 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 21099 VkCommandBuffer primary_command_buffer; 21100 ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &primary_command_buffer)); 21101 VkCommandBufferBeginInfo command_buffer_begin_info = {}; 21102 VkCommandBufferInheritanceInfo command_buffer_inheritance_info = {}; 21103 command_buffer_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; 21104 command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 21105 command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; 21106 command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info; 21107 21108 err = vkBeginCommandBuffer(secondary_command_buffer, &command_buffer_begin_info); 21109 ASSERT_VK_SUCCESS(err); 21110 VkImageObj image(m_device); 21111 image.Init(128, 128, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 21112 ASSERT_TRUE(image.initialized()); 21113 VkImageMemoryBarrier img_barrier = {}; 21114 img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 21115 img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; 21116 img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 21117 img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; 21118 img_barrier.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 21119 img_barrier.image = image.handle(); 21120 img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 21121 img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 21122 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 21123 img_barrier.subresourceRange.baseArrayLayer = 0; 21124 img_barrier.subresourceRange.baseMipLevel = 0; 21125 img_barrier.subresourceRange.layerCount = 1; 21126 img_barrier.subresourceRange.levelCount = 1; 21127 vkCmdPipelineBarrier(secondary_command_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 21128 0, nullptr, 1, &img_barrier); 21129 err = vkEndCommandBuffer(secondary_command_buffer); 21130 ASSERT_VK_SUCCESS(err); 21131 21132 // Now update primary cmd buffer to execute secondary and transitions image 21133 command_buffer_begin_info.pInheritanceInfo = nullptr; 21134 err = vkBeginCommandBuffer(primary_command_buffer, &command_buffer_begin_info); 21135 ASSERT_VK_SUCCESS(err); 21136 vkCmdExecuteCommands(primary_command_buffer, 1, &secondary_command_buffer); 21137 VkImageMemoryBarrier img_barrier2 = {}; 21138 img_barrier2.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 21139 img_barrier2.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; 21140 img_barrier2.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 21141 img_barrier2.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 21142 img_barrier2.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 21143 img_barrier2.image = image.handle(); 21144 img_barrier2.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 21145 img_barrier2.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 21146 img_barrier2.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 21147 img_barrier2.subresourceRange.baseArrayLayer = 0; 21148 img_barrier2.subresourceRange.baseMipLevel = 0; 21149 img_barrier2.subresourceRange.layerCount = 1; 21150 img_barrier2.subresourceRange.levelCount = 1; 21151 vkCmdPipelineBarrier(primary_command_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 0, 21152 nullptr, 1, &img_barrier2); 21153 err = vkEndCommandBuffer(primary_command_buffer); 21154 ASSERT_VK_SUCCESS(err); 21155 VkSubmitInfo submit_info = {}; 21156 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 21157 submit_info.commandBufferCount = 1; 21158 submit_info.pCommandBuffers = &primary_command_buffer; 21159 err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 21160 ASSERT_VK_SUCCESS(err); 21161 m_errorMonitor->VerifyNotFound(); 21162 err = vkDeviceWaitIdle(m_device->device()); 21163 ASSERT_VK_SUCCESS(err); 21164 vkFreeCommandBuffers(m_device->device(), m_commandPool->handle(), 1, &secondary_command_buffer); 21165 vkFreeCommandBuffers(m_device->device(), m_commandPool->handle(), 1, &primary_command_buffer); 21166 } 21167 21168 // This is a positive test. No failures are expected. 21169 TEST_F(VkPositiveLayerTest, IgnoreUnrelatedDescriptor) { 21170 TEST_DESCRIPTION( 21171 "Ensure that the vkUpdateDescriptorSets validation code is ignoring VkWriteDescriptorSet members that are not related to " 21172 "the descriptor type specified by VkWriteDescriptorSet::descriptorType. Correct validation behavior will result in the " 21173 "test running to completion without validation errors."); 21174 21175 const uintptr_t invalid_ptr = 0xcdcdcdcd; 21176 21177 ASSERT_NO_FATAL_FAILURE(Init()); 21178 21179 // Image Case 21180 { 21181 m_errorMonitor->ExpectSuccess(); 21182 21183 VkImageObj image(m_device); 21184 image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 21185 21186 VkImageView view = image.targetView(VK_FORMAT_B8G8R8A8_UNORM); 21187 21188 OneOffDescriptorSet ds(m_device, { 21189 {0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr}, 21190 }); 21191 21192 VkDescriptorImageInfo image_info = {}; 21193 image_info.imageView = view; 21194 image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 21195 21196 VkWriteDescriptorSet descriptor_write; 21197 memset(&descriptor_write, 0, sizeof(descriptor_write)); 21198 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 21199 descriptor_write.dstSet = ds.set_; 21200 descriptor_write.dstBinding = 0; 21201 descriptor_write.descriptorCount = 1; 21202 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; 21203 descriptor_write.pImageInfo = &image_info; 21204 21205 // Set pBufferInfo and pTexelBufferView to invalid values, which should 21206 // be 21207 // ignored for descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE. 21208 // This will most likely produce a crash if the parameter_validation 21209 // layer 21210 // does not correctly ignore pBufferInfo. 21211 descriptor_write.pBufferInfo = reinterpret_cast<const VkDescriptorBufferInfo *>(invalid_ptr); 21212 descriptor_write.pTexelBufferView = reinterpret_cast<const VkBufferView *>(invalid_ptr); 21213 21214 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 21215 21216 m_errorMonitor->VerifyNotFound(); 21217 } 21218 21219 // Buffer Case 21220 { 21221 m_errorMonitor->ExpectSuccess(); 21222 21223 VkBuffer buffer; 21224 uint32_t queue_family_index = 0; 21225 VkBufferCreateInfo buffer_create_info = {}; 21226 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 21227 buffer_create_info.size = 1024; 21228 buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 21229 buffer_create_info.queueFamilyIndexCount = 1; 21230 buffer_create_info.pQueueFamilyIndices = &queue_family_index; 21231 21232 VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer); 21233 ASSERT_VK_SUCCESS(err); 21234 21235 VkMemoryRequirements memory_reqs; 21236 VkDeviceMemory buffer_memory; 21237 bool pass; 21238 VkMemoryAllocateInfo memory_info = {}; 21239 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 21240 memory_info.pNext = NULL; 21241 memory_info.allocationSize = 0; 21242 memory_info.memoryTypeIndex = 0; 21243 21244 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs); 21245 memory_info.allocationSize = memory_reqs.size; 21246 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 21247 ASSERT_TRUE(pass); 21248 21249 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory); 21250 ASSERT_VK_SUCCESS(err); 21251 err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0); 21252 ASSERT_VK_SUCCESS(err); 21253 21254 OneOffDescriptorSet ds(m_device, { 21255 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, 21256 }); 21257 21258 VkDescriptorBufferInfo buffer_info = {}; 21259 buffer_info.buffer = buffer; 21260 buffer_info.offset = 0; 21261 buffer_info.range = 1024; 21262 21263 VkWriteDescriptorSet descriptor_write; 21264 memset(&descriptor_write, 0, sizeof(descriptor_write)); 21265 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 21266 descriptor_write.dstSet = ds.set_; 21267 descriptor_write.dstBinding = 0; 21268 descriptor_write.descriptorCount = 1; 21269 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 21270 descriptor_write.pBufferInfo = &buffer_info; 21271 21272 // Set pImageInfo and pTexelBufferView to invalid values, which should 21273 // be 21274 // ignored for descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER. 21275 // This will most likely produce a crash if the parameter_validation 21276 // layer 21277 // does not correctly ignore pImageInfo. 21278 descriptor_write.pImageInfo = reinterpret_cast<const VkDescriptorImageInfo *>(invalid_ptr); 21279 descriptor_write.pTexelBufferView = reinterpret_cast<const VkBufferView *>(invalid_ptr); 21280 21281 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 21282 21283 m_errorMonitor->VerifyNotFound(); 21284 21285 vkDestroyBuffer(m_device->device(), buffer, NULL); 21286 vkFreeMemory(m_device->device(), buffer_memory, NULL); 21287 } 21288 21289 // Texel Buffer Case 21290 { 21291 m_errorMonitor->ExpectSuccess(); 21292 21293 VkBuffer buffer; 21294 uint32_t queue_family_index = 0; 21295 VkBufferCreateInfo buffer_create_info = {}; 21296 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 21297 buffer_create_info.size = 1024; 21298 buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; 21299 buffer_create_info.queueFamilyIndexCount = 1; 21300 buffer_create_info.pQueueFamilyIndices = &queue_family_index; 21301 21302 VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer); 21303 ASSERT_VK_SUCCESS(err); 21304 21305 VkMemoryRequirements memory_reqs; 21306 VkDeviceMemory buffer_memory; 21307 bool pass; 21308 VkMemoryAllocateInfo memory_info = {}; 21309 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 21310 memory_info.pNext = NULL; 21311 memory_info.allocationSize = 0; 21312 memory_info.memoryTypeIndex = 0; 21313 21314 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs); 21315 memory_info.allocationSize = memory_reqs.size; 21316 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 21317 ASSERT_TRUE(pass); 21318 21319 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory); 21320 ASSERT_VK_SUCCESS(err); 21321 err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0); 21322 ASSERT_VK_SUCCESS(err); 21323 21324 VkBufferViewCreateInfo buff_view_ci = {}; 21325 buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; 21326 buff_view_ci.buffer = buffer; 21327 buff_view_ci.format = VK_FORMAT_R8_UNORM; 21328 buff_view_ci.range = VK_WHOLE_SIZE; 21329 VkBufferView buffer_view; 21330 err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buffer_view); 21331 21332 OneOffDescriptorSet ds(m_device, { 21333 {0, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, 21334 }); 21335 21336 VkWriteDescriptorSet descriptor_write; 21337 memset(&descriptor_write, 0, sizeof(descriptor_write)); 21338 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 21339 descriptor_write.dstSet = ds.set_; 21340 descriptor_write.dstBinding = 0; 21341 descriptor_write.descriptorCount = 1; 21342 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 21343 descriptor_write.pTexelBufferView = &buffer_view; 21344 21345 // Set pImageInfo and pBufferInfo to invalid values, which should be 21346 // ignored for descriptorType == 21347 // VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER. 21348 // This will most likely produce a crash if the parameter_validation 21349 // layer 21350 // does not correctly ignore pImageInfo and pBufferInfo. 21351 descriptor_write.pImageInfo = reinterpret_cast<const VkDescriptorImageInfo *>(invalid_ptr); 21352 descriptor_write.pBufferInfo = reinterpret_cast<const VkDescriptorBufferInfo *>(invalid_ptr); 21353 21354 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 21355 21356 m_errorMonitor->VerifyNotFound(); 21357 21358 vkDestroyBufferView(m_device->device(), buffer_view, NULL); 21359 vkDestroyBuffer(m_device->device(), buffer, NULL); 21360 vkFreeMemory(m_device->device(), buffer_memory, NULL); 21361 } 21362 } 21363 21364 TEST_F(VkPositiveLayerTest, ImmutableSamplerOnlyDescriptor) { 21365 TEST_DESCRIPTION("Bind a DescriptorSet with only an immutable samplerand make sure that we don't warn for no update."); 21366 21367 ASSERT_NO_FATAL_FAILURE(Init()); 21368 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 21369 21370 OneOffDescriptorSet ds(m_device, { 21371 {0, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}, 21372 }); 21373 21374 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo(); 21375 VkSampler sampler; 21376 VkResult err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 21377 ASSERT_VK_SUCCESS(err); 21378 21379 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_}); 21380 21381 m_errorMonitor->ExpectSuccess(); 21382 m_commandBuffer->begin(); 21383 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 21384 21385 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &ds.set_, 0, 21386 nullptr); 21387 m_errorMonitor->VerifyNotFound(); 21388 21389 vkDestroySampler(m_device->device(), sampler, NULL); 21390 } 21391 21392 TEST_F(VkLayerTest, DuplicateDescriptorBinding) { 21393 TEST_DESCRIPTION("Create a descriptor set layout with a duplicate binding number."); 21394 21395 ASSERT_NO_FATAL_FAILURE(Init()); 21396 // Create layout where two binding #s are "1" 21397 static const uint32_t NUM_BINDINGS = 3; 21398 VkDescriptorSetLayoutBinding dsl_binding[NUM_BINDINGS] = {}; 21399 dsl_binding[0].binding = 1; 21400 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 21401 dsl_binding[0].descriptorCount = 1; 21402 dsl_binding[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 21403 dsl_binding[0].pImmutableSamplers = NULL; 21404 dsl_binding[1].binding = 0; 21405 dsl_binding[1].descriptorCount = 1; 21406 dsl_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 21407 dsl_binding[1].descriptorCount = 1; 21408 dsl_binding[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 21409 dsl_binding[1].pImmutableSamplers = NULL; 21410 dsl_binding[2].binding = 1; // Duplicate binding should cause error 21411 dsl_binding[2].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 21412 dsl_binding[2].descriptorCount = 1; 21413 dsl_binding[2].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 21414 dsl_binding[2].pImmutableSamplers = NULL; 21415 21416 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 21417 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 21418 ds_layout_ci.pNext = NULL; 21419 ds_layout_ci.bindingCount = NUM_BINDINGS; 21420 ds_layout_ci.pBindings = dsl_binding; 21421 VkDescriptorSetLayout ds_layout; 21422 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0500022e); 21423 vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 21424 m_errorMonitor->VerifyFound(); 21425 } 21426 21427 TEST_F(VkLayerTest, InvalidPushDescriptorSetLayout) { 21428 TEST_DESCRIPTION("Create a push descriptor set layout with invalid bindings."); 21429 21430 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { 21431 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 21432 } else { 21433 printf(" Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n"); 21434 return; 21435 } 21436 21437 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 21438 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) { 21439 m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); 21440 } else { 21441 printf(" %s Extension not supported, skipping tests\n", VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); 21442 return; 21443 } 21444 21445 ASSERT_NO_FATAL_FAILURE(InitState()); 21446 21447 // Find address of extension call and make the call 21448 PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR = 21449 (PFN_vkGetPhysicalDeviceProperties2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceProperties2KHR"); 21450 assert(vkGetPhysicalDeviceProperties2KHR != nullptr); 21451 21452 // Get the push descriptor limits 21453 auto push_descriptor_prop = lvl_init_struct<VkPhysicalDevicePushDescriptorPropertiesKHR>(); 21454 auto prop2 = lvl_init_struct<VkPhysicalDeviceProperties2KHR>(&push_descriptor_prop); 21455 vkGetPhysicalDeviceProperties2KHR(m_device->phy().handle(), &prop2); 21456 21457 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}; 21458 21459 auto ds_layout_ci = lvl_init_struct<VkDescriptorSetLayoutCreateInfo>(); 21460 ds_layout_ci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR; 21461 ds_layout_ci.bindingCount = 1; 21462 ds_layout_ci.pBindings = &binding; 21463 21464 // Note that as binding is referenced in ds_layout_ci, it is effectively in the closure by reference as well. 21465 auto test_create_ds_layout = [&ds_layout_ci, this](UNIQUE_VALIDATION_ERROR_CODE error) { 21466 VkDescriptorSetLayout ds_layout = VK_NULL_HANDLE; 21467 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error); 21468 vkCreateDescriptorSetLayout(m_device->handle(), &ds_layout_ci, nullptr, &ds_layout); 21469 m_errorMonitor->VerifyFound(); 21470 vkDestroyDescriptorSetLayout(m_device->handle(), ds_layout, nullptr); 21471 }; 21472 21473 // Starting with the initial VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC type set above.. 21474 test_create_ds_layout(VALIDATION_ERROR_05000230); 21475 21476 binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC; 21477 test_create_ds_layout(VALIDATION_ERROR_05000230); // This is the same VUID as above, just a second error condition. 21478 21479 if (!(push_descriptor_prop.maxPushDescriptors == std::numeric_limits<uint32_t>::max())) { 21480 binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; 21481 binding.descriptorCount = push_descriptor_prop.maxPushDescriptors + 1; 21482 test_create_ds_layout(VALIDATION_ERROR_05000232); 21483 } else { 21484 printf(" maxPushDescriptors is set to maxiumum unit32_t value, skipping 'out of range test'.\n"); 21485 } 21486 } 21487 21488 TEST_F(VkLayerTest, PushDescriptorSetLayoutWithoutExtension) { 21489 TEST_DESCRIPTION("Create a push descriptor set layout without loading the needed extension."); 21490 ASSERT_NO_FATAL_FAILURE(Init()); 21491 21492 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}; 21493 21494 auto ds_layout_ci = lvl_init_struct<VkDescriptorSetLayoutCreateInfo>(); 21495 ds_layout_ci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR; 21496 ds_layout_ci.bindingCount = 1; 21497 ds_layout_ci.pBindings = &binding; 21498 21499 std::string error = "Attemped to use VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR in "; 21500 error = error + "VkDescriptorSetLayoutCreateInfo::flags but its required extension "; 21501 error = error + VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME; 21502 error = error + " has not been enabled."; 21503 21504 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error.c_str()); 21505 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_05000232); 21506 VkDescriptorSetLayout ds_layout = VK_NULL_HANDLE; 21507 vkCreateDescriptorSetLayout(m_device->handle(), &ds_layout_ci, nullptr, &ds_layout); 21508 m_errorMonitor->VerifyFound(); 21509 vkDestroyDescriptorSetLayout(m_device->handle(), ds_layout, nullptr); 21510 } 21511 21512 TEST_F(VkLayerTest, AllocatePushDescriptorSet) { 21513 TEST_DESCRIPTION("Attempt to allocate a push descriptor set."); 21514 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { 21515 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 21516 } else { 21517 printf(" %s Extension not supported, skipping tests\n", VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 21518 return; 21519 } 21520 21521 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 21522 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) { 21523 m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); 21524 } else { 21525 printf(" %s Extension not supported, skipping tests\n", VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); 21526 return; 21527 } 21528 ASSERT_NO_FATAL_FAILURE(InitState()); 21529 21530 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}; 21531 auto ds_layout_ci = lvl_init_struct<VkDescriptorSetLayoutCreateInfo>(); 21532 ds_layout_ci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR; 21533 ds_layout_ci.bindingCount = 1; 21534 ds_layout_ci.pBindings = &binding; 21535 VkDescriptorSetLayout ds_layout = VK_NULL_HANDLE; 21536 VkResult err = vkCreateDescriptorSetLayout(m_device->handle(), &ds_layout_ci, nullptr, &ds_layout); 21537 ASSERT_VK_SUCCESS(err); 21538 21539 VkDescriptorPoolSize pool_size = {binding.descriptorType, binding.descriptorCount}; 21540 auto dspci = lvl_init_struct<VkDescriptorPoolCreateInfo>(); 21541 dspci.poolSizeCount = 1; 21542 dspci.pPoolSizes = &pool_size; 21543 dspci.maxSets = 1; 21544 VkDescriptorPool pool; 21545 err = vkCreateDescriptorPool(m_device->handle(), &dspci, nullptr, &pool); 21546 ASSERT_VK_SUCCESS(err); 21547 21548 auto ds_alloc_info = lvl_init_struct<VkDescriptorSetAllocateInfo>(); 21549 ds_alloc_info.descriptorPool = pool; 21550 ds_alloc_info.descriptorSetCount = 1; 21551 ds_alloc_info.pSetLayouts = &ds_layout; 21552 21553 VkDescriptorSet ds = VK_NULL_HANDLE; 21554 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_04c00268); 21555 vkAllocateDescriptorSets(m_device->handle(), &ds_alloc_info, &ds); 21556 m_errorMonitor->VerifyFound(); 21557 21558 vkDestroyDescriptorPool(m_device->handle(), pool, nullptr); 21559 vkDestroyDescriptorSetLayout(m_device->handle(), ds_layout, nullptr); 21560 } 21561 21562 TEST_F(VkLayerTest, PushDescriptorSetCmdPushBadArgs) { 21563 TEST_DESCRIPTION("Attempt to push a push descriptor set with incorrect arguments."); 21564 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { 21565 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 21566 } else { 21567 printf(" %s Extension not supported, skipping tests\n", VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 21568 return; 21569 } 21570 21571 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 21572 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) { 21573 m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); 21574 } else { 21575 printf(" %s Extension not supported, skipping tests\n", VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); 21576 return; 21577 } 21578 ASSERT_NO_FATAL_FAILURE(InitState()); 21579 21580 // Create ordinary and push descriptor set layout 21581 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}; 21582 const VkDescriptorSetLayoutObj ds_layout(m_device, {binding}); 21583 ASSERT_TRUE(ds_layout.initialized()); 21584 const VkDescriptorSetLayoutObj push_ds_layout(m_device, {binding}, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR); 21585 ASSERT_TRUE(push_ds_layout.initialized()); 21586 21587 // Now use the descriptor set layouts to create a pipeline layout 21588 const VkPipelineLayoutObj pipeline_layout(m_device, {&push_ds_layout, &ds_layout}); 21589 ASSERT_TRUE(pipeline_layout.initialized()); 21590 21591 // Create a descriptor to push 21592 const uint32_t buffer_data[4] = {4, 5, 6, 7}; 21593 VkConstantBufferObj buffer_obj(m_device, sizeof(buffer_data), &buffer_data); 21594 ASSERT_TRUE(buffer_obj.initialized()); 21595 21596 // Create a "write" struct, noting that the buffer_info cannot be a temporary arg (the return from write_descriptor_set 21597 // references its data), and the DescriptorSet() can be temporary, because the value is ignored 21598 VkDescriptorBufferInfo buffer_info = {buffer_obj.handle(), 0, VK_WHOLE_SIZE}; 21599 21600 VkWriteDescriptorSet descriptor_write = vk_testing::Device::write_descriptor_set( 21601 vk_testing::DescriptorSet(), 0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &buffer_info); 21602 21603 // Find address of extension call and make the call 21604 PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR = 21605 (PFN_vkCmdPushDescriptorSetKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR"); 21606 ASSERT_TRUE(vkCmdPushDescriptorSetKHR != nullptr); 21607 21608 // Section 1: Queue family matching/capabilities. 21609 // Create command pool on a non-graphics queue 21610 const uint32_t no_gfx_qfi = m_device->QueueFamilyMatching(VK_QUEUE_COMPUTE_BIT, VK_QUEUE_GRAPHICS_BIT); 21611 const uint32_t transfer_only_qfi = 21612 m_device->QueueFamilyMatching(VK_QUEUE_TRANSFER_BIT, (VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT)); 21613 if ((UINT32_MAX == transfer_only_qfi) && (UINT32_MAX == no_gfx_qfi)) { 21614 printf(" No compute or transfer only queue family, skipping bindpoint and queue tests."); 21615 } else { 21616 const uint32_t err_qfi = (UINT32_MAX == no_gfx_qfi) ? transfer_only_qfi : no_gfx_qfi; 21617 21618 VkCommandPoolObj command_pool(m_device, err_qfi); 21619 ASSERT_TRUE(command_pool.initialized()); 21620 VkCommandBufferObj command_buffer(m_device, &command_pool); 21621 ASSERT_TRUE(command_buffer.initialized()); 21622 command_buffer.begin(); 21623 21624 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1be002d6); 21625 if (err_qfi == transfer_only_qfi) { 21626 // This as this queue neither supports the gfx or compute bindpoints, we'll get two errors 21627 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1be02415); 21628 } 21629 vkCmdPushDescriptorSetKHR(command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, 21630 &descriptor_write); 21631 m_errorMonitor->VerifyFound(); 21632 command_buffer.end(); 21633 21634 // If we succeed in testing only one condition above, we need to test the other below. 21635 if ((UINT32_MAX != transfer_only_qfi) && (err_qfi != transfer_only_qfi)) { 21636 // Need to test the neither compute/gfx supported case separately. 21637 VkCommandPoolObj tran_command_pool(m_device, transfer_only_qfi); 21638 ASSERT_TRUE(tran_command_pool.initialized()); 21639 VkCommandBufferObj tran_command_buffer(m_device, &tran_command_pool); 21640 ASSERT_TRUE(tran_command_buffer.initialized()); 21641 tran_command_buffer.begin(); 21642 21643 // We can't avoid getting *both* errors in this case 21644 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1be002d6); 21645 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1be02415); 21646 vkCmdPushDescriptorSetKHR(tran_command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, 21647 &descriptor_write); 21648 m_errorMonitor->VerifyFound(); 21649 tran_command_buffer.end(); 21650 } 21651 } 21652 21653 // Push to the non-push binding 21654 m_commandBuffer->begin(); 21655 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1be002da); 21656 vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 1, 1, 21657 &descriptor_write); 21658 m_errorMonitor->VerifyFound(); 21659 21660 // Specify set out of bounds 21661 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1be002d8); 21662 vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 2, 1, 21663 &descriptor_write); 21664 m_errorMonitor->VerifyFound(); 21665 m_commandBuffer->end(); 21666 21667 // This is a test for VUID-vkCmdPushDescriptorSetKHR-commandBuffer-recording 21668 // TODO: Add VALIDATION_ERROR_ code support to core_validation::ValidateCmd 21669 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 21670 "You must call vkBeginCommandBuffer() before this call to vkCmdPushDescriptorSetKHR()"); 21671 vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, 21672 &descriptor_write); 21673 m_errorMonitor->VerifyFound(); 21674 } 21675 21676 TEST_F(VkLayerTest, ViewportBoundsCheckingWithNVHExtensionEnabled) { 21677 TEST_DESCRIPTION("Verify errors are detected on misuse of SetViewport with a negative viewport extension enabled."); 21678 21679 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 21680 21681 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) { 21682 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME); 21683 } else { 21684 printf(" Maintenance1 Extension not supported, skipping tests\n"); 21685 return; 21686 } 21687 ASSERT_NO_FATAL_FAILURE(InitState()); 21688 const VkPhysicalDeviceLimits &limits = m_device->props.limits; 21689 21690 m_commandBuffer->begin(); 21691 { 21692 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1500099a); 21693 VkViewport viewport = {0, 0, 16, -(static_cast<float>(limits.maxViewportDimensions[1] + 1)), 0, 1}; 21694 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 21695 m_errorMonitor->VerifyFound(); 21696 } 21697 m_commandBuffer->end(); 21698 } 21699 21700 TEST_F(VkLayerTest, ViewportAndScissorBoundsChecking) { 21701 TEST_DESCRIPTION("Verify errors are detected on misuse of SetViewport and SetScissor."); 21702 21703 ASSERT_NO_FATAL_FAILURE(Init()); 21704 21705 m_commandBuffer->begin(); 21706 21707 const VkPhysicalDeviceLimits &limits = m_device->props.limits; 21708 21709 { 21710 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15000996); 21711 VkViewport viewport = {0, 0, static_cast<float>(limits.maxViewportDimensions[0] + 1), 16, 0, 1}; 21712 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 21713 m_errorMonitor->VerifyFound(); 21714 } 21715 21716 { 21717 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_15000998); 21718 VkViewport viewport = {0, 0, 16, static_cast<float>(limits.maxViewportDimensions[1] + 1), 0, 1}; 21719 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 21720 m_errorMonitor->VerifyFound(); 21721 } 21722 21723 { 21724 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1500099e); 21725 VkViewport viewport = {limits.viewportBoundsRange[0] - 1, 0, 16, 16, 0, 1}; 21726 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 21727 m_errorMonitor->VerifyFound(); 21728 } 21729 21730 { 21731 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1500099e); 21732 VkViewport viewport = {0, limits.viewportBoundsRange[0] - 1, 16, 16, 0, 1}; 21733 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 21734 m_errorMonitor->VerifyFound(); 21735 } 21736 21737 { 21738 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_150009a0); 21739 VkViewport viewport = {limits.viewportBoundsRange[1], 0, 16, 16, 0, 1}; 21740 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 21741 m_errorMonitor->VerifyFound(); 21742 } 21743 21744 { 21745 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_150009a2); 21746 VkViewport viewport = {0, limits.viewportBoundsRange[1], 16, 16, 0, 1}; 21747 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 21748 m_errorMonitor->VerifyFound(); 21749 } 21750 21751 { 21752 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1d8004a6); 21753 VkRect2D scissor = {{-1, 0}, {16, 16}}; 21754 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 21755 m_errorMonitor->VerifyFound(); 21756 } 21757 21758 { 21759 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1d8004a6); 21760 VkRect2D scissor = {{0, -2}, {16, 16}}; 21761 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 21762 m_errorMonitor->VerifyFound(); 21763 } 21764 21765 { 21766 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1d8004a8); 21767 VkRect2D scissor = {{100, 100}, {INT_MAX, 16}}; 21768 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 21769 m_errorMonitor->VerifyFound(); 21770 } 21771 21772 { 21773 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_1d8004aa); 21774 VkRect2D scissor = {{100, 100}, {16, INT_MAX}}; 21775 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 21776 m_errorMonitor->VerifyFound(); 21777 } 21778 21779 m_commandBuffer->end(); 21780 } 21781 21782 // This is a positive test. No failures are expected. 21783 TEST_F(VkPositiveLayerTest, EmptyDescriptorUpdateTest) { 21784 TEST_DESCRIPTION("Update last descriptor in a set that includes an empty binding"); 21785 VkResult err; 21786 21787 ASSERT_NO_FATAL_FAILURE(Init()); 21788 m_errorMonitor->ExpectSuccess(); 21789 21790 // Create layout with two uniform buffer descriptors w/ empty binding between them 21791 OneOffDescriptorSet ds(m_device, { 21792 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, 21793 {1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0 /*!*/, 0, nullptr}, 21794 {2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, 21795 }); 21796 21797 // Create a buffer to be used for update 21798 VkBufferCreateInfo buff_ci = {}; 21799 buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 21800 buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 21801 buff_ci.size = 256; 21802 buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 21803 VkBuffer buffer; 21804 err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer); 21805 ASSERT_VK_SUCCESS(err); 21806 // Have to bind memory to buffer before descriptor update 21807 VkMemoryAllocateInfo mem_alloc = {}; 21808 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 21809 mem_alloc.pNext = NULL; 21810 mem_alloc.allocationSize = 512; // one allocation for both buffers 21811 mem_alloc.memoryTypeIndex = 0; 21812 21813 VkMemoryRequirements mem_reqs; 21814 vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs); 21815 bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0); 21816 if (!pass) { 21817 vkDestroyBuffer(m_device->device(), buffer, NULL); 21818 return; 21819 } 21820 // Make sure allocation is sufficiently large to accommodate buffer requirements 21821 if (mem_reqs.size > mem_alloc.allocationSize) { 21822 mem_alloc.allocationSize = mem_reqs.size; 21823 } 21824 21825 VkDeviceMemory mem; 21826 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem); 21827 ASSERT_VK_SUCCESS(err); 21828 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0); 21829 ASSERT_VK_SUCCESS(err); 21830 21831 // Only update the descriptor at binding 2 21832 VkDescriptorBufferInfo buff_info = {}; 21833 buff_info.buffer = buffer; 21834 buff_info.offset = 0; 21835 buff_info.range = VK_WHOLE_SIZE; 21836 VkWriteDescriptorSet descriptor_write = {}; 21837 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 21838 descriptor_write.dstBinding = 2; 21839 descriptor_write.descriptorCount = 1; 21840 descriptor_write.pTexelBufferView = nullptr; 21841 descriptor_write.pBufferInfo = &buff_info; 21842 descriptor_write.pImageInfo = nullptr; 21843 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 21844 descriptor_write.dstSet = ds.set_; 21845 21846 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 21847 21848 m_errorMonitor->VerifyNotFound(); 21849 // Cleanup 21850 vkFreeMemory(m_device->device(), mem, NULL); 21851 vkDestroyBuffer(m_device->device(), buffer, NULL); 21852 } 21853 21854 TEST_F(VkLayerTest, MultiplePushDescriptorSets) { 21855 TEST_DESCRIPTION("Verify an error message for multiple push descriptor sets."); 21856 21857 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { 21858 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 21859 } else { 21860 printf(" Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n"); 21861 return; 21862 } 21863 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 21864 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) { 21865 m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); 21866 } else { 21867 printf(" Push Descriptors Extension not supported, skipping tests\n"); 21868 return; 21869 } 21870 ASSERT_NO_FATAL_FAILURE(InitState()); 21871 21872 VkDescriptorSetLayoutBinding dsl_binding = {}; 21873 dsl_binding.binding = 0; 21874 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 21875 dsl_binding.descriptorCount = 1; 21876 dsl_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 21877 dsl_binding.pImmutableSamplers = NULL; 21878 21879 const unsigned int descriptor_set_layout_count = 2; 21880 std::vector<VkDescriptorSetLayoutObj> ds_layouts; 21881 for (uint32_t i = 0; i < descriptor_set_layout_count; ++i) { 21882 dsl_binding.binding = i; 21883 ds_layouts.emplace_back(m_device, std::vector<VkDescriptorSetLayoutBinding>(1, dsl_binding), 21884 VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR); 21885 } 21886 const auto &ds_vk_layouts = MakeVkHandles<VkDescriptorSetLayout>(ds_layouts); 21887 21888 VkPipelineLayout pipeline_layout; 21889 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 21890 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 21891 pipeline_layout_ci.pNext = NULL; 21892 pipeline_layout_ci.pushConstantRangeCount = 0; 21893 pipeline_layout_ci.pPushConstantRanges = NULL; 21894 pipeline_layout_ci.setLayoutCount = ds_vk_layouts.size(); 21895 pipeline_layout_ci.pSetLayouts = ds_vk_layouts.data(); 21896 21897 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_0fe0024a); 21898 vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 21899 m_errorMonitor->VerifyFound(); 21900 } 21901 21902 // This is a positive test. No failures are expected. 21903 TEST_F(VkPositiveLayerTest, PushDescriptorNullDstSetTest) { 21904 TEST_DESCRIPTION("Use null dstSet in CmdPushDescriptorSetKHR"); 21905 21906 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { 21907 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 21908 } else { 21909 printf(" Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n"); 21910 return; 21911 } 21912 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 21913 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) { 21914 m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); 21915 } else { 21916 printf(" Push Descriptors Extension not supported, skipping tests\n"); 21917 return; 21918 } 21919 ASSERT_NO_FATAL_FAILURE(InitState()); 21920 m_errorMonitor->ExpectSuccess(); 21921 21922 VkDescriptorSetLayoutBinding dsl_binding = {}; 21923 dsl_binding.binding = 2; 21924 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 21925 dsl_binding.descriptorCount = 1; 21926 dsl_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 21927 dsl_binding.pImmutableSamplers = NULL; 21928 21929 const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding}, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR); 21930 21931 // Now use the descriptor layout to create a pipeline layout 21932 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout}); 21933 21934 static const float vbo_data[3] = {1.f, 0.f, 1.f}; 21935 VkConstantBufferObj vbo(m_device, sizeof(vbo_data), (const void *)&vbo_data); 21936 21937 VkDescriptorBufferInfo buff_info; 21938 buff_info.buffer = vbo.handle(); 21939 buff_info.offset = 0; 21940 buff_info.range = sizeof(vbo_data); 21941 VkWriteDescriptorSet descriptor_write = {}; 21942 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 21943 descriptor_write.dstBinding = 2; 21944 descriptor_write.descriptorCount = 1; 21945 descriptor_write.pTexelBufferView = nullptr; 21946 descriptor_write.pBufferInfo = &buff_info; 21947 descriptor_write.pImageInfo = nullptr; 21948 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 21949 descriptor_write.dstSet = 0; // Should not cause a validation error 21950 21951 // Find address of extension call and make the call 21952 PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR = 21953 (PFN_vkCmdPushDescriptorSetKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR"); 21954 assert(vkCmdPushDescriptorSetKHR != nullptr); 21955 m_commandBuffer->begin(); 21956 vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, 21957 &descriptor_write); 21958 21959 m_errorMonitor->VerifyNotFound(); 21960 } 21961 21962 // This is a positive test. No failures are expected. 21963 TEST_F(VkPositiveLayerTest, PushDescriptorUnboundSetTest) { 21964 TEST_DESCRIPTION("Ensure that no validation errors are produced for not bound push descriptor sets"); 21965 VkResult err; 21966 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { 21967 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 21968 } else { 21969 printf(" Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n"); 21970 return; 21971 } 21972 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 21973 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) { 21974 m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); 21975 } else { 21976 printf(" Push Descriptors Extension not supported, skipping tests\n"); 21977 return; 21978 } 21979 ASSERT_NO_FATAL_FAILURE(InitState()); 21980 ASSERT_NO_FATAL_FAILURE(InitViewport()); 21981 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 21982 m_errorMonitor->ExpectSuccess(); 21983 21984 VkDescriptorPoolSize ds_type_count = {}; 21985 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 21986 ds_type_count.descriptorCount = 1; 21987 21988 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 21989 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 21990 ds_pool_ci.pNext = NULL; 21991 ds_pool_ci.maxSets = 1; 21992 ds_pool_ci.poolSizeCount = 1; 21993 ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; 21994 ds_pool_ci.pPoolSizes = &ds_type_count; 21995 21996 VkDescriptorPool ds_pool; 21997 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 21998 ASSERT_VK_SUCCESS(err); 21999 22000 // Create descriptor set layout 22001 VkDescriptorSetLayoutBinding dsl_binding = {}; 22002 dsl_binding.binding = 2; 22003 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 22004 dsl_binding.descriptorCount = 1; 22005 dsl_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 22006 dsl_binding.pImmutableSamplers = NULL; 22007 22008 const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding}); 22009 22010 // Create push descriptor set layout 22011 const VkDescriptorSetLayoutObj push_ds_layout(m_device, {dsl_binding}, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR); 22012 22013 // Allocate descriptor set 22014 VkDescriptorSetAllocateInfo alloc_info = {}; 22015 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 22016 alloc_info.pNext = NULL; 22017 alloc_info.descriptorPool = ds_pool; 22018 alloc_info.descriptorSetCount = 1; 22019 alloc_info.pSetLayouts = &ds_layout.handle(); 22020 VkDescriptorSet descriptor_set; 22021 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set); 22022 ASSERT_VK_SUCCESS(err); 22023 22024 // Now use the descriptor layouts to create a pipeline layout 22025 const VkPipelineLayoutObj pipeline_layout(m_device, {&push_ds_layout, &ds_layout}); 22026 22027 // Create PSO 22028 char const *vsSource = 22029 "#version 450\n" 22030 "\n" 22031 "void main(){\n" 22032 " gl_Position = vec4(1);\n" 22033 "}\n"; 22034 char const *fsSource = 22035 "#version 450\n" 22036 "\n" 22037 "layout(location=0) out vec4 x;\n" 22038 "layout(set=0) layout(binding=2) uniform foo1 { float x; } bar1;\n" 22039 "layout(set=1) layout(binding=2) uniform foo2 { float y; } bar2;\n" 22040 "void main(){\n" 22041 " x = vec4(bar1.x) + vec4(bar2.y);\n" 22042 "}\n"; 22043 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 22044 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 22045 VkPipelineObj pipe(m_device); 22046 pipe.SetViewport(m_viewports); 22047 pipe.SetScissor(m_scissors); 22048 pipe.AddShader(&vs); 22049 pipe.AddShader(&fs); 22050 pipe.AddDefaultColorAttachment(); 22051 pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 22052 22053 static const float bo_data[1] = {1.f}; 22054 VkConstantBufferObj buffer(m_device, sizeof(bo_data), (const void *)&bo_data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); 22055 22056 // Update descriptor set 22057 VkDescriptorBufferInfo buff_info; 22058 buff_info.buffer = buffer.handle(); 22059 buff_info.offset = 0; 22060 buff_info.range = sizeof(bo_data); 22061 VkWriteDescriptorSet descriptor_write = {}; 22062 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 22063 descriptor_write.dstBinding = 2; 22064 descriptor_write.descriptorCount = 1; 22065 descriptor_write.pTexelBufferView = nullptr; 22066 descriptor_write.pBufferInfo = &buff_info; 22067 descriptor_write.pImageInfo = nullptr; 22068 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 22069 descriptor_write.dstSet = descriptor_set; 22070 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 22071 22072 PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR = 22073 (PFN_vkCmdPushDescriptorSetKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR"); 22074 assert(vkCmdPushDescriptorSetKHR != nullptr); 22075 22076 m_commandBuffer->begin(); 22077 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 22078 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 22079 22080 // Push descriptors and bind descriptor set 22081 vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, 22082 &descriptor_write); 22083 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 1, 1, 22084 &descriptor_set, 0, NULL); 22085 22086 // No errors should be generated. 22087 vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); 22088 22089 m_errorMonitor->VerifyNotFound(); 22090 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 22091 } 22092 22093 // This is a positive test. No failures are expected. 22094 TEST_F(VkPositiveLayerTest, TestAliasedMemoryTracking) { 22095 VkResult err; 22096 bool pass; 22097 22098 TEST_DESCRIPTION( 22099 "Create a buffer, allocate memory, bind memory, destroy the buffer, create an image, and bind the same memory to it"); 22100 22101 m_errorMonitor->ExpectSuccess(); 22102 22103 ASSERT_NO_FATAL_FAILURE(Init()); 22104 22105 VkBuffer buffer; 22106 VkImage image; 22107 VkDeviceMemory mem; 22108 VkMemoryRequirements mem_reqs; 22109 22110 VkBufferCreateInfo buf_info = {}; 22111 buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 22112 buf_info.pNext = NULL; 22113 buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 22114 buf_info.size = 256; 22115 buf_info.queueFamilyIndexCount = 0; 22116 buf_info.pQueueFamilyIndices = NULL; 22117 buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 22118 buf_info.flags = 0; 22119 err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer); 22120 ASSERT_VK_SUCCESS(err); 22121 22122 vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs); 22123 22124 VkMemoryAllocateInfo alloc_info = {}; 22125 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 22126 alloc_info.pNext = NULL; 22127 alloc_info.memoryTypeIndex = 0; 22128 22129 // Ensure memory is big enough for both bindings 22130 alloc_info.allocationSize = 0x10000; 22131 22132 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); 22133 if (!pass) { 22134 vkDestroyBuffer(m_device->device(), buffer, NULL); 22135 return; 22136 } 22137 22138 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem); 22139 ASSERT_VK_SUCCESS(err); 22140 22141 uint8_t *pData; 22142 err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData); 22143 ASSERT_VK_SUCCESS(err); 22144 22145 memset(pData, 0xCADECADE, static_cast<size_t>(mem_reqs.size)); 22146 22147 vkUnmapMemory(m_device->device(), mem); 22148 22149 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0); 22150 ASSERT_VK_SUCCESS(err); 22151 22152 // NOW, destroy the buffer. Obviously, the resource no longer occupies this 22153 // memory. In fact, it was never used by the GPU. 22154 // Just be be sure, wait for idle. 22155 vkDestroyBuffer(m_device->device(), buffer, NULL); 22156 vkDeviceWaitIdle(m_device->device()); 22157 22158 // Use optimal as some platforms report linear support but then fail image creation 22159 VkImageTiling image_tiling = VK_IMAGE_TILING_OPTIMAL; 22160 VkImageFormatProperties image_format_properties; 22161 vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, image_tiling, 22162 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0, &image_format_properties); 22163 if (image_format_properties.maxExtent.width == 0) { 22164 printf(" Image format not supported; skipped.\n"); 22165 vkFreeMemory(m_device->device(), mem, NULL); 22166 return; 22167 } 22168 VkImageCreateInfo image_create_info = {}; 22169 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 22170 image_create_info.pNext = NULL; 22171 image_create_info.imageType = VK_IMAGE_TYPE_2D; 22172 image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM; 22173 image_create_info.extent.width = 64; 22174 image_create_info.extent.height = 64; 22175 image_create_info.extent.depth = 1; 22176 image_create_info.mipLevels = 1; 22177 image_create_info.arrayLayers = 1; 22178 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 22179 image_create_info.tiling = image_tiling; 22180 image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; 22181 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 22182 image_create_info.queueFamilyIndexCount = 0; 22183 image_create_info.pQueueFamilyIndices = NULL; 22184 image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 22185 image_create_info.flags = 0; 22186 22187 /* Create a mappable image. It will be the texture if linear images are ok 22188 * to be textures or it will be the staging image if they are not. 22189 */ 22190 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 22191 ASSERT_VK_SUCCESS(err); 22192 22193 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs); 22194 22195 VkMemoryAllocateInfo mem_alloc = {}; 22196 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 22197 mem_alloc.pNext = NULL; 22198 mem_alloc.allocationSize = 0; 22199 mem_alloc.memoryTypeIndex = 0; 22200 mem_alloc.allocationSize = mem_reqs.size; 22201 22202 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); 22203 if (!pass) { 22204 vkFreeMemory(m_device->device(), mem, NULL); 22205 vkDestroyImage(m_device->device(), image, NULL); 22206 return; 22207 } 22208 22209 // VALIDATION FAILURE: 22210 err = vkBindImageMemory(m_device->device(), image, mem, 0); 22211 ASSERT_VK_SUCCESS(err); 22212 22213 m_errorMonitor->VerifyNotFound(); 22214 22215 vkFreeMemory(m_device->device(), mem, NULL); 22216 vkDestroyImage(m_device->device(), image, NULL); 22217 } 22218 22219 // This is a positive test. No failures are expected. 22220 TEST_F(VkPositiveLayerTest, TestDestroyFreeNullHandles) { 22221 VkResult err; 22222 22223 TEST_DESCRIPTION("Call all applicable destroy and free routines with NULL handles, expecting no validation errors"); 22224 22225 m_errorMonitor->ExpectSuccess(); 22226 22227 ASSERT_NO_FATAL_FAILURE(Init()); 22228 vkDestroyBuffer(m_device->device(), VK_NULL_HANDLE, NULL); 22229 vkDestroyBufferView(m_device->device(), VK_NULL_HANDLE, NULL); 22230 vkDestroyCommandPool(m_device->device(), VK_NULL_HANDLE, NULL); 22231 vkDestroyDescriptorPool(m_device->device(), VK_NULL_HANDLE, NULL); 22232 vkDestroyDescriptorSetLayout(m_device->device(), VK_NULL_HANDLE, NULL); 22233 vkDestroyDevice(VK_NULL_HANDLE, NULL); 22234 vkDestroyEvent(m_device->device(), VK_NULL_HANDLE, NULL); 22235 vkDestroyFence(m_device->device(), VK_NULL_HANDLE, NULL); 22236 vkDestroyFramebuffer(m_device->device(), VK_NULL_HANDLE, NULL); 22237 vkDestroyImage(m_device->device(), VK_NULL_HANDLE, NULL); 22238 vkDestroyImageView(m_device->device(), VK_NULL_HANDLE, NULL); 22239 vkDestroyInstance(VK_NULL_HANDLE, NULL); 22240 vkDestroyPipeline(m_device->device(), VK_NULL_HANDLE, NULL); 22241 vkDestroyPipelineCache(m_device->device(), VK_NULL_HANDLE, NULL); 22242 vkDestroyPipelineLayout(m_device->device(), VK_NULL_HANDLE, NULL); 22243 vkDestroyQueryPool(m_device->device(), VK_NULL_HANDLE, NULL); 22244 vkDestroyRenderPass(m_device->device(), VK_NULL_HANDLE, NULL); 22245 vkDestroySampler(m_device->device(), VK_NULL_HANDLE, NULL); 22246 vkDestroySemaphore(m_device->device(), VK_NULL_HANDLE, NULL); 22247 vkDestroyShaderModule(m_device->device(), VK_NULL_HANDLE, NULL); 22248 22249 VkCommandPool command_pool; 22250 VkCommandPoolCreateInfo pool_create_info{}; 22251 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 22252 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 22253 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 22254 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 22255 VkCommandBuffer command_buffers[3] = {}; 22256 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 22257 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 22258 command_buffer_allocate_info.commandPool = command_pool; 22259 command_buffer_allocate_info.commandBufferCount = 1; 22260 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 22261 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffers[1]); 22262 vkFreeCommandBuffers(m_device->device(), command_pool, 3, command_buffers); 22263 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 22264 22265 VkDescriptorPoolSize ds_type_count = {}; 22266 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 22267 ds_type_count.descriptorCount = 1; 22268 22269 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 22270 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 22271 ds_pool_ci.pNext = NULL; 22272 ds_pool_ci.maxSets = 1; 22273 ds_pool_ci.poolSizeCount = 1; 22274 ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; 22275 ds_pool_ci.pPoolSizes = &ds_type_count; 22276 22277 VkDescriptorPool ds_pool; 22278 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 22279 ASSERT_VK_SUCCESS(err); 22280 22281 VkDescriptorSetLayoutBinding dsl_binding = {}; 22282 dsl_binding.binding = 2; 22283 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 22284 dsl_binding.descriptorCount = 1; 22285 dsl_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 22286 dsl_binding.pImmutableSamplers = NULL; 22287 22288 const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding}); 22289 22290 VkDescriptorSet descriptor_sets[3] = {}; 22291 VkDescriptorSetAllocateInfo alloc_info = {}; 22292 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 22293 alloc_info.descriptorSetCount = 1; 22294 alloc_info.descriptorPool = ds_pool; 22295 alloc_info.pSetLayouts = &ds_layout.handle(); 22296 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_sets[1]); 22297 ASSERT_VK_SUCCESS(err); 22298 vkFreeDescriptorSets(m_device->device(), ds_pool, 3, descriptor_sets); 22299 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 22300 22301 vkFreeMemory(m_device->device(), VK_NULL_HANDLE, NULL); 22302 22303 m_errorMonitor->VerifyNotFound(); 22304 } 22305 22306 TEST_F(VkPositiveLayerTest, QueueSubmitSemaphoresAndLayoutTracking) { 22307 TEST_DESCRIPTION("Submit multiple command buffers with chained semaphore signals and layout transitions"); 22308 22309 m_errorMonitor->ExpectSuccess(); 22310 22311 ASSERT_NO_FATAL_FAILURE(Init()); 22312 VkCommandBuffer cmd_bufs[4]; 22313 VkCommandBufferAllocateInfo alloc_info; 22314 alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 22315 alloc_info.pNext = NULL; 22316 alloc_info.commandBufferCount = 4; 22317 alloc_info.commandPool = m_commandPool->handle(); 22318 alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 22319 vkAllocateCommandBuffers(m_device->device(), &alloc_info, cmd_bufs); 22320 VkImageObj image(m_device); 22321 image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, 22322 (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT), 22323 VK_IMAGE_TILING_OPTIMAL, 0); 22324 ASSERT_TRUE(image.initialized()); 22325 VkCommandBufferBeginInfo cb_binfo; 22326 cb_binfo.pNext = NULL; 22327 cb_binfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 22328 cb_binfo.pInheritanceInfo = VK_NULL_HANDLE; 22329 cb_binfo.flags = 0; 22330 // Use 4 command buffers, each with an image layout transition, ColorAO->General->ColorAO->TransferSrc->TransferDst 22331 vkBeginCommandBuffer(cmd_bufs[0], &cb_binfo); 22332 VkImageMemoryBarrier img_barrier = {}; 22333 img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 22334 img_barrier.pNext = NULL; 22335 img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; 22336 img_barrier.dstAccessMask = VK_ACCESS_HOST_WRITE_BIT; 22337 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 22338 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; 22339 img_barrier.image = image.handle(); 22340 img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 22341 img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 22342 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 22343 img_barrier.subresourceRange.baseArrayLayer = 0; 22344 img_barrier.subresourceRange.baseMipLevel = 0; 22345 img_barrier.subresourceRange.layerCount = 1; 22346 img_barrier.subresourceRange.levelCount = 1; 22347 vkCmdPipelineBarrier(cmd_bufs[0], VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, nullptr, 0, nullptr, 1, 22348 &img_barrier); 22349 vkEndCommandBuffer(cmd_bufs[0]); 22350 vkBeginCommandBuffer(cmd_bufs[1], &cb_binfo); 22351 img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL; 22352 img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 22353 vkCmdPipelineBarrier(cmd_bufs[1], VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, nullptr, 0, nullptr, 1, 22354 &img_barrier); 22355 vkEndCommandBuffer(cmd_bufs[1]); 22356 vkBeginCommandBuffer(cmd_bufs[2], &cb_binfo); 22357 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 22358 img_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 22359 vkCmdPipelineBarrier(cmd_bufs[2], VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, nullptr, 0, nullptr, 1, 22360 &img_barrier); 22361 vkEndCommandBuffer(cmd_bufs[2]); 22362 vkBeginCommandBuffer(cmd_bufs[3], &cb_binfo); 22363 img_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 22364 img_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 22365 vkCmdPipelineBarrier(cmd_bufs[3], VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, nullptr, 0, nullptr, 1, 22366 &img_barrier); 22367 vkEndCommandBuffer(cmd_bufs[3]); 22368 22369 // Submit 4 command buffers in 3 submits, with submits 2 and 3 waiting for semaphores from submits 1 and 2 22370 VkSemaphore semaphore1, semaphore2; 22371 VkSemaphoreCreateInfo semaphore_create_info{}; 22372 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 22373 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore1); 22374 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore2); 22375 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT}; 22376 VkSubmitInfo submit_info[3]; 22377 submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 22378 submit_info[0].pNext = nullptr; 22379 submit_info[0].commandBufferCount = 1; 22380 submit_info[0].pCommandBuffers = &cmd_bufs[0]; 22381 submit_info[0].signalSemaphoreCount = 1; 22382 submit_info[0].pSignalSemaphores = &semaphore1; 22383 submit_info[0].waitSemaphoreCount = 0; 22384 submit_info[0].pWaitDstStageMask = nullptr; 22385 submit_info[0].pWaitDstStageMask = flags; 22386 submit_info[1].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 22387 submit_info[1].pNext = nullptr; 22388 submit_info[1].commandBufferCount = 1; 22389 submit_info[1].pCommandBuffers = &cmd_bufs[1]; 22390 submit_info[1].waitSemaphoreCount = 1; 22391 submit_info[1].pWaitSemaphores = &semaphore1; 22392 submit_info[1].signalSemaphoreCount = 1; 22393 submit_info[1].pSignalSemaphores = &semaphore2; 22394 submit_info[1].pWaitDstStageMask = flags; 22395 submit_info[2].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 22396 submit_info[2].pNext = nullptr; 22397 submit_info[2].commandBufferCount = 2; 22398 submit_info[2].pCommandBuffers = &cmd_bufs[2]; 22399 submit_info[2].waitSemaphoreCount = 1; 22400 submit_info[2].pWaitSemaphores = &semaphore2; 22401 submit_info[2].signalSemaphoreCount = 0; 22402 submit_info[2].pSignalSemaphores = nullptr; 22403 submit_info[2].pWaitDstStageMask = flags; 22404 vkQueueSubmit(m_device->m_queue, 3, submit_info, VK_NULL_HANDLE); 22405 vkQueueWaitIdle(m_device->m_queue); 22406 22407 vkDestroySemaphore(m_device->device(), semaphore1, NULL); 22408 vkDestroySemaphore(m_device->device(), semaphore2, NULL); 22409 m_errorMonitor->VerifyNotFound(); 22410 } 22411 22412 TEST_F(VkPositiveLayerTest, DynamicOffsetWithInactiveBinding) { 22413 // Create a descriptorSet w/ dynamic descriptors where 1 binding is inactive 22414 // We previously had a bug where dynamic offset of inactive bindings was still being used 22415 VkResult err; 22416 m_errorMonitor->ExpectSuccess(); 22417 22418 ASSERT_NO_FATAL_FAILURE(Init()); 22419 ASSERT_NO_FATAL_FAILURE(InitViewport()); 22420 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 22421 22422 OneOffDescriptorSet ds(m_device, { 22423 {2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}, 22424 {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}, 22425 {1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}, 22426 }); 22427 22428 const VkPipelineLayoutObj pipeline_layout(m_device, {&ds.layout_}); 22429 22430 // Create two buffers to update the descriptors with 22431 // The first will be 2k and used for bindings 0 & 1, the second is 1k for binding 2 22432 uint32_t qfi = 0; 22433 VkBufferCreateInfo buffCI = {}; 22434 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 22435 buffCI.size = 2048; 22436 buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 22437 buffCI.queueFamilyIndexCount = 1; 22438 buffCI.pQueueFamilyIndices = &qfi; 22439 22440 VkBuffer dyub1; 22441 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub1); 22442 ASSERT_VK_SUCCESS(err); 22443 // buffer2 22444 buffCI.size = 1024; 22445 VkBuffer dyub2; 22446 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub2); 22447 ASSERT_VK_SUCCESS(err); 22448 // Allocate memory and bind to buffers 22449 VkMemoryAllocateInfo mem_alloc[2] = {}; 22450 mem_alloc[0].sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 22451 mem_alloc[0].pNext = NULL; 22452 mem_alloc[0].memoryTypeIndex = 0; 22453 mem_alloc[1].sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 22454 mem_alloc[1].pNext = NULL; 22455 mem_alloc[1].memoryTypeIndex = 0; 22456 22457 VkMemoryRequirements mem_reqs1; 22458 vkGetBufferMemoryRequirements(m_device->device(), dyub1, &mem_reqs1); 22459 VkMemoryRequirements mem_reqs2; 22460 vkGetBufferMemoryRequirements(m_device->device(), dyub2, &mem_reqs2); 22461 mem_alloc[0].allocationSize = mem_reqs1.size; 22462 bool pass = m_device->phy().set_memory_type(mem_reqs1.memoryTypeBits, &mem_alloc[0], 0); 22463 mem_alloc[1].allocationSize = mem_reqs2.size; 22464 pass &= m_device->phy().set_memory_type(mem_reqs2.memoryTypeBits, &mem_alloc[1], 0); 22465 if (!pass) { 22466 vkDestroyBuffer(m_device->device(), dyub1, NULL); 22467 vkDestroyBuffer(m_device->device(), dyub2, NULL); 22468 return; 22469 } 22470 22471 VkDeviceMemory mem1; 22472 err = vkAllocateMemory(m_device->device(), &mem_alloc[0], NULL, &mem1); 22473 ASSERT_VK_SUCCESS(err); 22474 err = vkBindBufferMemory(m_device->device(), dyub1, mem1, 0); 22475 ASSERT_VK_SUCCESS(err); 22476 VkDeviceMemory mem2; 22477 err = vkAllocateMemory(m_device->device(), &mem_alloc[1], NULL, &mem2); 22478 ASSERT_VK_SUCCESS(err); 22479 err = vkBindBufferMemory(m_device->device(), dyub2, mem2, 0); 22480 ASSERT_VK_SUCCESS(err); 22481 // Update descriptors 22482 const uint32_t BINDING_COUNT = 3; 22483 VkDescriptorBufferInfo buff_info[BINDING_COUNT] = {}; 22484 buff_info[0].buffer = dyub1; 22485 buff_info[0].offset = 0; 22486 buff_info[0].range = 256; 22487 buff_info[1].buffer = dyub1; 22488 buff_info[1].offset = 256; 22489 buff_info[1].range = 512; 22490 buff_info[2].buffer = dyub2; 22491 buff_info[2].offset = 0; 22492 buff_info[2].range = 512; 22493 22494 VkWriteDescriptorSet descriptor_write; 22495 memset(&descriptor_write, 0, sizeof(descriptor_write)); 22496 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 22497 descriptor_write.dstSet = ds.set_; 22498 descriptor_write.dstBinding = 0; 22499 descriptor_write.descriptorCount = BINDING_COUNT; 22500 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 22501 descriptor_write.pBufferInfo = buff_info; 22502 22503 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 22504 22505 m_commandBuffer->begin(); 22506 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo); 22507 22508 // Create PSO to be used for draw-time errors below 22509 char const *vsSource = 22510 "#version 450\n" 22511 "\n" 22512 "void main(){\n" 22513 " gl_Position = vec4(1);\n" 22514 "}\n"; 22515 char const *fsSource = 22516 "#version 450\n" 22517 "\n" 22518 "layout(location=0) out vec4 x;\n" 22519 "layout(set=0) layout(binding=0) uniform foo1 { int x; int y; } bar1;\n" 22520 "layout(set=0) layout(binding=2) uniform foo2 { int x; int y; } bar2;\n" 22521 "void main(){\n" 22522 " x = vec4(bar1.y) + vec4(bar2.y);\n" 22523 "}\n"; 22524 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 22525 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 22526 VkPipelineObj pipe(m_device); 22527 pipe.SetViewport(m_viewports); 22528 pipe.SetScissor(m_scissors); 22529 pipe.AddShader(&vs); 22530 pipe.AddShader(&fs); 22531 pipe.AddDefaultColorAttachment(); 22532 pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass()); 22533 22534 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 22535 // This update should succeed, but offset of inactive binding 1 oversteps binding 2 buffer size 22536 // we used to have a bug in this case. 22537 uint32_t dyn_off[BINDING_COUNT] = {0, 1024, 256}; 22538 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1, &ds.set_, 22539 BINDING_COUNT, dyn_off); 22540 m_commandBuffer->Draw(1, 0, 0, 0); 22541 m_errorMonitor->VerifyNotFound(); 22542 22543 vkDestroyBuffer(m_device->device(), dyub1, NULL); 22544 vkDestroyBuffer(m_device->device(), dyub2, NULL); 22545 vkFreeMemory(m_device->device(), mem1, NULL); 22546 vkFreeMemory(m_device->device(), mem2, NULL); 22547 } 22548 22549 TEST_F(VkPositiveLayerTest, NonCoherentMemoryMapping) { 22550 TEST_DESCRIPTION( 22551 "Ensure that validations handling of non-coherent memory mapping while using VK_WHOLE_SIZE does not cause access " 22552 "violations"); 22553 VkResult err; 22554 uint8_t *pData; 22555 ASSERT_NO_FATAL_FAILURE(Init()); 22556 22557 VkDeviceMemory mem; 22558 VkMemoryRequirements mem_reqs; 22559 mem_reqs.memoryTypeBits = 0xFFFFFFFF; 22560 const VkDeviceSize atom_size = m_device->props.limits.nonCoherentAtomSize; 22561 VkMemoryAllocateInfo alloc_info = {}; 22562 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 22563 alloc_info.pNext = NULL; 22564 alloc_info.memoryTypeIndex = 0; 22565 22566 static const VkDeviceSize allocation_size = 32 * atom_size; 22567 alloc_info.allocationSize = allocation_size; 22568 22569 // Find a memory configurations WITHOUT a COHERENT bit, otherwise exit 22570 bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 22571 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); 22572 if (!pass) { 22573 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, 22574 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 22575 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); 22576 if (!pass) { 22577 pass = m_device->phy().set_memory_type( 22578 mem_reqs.memoryTypeBits, &alloc_info, 22579 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT, 22580 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); 22581 if (!pass) { 22582 return; 22583 } 22584 } 22585 } 22586 22587 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem); 22588 ASSERT_VK_SUCCESS(err); 22589 22590 // Map/Flush/Invalidate using WHOLE_SIZE and zero offsets and entire mapped range 22591 m_errorMonitor->ExpectSuccess(); 22592 err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, (void **)&pData); 22593 ASSERT_VK_SUCCESS(err); 22594 VkMappedMemoryRange mmr = {}; 22595 mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; 22596 mmr.memory = mem; 22597 mmr.offset = 0; 22598 mmr.size = VK_WHOLE_SIZE; 22599 err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr); 22600 ASSERT_VK_SUCCESS(err); 22601 err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr); 22602 ASSERT_VK_SUCCESS(err); 22603 m_errorMonitor->VerifyNotFound(); 22604 vkUnmapMemory(m_device->device(), mem); 22605 22606 // Map/Flush/Invalidate using WHOLE_SIZE and an offset and entire mapped range 22607 m_errorMonitor->ExpectSuccess(); 22608 err = vkMapMemory(m_device->device(), mem, 5 * atom_size, VK_WHOLE_SIZE, 0, (void **)&pData); 22609 ASSERT_VK_SUCCESS(err); 22610 mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; 22611 mmr.memory = mem; 22612 mmr.offset = 6 * atom_size; 22613 mmr.size = VK_WHOLE_SIZE; 22614 err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr); 22615 ASSERT_VK_SUCCESS(err); 22616 err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr); 22617 ASSERT_VK_SUCCESS(err); 22618 m_errorMonitor->VerifyNotFound(); 22619 vkUnmapMemory(m_device->device(), mem); 22620 22621 // Map with offset and size 22622 // Flush/Invalidate subrange of mapped area with offset and size 22623 m_errorMonitor->ExpectSuccess(); 22624 err = vkMapMemory(m_device->device(), mem, 3 * atom_size, 9 * atom_size, 0, (void **)&pData); 22625 ASSERT_VK_SUCCESS(err); 22626 mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; 22627 mmr.memory = mem; 22628 mmr.offset = 4 * atom_size; 22629 mmr.size = 2 * atom_size; 22630 err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr); 22631 ASSERT_VK_SUCCESS(err); 22632 err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr); 22633 ASSERT_VK_SUCCESS(err); 22634 m_errorMonitor->VerifyNotFound(); 22635 vkUnmapMemory(m_device->device(), mem); 22636 22637 // Map without offset and flush WHOLE_SIZE with two separate offsets 22638 m_errorMonitor->ExpectSuccess(); 22639 err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, (void **)&pData); 22640 ASSERT_VK_SUCCESS(err); 22641 mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; 22642 mmr.memory = mem; 22643 mmr.offset = allocation_size - (4 * atom_size); 22644 mmr.size = VK_WHOLE_SIZE; 22645 err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr); 22646 ASSERT_VK_SUCCESS(err); 22647 mmr.offset = allocation_size - (6 * atom_size); 22648 mmr.size = VK_WHOLE_SIZE; 22649 err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr); 22650 ASSERT_VK_SUCCESS(err); 22651 m_errorMonitor->VerifyNotFound(); 22652 vkUnmapMemory(m_device->device(), mem); 22653 22654 vkFreeMemory(m_device->device(), mem, NULL); 22655 } 22656 22657 // This is a positive test. We used to expect error in this case but spec now allows it 22658 TEST_F(VkPositiveLayerTest, ResetUnsignaledFence) { 22659 m_errorMonitor->ExpectSuccess(); 22660 vk_testing::Fence testFence; 22661 VkFenceCreateInfo fenceInfo = {}; 22662 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 22663 fenceInfo.pNext = NULL; 22664 22665 ASSERT_NO_FATAL_FAILURE(Init()); 22666 testFence.init(*m_device, fenceInfo); 22667 VkFence fences[1] = {testFence.handle()}; 22668 VkResult result = vkResetFences(m_device->device(), 1, fences); 22669 ASSERT_VK_SUCCESS(result); 22670 22671 m_errorMonitor->VerifyNotFound(); 22672 } 22673 22674 TEST_F(VkPositiveLayerTest, CommandBufferSimultaneousUseSync) { 22675 m_errorMonitor->ExpectSuccess(); 22676 22677 ASSERT_NO_FATAL_FAILURE(Init()); 22678 VkResult err; 22679 22680 // Record (empty!) command buffer that can be submitted multiple times 22681 // simultaneously. 22682 VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 22683 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, nullptr}; 22684 m_commandBuffer->begin(&cbbi); 22685 m_commandBuffer->end(); 22686 22687 VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0}; 22688 VkFence fence; 22689 err = vkCreateFence(m_device->device(), &fci, nullptr, &fence); 22690 ASSERT_VK_SUCCESS(err); 22691 22692 VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0}; 22693 VkSemaphore s1, s2; 22694 err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s1); 22695 ASSERT_VK_SUCCESS(err); 22696 err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s2); 22697 ASSERT_VK_SUCCESS(err); 22698 22699 // Submit CB once signaling s1, with fence so we can roll forward to its retirement. 22700 VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &m_commandBuffer->handle(), 1, &s1}; 22701 err = vkQueueSubmit(m_device->m_queue, 1, &si, fence); 22702 ASSERT_VK_SUCCESS(err); 22703 22704 // Submit CB again, signaling s2. 22705 si.pSignalSemaphores = &s2; 22706 err = vkQueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE); 22707 ASSERT_VK_SUCCESS(err); 22708 22709 // Wait for fence. 22710 err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX); 22711 ASSERT_VK_SUCCESS(err); 22712 22713 // CB is still in flight from second submission, but semaphore s1 is no 22714 // longer in flight. delete it. 22715 vkDestroySemaphore(m_device->device(), s1, nullptr); 22716 22717 m_errorMonitor->VerifyNotFound(); 22718 22719 // Force device idle and clean up remaining objects 22720 vkDeviceWaitIdle(m_device->device()); 22721 vkDestroySemaphore(m_device->device(), s2, nullptr); 22722 vkDestroyFence(m_device->device(), fence, nullptr); 22723 } 22724 22725 TEST_F(VkPositiveLayerTest, FenceCreateSignaledWaitHandling) { 22726 m_errorMonitor->ExpectSuccess(); 22727 22728 ASSERT_NO_FATAL_FAILURE(Init()); 22729 VkResult err; 22730 22731 // A fence created signaled 22732 VkFenceCreateInfo fci1 = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, VK_FENCE_CREATE_SIGNALED_BIT}; 22733 VkFence f1; 22734 err = vkCreateFence(m_device->device(), &fci1, nullptr, &f1); 22735 ASSERT_VK_SUCCESS(err); 22736 22737 // A fence created not 22738 VkFenceCreateInfo fci2 = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0}; 22739 VkFence f2; 22740 err = vkCreateFence(m_device->device(), &fci2, nullptr, &f2); 22741 ASSERT_VK_SUCCESS(err); 22742 22743 // Submit the unsignaled fence 22744 VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 0, nullptr, 0, nullptr}; 22745 err = vkQueueSubmit(m_device->m_queue, 1, &si, f2); 22746 22747 // Wait on both fences, with signaled first. 22748 VkFence fences[] = {f1, f2}; 22749 vkWaitForFences(m_device->device(), 2, fences, VK_TRUE, UINT64_MAX); 22750 22751 // Should have both retired! 22752 vkDestroyFence(m_device->device(), f1, nullptr); 22753 vkDestroyFence(m_device->device(), f2, nullptr); 22754 22755 m_errorMonitor->VerifyNotFound(); 22756 } 22757 22758 TEST_F(VkPositiveLayerTest, CreateImageViewFollowsParameterCompatibilityRequirements) { 22759 TEST_DESCRIPTION("Verify that creating an ImageView with valid usage does not generate validation errors."); 22760 22761 ASSERT_NO_FATAL_FAILURE(Init()); 22762 22763 m_errorMonitor->ExpectSuccess(); 22764 22765 VkImageCreateInfo imgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 22766 nullptr, 22767 VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, 22768 VK_IMAGE_TYPE_2D, 22769 VK_FORMAT_R8G8B8A8_UNORM, 22770 {128, 128, 1}, 22771 1, 22772 1, 22773 VK_SAMPLE_COUNT_1_BIT, 22774 VK_IMAGE_TILING_OPTIMAL, 22775 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 22776 VK_SHARING_MODE_EXCLUSIVE, 22777 0, 22778 nullptr, 22779 VK_IMAGE_LAYOUT_UNDEFINED}; 22780 VkImageObj image(m_device); 22781 image.init(&imgInfo); 22782 ASSERT_TRUE(image.initialized()); 22783 VkImageView imageView; 22784 VkImageViewCreateInfo ivci = {}; 22785 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 22786 ivci.image = image.handle(); 22787 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; 22788 ivci.format = VK_FORMAT_R8G8B8A8_UNORM; 22789 ivci.subresourceRange.layerCount = 1; 22790 ivci.subresourceRange.baseMipLevel = 0; 22791 ivci.subresourceRange.levelCount = 1; 22792 ivci.subresourceRange.baseArrayLayer = 0; 22793 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 22794 22795 vkCreateImageView(m_device->device(), &ivci, NULL, &imageView); 22796 m_errorMonitor->VerifyNotFound(); 22797 vkDestroyImageView(m_device->device(), imageView, NULL); 22798 } 22799 22800 TEST_F(VkPositiveLayerTest, ValidUsage) { 22801 TEST_DESCRIPTION("Verify that creating an image view from an image with valid usage doesn't generate validation errors"); 22802 22803 ASSERT_NO_FATAL_FAILURE(Init()); 22804 22805 m_errorMonitor->ExpectSuccess(); 22806 // Verify that we can create a view with usage INPUT_ATTACHMENT 22807 VkImageObj image(m_device); 22808 image.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 22809 ASSERT_TRUE(image.initialized()); 22810 VkImageView imageView; 22811 VkImageViewCreateInfo ivci = {}; 22812 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 22813 ivci.image = image.handle(); 22814 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; 22815 ivci.format = VK_FORMAT_R8G8B8A8_UNORM; 22816 ivci.subresourceRange.layerCount = 1; 22817 ivci.subresourceRange.baseMipLevel = 0; 22818 ivci.subresourceRange.levelCount = 1; 22819 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 22820 22821 vkCreateImageView(m_device->device(), &ivci, NULL, &imageView); 22822 m_errorMonitor->VerifyNotFound(); 22823 vkDestroyImageView(m_device->device(), imageView, NULL); 22824 } 22825 22826 // This is a positive test. No failures are expected. 22827 TEST_F(VkPositiveLayerTest, BindSparse) { 22828 TEST_DESCRIPTION("Bind 2 memory ranges to one image using vkQueueBindSparse, destroy the image and then free the memory"); 22829 22830 ASSERT_NO_FATAL_FAILURE(Init()); 22831 22832 auto index = m_device->graphics_queue_node_index_; 22833 if (!(m_device->queue_props[index].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT)) return; 22834 if (!m_device->phy().features().sparseBinding) return; 22835 22836 m_errorMonitor->ExpectSuccess(); 22837 22838 VkImage image; 22839 VkImageCreateInfo image_create_info = {}; 22840 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 22841 image_create_info.pNext = NULL; 22842 image_create_info.imageType = VK_IMAGE_TYPE_2D; 22843 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; 22844 image_create_info.extent.width = 64; 22845 image_create_info.extent.height = 64; 22846 image_create_info.extent.depth = 1; 22847 image_create_info.mipLevels = 1; 22848 image_create_info.arrayLayers = 1; 22849 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 22850 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 22851 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 22852 image_create_info.flags = VK_IMAGE_CREATE_SPARSE_BINDING_BIT; 22853 VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 22854 ASSERT_VK_SUCCESS(err); 22855 22856 VkMemoryRequirements memory_reqs; 22857 VkDeviceMemory memory_one, memory_two; 22858 bool pass; 22859 VkMemoryAllocateInfo memory_info = {}; 22860 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 22861 memory_info.pNext = NULL; 22862 memory_info.allocationSize = 0; 22863 memory_info.memoryTypeIndex = 0; 22864 vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs); 22865 // Find an image big enough to allow sparse mapping of 2 memory regions 22866 // Increase the image size until it is at least twice the 22867 // size of the required alignment, to ensure we can bind both 22868 // allocated memory blocks to the image on aligned offsets. 22869 while (memory_reqs.size < (memory_reqs.alignment * 2)) { 22870 vkDestroyImage(m_device->device(), image, nullptr); 22871 image_create_info.extent.width *= 2; 22872 image_create_info.extent.height *= 2; 22873 err = vkCreateImage(m_device->device(), &image_create_info, nullptr, &image); 22874 ASSERT_VK_SUCCESS(err); 22875 vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs); 22876 } 22877 // Allocate 2 memory regions of minimum alignment size, bind one at 0, the other 22878 // at the end of the first 22879 memory_info.allocationSize = memory_reqs.alignment; 22880 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 22881 ASSERT_TRUE(pass); 22882 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &memory_one); 22883 ASSERT_VK_SUCCESS(err); 22884 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &memory_two); 22885 ASSERT_VK_SUCCESS(err); 22886 VkSparseMemoryBind binds[2]; 22887 binds[0].flags = 0; 22888 binds[0].memory = memory_one; 22889 binds[0].memoryOffset = 0; 22890 binds[0].resourceOffset = 0; 22891 binds[0].size = memory_info.allocationSize; 22892 binds[1].flags = 0; 22893 binds[1].memory = memory_two; 22894 binds[1].memoryOffset = 0; 22895 binds[1].resourceOffset = memory_info.allocationSize; 22896 binds[1].size = memory_info.allocationSize; 22897 22898 VkSparseImageOpaqueMemoryBindInfo opaqueBindInfo; 22899 opaqueBindInfo.image = image; 22900 opaqueBindInfo.bindCount = 2; 22901 opaqueBindInfo.pBinds = binds; 22902 22903 VkFence fence = VK_NULL_HANDLE; 22904 VkBindSparseInfo bindSparseInfo = {}; 22905 bindSparseInfo.sType = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO; 22906 bindSparseInfo.imageOpaqueBindCount = 1; 22907 bindSparseInfo.pImageOpaqueBinds = &opaqueBindInfo; 22908 22909 vkQueueBindSparse(m_device->m_queue, 1, &bindSparseInfo, fence); 22910 vkQueueWaitIdle(m_device->m_queue); 22911 vkDestroyImage(m_device->device(), image, NULL); 22912 vkFreeMemory(m_device->device(), memory_one, NULL); 22913 vkFreeMemory(m_device->device(), memory_two, NULL); 22914 m_errorMonitor->VerifyNotFound(); 22915 } 22916 22917 TEST_F(VkPositiveLayerTest, RenderPassInitialLayoutUndefined) { 22918 TEST_DESCRIPTION( 22919 "Ensure that CmdBeginRenderPass with an attachment's initialLayout of VK_IMAGE_LAYOUT_UNDEFINED works when the command " 22920 "buffer has prior knowledge of that attachment's layout."); 22921 22922 m_errorMonitor->ExpectSuccess(); 22923 22924 ASSERT_NO_FATAL_FAILURE(Init()); 22925 22926 // A renderpass with one color attachment. 22927 VkAttachmentDescription attachment = {0, 22928 VK_FORMAT_R8G8B8A8_UNORM, 22929 VK_SAMPLE_COUNT_1_BIT, 22930 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 22931 VK_ATTACHMENT_STORE_OP_STORE, 22932 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 22933 VK_ATTACHMENT_STORE_OP_DONT_CARE, 22934 VK_IMAGE_LAYOUT_UNDEFINED, 22935 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; 22936 22937 VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; 22938 22939 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr}; 22940 22941 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr}; 22942 22943 VkRenderPass rp; 22944 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 22945 ASSERT_VK_SUCCESS(err); 22946 22947 // A compatible framebuffer. 22948 VkImageObj image(m_device); 22949 image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 22950 ASSERT_TRUE(image.initialized()); 22951 22952 VkImageViewCreateInfo ivci = { 22953 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 22954 nullptr, 22955 0, 22956 image.handle(), 22957 VK_IMAGE_VIEW_TYPE_2D, 22958 VK_FORMAT_R8G8B8A8_UNORM, 22959 {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, 22960 VK_COMPONENT_SWIZZLE_IDENTITY}, 22961 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}, 22962 }; 22963 VkImageView view; 22964 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view); 22965 ASSERT_VK_SUCCESS(err); 22966 22967 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1}; 22968 VkFramebuffer fb; 22969 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); 22970 ASSERT_VK_SUCCESS(err); 22971 22972 // Record a single command buffer which uses this renderpass twice. The 22973 // bug is triggered at the beginning of the second renderpass, when the 22974 // command buffer already has a layout recorded for the attachment. 22975 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr}; 22976 m_commandBuffer->begin(); 22977 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); 22978 vkCmdEndRenderPass(m_commandBuffer->handle()); 22979 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); 22980 22981 m_errorMonitor->VerifyNotFound(); 22982 22983 vkCmdEndRenderPass(m_commandBuffer->handle()); 22984 m_commandBuffer->end(); 22985 22986 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 22987 vkDestroyRenderPass(m_device->device(), rp, nullptr); 22988 vkDestroyImageView(m_device->device(), view, nullptr); 22989 } 22990 22991 TEST_F(VkPositiveLayerTest, FramebufferBindingDestroyCommandPool) { 22992 TEST_DESCRIPTION( 22993 "This test should pass. Create a Framebuffer and command buffer, bind them together, then destroy command pool and " 22994 "framebuffer and verify there are no errors."); 22995 22996 m_errorMonitor->ExpectSuccess(); 22997 22998 ASSERT_NO_FATAL_FAILURE(Init()); 22999 23000 // A renderpass with one color attachment. 23001 VkAttachmentDescription attachment = {0, 23002 VK_FORMAT_R8G8B8A8_UNORM, 23003 VK_SAMPLE_COUNT_1_BIT, 23004 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 23005 VK_ATTACHMENT_STORE_OP_STORE, 23006 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 23007 VK_ATTACHMENT_STORE_OP_DONT_CARE, 23008 VK_IMAGE_LAYOUT_UNDEFINED, 23009 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; 23010 23011 VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; 23012 23013 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr}; 23014 23015 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr}; 23016 23017 VkRenderPass rp; 23018 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 23019 ASSERT_VK_SUCCESS(err); 23020 23021 // A compatible framebuffer. 23022 VkImageObj image(m_device); 23023 image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 23024 ASSERT_TRUE(image.initialized()); 23025 23026 VkImageView view = image.targetView(VK_FORMAT_R8G8B8A8_UNORM); 23027 23028 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1}; 23029 VkFramebuffer fb; 23030 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); 23031 ASSERT_VK_SUCCESS(err); 23032 23033 // Explicitly create a command buffer to bind the FB to so that we can then 23034 // destroy the command pool in order to implicitly free command buffer 23035 VkCommandPool command_pool; 23036 VkCommandPoolCreateInfo pool_create_info{}; 23037 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 23038 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 23039 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 23040 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 23041 23042 VkCommandBuffer command_buffer; 23043 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 23044 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 23045 command_buffer_allocate_info.commandPool = command_pool; 23046 command_buffer_allocate_info.commandBufferCount = 1; 23047 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 23048 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer); 23049 23050 // Begin our cmd buffer with renderpass using our framebuffer 23051 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr}; 23052 VkCommandBufferBeginInfo begin_info{}; 23053 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 23054 vkBeginCommandBuffer(command_buffer, &begin_info); 23055 23056 vkCmdBeginRenderPass(command_buffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE); 23057 vkCmdEndRenderPass(command_buffer); 23058 vkEndCommandBuffer(command_buffer); 23059 // Destroy command pool to implicitly free command buffer 23060 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 23061 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 23062 vkDestroyRenderPass(m_device->device(), rp, nullptr); 23063 m_errorMonitor->VerifyNotFound(); 23064 } 23065 23066 TEST_F(VkPositiveLayerTest, RenderPassSubpassZeroTransitionsApplied) { 23067 TEST_DESCRIPTION("Ensure that CmdBeginRenderPass applies the layout transitions for the first subpass"); 23068 23069 m_errorMonitor->ExpectSuccess(); 23070 23071 ASSERT_NO_FATAL_FAILURE(Init()); 23072 23073 // A renderpass with one color attachment. 23074 VkAttachmentDescription attachment = {0, 23075 VK_FORMAT_R8G8B8A8_UNORM, 23076 VK_SAMPLE_COUNT_1_BIT, 23077 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 23078 VK_ATTACHMENT_STORE_OP_STORE, 23079 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 23080 VK_ATTACHMENT_STORE_OP_DONT_CARE, 23081 VK_IMAGE_LAYOUT_UNDEFINED, 23082 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; 23083 23084 VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; 23085 23086 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr}; 23087 23088 VkSubpassDependency dep = {0, 23089 0, 23090 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 23091 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 23092 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 23093 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 23094 VK_DEPENDENCY_BY_REGION_BIT}; 23095 23096 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep}; 23097 23098 VkResult err; 23099 VkRenderPass rp; 23100 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 23101 ASSERT_VK_SUCCESS(err); 23102 23103 // A compatible framebuffer. 23104 VkImageObj image(m_device); 23105 image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 23106 ASSERT_TRUE(image.initialized()); 23107 23108 VkImageView view = image.targetView(VK_FORMAT_R8G8B8A8_UNORM); 23109 23110 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1}; 23111 VkFramebuffer fb; 23112 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); 23113 ASSERT_VK_SUCCESS(err); 23114 23115 // Record a single command buffer which issues a pipeline barrier w/ 23116 // image memory barrier for the attachment. This detects the previously 23117 // missing tracking of the subpass layout by throwing a validation error 23118 // if it doesn't occur. 23119 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr}; 23120 m_commandBuffer->begin(); 23121 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); 23122 23123 VkImageMemoryBarrier imb = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 23124 nullptr, 23125 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 23126 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 23127 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 23128 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 23129 VK_QUEUE_FAMILY_IGNORED, 23130 VK_QUEUE_FAMILY_IGNORED, 23131 image.handle(), 23132 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; 23133 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 23134 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 23135 &imb); 23136 23137 vkCmdEndRenderPass(m_commandBuffer->handle()); 23138 m_errorMonitor->VerifyNotFound(); 23139 m_commandBuffer->end(); 23140 23141 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 23142 vkDestroyRenderPass(m_device->device(), rp, nullptr); 23143 } 23144 23145 TEST_F(VkPositiveLayerTest, DepthStencilLayoutTransitionForDepthOnlyImageview) { 23146 TEST_DESCRIPTION( 23147 "Validate that when an imageView of a depth/stencil image is used as a depth/stencil framebuffer attachment, the " 23148 "aspectMask is ignored and both depth and stencil image subresources are used."); 23149 23150 ASSERT_NO_FATAL_FAILURE(Init()); 23151 VkFormatProperties format_properties; 23152 vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_D32_SFLOAT_S8_UINT, &format_properties); 23153 if (!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { 23154 return; 23155 } 23156 23157 m_errorMonitor->ExpectSuccess(); 23158 23159 VkAttachmentDescription attachment = {0, 23160 VK_FORMAT_D32_SFLOAT_S8_UINT, 23161 VK_SAMPLE_COUNT_1_BIT, 23162 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 23163 VK_ATTACHMENT_STORE_OP_STORE, 23164 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 23165 VK_ATTACHMENT_STORE_OP_DONT_CARE, 23166 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 23167 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; 23168 23169 VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; 23170 23171 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &att_ref, 0, nullptr}; 23172 23173 VkSubpassDependency dep = {0, 23174 0, 23175 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 23176 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 23177 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 23178 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 23179 VK_DEPENDENCY_BY_REGION_BIT}; 23180 23181 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep}; 23182 23183 VkResult err; 23184 VkRenderPass rp; 23185 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 23186 ASSERT_VK_SUCCESS(err); 23187 23188 VkImageObj image(m_device); 23189 image.InitNoLayout(32, 32, 1, VK_FORMAT_D32_SFLOAT_S8_UINT, 23190 0x26, // usage 23191 VK_IMAGE_TILING_OPTIMAL, 0); 23192 ASSERT_TRUE(image.initialized()); 23193 image.SetLayout(0x6, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); 23194 23195 VkImageViewCreateInfo ivci = { 23196 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 23197 nullptr, 23198 0, 23199 image.handle(), 23200 VK_IMAGE_VIEW_TYPE_2D, 23201 VK_FORMAT_D32_SFLOAT_S8_UINT, 23202 {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A}, 23203 {0x2, 0, 1, 0, 1}, 23204 }; 23205 VkImageView view; 23206 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view); 23207 ASSERT_VK_SUCCESS(err); 23208 23209 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1}; 23210 VkFramebuffer fb; 23211 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); 23212 ASSERT_VK_SUCCESS(err); 23213 23214 m_commandBuffer->begin(); 23215 23216 VkImageMemoryBarrier imb = {}; 23217 imb.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 23218 imb.pNext = nullptr; 23219 imb.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 23220 imb.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 23221 imb.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 23222 imb.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 23223 imb.srcQueueFamilyIndex = 0; 23224 imb.dstQueueFamilyIndex = 0; 23225 imb.image = image.handle(); 23226 imb.subresourceRange.aspectMask = 0x6; 23227 imb.subresourceRange.baseMipLevel = 0; 23228 imb.subresourceRange.levelCount = 0x1; 23229 imb.subresourceRange.baseArrayLayer = 0; 23230 imb.subresourceRange.layerCount = 0x1; 23231 23232 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, 23233 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &imb); 23234 23235 m_commandBuffer->end(); 23236 m_commandBuffer->QueueCommandBuffer(false); 23237 m_errorMonitor->VerifyNotFound(); 23238 23239 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 23240 vkDestroyRenderPass(m_device->device(), rp, nullptr); 23241 vkDestroyImageView(m_device->device(), view, nullptr); 23242 } 23243 23244 TEST_F(VkPositiveLayerTest, RenderPassTransitionsAttachmentUnused) { 23245 TEST_DESCRIPTION( 23246 "Ensure that layout transitions work correctly without errors, when an attachment reference is VK_ATTACHMENT_UNUSED"); 23247 23248 m_errorMonitor->ExpectSuccess(); 23249 23250 ASSERT_NO_FATAL_FAILURE(Init()); 23251 23252 // A renderpass with no attachments 23253 VkAttachmentReference att_ref = {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; 23254 23255 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr}; 23256 23257 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, &subpass, 0, nullptr}; 23258 23259 VkRenderPass rp; 23260 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 23261 ASSERT_VK_SUCCESS(err); 23262 23263 // A compatible framebuffer. 23264 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 32, 32, 1}; 23265 VkFramebuffer fb; 23266 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); 23267 ASSERT_VK_SUCCESS(err); 23268 23269 // Record a command buffer which just begins and ends the renderpass. The 23270 // bug manifests in BeginRenderPass. 23271 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr}; 23272 m_commandBuffer->begin(); 23273 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); 23274 vkCmdEndRenderPass(m_commandBuffer->handle()); 23275 m_errorMonitor->VerifyNotFound(); 23276 m_commandBuffer->end(); 23277 23278 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 23279 vkDestroyRenderPass(m_device->device(), rp, nullptr); 23280 } 23281 23282 // This is a positive test. No errors are expected. 23283 TEST_F(VkPositiveLayerTest, StencilLoadOp) { 23284 TEST_DESCRIPTION("Create a stencil-only attachment with a LOAD_OP set to CLEAR. stencil[Load|Store]Op used to be ignored."); 23285 VkResult result = VK_SUCCESS; 23286 ASSERT_NO_FATAL_FAILURE(Init()); 23287 auto depth_format = FindSupportedDepthStencilFormat(gpu()); 23288 if (!depth_format) { 23289 printf(" No Depth + Stencil format found. Skipped.\n"); 23290 return; 23291 } 23292 VkImageFormatProperties formatProps; 23293 vkGetPhysicalDeviceImageFormatProperties(gpu(), depth_format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, 23294 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0, 23295 &formatProps); 23296 if (formatProps.maxExtent.width < 100 || formatProps.maxExtent.height < 100) { 23297 return; 23298 } 23299 23300 VkFormat depth_stencil_fmt = depth_format; 23301 m_depthStencil->Init(m_device, 100, 100, depth_stencil_fmt, 23302 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT); 23303 VkAttachmentDescription att = {}; 23304 VkAttachmentReference ref = {}; 23305 att.format = depth_stencil_fmt; 23306 att.samples = VK_SAMPLE_COUNT_1_BIT; 23307 att.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; 23308 att.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; 23309 att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 23310 att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; 23311 att.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 23312 att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 23313 23314 VkClearValue clear; 23315 clear.depthStencil.depth = 1.0; 23316 clear.depthStencil.stencil = 0; 23317 ref.attachment = 0; 23318 ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 23319 23320 VkSubpassDescription subpass = {}; 23321 subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; 23322 subpass.flags = 0; 23323 subpass.inputAttachmentCount = 0; 23324 subpass.pInputAttachments = NULL; 23325 subpass.colorAttachmentCount = 0; 23326 subpass.pColorAttachments = NULL; 23327 subpass.pResolveAttachments = NULL; 23328 subpass.pDepthStencilAttachment = &ref; 23329 subpass.preserveAttachmentCount = 0; 23330 subpass.pPreserveAttachments = NULL; 23331 23332 VkRenderPass rp; 23333 VkRenderPassCreateInfo rp_info = {}; 23334 rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 23335 rp_info.attachmentCount = 1; 23336 rp_info.pAttachments = &att; 23337 rp_info.subpassCount = 1; 23338 rp_info.pSubpasses = &subpass; 23339 result = vkCreateRenderPass(device(), &rp_info, NULL, &rp); 23340 ASSERT_VK_SUCCESS(result); 23341 23342 VkImageView *depthView = m_depthStencil->BindInfo(); 23343 VkFramebufferCreateInfo fb_info = {}; 23344 fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; 23345 fb_info.pNext = NULL; 23346 fb_info.renderPass = rp; 23347 fb_info.attachmentCount = 1; 23348 fb_info.pAttachments = depthView; 23349 fb_info.width = 100; 23350 fb_info.height = 100; 23351 fb_info.layers = 1; 23352 VkFramebuffer fb; 23353 result = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 23354 ASSERT_VK_SUCCESS(result); 23355 23356 VkRenderPassBeginInfo rpbinfo = {}; 23357 rpbinfo.clearValueCount = 1; 23358 rpbinfo.pClearValues = &clear; 23359 rpbinfo.pNext = NULL; 23360 rpbinfo.renderPass = rp; 23361 rpbinfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; 23362 rpbinfo.renderArea.extent.width = 100; 23363 rpbinfo.renderArea.extent.height = 100; 23364 rpbinfo.renderArea.offset.x = 0; 23365 rpbinfo.renderArea.offset.y = 0; 23366 rpbinfo.framebuffer = fb; 23367 23368 VkFence fence = {}; 23369 VkFenceCreateInfo fence_ci = {}; 23370 fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 23371 fence_ci.pNext = nullptr; 23372 fence_ci.flags = 0; 23373 result = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fence); 23374 ASSERT_VK_SUCCESS(result); 23375 23376 m_commandBuffer->begin(); 23377 m_commandBuffer->BeginRenderPass(rpbinfo); 23378 m_commandBuffer->EndRenderPass(); 23379 m_commandBuffer->end(); 23380 m_commandBuffer->QueueCommandBuffer(fence); 23381 23382 VkImageObj destImage(m_device); 23383 destImage.Init(100, 100, 1, depth_stencil_fmt, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 23384 VK_IMAGE_TILING_OPTIMAL, 0); 23385 VkImageMemoryBarrier barrier = {}; 23386 VkImageSubresourceRange range; 23387 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 23388 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 23389 barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; 23390 barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 23391 barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 23392 barrier.image = m_depthStencil->handle(); 23393 range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 23394 range.baseMipLevel = 0; 23395 range.levelCount = 1; 23396 range.baseArrayLayer = 0; 23397 range.layerCount = 1; 23398 barrier.subresourceRange = range; 23399 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX); 23400 VkCommandBufferObj cmdbuf(m_device, m_commandPool); 23401 cmdbuf.begin(); 23402 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, 23403 &barrier); 23404 barrier.srcAccessMask = 0; 23405 barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; 23406 barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 23407 barrier.image = destImage.handle(); 23408 barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 23409 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, 23410 &barrier); 23411 VkImageCopy cregion; 23412 cregion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 23413 cregion.srcSubresource.mipLevel = 0; 23414 cregion.srcSubresource.baseArrayLayer = 0; 23415 cregion.srcSubresource.layerCount = 1; 23416 cregion.srcOffset.x = 0; 23417 cregion.srcOffset.y = 0; 23418 cregion.srcOffset.z = 0; 23419 cregion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 23420 cregion.dstSubresource.mipLevel = 0; 23421 cregion.dstSubresource.baseArrayLayer = 0; 23422 cregion.dstSubresource.layerCount = 1; 23423 cregion.dstOffset.x = 0; 23424 cregion.dstOffset.y = 0; 23425 cregion.dstOffset.z = 0; 23426 cregion.extent.width = 100; 23427 cregion.extent.height = 100; 23428 cregion.extent.depth = 1; 23429 cmdbuf.CopyImage(m_depthStencil->handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, destImage.handle(), 23430 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cregion); 23431 cmdbuf.end(); 23432 23433 VkSubmitInfo submit_info; 23434 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 23435 submit_info.pNext = NULL; 23436 submit_info.waitSemaphoreCount = 0; 23437 submit_info.pWaitSemaphores = NULL; 23438 submit_info.pWaitDstStageMask = NULL; 23439 submit_info.commandBufferCount = 1; 23440 submit_info.pCommandBuffers = &cmdbuf.handle(); 23441 submit_info.signalSemaphoreCount = 0; 23442 submit_info.pSignalSemaphores = NULL; 23443 23444 m_errorMonitor->ExpectSuccess(); 23445 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 23446 m_errorMonitor->VerifyNotFound(); 23447 23448 vkQueueWaitIdle(m_device->m_queue); 23449 vkDestroyFence(m_device->device(), fence, nullptr); 23450 vkDestroyRenderPass(m_device->device(), rp, nullptr); 23451 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 23452 } 23453 23454 // This is a positive test. No errors should be generated. 23455 TEST_F(VkPositiveLayerTest, BarrierLayoutToImageUsage) { 23456 TEST_DESCRIPTION("Ensure barriers' new and old VkImageLayout are compatible with their images' VkImageUsageFlags"); 23457 23458 m_errorMonitor->ExpectSuccess(); 23459 23460 ASSERT_NO_FATAL_FAILURE(Init()); 23461 auto depth_format = FindSupportedDepthStencilFormat(gpu()); 23462 if (!depth_format) { 23463 printf(" No Depth + Stencil format found. Skipped.\n"); 23464 return; 23465 } 23466 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 23467 23468 VkImageMemoryBarrier img_barrier = {}; 23469 img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 23470 img_barrier.pNext = NULL; 23471 img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; 23472 img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 23473 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 23474 img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 23475 img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 23476 img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 23477 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 23478 img_barrier.subresourceRange.baseArrayLayer = 0; 23479 img_barrier.subresourceRange.baseMipLevel = 0; 23480 img_barrier.subresourceRange.layerCount = 1; 23481 img_barrier.subresourceRange.levelCount = 1; 23482 23483 { 23484 VkImageObj img_color(m_device); 23485 img_color.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL); 23486 ASSERT_TRUE(img_color.initialized()); 23487 23488 VkImageObj img_ds1(m_device); 23489 img_ds1.Init(128, 128, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL); 23490 ASSERT_TRUE(img_ds1.initialized()); 23491 23492 VkImageObj img_ds2(m_device); 23493 img_ds2.Init(128, 128, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL); 23494 ASSERT_TRUE(img_ds2.initialized()); 23495 23496 VkImageObj img_xfer_src(m_device); 23497 img_xfer_src.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL); 23498 ASSERT_TRUE(img_xfer_src.initialized()); 23499 23500 VkImageObj img_xfer_dst(m_device); 23501 img_xfer_dst.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL); 23502 ASSERT_TRUE(img_xfer_dst.initialized()); 23503 23504 VkImageObj img_sampled(m_device); 23505 img_sampled.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL); 23506 ASSERT_TRUE(img_sampled.initialized()); 23507 23508 VkImageObj img_input(m_device); 23509 img_input.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL); 23510 ASSERT_TRUE(img_input.initialized()); 23511 23512 const struct { 23513 VkImageObj &image_obj; 23514 VkImageLayout old_layout; 23515 VkImageLayout new_layout; 23516 } buffer_layouts[] = { 23517 // clang-format off 23518 {img_color, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL}, 23519 {img_ds1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL}, 23520 {img_ds2, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL}, 23521 {img_sampled, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL}, 23522 {img_input, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL}, 23523 {img_xfer_src, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL}, 23524 {img_xfer_dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL}, 23525 // clang-format on 23526 }; 23527 const uint32_t layout_count = sizeof(buffer_layouts) / sizeof(buffer_layouts[0]); 23528 23529 m_commandBuffer->begin(); 23530 for (uint32_t i = 0; i < layout_count; ++i) { 23531 img_barrier.image = buffer_layouts[i].image_obj.handle(); 23532 const VkImageUsageFlags usage = buffer_layouts[i].image_obj.usage(); 23533 img_barrier.subresourceRange.aspectMask = (usage == VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) 23534 ? (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) 23535 : VK_IMAGE_ASPECT_COLOR_BIT; 23536 23537 img_barrier.oldLayout = buffer_layouts[i].old_layout; 23538 img_barrier.newLayout = buffer_layouts[i].new_layout; 23539 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, 23540 nullptr, 0, nullptr, 1, &img_barrier); 23541 23542 img_barrier.oldLayout = buffer_layouts[i].new_layout; 23543 img_barrier.newLayout = buffer_layouts[i].old_layout; 23544 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, 23545 nullptr, 0, nullptr, 1, &img_barrier); 23546 } 23547 m_commandBuffer->end(); 23548 23549 img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL; 23550 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; 23551 } 23552 m_errorMonitor->VerifyNotFound(); 23553 } 23554 23555 // This is a positive test. No errors should be generated. 23556 TEST_F(VkPositiveLayerTest, WaitEventThenSet) { 23557 TEST_DESCRIPTION("Wait on a event then set it after the wait has been submitted."); 23558 23559 m_errorMonitor->ExpectSuccess(); 23560 ASSERT_NO_FATAL_FAILURE(Init()); 23561 23562 VkEvent event; 23563 VkEventCreateInfo event_create_info{}; 23564 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 23565 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event); 23566 23567 VkCommandPool command_pool; 23568 VkCommandPoolCreateInfo pool_create_info{}; 23569 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 23570 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 23571 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 23572 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 23573 23574 VkCommandBuffer command_buffer; 23575 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 23576 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 23577 command_buffer_allocate_info.commandPool = command_pool; 23578 command_buffer_allocate_info.commandBufferCount = 1; 23579 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 23580 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer); 23581 23582 VkQueue queue = VK_NULL_HANDLE; 23583 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue); 23584 23585 { 23586 VkCommandBufferBeginInfo begin_info{}; 23587 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 23588 vkBeginCommandBuffer(command_buffer, &begin_info); 23589 23590 vkCmdWaitEvents(command_buffer, 1, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, 23591 nullptr, 0, nullptr); 23592 vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); 23593 vkEndCommandBuffer(command_buffer); 23594 } 23595 { 23596 VkSubmitInfo submit_info{}; 23597 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 23598 submit_info.commandBufferCount = 1; 23599 submit_info.pCommandBuffers = &command_buffer; 23600 submit_info.signalSemaphoreCount = 0; 23601 submit_info.pSignalSemaphores = nullptr; 23602 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE); 23603 } 23604 { vkSetEvent(m_device->device(), event); } 23605 23606 vkQueueWaitIdle(queue); 23607 23608 vkDestroyEvent(m_device->device(), event, nullptr); 23609 vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer); 23610 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 23611 23612 m_errorMonitor->VerifyNotFound(); 23613 } 23614 // This is a positive test. No errors should be generated. 23615 TEST_F(VkPositiveLayerTest, QueryAndCopySecondaryCommandBuffers) { 23616 TEST_DESCRIPTION("Issue a query on a secondary command buffer and copy it on a primary."); 23617 23618 ASSERT_NO_FATAL_FAILURE(Init()); 23619 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) return; 23620 23621 m_errorMonitor->ExpectSuccess(); 23622 23623 VkQueryPool query_pool; 23624 VkQueryPoolCreateInfo query_pool_create_info{}; 23625 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; 23626 query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP; 23627 query_pool_create_info.queryCount = 1; 23628 vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool); 23629 23630 VkCommandPoolObj command_pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); 23631 VkCommandBufferObj primary_buffer(m_device, &command_pool); 23632 VkCommandBufferObj secondary_buffer(m_device, &command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); 23633 23634 VkQueue queue = VK_NULL_HANDLE; 23635 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue); 23636 23637 uint32_t qfi = 0; 23638 VkBufferCreateInfo buff_create_info = {}; 23639 buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 23640 buff_create_info.size = 1024; 23641 buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT; 23642 buff_create_info.queueFamilyIndexCount = 1; 23643 buff_create_info.pQueueFamilyIndices = &qfi; 23644 23645 VkResult err; 23646 VkBuffer buffer; 23647 err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer); 23648 ASSERT_VK_SUCCESS(err); 23649 23650 VkMemoryRequirements memReqs; 23651 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs); 23652 VkMemoryAllocateInfo mem_alloc = {}; 23653 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 23654 mem_alloc.pNext = NULL; 23655 mem_alloc.allocationSize = memReqs.size; 23656 mem_alloc.memoryTypeIndex = 0; 23657 bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0); 23658 if (!pass) { 23659 vkDestroyBuffer(m_device->device(), buffer, NULL); 23660 return; 23661 } 23662 23663 VkDeviceMemory mem; 23664 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem); 23665 ASSERT_VK_SUCCESS(err); 23666 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0); 23667 ASSERT_VK_SUCCESS(err); 23668 23669 VkCommandBufferInheritanceInfo hinfo = {}; 23670 hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; 23671 hinfo.renderPass = VK_NULL_HANDLE; 23672 hinfo.subpass = 0; 23673 hinfo.framebuffer = VK_NULL_HANDLE; 23674 hinfo.occlusionQueryEnable = VK_FALSE; 23675 hinfo.queryFlags = 0; 23676 hinfo.pipelineStatistics = 0; 23677 23678 { 23679 VkCommandBufferBeginInfo begin_info{}; 23680 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 23681 begin_info.pInheritanceInfo = &hinfo; 23682 secondary_buffer.begin(&begin_info); 23683 vkCmdResetQueryPool(secondary_buffer.handle(), query_pool, 0, 1); 23684 vkCmdWriteTimestamp(secondary_buffer.handle(), VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0); 23685 secondary_buffer.end(); 23686 23687 primary_buffer.begin(); 23688 vkCmdExecuteCommands(primary_buffer.handle(), 1, &secondary_buffer.handle()); 23689 vkCmdCopyQueryPoolResults(primary_buffer.handle(), query_pool, 0, 1, buffer, 0, 0, 0); 23690 primary_buffer.end(); 23691 } 23692 23693 primary_buffer.QueueCommandBuffer(); 23694 vkQueueWaitIdle(queue); 23695 23696 vkDestroyQueryPool(m_device->device(), query_pool, nullptr); 23697 vkDestroyBuffer(m_device->device(), buffer, NULL); 23698 vkFreeMemory(m_device->device(), mem, NULL); 23699 23700 m_errorMonitor->VerifyNotFound(); 23701 } 23702 23703 // This is a positive test. No errors should be generated. 23704 TEST_F(VkPositiveLayerTest, QueryAndCopyMultipleCommandBuffers) { 23705 TEST_DESCRIPTION("Issue a query and copy from it on a second command buffer."); 23706 23707 ASSERT_NO_FATAL_FAILURE(Init()); 23708 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) return; 23709 23710 m_errorMonitor->ExpectSuccess(); 23711 23712 VkQueryPool query_pool; 23713 VkQueryPoolCreateInfo query_pool_create_info{}; 23714 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; 23715 query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP; 23716 query_pool_create_info.queryCount = 1; 23717 vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool); 23718 23719 VkCommandPool command_pool; 23720 VkCommandPoolCreateInfo pool_create_info{}; 23721 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 23722 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 23723 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 23724 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 23725 23726 VkCommandBuffer command_buffer[2]; 23727 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 23728 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 23729 command_buffer_allocate_info.commandPool = command_pool; 23730 command_buffer_allocate_info.commandBufferCount = 2; 23731 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 23732 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer); 23733 23734 VkQueue queue = VK_NULL_HANDLE; 23735 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue); 23736 23737 uint32_t qfi = 0; 23738 VkBufferCreateInfo buff_create_info = {}; 23739 buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 23740 buff_create_info.size = 1024; 23741 buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT; 23742 buff_create_info.queueFamilyIndexCount = 1; 23743 buff_create_info.pQueueFamilyIndices = &qfi; 23744 23745 VkResult err; 23746 VkBuffer buffer; 23747 err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer); 23748 ASSERT_VK_SUCCESS(err); 23749 23750 VkMemoryRequirements memReqs; 23751 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs); 23752 VkMemoryAllocateInfo mem_alloc = {}; 23753 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 23754 mem_alloc.pNext = NULL; 23755 mem_alloc.allocationSize = memReqs.size; 23756 mem_alloc.memoryTypeIndex = 0; 23757 bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0); 23758 if (!pass) { 23759 vkDestroyBuffer(m_device->device(), buffer, NULL); 23760 return; 23761 } 23762 23763 VkDeviceMemory mem; 23764 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem); 23765 ASSERT_VK_SUCCESS(err); 23766 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0); 23767 ASSERT_VK_SUCCESS(err); 23768 23769 { 23770 VkCommandBufferBeginInfo begin_info{}; 23771 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 23772 vkBeginCommandBuffer(command_buffer[0], &begin_info); 23773 23774 vkCmdResetQueryPool(command_buffer[0], query_pool, 0, 1); 23775 vkCmdWriteTimestamp(command_buffer[0], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0); 23776 23777 vkEndCommandBuffer(command_buffer[0]); 23778 23779 vkBeginCommandBuffer(command_buffer[1], &begin_info); 23780 23781 vkCmdCopyQueryPoolResults(command_buffer[1], query_pool, 0, 1, buffer, 0, 0, 0); 23782 23783 vkEndCommandBuffer(command_buffer[1]); 23784 } 23785 { 23786 VkSubmitInfo submit_info{}; 23787 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 23788 submit_info.commandBufferCount = 2; 23789 submit_info.pCommandBuffers = command_buffer; 23790 submit_info.signalSemaphoreCount = 0; 23791 submit_info.pSignalSemaphores = nullptr; 23792 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE); 23793 } 23794 23795 vkQueueWaitIdle(queue); 23796 23797 vkDestroyQueryPool(m_device->device(), query_pool, nullptr); 23798 vkFreeCommandBuffers(m_device->device(), command_pool, 2, command_buffer); 23799 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 23800 vkDestroyBuffer(m_device->device(), buffer, NULL); 23801 vkFreeMemory(m_device->device(), mem, NULL); 23802 23803 m_errorMonitor->VerifyNotFound(); 23804 } 23805 23806 TEST_F(VkLayerTest, ResetEventThenSet) { 23807 TEST_DESCRIPTION("Reset an event then set it after the reset has been submitted."); 23808 23809 ASSERT_NO_FATAL_FAILURE(Init()); 23810 VkEvent event; 23811 VkEventCreateInfo event_create_info{}; 23812 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 23813 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event); 23814 23815 VkCommandPool command_pool; 23816 VkCommandPoolCreateInfo pool_create_info{}; 23817 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 23818 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 23819 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 23820 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 23821 23822 VkCommandBuffer command_buffer; 23823 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 23824 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 23825 command_buffer_allocate_info.commandPool = command_pool; 23826 command_buffer_allocate_info.commandBufferCount = 1; 23827 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 23828 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer); 23829 23830 VkQueue queue = VK_NULL_HANDLE; 23831 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue); 23832 23833 { 23834 VkCommandBufferBeginInfo begin_info{}; 23835 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 23836 vkBeginCommandBuffer(command_buffer, &begin_info); 23837 23838 vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); 23839 vkEndCommandBuffer(command_buffer); 23840 } 23841 { 23842 VkSubmitInfo submit_info{}; 23843 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 23844 submit_info.commandBufferCount = 1; 23845 submit_info.pCommandBuffers = &command_buffer; 23846 submit_info.signalSemaphoreCount = 0; 23847 submit_info.pSignalSemaphores = nullptr; 23848 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE); 23849 } 23850 { 23851 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is already in use by a command buffer."); 23852 vkSetEvent(m_device->device(), event); 23853 m_errorMonitor->VerifyFound(); 23854 } 23855 23856 vkQueueWaitIdle(queue); 23857 23858 vkDestroyEvent(m_device->device(), event, nullptr); 23859 vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer); 23860 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 23861 } 23862 23863 // This is a positive test. No errors should be generated. 23864 TEST_F(VkPositiveLayerTest, TwoFencesThreeFrames) { 23865 TEST_DESCRIPTION( 23866 "Two command buffers with two separate fences are each run through a Submit & WaitForFences cycle 3 times. This previously " 23867 "revealed a bug so running this positive test to prevent a regression."); 23868 m_errorMonitor->ExpectSuccess(); 23869 23870 ASSERT_NO_FATAL_FAILURE(Init()); 23871 VkQueue queue = VK_NULL_HANDLE; 23872 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue); 23873 23874 static const uint32_t NUM_OBJECTS = 2; 23875 static const uint32_t NUM_FRAMES = 3; 23876 VkCommandBuffer cmd_buffers[NUM_OBJECTS] = {}; 23877 VkFence fences[NUM_OBJECTS] = {}; 23878 23879 VkCommandPool cmd_pool; 23880 VkCommandPoolCreateInfo cmd_pool_ci = {}; 23881 cmd_pool_ci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 23882 cmd_pool_ci.queueFamilyIndex = m_device->graphics_queue_node_index_; 23883 cmd_pool_ci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 23884 VkResult err = vkCreateCommandPool(m_device->device(), &cmd_pool_ci, nullptr, &cmd_pool); 23885 ASSERT_VK_SUCCESS(err); 23886 23887 VkCommandBufferAllocateInfo cmd_buf_info = {}; 23888 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 23889 cmd_buf_info.commandPool = cmd_pool; 23890 cmd_buf_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 23891 cmd_buf_info.commandBufferCount = 1; 23892 23893 VkFenceCreateInfo fence_ci = {}; 23894 fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 23895 fence_ci.pNext = nullptr; 23896 fence_ci.flags = 0; 23897 23898 for (uint32_t i = 0; i < NUM_OBJECTS; ++i) { 23899 err = vkAllocateCommandBuffers(m_device->device(), &cmd_buf_info, &cmd_buffers[i]); 23900 ASSERT_VK_SUCCESS(err); 23901 err = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fences[i]); 23902 ASSERT_VK_SUCCESS(err); 23903 } 23904 23905 for (uint32_t frame = 0; frame < NUM_FRAMES; ++frame) { 23906 for (uint32_t obj = 0; obj < NUM_OBJECTS; ++obj) { 23907 // Create empty cmd buffer 23908 VkCommandBufferBeginInfo cmdBufBeginDesc = {}; 23909 cmdBufBeginDesc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 23910 23911 err = vkBeginCommandBuffer(cmd_buffers[obj], &cmdBufBeginDesc); 23912 ASSERT_VK_SUCCESS(err); 23913 err = vkEndCommandBuffer(cmd_buffers[obj]); 23914 ASSERT_VK_SUCCESS(err); 23915 23916 VkSubmitInfo submit_info = {}; 23917 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 23918 submit_info.commandBufferCount = 1; 23919 submit_info.pCommandBuffers = &cmd_buffers[obj]; 23920 // Submit cmd buffer and wait for fence 23921 err = vkQueueSubmit(queue, 1, &submit_info, fences[obj]); 23922 ASSERT_VK_SUCCESS(err); 23923 err = vkWaitForFences(m_device->device(), 1, &fences[obj], VK_TRUE, UINT64_MAX); 23924 ASSERT_VK_SUCCESS(err); 23925 err = vkResetFences(m_device->device(), 1, &fences[obj]); 23926 ASSERT_VK_SUCCESS(err); 23927 } 23928 } 23929 m_errorMonitor->VerifyNotFound(); 23930 vkDestroyCommandPool(m_device->device(), cmd_pool, NULL); 23931 for (uint32_t i = 0; i < NUM_OBJECTS; ++i) { 23932 vkDestroyFence(m_device->device(), fences[i], nullptr); 23933 } 23934 } 23935 // This is a positive test. No errors should be generated. 23936 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWI) { 23937 TEST_DESCRIPTION( 23938 "Two command buffers, each in a separate QueueSubmit call submitted on separate queues followed by a QueueWaitIdle."); 23939 23940 ASSERT_NO_FATAL_FAILURE(Init()); 23941 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) return; 23942 23943 m_errorMonitor->ExpectSuccess(); 23944 23945 VkSemaphore semaphore; 23946 VkSemaphoreCreateInfo semaphore_create_info{}; 23947 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 23948 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore); 23949 23950 VkCommandPool command_pool; 23951 VkCommandPoolCreateInfo pool_create_info{}; 23952 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 23953 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 23954 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 23955 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 23956 23957 VkCommandBuffer command_buffer[2]; 23958 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 23959 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 23960 command_buffer_allocate_info.commandPool = command_pool; 23961 command_buffer_allocate_info.commandBufferCount = 2; 23962 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 23963 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer); 23964 23965 VkQueue queue = VK_NULL_HANDLE; 23966 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue); 23967 23968 { 23969 VkCommandBufferBeginInfo begin_info{}; 23970 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 23971 vkBeginCommandBuffer(command_buffer[0], &begin_info); 23972 23973 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 23974 nullptr, 0, nullptr, 0, nullptr); 23975 23976 VkViewport viewport{}; 23977 viewport.maxDepth = 1.0f; 23978 viewport.minDepth = 0.0f; 23979 viewport.width = 512; 23980 viewport.height = 512; 23981 viewport.x = 0; 23982 viewport.y = 0; 23983 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport); 23984 vkEndCommandBuffer(command_buffer[0]); 23985 } 23986 { 23987 VkCommandBufferBeginInfo begin_info{}; 23988 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 23989 vkBeginCommandBuffer(command_buffer[1], &begin_info); 23990 23991 VkViewport viewport{}; 23992 viewport.maxDepth = 1.0f; 23993 viewport.minDepth = 0.0f; 23994 viewport.width = 512; 23995 viewport.height = 512; 23996 viewport.x = 0; 23997 viewport.y = 0; 23998 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport); 23999 vkEndCommandBuffer(command_buffer[1]); 24000 } 24001 { 24002 VkSubmitInfo submit_info{}; 24003 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 24004 submit_info.commandBufferCount = 1; 24005 submit_info.pCommandBuffers = &command_buffer[0]; 24006 submit_info.signalSemaphoreCount = 1; 24007 submit_info.pSignalSemaphores = &semaphore; 24008 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE); 24009 } 24010 { 24011 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT}; 24012 VkSubmitInfo submit_info{}; 24013 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 24014 submit_info.commandBufferCount = 1; 24015 submit_info.pCommandBuffers = &command_buffer[1]; 24016 submit_info.waitSemaphoreCount = 1; 24017 submit_info.pWaitSemaphores = &semaphore; 24018 submit_info.pWaitDstStageMask = flags; 24019 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 24020 } 24021 24022 vkQueueWaitIdle(m_device->m_queue); 24023 24024 vkDestroySemaphore(m_device->device(), semaphore, nullptr); 24025 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]); 24026 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 24027 24028 m_errorMonitor->VerifyNotFound(); 24029 } 24030 24031 // This is a positive test. No errors should be generated. 24032 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWIFence) { 24033 TEST_DESCRIPTION( 24034 "Two command buffers, each in a separate QueueSubmit call submitted on separate queues, the second having a fencefollowed " 24035 "by a QueueWaitIdle."); 24036 24037 ASSERT_NO_FATAL_FAILURE(Init()); 24038 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) return; 24039 24040 m_errorMonitor->ExpectSuccess(); 24041 24042 VkFence fence; 24043 VkFenceCreateInfo fence_create_info{}; 24044 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 24045 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence); 24046 24047 VkSemaphore semaphore; 24048 VkSemaphoreCreateInfo semaphore_create_info{}; 24049 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 24050 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore); 24051 24052 VkCommandPool command_pool; 24053 VkCommandPoolCreateInfo pool_create_info{}; 24054 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 24055 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 24056 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 24057 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 24058 24059 VkCommandBuffer command_buffer[2]; 24060 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 24061 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 24062 command_buffer_allocate_info.commandPool = command_pool; 24063 command_buffer_allocate_info.commandBufferCount = 2; 24064 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 24065 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer); 24066 24067 VkQueue queue = VK_NULL_HANDLE; 24068 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue); 24069 24070 { 24071 VkCommandBufferBeginInfo begin_info{}; 24072 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 24073 vkBeginCommandBuffer(command_buffer[0], &begin_info); 24074 24075 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 24076 nullptr, 0, nullptr, 0, nullptr); 24077 24078 VkViewport viewport{}; 24079 viewport.maxDepth = 1.0f; 24080 viewport.minDepth = 0.0f; 24081 viewport.width = 512; 24082 viewport.height = 512; 24083 viewport.x = 0; 24084 viewport.y = 0; 24085 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport); 24086 vkEndCommandBuffer(command_buffer[0]); 24087 } 24088 { 24089 VkCommandBufferBeginInfo begin_info{}; 24090 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 24091 vkBeginCommandBuffer(command_buffer[1], &begin_info); 24092 24093 VkViewport viewport{}; 24094 viewport.maxDepth = 1.0f; 24095 viewport.minDepth = 0.0f; 24096 viewport.width = 512; 24097 viewport.height = 512; 24098 viewport.x = 0; 24099 viewport.y = 0; 24100 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport); 24101 vkEndCommandBuffer(command_buffer[1]); 24102 } 24103 { 24104 VkSubmitInfo submit_info{}; 24105 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 24106 submit_info.commandBufferCount = 1; 24107 submit_info.pCommandBuffers = &command_buffer[0]; 24108 submit_info.signalSemaphoreCount = 1; 24109 submit_info.pSignalSemaphores = &semaphore; 24110 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE); 24111 } 24112 { 24113 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT}; 24114 VkSubmitInfo submit_info{}; 24115 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 24116 submit_info.commandBufferCount = 1; 24117 submit_info.pCommandBuffers = &command_buffer[1]; 24118 submit_info.waitSemaphoreCount = 1; 24119 submit_info.pWaitSemaphores = &semaphore; 24120 submit_info.pWaitDstStageMask = flags; 24121 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence); 24122 } 24123 24124 vkQueueWaitIdle(m_device->m_queue); 24125 24126 vkDestroyFence(m_device->device(), fence, nullptr); 24127 vkDestroySemaphore(m_device->device(), semaphore, nullptr); 24128 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]); 24129 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 24130 24131 m_errorMonitor->VerifyNotFound(); 24132 } 24133 24134 // This is a positive test. No errors should be generated. 24135 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceTwoWFF) { 24136 TEST_DESCRIPTION( 24137 "Two command buffers, each in a separate QueueSubmit call submitted on separate queues, the second having a fencefollowed " 24138 "by two consecutive WaitForFences calls on the same fence."); 24139 24140 ASSERT_NO_FATAL_FAILURE(Init()); 24141 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) return; 24142 24143 m_errorMonitor->ExpectSuccess(); 24144 24145 VkFence fence; 24146 VkFenceCreateInfo fence_create_info{}; 24147 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 24148 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence); 24149 24150 VkSemaphore semaphore; 24151 VkSemaphoreCreateInfo semaphore_create_info{}; 24152 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 24153 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore); 24154 24155 VkCommandPool command_pool; 24156 VkCommandPoolCreateInfo pool_create_info{}; 24157 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 24158 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 24159 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 24160 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 24161 24162 VkCommandBuffer command_buffer[2]; 24163 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 24164 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 24165 command_buffer_allocate_info.commandPool = command_pool; 24166 command_buffer_allocate_info.commandBufferCount = 2; 24167 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 24168 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer); 24169 24170 VkQueue queue = VK_NULL_HANDLE; 24171 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue); 24172 24173 { 24174 VkCommandBufferBeginInfo begin_info{}; 24175 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 24176 vkBeginCommandBuffer(command_buffer[0], &begin_info); 24177 24178 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 24179 nullptr, 0, nullptr, 0, nullptr); 24180 24181 VkViewport viewport{}; 24182 viewport.maxDepth = 1.0f; 24183 viewport.minDepth = 0.0f; 24184 viewport.width = 512; 24185 viewport.height = 512; 24186 viewport.x = 0; 24187 viewport.y = 0; 24188 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport); 24189 vkEndCommandBuffer(command_buffer[0]); 24190 } 24191 { 24192 VkCommandBufferBeginInfo begin_info{}; 24193 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 24194 vkBeginCommandBuffer(command_buffer[1], &begin_info); 24195 24196 VkViewport viewport{}; 24197 viewport.maxDepth = 1.0f; 24198 viewport.minDepth = 0.0f; 24199 viewport.width = 512; 24200 viewport.height = 512; 24201 viewport.x = 0; 24202 viewport.y = 0; 24203 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport); 24204 vkEndCommandBuffer(command_buffer[1]); 24205 } 24206 { 24207 VkSubmitInfo submit_info{}; 24208 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 24209 submit_info.commandBufferCount = 1; 24210 submit_info.pCommandBuffers = &command_buffer[0]; 24211 submit_info.signalSemaphoreCount = 1; 24212 submit_info.pSignalSemaphores = &semaphore; 24213 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE); 24214 } 24215 { 24216 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT}; 24217 VkSubmitInfo submit_info{}; 24218 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 24219 submit_info.commandBufferCount = 1; 24220 submit_info.pCommandBuffers = &command_buffer[1]; 24221 submit_info.waitSemaphoreCount = 1; 24222 submit_info.pWaitSemaphores = &semaphore; 24223 submit_info.pWaitDstStageMask = flags; 24224 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence); 24225 } 24226 24227 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX); 24228 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX); 24229 24230 vkDestroyFence(m_device->device(), fence, nullptr); 24231 vkDestroySemaphore(m_device->device(), semaphore, nullptr); 24232 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]); 24233 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 24234 24235 m_errorMonitor->VerifyNotFound(); 24236 } 24237 24238 TEST_F(VkPositiveLayerTest, TwoQueuesEnsureCorrectRetirementWithWorkStolen) { 24239 ASSERT_NO_FATAL_FAILURE(Init()); 24240 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) { 24241 printf(" Test requires two queues, skipping\n"); 24242 return; 24243 } 24244 24245 VkResult err; 24246 24247 m_errorMonitor->ExpectSuccess(); 24248 24249 VkQueue q0 = m_device->m_queue; 24250 VkQueue q1 = nullptr; 24251 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &q1); 24252 ASSERT_NE(q1, nullptr); 24253 24254 // An (empty) command buffer. We must have work in the first submission -- 24255 // the layer treats unfenced work differently from fenced work. 24256 VkCommandPoolCreateInfo cpci = {VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, nullptr, 0, 0}; 24257 VkCommandPool pool; 24258 err = vkCreateCommandPool(m_device->device(), &cpci, nullptr, &pool); 24259 ASSERT_VK_SUCCESS(err); 24260 VkCommandBufferAllocateInfo cbai = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, nullptr, pool, 24261 VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1}; 24262 VkCommandBuffer cb; 24263 err = vkAllocateCommandBuffers(m_device->device(), &cbai, &cb); 24264 ASSERT_VK_SUCCESS(err); 24265 VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, nullptr}; 24266 err = vkBeginCommandBuffer(cb, &cbbi); 24267 ASSERT_VK_SUCCESS(err); 24268 err = vkEndCommandBuffer(cb); 24269 ASSERT_VK_SUCCESS(err); 24270 24271 // A semaphore 24272 VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0}; 24273 VkSemaphore s; 24274 err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s); 24275 ASSERT_VK_SUCCESS(err); 24276 24277 // First submission, to q0 24278 VkSubmitInfo s0 = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &cb, 1, &s}; 24279 24280 err = vkQueueSubmit(q0, 1, &s0, VK_NULL_HANDLE); 24281 ASSERT_VK_SUCCESS(err); 24282 24283 // Second submission, to q1, waiting on s 24284 VkFlags waitmask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; // doesn't really matter what this value is. 24285 VkSubmitInfo s1 = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &s, &waitmask, 0, nullptr, 0, nullptr}; 24286 24287 err = vkQueueSubmit(q1, 1, &s1, VK_NULL_HANDLE); 24288 ASSERT_VK_SUCCESS(err); 24289 24290 // Wait for q0 idle 24291 err = vkQueueWaitIdle(q0); 24292 ASSERT_VK_SUCCESS(err); 24293 24294 // Command buffer should have been completed (it was on q0); reset the pool. 24295 vkFreeCommandBuffers(m_device->device(), pool, 1, &cb); 24296 24297 m_errorMonitor->VerifyNotFound(); 24298 24299 // Force device completely idle and clean up resources 24300 vkDeviceWaitIdle(m_device->device()); 24301 vkDestroyCommandPool(m_device->device(), pool, nullptr); 24302 vkDestroySemaphore(m_device->device(), s, nullptr); 24303 } 24304 24305 // This is a positive test. No errors should be generated. 24306 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFence) { 24307 TEST_DESCRIPTION( 24308 "Two command buffers, each in a separate QueueSubmit call submitted on separate queues, the second having a fence, " 24309 "followed by a WaitForFences call."); 24310 24311 ASSERT_NO_FATAL_FAILURE(Init()); 24312 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) return; 24313 24314 m_errorMonitor->ExpectSuccess(); 24315 24316 VkFence fence; 24317 VkFenceCreateInfo fence_create_info{}; 24318 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 24319 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence); 24320 24321 VkSemaphore semaphore; 24322 VkSemaphoreCreateInfo semaphore_create_info{}; 24323 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 24324 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore); 24325 24326 VkCommandPool command_pool; 24327 VkCommandPoolCreateInfo pool_create_info{}; 24328 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 24329 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 24330 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 24331 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 24332 24333 VkCommandBuffer command_buffer[2]; 24334 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 24335 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 24336 command_buffer_allocate_info.commandPool = command_pool; 24337 command_buffer_allocate_info.commandBufferCount = 2; 24338 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 24339 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer); 24340 24341 VkQueue queue = VK_NULL_HANDLE; 24342 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue); 24343 24344 { 24345 VkCommandBufferBeginInfo begin_info{}; 24346 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 24347 vkBeginCommandBuffer(command_buffer[0], &begin_info); 24348 24349 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 24350 nullptr, 0, nullptr, 0, nullptr); 24351 24352 VkViewport viewport{}; 24353 viewport.maxDepth = 1.0f; 24354 viewport.minDepth = 0.0f; 24355 viewport.width = 512; 24356 viewport.height = 512; 24357 viewport.x = 0; 24358 viewport.y = 0; 24359 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport); 24360 vkEndCommandBuffer(command_buffer[0]); 24361 } 24362 { 24363 VkCommandBufferBeginInfo begin_info{}; 24364 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 24365 vkBeginCommandBuffer(command_buffer[1], &begin_info); 24366 24367 VkViewport viewport{}; 24368 viewport.maxDepth = 1.0f; 24369 viewport.minDepth = 0.0f; 24370 viewport.width = 512; 24371 viewport.height = 512; 24372 viewport.x = 0; 24373 viewport.y = 0; 24374 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport); 24375 vkEndCommandBuffer(command_buffer[1]); 24376 } 24377 { 24378 VkSubmitInfo submit_info{}; 24379 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 24380 submit_info.commandBufferCount = 1; 24381 submit_info.pCommandBuffers = &command_buffer[0]; 24382 submit_info.signalSemaphoreCount = 1; 24383 submit_info.pSignalSemaphores = &semaphore; 24384 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE); 24385 } 24386 { 24387 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT}; 24388 VkSubmitInfo submit_info{}; 24389 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 24390 submit_info.commandBufferCount = 1; 24391 submit_info.pCommandBuffers = &command_buffer[1]; 24392 submit_info.waitSemaphoreCount = 1; 24393 submit_info.pWaitSemaphores = &semaphore; 24394 submit_info.pWaitDstStageMask = flags; 24395 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence); 24396 } 24397 24398 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX); 24399 24400 vkDestroyFence(m_device->device(), fence, nullptr); 24401 vkDestroySemaphore(m_device->device(), semaphore, nullptr); 24402 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]); 24403 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 24404 24405 m_errorMonitor->VerifyNotFound(); 24406 } 24407 24408 // This is a positive test. No errors should be generated. 24409 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsOneQueueWithSemaphoreAndOneFence) { 24410 TEST_DESCRIPTION( 24411 "Two command buffers, each in a separate QueueSubmit call on the same queue, sharing a signal/wait semaphore, the second " 24412 "having a fence, followed by a WaitForFences call."); 24413 24414 m_errorMonitor->ExpectSuccess(); 24415 24416 ASSERT_NO_FATAL_FAILURE(Init()); 24417 VkFence fence; 24418 VkFenceCreateInfo fence_create_info{}; 24419 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 24420 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence); 24421 24422 VkSemaphore semaphore; 24423 VkSemaphoreCreateInfo semaphore_create_info{}; 24424 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 24425 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore); 24426 24427 VkCommandPool command_pool; 24428 VkCommandPoolCreateInfo pool_create_info{}; 24429 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 24430 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 24431 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 24432 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 24433 24434 VkCommandBuffer command_buffer[2]; 24435 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 24436 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 24437 command_buffer_allocate_info.commandPool = command_pool; 24438 command_buffer_allocate_info.commandBufferCount = 2; 24439 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 24440 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer); 24441 24442 { 24443 VkCommandBufferBeginInfo begin_info{}; 24444 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 24445 vkBeginCommandBuffer(command_buffer[0], &begin_info); 24446 24447 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 24448 nullptr, 0, nullptr, 0, nullptr); 24449 24450 VkViewport viewport{}; 24451 viewport.maxDepth = 1.0f; 24452 viewport.minDepth = 0.0f; 24453 viewport.width = 512; 24454 viewport.height = 512; 24455 viewport.x = 0; 24456 viewport.y = 0; 24457 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport); 24458 vkEndCommandBuffer(command_buffer[0]); 24459 } 24460 { 24461 VkCommandBufferBeginInfo begin_info{}; 24462 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 24463 vkBeginCommandBuffer(command_buffer[1], &begin_info); 24464 24465 VkViewport viewport{}; 24466 viewport.maxDepth = 1.0f; 24467 viewport.minDepth = 0.0f; 24468 viewport.width = 512; 24469 viewport.height = 512; 24470 viewport.x = 0; 24471 viewport.y = 0; 24472 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport); 24473 vkEndCommandBuffer(command_buffer[1]); 24474 } 24475 { 24476 VkSubmitInfo submit_info{}; 24477 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 24478 submit_info.commandBufferCount = 1; 24479 submit_info.pCommandBuffers = &command_buffer[0]; 24480 submit_info.signalSemaphoreCount = 1; 24481 submit_info.pSignalSemaphores = &semaphore; 24482 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 24483 } 24484 { 24485 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT}; 24486 VkSubmitInfo submit_info{}; 24487 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 24488 submit_info.commandBufferCount = 1; 24489 submit_info.pCommandBuffers = &command_buffer[1]; 24490 submit_info.waitSemaphoreCount = 1; 24491 submit_info.pWaitSemaphores = &semaphore; 24492 submit_info.pWaitDstStageMask = flags; 24493 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence); 24494 } 24495 24496 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX); 24497 24498 vkDestroyFence(m_device->device(), fence, nullptr); 24499 vkDestroySemaphore(m_device->device(), semaphore, nullptr); 24500 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]); 24501 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 24502 24503 m_errorMonitor->VerifyNotFound(); 24504 } 24505 24506 // This is a positive test. No errors should be generated. 24507 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsOneQueueNullQueueSubmitWithFence) { 24508 TEST_DESCRIPTION( 24509 "Two command buffers, each in a separate QueueSubmit call on the same queue, no fences, followed by a third QueueSubmit " 24510 "with NO SubmitInfos but with a fence, followed by a WaitForFences call."); 24511 24512 m_errorMonitor->ExpectSuccess(); 24513 24514 ASSERT_NO_FATAL_FAILURE(Init()); 24515 VkFence fence; 24516 VkFenceCreateInfo fence_create_info{}; 24517 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 24518 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence); 24519 24520 VkCommandPool command_pool; 24521 VkCommandPoolCreateInfo pool_create_info{}; 24522 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 24523 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 24524 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 24525 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 24526 24527 VkCommandBuffer command_buffer[2]; 24528 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 24529 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 24530 command_buffer_allocate_info.commandPool = command_pool; 24531 command_buffer_allocate_info.commandBufferCount = 2; 24532 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 24533 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer); 24534 24535 { 24536 VkCommandBufferBeginInfo begin_info{}; 24537 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 24538 vkBeginCommandBuffer(command_buffer[0], &begin_info); 24539 24540 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 24541 nullptr, 0, nullptr, 0, nullptr); 24542 24543 VkViewport viewport{}; 24544 viewport.maxDepth = 1.0f; 24545 viewport.minDepth = 0.0f; 24546 viewport.width = 512; 24547 viewport.height = 512; 24548 viewport.x = 0; 24549 viewport.y = 0; 24550 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport); 24551 vkEndCommandBuffer(command_buffer[0]); 24552 } 24553 { 24554 VkCommandBufferBeginInfo begin_info{}; 24555 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 24556 vkBeginCommandBuffer(command_buffer[1], &begin_info); 24557 24558 VkViewport viewport{}; 24559 viewport.maxDepth = 1.0f; 24560 viewport.minDepth = 0.0f; 24561 viewport.width = 512; 24562 viewport.height = 512; 24563 viewport.x = 0; 24564 viewport.y = 0; 24565 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport); 24566 vkEndCommandBuffer(command_buffer[1]); 24567 } 24568 { 24569 VkSubmitInfo submit_info{}; 24570 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 24571 submit_info.commandBufferCount = 1; 24572 submit_info.pCommandBuffers = &command_buffer[0]; 24573 submit_info.signalSemaphoreCount = 0; 24574 submit_info.pSignalSemaphores = VK_NULL_HANDLE; 24575 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 24576 } 24577 { 24578 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT}; 24579 VkSubmitInfo submit_info{}; 24580 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 24581 submit_info.commandBufferCount = 1; 24582 submit_info.pCommandBuffers = &command_buffer[1]; 24583 submit_info.waitSemaphoreCount = 0; 24584 submit_info.pWaitSemaphores = VK_NULL_HANDLE; 24585 submit_info.pWaitDstStageMask = flags; 24586 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 24587 } 24588 24589 vkQueueSubmit(m_device->m_queue, 0, NULL, fence); 24590 24591 VkResult err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX); 24592 ASSERT_VK_SUCCESS(err); 24593 24594 vkDestroyFence(m_device->device(), fence, nullptr); 24595 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]); 24596 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 24597 24598 m_errorMonitor->VerifyNotFound(); 24599 } 24600 24601 // This is a positive test. No errors should be generated. 24602 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsOneQueueOneFence) { 24603 TEST_DESCRIPTION( 24604 "Two command buffers, each in a separate QueueSubmit call on the same queue, the second having a fence, followed by a " 24605 "WaitForFences call."); 24606 24607 m_errorMonitor->ExpectSuccess(); 24608 24609 ASSERT_NO_FATAL_FAILURE(Init()); 24610 VkFence fence; 24611 VkFenceCreateInfo fence_create_info{}; 24612 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 24613 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence); 24614 24615 VkCommandPool command_pool; 24616 VkCommandPoolCreateInfo pool_create_info{}; 24617 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 24618 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 24619 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 24620 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 24621 24622 VkCommandBuffer command_buffer[2]; 24623 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 24624 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 24625 command_buffer_allocate_info.commandPool = command_pool; 24626 command_buffer_allocate_info.commandBufferCount = 2; 24627 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 24628 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer); 24629 24630 { 24631 VkCommandBufferBeginInfo begin_info{}; 24632 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 24633 vkBeginCommandBuffer(command_buffer[0], &begin_info); 24634 24635 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 24636 nullptr, 0, nullptr, 0, nullptr); 24637 24638 VkViewport viewport{}; 24639 viewport.maxDepth = 1.0f; 24640 viewport.minDepth = 0.0f; 24641 viewport.width = 512; 24642 viewport.height = 512; 24643 viewport.x = 0; 24644 viewport.y = 0; 24645 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport); 24646 vkEndCommandBuffer(command_buffer[0]); 24647 } 24648 { 24649 VkCommandBufferBeginInfo begin_info{}; 24650 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 24651 vkBeginCommandBuffer(command_buffer[1], &begin_info); 24652 24653 VkViewport viewport{}; 24654 viewport.maxDepth = 1.0f; 24655 viewport.minDepth = 0.0f; 24656 viewport.width = 512; 24657 viewport.height = 512; 24658 viewport.x = 0; 24659 viewport.y = 0; 24660 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport); 24661 vkEndCommandBuffer(command_buffer[1]); 24662 } 24663 { 24664 VkSubmitInfo submit_info{}; 24665 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 24666 submit_info.commandBufferCount = 1; 24667 submit_info.pCommandBuffers = &command_buffer[0]; 24668 submit_info.signalSemaphoreCount = 0; 24669 submit_info.pSignalSemaphores = VK_NULL_HANDLE; 24670 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 24671 } 24672 { 24673 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT}; 24674 VkSubmitInfo submit_info{}; 24675 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 24676 submit_info.commandBufferCount = 1; 24677 submit_info.pCommandBuffers = &command_buffer[1]; 24678 submit_info.waitSemaphoreCount = 0; 24679 submit_info.pWaitSemaphores = VK_NULL_HANDLE; 24680 submit_info.pWaitDstStageMask = flags; 24681 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence); 24682 } 24683 24684 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX); 24685 24686 vkDestroyFence(m_device->device(), fence, nullptr); 24687 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]); 24688 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 24689 24690 m_errorMonitor->VerifyNotFound(); 24691 } 24692 24693 // This is a positive test. No errors should be generated. 24694 TEST_F(VkPositiveLayerTest, TwoSubmitInfosWithSemaphoreOneQueueSubmitsOneFence) { 24695 TEST_DESCRIPTION( 24696 "Two command buffers each in a separate SubmitInfo sent in a single QueueSubmit call followed by a WaitForFences call."); 24697 ASSERT_NO_FATAL_FAILURE(Init()); 24698 24699 m_errorMonitor->ExpectSuccess(); 24700 24701 VkFence fence; 24702 VkFenceCreateInfo fence_create_info{}; 24703 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 24704 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence); 24705 24706 VkSemaphore semaphore; 24707 VkSemaphoreCreateInfo semaphore_create_info{}; 24708 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 24709 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore); 24710 24711 VkCommandPool command_pool; 24712 VkCommandPoolCreateInfo pool_create_info{}; 24713 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 24714 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 24715 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 24716 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 24717 24718 VkCommandBuffer command_buffer[2]; 24719 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 24720 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 24721 command_buffer_allocate_info.commandPool = command_pool; 24722 command_buffer_allocate_info.commandBufferCount = 2; 24723 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 24724 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer); 24725 24726 { 24727 VkCommandBufferBeginInfo begin_info{}; 24728 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 24729 vkBeginCommandBuffer(command_buffer[0], &begin_info); 24730 24731 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 24732 nullptr, 0, nullptr, 0, nullptr); 24733 24734 VkViewport viewport{}; 24735 viewport.maxDepth = 1.0f; 24736 viewport.minDepth = 0.0f; 24737 viewport.width = 512; 24738 viewport.height = 512; 24739 viewport.x = 0; 24740 viewport.y = 0; 24741 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport); 24742 vkEndCommandBuffer(command_buffer[0]); 24743 } 24744 { 24745 VkCommandBufferBeginInfo begin_info{}; 24746 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 24747 vkBeginCommandBuffer(command_buffer[1], &begin_info); 24748 24749 VkViewport viewport{}; 24750 viewport.maxDepth = 1.0f; 24751 viewport.minDepth = 0.0f; 24752 viewport.width = 512; 24753 viewport.height = 512; 24754 viewport.x = 0; 24755 viewport.y = 0; 24756 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport); 24757 vkEndCommandBuffer(command_buffer[1]); 24758 } 24759 { 24760 VkSubmitInfo submit_info[2]; 24761 VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT}; 24762 24763 submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 24764 submit_info[0].pNext = NULL; 24765 submit_info[0].commandBufferCount = 1; 24766 submit_info[0].pCommandBuffers = &command_buffer[0]; 24767 submit_info[0].signalSemaphoreCount = 1; 24768 submit_info[0].pSignalSemaphores = &semaphore; 24769 submit_info[0].waitSemaphoreCount = 0; 24770 submit_info[0].pWaitSemaphores = NULL; 24771 submit_info[0].pWaitDstStageMask = 0; 24772 24773 submit_info[1].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 24774 submit_info[1].pNext = NULL; 24775 submit_info[1].commandBufferCount = 1; 24776 submit_info[1].pCommandBuffers = &command_buffer[1]; 24777 submit_info[1].waitSemaphoreCount = 1; 24778 submit_info[1].pWaitSemaphores = &semaphore; 24779 submit_info[1].pWaitDstStageMask = flags; 24780 submit_info[1].signalSemaphoreCount = 0; 24781 submit_info[1].pSignalSemaphores = NULL; 24782 vkQueueSubmit(m_device->m_queue, 2, &submit_info[0], fence); 24783 } 24784 24785 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX); 24786 24787 vkDestroyFence(m_device->device(), fence, nullptr); 24788 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]); 24789 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 24790 vkDestroySemaphore(m_device->device(), semaphore, nullptr); 24791 24792 m_errorMonitor->VerifyNotFound(); 24793 } 24794 24795 TEST_F(VkPositiveLayerTest, RenderPassSecondaryCommandBuffersMultipleTimes) { 24796 m_errorMonitor->ExpectSuccess(); 24797 24798 ASSERT_NO_FATAL_FAILURE(Init()); 24799 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 24800 24801 m_commandBuffer->begin(); 24802 24803 vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); 24804 vkCmdEndRenderPass(m_commandBuffer->handle()); 24805 m_errorMonitor->VerifyNotFound(); 24806 vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 24807 m_errorMonitor->VerifyNotFound(); 24808 vkCmdEndRenderPass(m_commandBuffer->handle()); 24809 m_errorMonitor->VerifyNotFound(); 24810 24811 m_commandBuffer->end(); 24812 m_errorMonitor->VerifyNotFound(); 24813 } 24814 24815 TEST_F(VkPositiveLayerTest, ValidRenderPassAttachmentLayoutWithLoadOp) { 24816 TEST_DESCRIPTION( 24817 "Positive test where we create a renderpass with an attachment that uses LOAD_OP_CLEAR, the first subpass has a valid " 24818 "layout, and a second subpass then uses a valid *READ_ONLY* layout."); 24819 m_errorMonitor->ExpectSuccess(); 24820 ASSERT_NO_FATAL_FAILURE(Init()); 24821 auto depth_format = FindSupportedDepthStencilFormat(gpu()); 24822 if (!depth_format) { 24823 printf(" No Depth + Stencil format found. Skipped.\n"); 24824 return; 24825 } 24826 24827 VkAttachmentReference attach[2] = {}; 24828 attach[0].attachment = 0; 24829 attach[0].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 24830 attach[1].attachment = 0; 24831 attach[1].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; 24832 VkSubpassDescription subpasses[2] = {}; 24833 // First subpass clears DS attach on load 24834 subpasses[0].pDepthStencilAttachment = &attach[0]; 24835 // 2nd subpass reads in DS as input attachment 24836 subpasses[1].inputAttachmentCount = 1; 24837 subpasses[1].pInputAttachments = &attach[1]; 24838 VkAttachmentDescription attach_desc = {}; 24839 attach_desc.format = depth_format; 24840 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; 24841 attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; 24842 attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; 24843 attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 24844 attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 24845 attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 24846 attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; 24847 VkRenderPassCreateInfo rpci = {}; 24848 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 24849 rpci.attachmentCount = 1; 24850 rpci.pAttachments = &attach_desc; 24851 rpci.subpassCount = 2; 24852 rpci.pSubpasses = subpasses; 24853 24854 // Now create RenderPass and verify no errors 24855 VkRenderPass rp; 24856 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 24857 m_errorMonitor->VerifyNotFound(); 24858 24859 vkDestroyRenderPass(m_device->device(), rp, NULL); 24860 } 24861 24862 TEST_F(VkPositiveLayerTest, RenderPassDepthStencilLayoutTransition) { 24863 TEST_DESCRIPTION( 24864 "Create a render pass with depth-stencil attachment where layout transition from UNDEFINED TO DS_READ_ONLY_OPTIMAL is set " 24865 "by render pass and verify that transition has correctly occurred at queue submit time with no validation errors."); 24866 24867 ASSERT_NO_FATAL_FAILURE(Init()); 24868 auto depth_format = FindSupportedDepthStencilFormat(gpu()); 24869 if (!depth_format) { 24870 printf(" No Depth + Stencil format found. Skipped.\n"); 24871 return; 24872 } 24873 VkImageFormatProperties format_props; 24874 vkGetPhysicalDeviceImageFormatProperties(gpu(), depth_format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, 24875 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 0, &format_props); 24876 if (format_props.maxExtent.width < 32 || format_props.maxExtent.height < 32) { 24877 printf("Depth extent too small, RenderPassDepthStencilLayoutTransition skipped.\n"); 24878 return; 24879 } 24880 24881 m_errorMonitor->ExpectSuccess(); 24882 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 24883 24884 // A renderpass with one depth/stencil attachment. 24885 VkAttachmentDescription attachment = {0, 24886 depth_format, 24887 VK_SAMPLE_COUNT_1_BIT, 24888 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 24889 VK_ATTACHMENT_STORE_OP_DONT_CARE, 24890 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 24891 VK_ATTACHMENT_STORE_OP_DONT_CARE, 24892 VK_IMAGE_LAYOUT_UNDEFINED, 24893 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; 24894 24895 VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; 24896 24897 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &att_ref, 0, nullptr}; 24898 24899 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr}; 24900 24901 VkRenderPass rp; 24902 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 24903 ASSERT_VK_SUCCESS(err); 24904 // A compatible ds image. 24905 VkImageObj image(m_device); 24906 image.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 24907 ASSERT_TRUE(image.initialized()); 24908 24909 VkImageViewCreateInfo ivci = { 24910 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 24911 nullptr, 24912 0, 24913 image.handle(), 24914 VK_IMAGE_VIEW_TYPE_2D, 24915 depth_format, 24916 {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, 24917 VK_COMPONENT_SWIZZLE_IDENTITY}, 24918 {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 1, 0, 1}, 24919 }; 24920 VkImageView view; 24921 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view); 24922 ASSERT_VK_SUCCESS(err); 24923 24924 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1}; 24925 VkFramebuffer fb; 24926 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); 24927 ASSERT_VK_SUCCESS(err); 24928 24929 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr}; 24930 m_commandBuffer->begin(); 24931 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); 24932 vkCmdEndRenderPass(m_commandBuffer->handle()); 24933 m_commandBuffer->end(); 24934 m_commandBuffer->QueueCommandBuffer(false); 24935 m_errorMonitor->VerifyNotFound(); 24936 24937 // Cleanup 24938 vkDestroyImageView(m_device->device(), view, NULL); 24939 vkDestroyRenderPass(m_device->device(), rp, NULL); 24940 vkDestroyFramebuffer(m_device->device(), fb, NULL); 24941 } 24942 24943 TEST_F(VkPositiveLayerTest, CreatePipelineAttribMatrixType) { 24944 TEST_DESCRIPTION("Test that pipeline validation accepts matrices passed as vertex attributes"); 24945 m_errorMonitor->ExpectSuccess(); 24946 24947 ASSERT_NO_FATAL_FAILURE(Init()); 24948 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 24949 24950 VkVertexInputBindingDescription input_binding; 24951 memset(&input_binding, 0, sizeof(input_binding)); 24952 24953 VkVertexInputAttributeDescription input_attribs[2]; 24954 memset(input_attribs, 0, sizeof(input_attribs)); 24955 24956 for (int i = 0; i < 2; i++) { 24957 input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT; 24958 input_attribs[i].location = i; 24959 } 24960 24961 char const *vsSource = 24962 "#version 450\n" 24963 "\n" 24964 "layout(location=0) in mat2x4 x;\n" 24965 "void main(){\n" 24966 " gl_Position = x[0] + x[1];\n" 24967 "}\n"; 24968 char const *fsSource = 24969 "#version 450\n" 24970 "\n" 24971 "layout(location=0) out vec4 color;\n" 24972 "void main(){\n" 24973 " color = vec4(1);\n" 24974 "}\n"; 24975 24976 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 24977 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 24978 24979 VkPipelineObj pipe(m_device); 24980 pipe.AddDefaultColorAttachment(); 24981 pipe.AddShader(&vs); 24982 pipe.AddShader(&fs); 24983 24984 pipe.AddVertexInputBindings(&input_binding, 1); 24985 pipe.AddVertexInputAttribs(input_attribs, 2); 24986 24987 VkDescriptorSetObj descriptorSet(m_device); 24988 descriptorSet.AppendDummy(); 24989 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 24990 24991 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 24992 24993 /* expect success */ 24994 m_errorMonitor->VerifyNotFound(); 24995 } 24996 24997 TEST_F(VkPositiveLayerTest, CreatePipelineAttribArrayType) { 24998 m_errorMonitor->ExpectSuccess(); 24999 25000 ASSERT_NO_FATAL_FAILURE(Init()); 25001 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 25002 25003 VkVertexInputBindingDescription input_binding; 25004 memset(&input_binding, 0, sizeof(input_binding)); 25005 25006 VkVertexInputAttributeDescription input_attribs[2]; 25007 memset(input_attribs, 0, sizeof(input_attribs)); 25008 25009 for (int i = 0; i < 2; i++) { 25010 input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT; 25011 input_attribs[i].location = i; 25012 } 25013 25014 char const *vsSource = 25015 "#version 450\n" 25016 "\n" 25017 "layout(location=0) in vec4 x[2];\n" 25018 "void main(){\n" 25019 " gl_Position = x[0] + x[1];\n" 25020 "}\n"; 25021 char const *fsSource = 25022 "#version 450\n" 25023 "\n" 25024 "layout(location=0) out vec4 color;\n" 25025 "void main(){\n" 25026 " color = vec4(1);\n" 25027 "}\n"; 25028 25029 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 25030 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 25031 25032 VkPipelineObj pipe(m_device); 25033 pipe.AddDefaultColorAttachment(); 25034 pipe.AddShader(&vs); 25035 pipe.AddShader(&fs); 25036 25037 pipe.AddVertexInputBindings(&input_binding, 1); 25038 pipe.AddVertexInputAttribs(input_attribs, 2); 25039 25040 VkDescriptorSetObj descriptorSet(m_device); 25041 descriptorSet.AppendDummy(); 25042 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 25043 25044 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 25045 25046 m_errorMonitor->VerifyNotFound(); 25047 } 25048 25049 TEST_F(VkPositiveLayerTest, CreatePipelineAttribComponents) { 25050 TEST_DESCRIPTION( 25051 "Test that pipeline validation accepts consuming a vertex attribute through multiple vertex shader inputs, each consuming " 25052 "a different subset of the components."); 25053 m_errorMonitor->ExpectSuccess(); 25054 25055 ASSERT_NO_FATAL_FAILURE(Init()); 25056 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 25057 25058 VkVertexInputBindingDescription input_binding; 25059 memset(&input_binding, 0, sizeof(input_binding)); 25060 25061 VkVertexInputAttributeDescription input_attribs[3]; 25062 memset(input_attribs, 0, sizeof(input_attribs)); 25063 25064 for (int i = 0; i < 3; i++) { 25065 input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT; 25066 input_attribs[i].location = i; 25067 } 25068 25069 char const *vsSource = 25070 "#version 450\n" 25071 "\n" 25072 "layout(location=0) in vec4 x;\n" 25073 "layout(location=1) in vec3 y1;\n" 25074 "layout(location=1, component=3) in float y2;\n" 25075 "layout(location=2) in vec4 z;\n" 25076 "void main(){\n" 25077 " gl_Position = x + vec4(y1, y2) + z;\n" 25078 "}\n"; 25079 char const *fsSource = 25080 "#version 450\n" 25081 "\n" 25082 "layout(location=0) out vec4 color;\n" 25083 "void main(){\n" 25084 " color = vec4(1);\n" 25085 "}\n"; 25086 25087 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 25088 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 25089 25090 VkPipelineObj pipe(m_device); 25091 pipe.AddDefaultColorAttachment(); 25092 pipe.AddShader(&vs); 25093 pipe.AddShader(&fs); 25094 25095 pipe.AddVertexInputBindings(&input_binding, 1); 25096 pipe.AddVertexInputAttribs(input_attribs, 3); 25097 25098 VkDescriptorSetObj descriptorSet(m_device); 25099 descriptorSet.AppendDummy(); 25100 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 25101 25102 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 25103 25104 m_errorMonitor->VerifyNotFound(); 25105 } 25106 25107 TEST_F(VkPositiveLayerTest, CreatePipelineSimplePositive) { 25108 m_errorMonitor->ExpectSuccess(); 25109 25110 ASSERT_NO_FATAL_FAILURE(Init()); 25111 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 25112 25113 char const *vsSource = 25114 "#version 450\n" 25115 "void main(){\n" 25116 " gl_Position = vec4(0);\n" 25117 "}\n"; 25118 char const *fsSource = 25119 "#version 450\n" 25120 "\n" 25121 "layout(location=0) out vec4 color;\n" 25122 "void main(){\n" 25123 " color = vec4(1);\n" 25124 "}\n"; 25125 25126 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 25127 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 25128 25129 VkPipelineObj pipe(m_device); 25130 pipe.AddDefaultColorAttachment(); 25131 pipe.AddShader(&vs); 25132 pipe.AddShader(&fs); 25133 25134 VkDescriptorSetObj descriptorSet(m_device); 25135 descriptorSet.AppendDummy(); 25136 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 25137 25138 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 25139 25140 m_errorMonitor->VerifyNotFound(); 25141 } 25142 25143 TEST_F(VkPositiveLayerTest, CreatePipelineRelaxedTypeMatch) { 25144 TEST_DESCRIPTION( 25145 "Test that pipeline validation accepts the relaxed type matching rules set out in 14.1.3: fundamental type must match, and " 25146 "producer side must have at least as many components"); 25147 m_errorMonitor->ExpectSuccess(); 25148 25149 // VK 1.0.8 Specification, 14.1.3 "Additionally,..." block 25150 25151 ASSERT_NO_FATAL_FAILURE(Init()); 25152 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 25153 25154 char const *vsSource = 25155 "#version 450\n" 25156 "layout(location=0) out vec3 x;\n" 25157 "layout(location=1) out ivec3 y;\n" 25158 "layout(location=2) out vec3 z;\n" 25159 "void main(){\n" 25160 " gl_Position = vec4(0);\n" 25161 " x = vec3(0); y = ivec3(0); z = vec3(0);\n" 25162 "}\n"; 25163 char const *fsSource = 25164 "#version 450\n" 25165 "\n" 25166 "layout(location=0) out vec4 color;\n" 25167 "layout(location=0) in float x;\n" 25168 "layout(location=1) flat in int y;\n" 25169 "layout(location=2) in vec2 z;\n" 25170 "void main(){\n" 25171 " color = vec4(1 + x + y + z.x);\n" 25172 "}\n"; 25173 25174 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 25175 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 25176 25177 VkPipelineObj pipe(m_device); 25178 pipe.AddDefaultColorAttachment(); 25179 pipe.AddShader(&vs); 25180 pipe.AddShader(&fs); 25181 25182 VkDescriptorSetObj descriptorSet(m_device); 25183 descriptorSet.AppendDummy(); 25184 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 25185 25186 VkResult err = VK_SUCCESS; 25187 err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 25188 ASSERT_VK_SUCCESS(err); 25189 25190 m_errorMonitor->VerifyNotFound(); 25191 } 25192 25193 TEST_F(VkPositiveLayerTest, CreatePipelineTessPerVertex) { 25194 TEST_DESCRIPTION("Test that pipeline validation accepts per-vertex variables passed between the TCS and TES stages"); 25195 m_errorMonitor->ExpectSuccess(); 25196 25197 ASSERT_NO_FATAL_FAILURE(Init()); 25198 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 25199 25200 if (!m_device->phy().features().tessellationShader) { 25201 printf(" Device does not support tessellation shaders; skipped.\n"); 25202 return; 25203 } 25204 25205 char const *vsSource = 25206 "#version 450\n" 25207 "void main(){}\n"; 25208 char const *tcsSource = 25209 "#version 450\n" 25210 "layout(location=0) out int x[];\n" 25211 "layout(vertices=3) out;\n" 25212 "void main(){\n" 25213 " gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n" 25214 " gl_TessLevelInner[0] = 1;\n" 25215 " x[gl_InvocationID] = gl_InvocationID;\n" 25216 "}\n"; 25217 char const *tesSource = 25218 "#version 450\n" 25219 "layout(triangles, equal_spacing, cw) in;\n" 25220 "layout(location=0) in int x[];\n" 25221 "void main(){\n" 25222 " gl_Position.xyz = gl_TessCoord;\n" 25223 " gl_Position.w = x[0] + x[1] + x[2];\n" 25224 "}\n"; 25225 char const *fsSource = 25226 "#version 450\n" 25227 "layout(location=0) out vec4 color;\n" 25228 "void main(){\n" 25229 " color = vec4(1);\n" 25230 "}\n"; 25231 25232 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 25233 VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this); 25234 VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this); 25235 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 25236 25237 VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0, 25238 VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE}; 25239 25240 VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3}; 25241 25242 VkPipelineObj pipe(m_device); 25243 pipe.SetInputAssembly(&iasci); 25244 pipe.SetTessellation(&tsci); 25245 pipe.AddDefaultColorAttachment(); 25246 pipe.AddShader(&vs); 25247 pipe.AddShader(&tcs); 25248 pipe.AddShader(&tes); 25249 pipe.AddShader(&fs); 25250 25251 VkDescriptorSetObj descriptorSet(m_device); 25252 descriptorSet.AppendDummy(); 25253 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 25254 25255 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 25256 25257 m_errorMonitor->VerifyNotFound(); 25258 } 25259 25260 TEST_F(VkPositiveLayerTest, CreatePipelineGeometryInputBlockPositive) { 25261 TEST_DESCRIPTION( 25262 "Test that pipeline validation accepts a user-defined interface block passed into the geometry shader. This is interesting " 25263 "because the 'extra' array level is not present on the member type, but on the block instance."); 25264 m_errorMonitor->ExpectSuccess(); 25265 25266 ASSERT_NO_FATAL_FAILURE(Init()); 25267 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 25268 25269 if (!m_device->phy().features().geometryShader) { 25270 printf(" Device does not support geometry shaders; skipped.\n"); 25271 return; 25272 } 25273 25274 char const *vsSource = 25275 "#version 450\n" 25276 "layout(location=0) out VertexData { vec4 x; } vs_out;\n" 25277 "void main(){\n" 25278 " vs_out.x = vec4(1);\n" 25279 "}\n"; 25280 char const *gsSource = 25281 "#version 450\n" 25282 "layout(triangles) in;\n" 25283 "layout(triangle_strip, max_vertices=3) out;\n" 25284 "layout(location=0) in VertexData { vec4 x; } gs_in[];\n" 25285 "void main() {\n" 25286 " gl_Position = gs_in[0].x;\n" 25287 " EmitVertex();\n" 25288 "}\n"; 25289 char const *fsSource = 25290 "#version 450\n" 25291 "layout(location=0) out vec4 color;\n" 25292 "void main(){\n" 25293 " color = vec4(1);\n" 25294 "}\n"; 25295 25296 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 25297 VkShaderObj gs(m_device, gsSource, VK_SHADER_STAGE_GEOMETRY_BIT, this); 25298 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 25299 25300 VkPipelineObj pipe(m_device); 25301 pipe.AddDefaultColorAttachment(); 25302 pipe.AddShader(&vs); 25303 pipe.AddShader(&gs); 25304 pipe.AddShader(&fs); 25305 25306 VkDescriptorSetObj descriptorSet(m_device); 25307 descriptorSet.AppendDummy(); 25308 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 25309 25310 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 25311 25312 m_errorMonitor->VerifyNotFound(); 25313 } 25314 25315 TEST_F(VkPositiveLayerTest, CreatePipeline64BitAttributesPositive) { 25316 TEST_DESCRIPTION( 25317 "Test that pipeline validation accepts basic use of 64bit vertex attributes. This is interesting because they consume " 25318 "multiple locations."); 25319 m_errorMonitor->ExpectSuccess(); 25320 25321 if (!EnableDeviceProfileLayer()) return; 25322 25323 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 25324 ASSERT_NO_FATAL_FAILURE(InitState()); 25325 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 25326 25327 if (!m_device->phy().features().shaderFloat64) { 25328 printf(" Device does not support 64bit vertex attributes; skipped.\n"); 25329 return; 25330 } 25331 // Set 64bit format to support VTX Buffer feature 25332 PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr; 25333 PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr; 25334 25335 // Load required functions 25336 if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) { 25337 return; 25338 } 25339 VkFormatProperties format_props; 25340 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R64G64B64A64_SFLOAT, &format_props); 25341 format_props.bufferFeatures |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT; 25342 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R64G64B64A64_SFLOAT, format_props); 25343 25344 VkVertexInputBindingDescription input_bindings[1]; 25345 memset(input_bindings, 0, sizeof(input_bindings)); 25346 25347 VkVertexInputAttributeDescription input_attribs[4]; 25348 memset(input_attribs, 0, sizeof(input_attribs)); 25349 input_attribs[0].location = 0; 25350 input_attribs[0].offset = 0; 25351 input_attribs[0].format = VK_FORMAT_R64G64B64A64_SFLOAT; 25352 input_attribs[1].location = 2; 25353 input_attribs[1].offset = 32; 25354 input_attribs[1].format = VK_FORMAT_R64G64B64A64_SFLOAT; 25355 input_attribs[2].location = 4; 25356 input_attribs[2].offset = 64; 25357 input_attribs[2].format = VK_FORMAT_R64G64B64A64_SFLOAT; 25358 input_attribs[3].location = 6; 25359 input_attribs[3].offset = 96; 25360 input_attribs[3].format = VK_FORMAT_R64G64B64A64_SFLOAT; 25361 25362 char const *vsSource = 25363 "#version 450\n" 25364 "\n" 25365 "layout(location=0) in dmat4 x;\n" 25366 "void main(){\n" 25367 " gl_Position = vec4(x[0][0]);\n" 25368 "}\n"; 25369 char const *fsSource = 25370 "#version 450\n" 25371 "\n" 25372 "layout(location=0) out vec4 color;\n" 25373 "void main(){\n" 25374 " color = vec4(1);\n" 25375 "}\n"; 25376 25377 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 25378 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 25379 25380 VkPipelineObj pipe(m_device); 25381 pipe.AddDefaultColorAttachment(); 25382 pipe.AddShader(&vs); 25383 pipe.AddShader(&fs); 25384 25385 pipe.AddVertexInputBindings(input_bindings, 1); 25386 pipe.AddVertexInputAttribs(input_attribs, 4); 25387 25388 VkDescriptorSetObj descriptorSet(m_device); 25389 descriptorSet.AppendDummy(); 25390 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 25391 25392 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 25393 25394 m_errorMonitor->VerifyNotFound(); 25395 } 25396 25397 TEST_F(VkPositiveLayerTest, CreatePipelineInputAttachmentPositive) { 25398 TEST_DESCRIPTION("Positive test for a correctly matched input attachment"); 25399 m_errorMonitor->ExpectSuccess(); 25400 25401 ASSERT_NO_FATAL_FAILURE(Init()); 25402 25403 char const *vsSource = 25404 "#version 450\n" 25405 "\n" 25406 "void main(){\n" 25407 " gl_Position = vec4(1);\n" 25408 "}\n"; 25409 char const *fsSource = 25410 "#version 450\n" 25411 "\n" 25412 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n" 25413 "layout(location=0) out vec4 color;\n" 25414 "void main() {\n" 25415 " color = subpassLoad(x);\n" 25416 "}\n"; 25417 25418 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 25419 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 25420 25421 VkPipelineObj pipe(m_device); 25422 pipe.AddShader(&vs); 25423 pipe.AddShader(&fs); 25424 pipe.AddDefaultColorAttachment(); 25425 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 25426 25427 VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}; 25428 const VkDescriptorSetLayoutObj dsl(m_device, {dslb}); 25429 const VkPipelineLayoutObj pl(m_device, {&dsl}); 25430 25431 VkAttachmentDescription descs[2] = { 25432 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, 25433 VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 25434 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 25435 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, 25436 VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL}, 25437 }; 25438 VkAttachmentReference color = { 25439 0, 25440 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 25441 }; 25442 VkAttachmentReference input = { 25443 1, 25444 VK_IMAGE_LAYOUT_GENERAL, 25445 }; 25446 25447 VkSubpassDescription sd = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr}; 25448 25449 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr}; 25450 VkRenderPass rp; 25451 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 25452 ASSERT_VK_SUCCESS(err); 25453 25454 // should be OK. would go wrong here if it's going to... 25455 pipe.CreateVKPipeline(pl.handle(), rp); 25456 25457 m_errorMonitor->VerifyNotFound(); 25458 25459 vkDestroyRenderPass(m_device->device(), rp, nullptr); 25460 } 25461 25462 TEST_F(VkPositiveLayerTest, CreateComputePipelineMissingDescriptorUnusedPositive) { 25463 TEST_DESCRIPTION( 25464 "Test that pipeline validation accepts a compute pipeline which declares a descriptor-backed resource which is not " 25465 "provided, but the shader does not statically use it. This is interesting because it requires compute pipelines to have a " 25466 "proper descriptor use walk, which they didn't for some time."); 25467 m_errorMonitor->ExpectSuccess(); 25468 25469 ASSERT_NO_FATAL_FAILURE(Init()); 25470 25471 char const *csSource = 25472 "#version 450\n" 25473 "\n" 25474 "layout(local_size_x=1) in;\n" 25475 "layout(set=0, binding=0) buffer block { vec4 x; };\n" 25476 "void main(){\n" 25477 " // x is not used.\n" 25478 "}\n"; 25479 25480 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this); 25481 25482 VkDescriptorSetObj descriptorSet(m_device); 25483 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 25484 25485 VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, 25486 nullptr, 25487 0, 25488 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, 25489 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr}, 25490 descriptorSet.GetPipelineLayout(), 25491 VK_NULL_HANDLE, 25492 -1}; 25493 25494 VkPipeline pipe; 25495 VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe); 25496 25497 m_errorMonitor->VerifyNotFound(); 25498 25499 if (err == VK_SUCCESS) { 25500 vkDestroyPipeline(m_device->device(), pipe, nullptr); 25501 } 25502 } 25503 25504 TEST_F(VkPositiveLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsSampler) { 25505 TEST_DESCRIPTION( 25506 "Test that pipeline validation accepts a shader consuming only the sampler portion of a combined image + sampler"); 25507 m_errorMonitor->ExpectSuccess(); 25508 25509 ASSERT_NO_FATAL_FAILURE(Init()); 25510 25511 std::vector<VkDescriptorSetLayoutBinding> bindings = { 25512 {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}, 25513 {1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}, 25514 {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}, 25515 }; 25516 25517 const VkDescriptorSetLayoutObj dsl(m_device, bindings); 25518 const VkPipelineLayoutObj pl(m_device, {&dsl}); 25519 25520 char const *csSource = 25521 "#version 450\n" 25522 "\n" 25523 "layout(local_size_x=1) in;\n" 25524 "layout(set=0, binding=0) uniform sampler s;\n" 25525 "layout(set=0, binding=1) uniform texture2D t;\n" 25526 "layout(set=0, binding=2) buffer block { vec4 x; };\n" 25527 "void main() {\n" 25528 " x = texture(sampler2D(t, s), vec2(0));\n" 25529 "}\n"; 25530 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this); 25531 25532 VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, 25533 nullptr, 25534 0, 25535 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, 25536 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr}, 25537 pl.handle(), 25538 VK_NULL_HANDLE, 25539 -1}; 25540 25541 VkPipeline pipe; 25542 VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe); 25543 25544 m_errorMonitor->VerifyNotFound(); 25545 25546 if (err == VK_SUCCESS) { 25547 vkDestroyPipeline(m_device->device(), pipe, nullptr); 25548 } 25549 } 25550 25551 TEST_F(VkPositiveLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsImage) { 25552 TEST_DESCRIPTION( 25553 "Test that pipeline validation accepts a shader consuming only the image portion of a combined image + sampler"); 25554 m_errorMonitor->ExpectSuccess(); 25555 25556 ASSERT_NO_FATAL_FAILURE(Init()); 25557 25558 std::vector<VkDescriptorSetLayoutBinding> bindings = { 25559 {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}, 25560 {1, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}, 25561 {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}, 25562 }; 25563 25564 const VkDescriptorSetLayoutObj dsl(m_device, bindings); 25565 const VkPipelineLayoutObj pl(m_device, {&dsl}); 25566 25567 char const *csSource = 25568 "#version 450\n" 25569 "\n" 25570 "layout(local_size_x=1) in;\n" 25571 "layout(set=0, binding=0) uniform texture2D t;\n" 25572 "layout(set=0, binding=1) uniform sampler s;\n" 25573 "layout(set=0, binding=2) buffer block { vec4 x; };\n" 25574 "void main() {\n" 25575 " x = texture(sampler2D(t, s), vec2(0));\n" 25576 "}\n"; 25577 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this); 25578 25579 VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, 25580 nullptr, 25581 0, 25582 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, 25583 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr}, 25584 pl.handle(), 25585 VK_NULL_HANDLE, 25586 -1}; 25587 25588 VkPipeline pipe; 25589 VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe); 25590 25591 m_errorMonitor->VerifyNotFound(); 25592 25593 if (err == VK_SUCCESS) { 25594 vkDestroyPipeline(m_device->device(), pipe, nullptr); 25595 } 25596 } 25597 25598 TEST_F(VkPositiveLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsBoth) { 25599 TEST_DESCRIPTION( 25600 "Test that pipeline validation accepts a shader consuming both the sampler and the image of a combined image+sampler but " 25601 "via separate variables"); 25602 m_errorMonitor->ExpectSuccess(); 25603 25604 ASSERT_NO_FATAL_FAILURE(Init()); 25605 25606 std::vector<VkDescriptorSetLayoutBinding> bindings = { 25607 {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}, 25608 {1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}, 25609 }; 25610 25611 const VkDescriptorSetLayoutObj dsl(m_device, bindings); 25612 const VkPipelineLayoutObj pl(m_device, {&dsl}); 25613 25614 char const *csSource = 25615 "#version 450\n" 25616 "\n" 25617 "layout(local_size_x=1) in;\n" 25618 "layout(set=0, binding=0) uniform texture2D t;\n" 25619 "layout(set=0, binding=0) uniform sampler s; // both binding 0!\n" 25620 "layout(set=0, binding=1) buffer block { vec4 x; };\n" 25621 "void main() {\n" 25622 " x = texture(sampler2D(t, s), vec2(0));\n" 25623 "}\n"; 25624 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this); 25625 25626 VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, 25627 nullptr, 25628 0, 25629 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, 25630 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr}, 25631 pl.handle(), 25632 VK_NULL_HANDLE, 25633 -1}; 25634 25635 VkPipeline pipe; 25636 VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe); 25637 25638 m_errorMonitor->VerifyNotFound(); 25639 25640 if (err == VK_SUCCESS) { 25641 vkDestroyPipeline(m_device->device(), pipe, nullptr); 25642 } 25643 } 25644 25645 TEST_F(VkPositiveLayerTest, CreateDescriptorSetBindingWithIgnoredSamplers) { 25646 TEST_DESCRIPTION("Test that layers conditionally do ignore the pImmutableSamplers on vkCreateDescriptorSetLayout"); 25647 25648 bool prop2_found = false; 25649 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { 25650 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 25651 prop2_found = true; 25652 } else { 25653 printf(" %s Extension not supported, skipping push descriptor sub-tests\n", 25654 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 25655 } 25656 25657 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 25658 bool push_descriptor_found = false; 25659 if (prop2_found && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) { 25660 m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); 25661 push_descriptor_found = true; 25662 } else { 25663 printf(" %s Extension not supported, skipping push descriptor sub-tests\n", 25664 VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); 25665 } 25666 25667 ASSERT_NO_FATAL_FAILURE(InitState()); 25668 const uint64_t fake_address_64 = 0xCDCDCDCDCDCDCDCD; 25669 const uint64_t fake_address_32 = 0xCDCDCDCD; 25670 const void *fake_pointer = 25671 sizeof(void *) == 8 ? reinterpret_cast<void *>(fake_address_64) : reinterpret_cast<void *>(fake_address_32); 25672 const VkSampler *hopefully_undereferencable_pointer = reinterpret_cast<const VkSampler *>(fake_pointer); 25673 25674 // regular descriptors 25675 m_errorMonitor->ExpectSuccess(); 25676 { 25677 const VkDescriptorSetLayoutBinding non_sampler_bindings[] = { 25678 {0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer}, 25679 {1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer}, 25680 {2, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer}, 25681 {3, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer}, 25682 {4, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer}, 25683 {5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer}, 25684 {6, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer}, 25685 {7, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer}, 25686 {8, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer}, 25687 }; 25688 const VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 25689 static_cast<uint32_t>(size(non_sampler_bindings)), non_sampler_bindings}; 25690 VkDescriptorSetLayout dsl; 25691 const VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl); 25692 ASSERT_VK_SUCCESS(err); 25693 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr); 25694 } 25695 m_errorMonitor->VerifyNotFound(); 25696 25697 if (push_descriptor_found) { 25698 // push descriptors 25699 m_errorMonitor->ExpectSuccess(); 25700 { 25701 const VkDescriptorSetLayoutBinding non_sampler_bindings[] = { 25702 {0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer}, 25703 {1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer}, 25704 {2, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer}, 25705 {3, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer}, 25706 {4, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer}, 25707 {5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer}, 25708 {6, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer}, 25709 }; 25710 const VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 25711 VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, 25712 static_cast<uint32_t>(size(non_sampler_bindings)), non_sampler_bindings}; 25713 VkDescriptorSetLayout dsl; 25714 const VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl); 25715 ASSERT_VK_SUCCESS(err); 25716 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr); 25717 } 25718 m_errorMonitor->VerifyNotFound(); 25719 } 25720 } 25721 25722 TEST_F(VkPositiveLayerTest, Maintenance1Tests) { 25723 TEST_DESCRIPTION("Validate various special cases for the Maintenance1_KHR extension"); 25724 25725 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 25726 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) { 25727 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME); 25728 } else { 25729 printf(" Maintenance1 Extension not supported, skipping tests\n"); 25730 return; 25731 } 25732 ASSERT_NO_FATAL_FAILURE(InitState()); 25733 25734 m_errorMonitor->ExpectSuccess(); 25735 25736 VkCommandBufferObj cmd_buf(m_device, m_commandPool); 25737 cmd_buf.begin(); 25738 // Set Negative height, should give error if Maintenance 1 is not enabled 25739 VkViewport viewport = {0, 0, 16, -16, 0, 1}; 25740 vkCmdSetViewport(cmd_buf.handle(), 0, 1, &viewport); 25741 cmd_buf.end(); 25742 25743 m_errorMonitor->VerifyNotFound(); 25744 } 25745 25746 TEST_F(VkLayerTest, DuplicateValidPNextStructures) { 25747 TEST_DESCRIPTION("Create a pNext chain containing valid strutures, but with a duplicate structure type"); 25748 25749 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 25750 if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME)) { 25751 m_device_extension_names.push_back(VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME); 25752 } else { 25753 printf(" VK_NV_dedicated_allocation extension not supported, skipping test\n"); 25754 return; 25755 } 25756 ASSERT_NO_FATAL_FAILURE(InitState()); 25757 25758 // Create two pNext structures which by themselves would be valid 25759 VkDedicatedAllocationBufferCreateInfoNV dedicated_buffer_create_info = {}; 25760 VkDedicatedAllocationBufferCreateInfoNV dedicated_buffer_create_info_2 = {}; 25761 dedicated_buffer_create_info.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV; 25762 dedicated_buffer_create_info.pNext = &dedicated_buffer_create_info_2; 25763 dedicated_buffer_create_info.dedicatedAllocation = VK_TRUE; 25764 25765 dedicated_buffer_create_info_2.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV; 25766 dedicated_buffer_create_info_2.pNext = nullptr; 25767 dedicated_buffer_create_info_2.dedicatedAllocation = VK_TRUE; 25768 25769 uint32_t queue_family_index = 0; 25770 VkBufferCreateInfo buffer_create_info = {}; 25771 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 25772 buffer_create_info.pNext = &dedicated_buffer_create_info; 25773 buffer_create_info.size = 1024; 25774 buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 25775 buffer_create_info.queueFamilyIndexCount = 1; 25776 buffer_create_info.pQueueFamilyIndices = &queue_family_index; 25777 25778 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "chain contains duplicate structure types"); 25779 VkBuffer buffer; 25780 vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer); 25781 m_errorMonitor->VerifyFound(); 25782 } 25783 25784 TEST_F(VkPositiveLayerTest, ValidStructPNext) { 25785 TEST_DESCRIPTION("Verify that a valid pNext value is handled correctly"); 25786 25787 // Positive test to check parameter_validation and unique_objects support for NV_dedicated_allocation 25788 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 25789 if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME)) { 25790 m_device_extension_names.push_back(VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME); 25791 } else { 25792 printf(" VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME Extension not supported, skipping test\n"); 25793 return; 25794 } 25795 ASSERT_NO_FATAL_FAILURE(InitState()); 25796 25797 m_errorMonitor->ExpectSuccess(); 25798 25799 VkDedicatedAllocationBufferCreateInfoNV dedicated_buffer_create_info = {}; 25800 dedicated_buffer_create_info.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV; 25801 dedicated_buffer_create_info.pNext = nullptr; 25802 dedicated_buffer_create_info.dedicatedAllocation = VK_TRUE; 25803 25804 uint32_t queue_family_index = 0; 25805 VkBufferCreateInfo buffer_create_info = {}; 25806 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 25807 buffer_create_info.pNext = &dedicated_buffer_create_info; 25808 buffer_create_info.size = 1024; 25809 buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 25810 buffer_create_info.queueFamilyIndexCount = 1; 25811 buffer_create_info.pQueueFamilyIndices = &queue_family_index; 25812 25813 VkBuffer buffer; 25814 VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer); 25815 ASSERT_VK_SUCCESS(err); 25816 25817 VkMemoryRequirements memory_reqs; 25818 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs); 25819 25820 VkDedicatedAllocationMemoryAllocateInfoNV dedicated_memory_info = {}; 25821 dedicated_memory_info.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV; 25822 dedicated_memory_info.pNext = nullptr; 25823 dedicated_memory_info.buffer = buffer; 25824 dedicated_memory_info.image = VK_NULL_HANDLE; 25825 25826 VkMemoryAllocateInfo memory_info = {}; 25827 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 25828 memory_info.pNext = &dedicated_memory_info; 25829 memory_info.allocationSize = memory_reqs.size; 25830 25831 bool pass; 25832 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 25833 ASSERT_TRUE(pass); 25834 25835 VkDeviceMemory buffer_memory; 25836 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory); 25837 ASSERT_VK_SUCCESS(err); 25838 25839 err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0); 25840 ASSERT_VK_SUCCESS(err); 25841 25842 vkDestroyBuffer(m_device->device(), buffer, NULL); 25843 vkFreeMemory(m_device->device(), buffer_memory, NULL); 25844 25845 m_errorMonitor->VerifyNotFound(); 25846 } 25847 25848 TEST_F(VkPositiveLayerTest, PSOPolygonModeValid) { 25849 TEST_DESCRIPTION("Verify that using a solid polygon fill mode works correctly."); 25850 25851 ASSERT_NO_FATAL_FAILURE(Init()); 25852 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 25853 25854 std::vector<const char *> device_extension_names; 25855 auto features = m_device->phy().features(); 25856 // Artificially disable support for non-solid fill modes 25857 features.fillModeNonSolid = false; 25858 // The sacrificial device object 25859 VkDeviceObj test_device(0, gpu(), device_extension_names, &features); 25860 25861 VkRenderpassObj render_pass(&test_device); 25862 25863 const VkPipelineLayoutObj pipeline_layout(&test_device); 25864 25865 VkPipelineRasterizationStateCreateInfo rs_ci = {}; 25866 rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 25867 rs_ci.pNext = nullptr; 25868 rs_ci.lineWidth = 1.0f; 25869 rs_ci.rasterizerDiscardEnable = true; 25870 25871 VkShaderObj vs(&test_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 25872 VkShaderObj fs(&test_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 25873 25874 // Set polygonMode=FILL. No error is expected 25875 m_errorMonitor->ExpectSuccess(); 25876 { 25877 VkPipelineObj pipe(&test_device); 25878 pipe.AddShader(&vs); 25879 pipe.AddShader(&fs); 25880 pipe.AddDefaultColorAttachment(); 25881 // Set polygonMode to a good value 25882 rs_ci.polygonMode = VK_POLYGON_MODE_FILL; 25883 pipe.SetRasterization(&rs_ci); 25884 pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle()); 25885 } 25886 m_errorMonitor->VerifyNotFound(); 25887 } 25888 25889 TEST_F(VkPositiveLayerTest, LongSemaphoreChain) { 25890 m_errorMonitor->ExpectSuccess(); 25891 25892 ASSERT_NO_FATAL_FAILURE(Init()); 25893 VkResult err; 25894 25895 std::vector<VkSemaphore> semaphores; 25896 25897 const int chainLength = 32768; 25898 VkPipelineStageFlags flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; 25899 25900 for (int i = 0; i < chainLength; i++) { 25901 VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0}; 25902 VkSemaphore semaphore; 25903 err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &semaphore); 25904 ASSERT_VK_SUCCESS(err); 25905 25906 semaphores.push_back(semaphore); 25907 25908 VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, 25909 nullptr, 25910 semaphores.size() > 1 ? 1u : 0u, 25911 semaphores.size() > 1 ? &semaphores[semaphores.size() - 2] : nullptr, 25912 &flags, 25913 0, 25914 nullptr, 25915 1, 25916 &semaphores[semaphores.size() - 1]}; 25917 err = vkQueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE); 25918 ASSERT_VK_SUCCESS(err); 25919 } 25920 25921 VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0}; 25922 VkFence fence; 25923 err = vkCreateFence(m_device->device(), &fci, nullptr, &fence); 25924 ASSERT_VK_SUCCESS(err); 25925 VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &semaphores.back(), &flags, 0, nullptr, 0, nullptr}; 25926 err = vkQueueSubmit(m_device->m_queue, 1, &si, fence); 25927 ASSERT_VK_SUCCESS(err); 25928 25929 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX); 25930 25931 for (auto semaphore : semaphores) vkDestroySemaphore(m_device->device(), semaphore, nullptr); 25932 25933 vkDestroyFence(m_device->device(), fence, nullptr); 25934 25935 m_errorMonitor->VerifyNotFound(); 25936 } 25937 25938 TEST_F(VkPositiveLayerTest, ExternalSemaphore) { 25939 #ifdef _WIN32 25940 const auto extension_name = VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME; 25941 const auto handle_type = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR; 25942 #else 25943 const auto extension_name = VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME; 25944 const auto handle_type = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR; 25945 #endif 25946 // Check for external semaphore instance extensions 25947 if (InstanceExtensionSupported(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME)) { 25948 m_instance_extension_names.push_back(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME); 25949 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 25950 } else { 25951 printf(" External semaphore extension not supported, skipping test\n"); 25952 return; 25953 } 25954 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 25955 25956 // Check for external semaphore device extensions 25957 if (DeviceExtensionSupported(gpu(), nullptr, extension_name)) { 25958 m_device_extension_names.push_back(extension_name); 25959 m_device_extension_names.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME); 25960 } else { 25961 printf(" External semaphore extension not supported, skipping test\n"); 25962 return; 25963 } 25964 ASSERT_NO_FATAL_FAILURE(InitState()); 25965 25966 // Check for external semaphore import and export capability 25967 VkPhysicalDeviceExternalSemaphoreInfoKHR esi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR, nullptr, 25968 handle_type}; 25969 VkExternalSemaphorePropertiesKHR esp = {VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR, nullptr}; 25970 auto vkGetPhysicalDeviceExternalSemaphorePropertiesKHR = 25971 (PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)vkGetInstanceProcAddr( 25972 instance(), "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR"); 25973 vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(gpu(), &esi, &esp); 25974 25975 if (!(esp.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR) || 25976 !(esp.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR)) { 25977 printf(" External semaphore does not support importing and exporting, skipping test\n"); 25978 return; 25979 } 25980 25981 VkResult err; 25982 m_errorMonitor->ExpectSuccess(); 25983 25984 // Create a semaphore to export payload from 25985 VkExportSemaphoreCreateInfoKHR esci = {VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR, nullptr, handle_type}; 25986 VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &esci, 0}; 25987 25988 VkSemaphore export_semaphore; 25989 err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &export_semaphore); 25990 ASSERT_VK_SUCCESS(err); 25991 25992 // Create a semaphore to import payload into 25993 sci.pNext = nullptr; 25994 VkSemaphore import_semaphore; 25995 err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &import_semaphore); 25996 ASSERT_VK_SUCCESS(err); 25997 25998 #ifdef _WIN32 25999 // Export semaphore payload to an opaque handle 26000 HANDLE handle = nullptr; 26001 VkSemaphoreGetWin32HandleInfoKHR ghi = {VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR, nullptr, export_semaphore, 26002 handle_type}; 26003 auto vkGetSemaphoreWin32HandleKHR = 26004 (PFN_vkGetSemaphoreWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetSemaphoreWin32HandleKHR"); 26005 err = vkGetSemaphoreWin32HandleKHR(m_device->device(), &ghi, &handle); 26006 ASSERT_VK_SUCCESS(err); 26007 26008 // Import opaque handle exported above 26009 VkImportSemaphoreWin32HandleInfoKHR ihi = { 26010 VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR, nullptr, import_semaphore, 0, handle_type, handle, nullptr}; 26011 auto vkImportSemaphoreWin32HandleKHR = 26012 (PFN_vkImportSemaphoreWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportSemaphoreWin32HandleKHR"); 26013 err = vkImportSemaphoreWin32HandleKHR(m_device->device(), &ihi); 26014 ASSERT_VK_SUCCESS(err); 26015 #else 26016 // Export semaphore payload to an opaque handle 26017 int fd = 0; 26018 VkSemaphoreGetFdInfoKHR ghi = {VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR, nullptr, export_semaphore, handle_type}; 26019 auto vkGetSemaphoreFdKHR = (PFN_vkGetSemaphoreFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetSemaphoreFdKHR"); 26020 err = vkGetSemaphoreFdKHR(m_device->device(), &ghi, &fd); 26021 ASSERT_VK_SUCCESS(err); 26022 26023 // Import opaque handle exported above 26024 VkImportSemaphoreFdInfoKHR ihi = { 26025 VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR, nullptr, import_semaphore, 0, handle_type, fd}; 26026 auto vkImportSemaphoreFdKHR = (PFN_vkImportSemaphoreFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportSemaphoreFdKHR"); 26027 err = vkImportSemaphoreFdKHR(m_device->device(), &ihi); 26028 ASSERT_VK_SUCCESS(err); 26029 #endif 26030 26031 // Signal the exported semaphore and wait on the imported semaphore 26032 VkPipelineStageFlags flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; 26033 VkSubmitInfo si[] = { 26034 {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, &flags, 0, nullptr, 1, &export_semaphore}, 26035 {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &import_semaphore, &flags, 0, nullptr, 0, nullptr}, 26036 {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, &flags, 0, nullptr, 1, &export_semaphore}, 26037 {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &import_semaphore, &flags, 0, nullptr, 0, nullptr}, 26038 }; 26039 err = vkQueueSubmit(m_device->m_queue, 4, si, VK_NULL_HANDLE); 26040 ASSERT_VK_SUCCESS(err); 26041 26042 if (m_device->phy().features().sparseBinding) { 26043 // Signal the imported semaphore and wait on the exported semaphore 26044 VkBindSparseInfo bi[] = { 26045 {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 1, &import_semaphore}, 26046 {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 1, &export_semaphore, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr}, 26047 {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 1, &import_semaphore}, 26048 {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 1, &export_semaphore, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr}, 26049 }; 26050 err = vkQueueBindSparse(m_device->m_queue, 4, bi, VK_NULL_HANDLE); 26051 ASSERT_VK_SUCCESS(err); 26052 } 26053 26054 // Cleanup 26055 err = vkQueueWaitIdle(m_device->m_queue); 26056 ASSERT_VK_SUCCESS(err); 26057 vkDestroySemaphore(m_device->device(), export_semaphore, nullptr); 26058 vkDestroySemaphore(m_device->device(), import_semaphore, nullptr); 26059 26060 m_errorMonitor->VerifyNotFound(); 26061 } 26062 26063 TEST_F(VkPositiveLayerTest, ExternalFence) { 26064 #ifdef _WIN32 26065 const auto extension_name = VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME; 26066 const auto handle_type = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR; 26067 #else 26068 const auto extension_name = VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME; 26069 const auto handle_type = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR; 26070 #endif 26071 // Check for external fence instance extensions 26072 if (InstanceExtensionSupported(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME)) { 26073 m_instance_extension_names.push_back(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME); 26074 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 26075 } else { 26076 printf(" External fence extension not supported, skipping test\n"); 26077 return; 26078 } 26079 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 26080 26081 // Check for external fence device extensions 26082 if (DeviceExtensionSupported(gpu(), nullptr, extension_name)) { 26083 m_device_extension_names.push_back(extension_name); 26084 m_device_extension_names.push_back(VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME); 26085 } else { 26086 printf(" External fence extension not supported, skipping test\n"); 26087 return; 26088 } 26089 ASSERT_NO_FATAL_FAILURE(InitState()); 26090 26091 // Check for external fence import and export capability 26092 VkPhysicalDeviceExternalFenceInfoKHR efi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR, nullptr, handle_type}; 26093 VkExternalFencePropertiesKHR efp = {VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR, nullptr}; 26094 auto vkGetPhysicalDeviceExternalFencePropertiesKHR = (PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR)vkGetInstanceProcAddr( 26095 instance(), "vkGetPhysicalDeviceExternalFencePropertiesKHR"); 26096 vkGetPhysicalDeviceExternalFencePropertiesKHR(gpu(), &efi, &efp); 26097 26098 if (!(efp.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR) || 26099 !(efp.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR)) { 26100 printf(" External fence does not support importing and exporting, skipping test\n"); 26101 return; 26102 } 26103 26104 VkResult err; 26105 m_errorMonitor->ExpectSuccess(); 26106 26107 // Create a fence to export payload from 26108 VkFence export_fence; 26109 { 26110 VkExportFenceCreateInfoKHR efci = {VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR, nullptr, handle_type}; 26111 VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, &efci, 0}; 26112 err = vkCreateFence(m_device->device(), &fci, nullptr, &export_fence); 26113 ASSERT_VK_SUCCESS(err); 26114 } 26115 26116 // Create a fence to import payload into 26117 VkFence import_fence; 26118 { 26119 VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0}; 26120 err = vkCreateFence(m_device->device(), &fci, nullptr, &import_fence); 26121 ASSERT_VK_SUCCESS(err); 26122 } 26123 26124 #ifdef _WIN32 26125 // Export fence payload to an opaque handle 26126 HANDLE handle = nullptr; 26127 { 26128 VkFenceGetWin32HandleInfoKHR ghi = {VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR, nullptr, export_fence, handle_type}; 26129 auto vkGetFenceWin32HandleKHR = 26130 (PFN_vkGetFenceWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetFenceWin32HandleKHR"); 26131 err = vkGetFenceWin32HandleKHR(m_device->device(), &ghi, &handle); 26132 ASSERT_VK_SUCCESS(err); 26133 } 26134 26135 // Import opaque handle exported above 26136 { 26137 VkImportFenceWin32HandleInfoKHR ifi = { 26138 VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR, nullptr, import_fence, 0, handle_type, handle, nullptr}; 26139 auto vkImportFenceWin32HandleKHR = 26140 (PFN_vkImportFenceWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportFenceWin32HandleKHR"); 26141 err = vkImportFenceWin32HandleKHR(m_device->device(), &ifi); 26142 ASSERT_VK_SUCCESS(err); 26143 } 26144 #else 26145 // Export fence payload to an opaque handle 26146 int fd = 0; 26147 { 26148 VkFenceGetFdInfoKHR gfi = {VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR, nullptr, export_fence, handle_type}; 26149 auto vkGetFenceFdKHR = (PFN_vkGetFenceFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetFenceFdKHR"); 26150 err = vkGetFenceFdKHR(m_device->device(), &gfi, &fd); 26151 ASSERT_VK_SUCCESS(err); 26152 } 26153 26154 // Import opaque handle exported above 26155 { 26156 VkImportFenceFdInfoKHR ifi = {VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR, nullptr, import_fence, 0, handle_type, fd}; 26157 auto vkImportFenceFdKHR = (PFN_vkImportFenceFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportFenceFdKHR"); 26158 err = vkImportFenceFdKHR(m_device->device(), &ifi); 26159 ASSERT_VK_SUCCESS(err); 26160 } 26161 #endif 26162 26163 // Signal the exported fence and wait on the imported fence 26164 vkQueueSubmit(m_device->m_queue, 0, nullptr, export_fence); 26165 vkWaitForFences(m_device->device(), 1, &import_fence, VK_TRUE, 1000000000); 26166 vkResetFences(m_device->device(), 1, &import_fence); 26167 vkQueueSubmit(m_device->m_queue, 0, nullptr, export_fence); 26168 vkWaitForFences(m_device->device(), 1, &import_fence, VK_TRUE, 1000000000); 26169 vkResetFences(m_device->device(), 1, &import_fence); 26170 26171 // Signal the imported fence and wait on the exported fence 26172 vkQueueSubmit(m_device->m_queue, 0, nullptr, import_fence); 26173 vkWaitForFences(m_device->device(), 1, &export_fence, VK_TRUE, 1000000000); 26174 vkResetFences(m_device->device(), 1, &export_fence); 26175 vkQueueSubmit(m_device->m_queue, 0, nullptr, import_fence); 26176 vkWaitForFences(m_device->device(), 1, &export_fence, VK_TRUE, 1000000000); 26177 vkResetFences(m_device->device(), 1, &export_fence); 26178 26179 // Cleanup 26180 err = vkQueueWaitIdle(m_device->m_queue); 26181 ASSERT_VK_SUCCESS(err); 26182 vkDestroyFence(m_device->device(), export_fence, nullptr); 26183 vkDestroyFence(m_device->device(), import_fence, nullptr); 26184 26185 m_errorMonitor->VerifyNotFound(); 26186 } 26187 26188 extern "C" void *ReleaseNullFence(void *arg) { 26189 struct thread_data_struct *data = (struct thread_data_struct *)arg; 26190 26191 for (int i = 0; i < 40000; i++) { 26192 vkDestroyFence(data->device, VK_NULL_HANDLE, NULL); 26193 if (data->bailout) { 26194 break; 26195 } 26196 } 26197 return NULL; 26198 } 26199 26200 TEST_F(VkPositiveLayerTest, ThreadNullFenceCollision) { 26201 test_platform_thread thread; 26202 26203 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "THREADING ERROR"); 26204 26205 ASSERT_NO_FATAL_FAILURE(Init()); 26206 26207 struct thread_data_struct data; 26208 data.device = m_device->device(); 26209 data.bailout = false; 26210 m_errorMonitor->SetBailout(&data.bailout); 26211 26212 // Call vkDestroyFence of VK_NULL_HANDLE repeatedly using multiple threads. 26213 // There should be no validation error from collision of that non-object. 26214 test_platform_thread_create(&thread, ReleaseNullFence, (void *)&data); 26215 for (int i = 0; i < 40000; i++) { 26216 vkDestroyFence(m_device->device(), VK_NULL_HANDLE, NULL); 26217 } 26218 test_platform_thread_join(thread, NULL); 26219 26220 m_errorMonitor->SetBailout(NULL); 26221 26222 m_errorMonitor->VerifyNotFound(); 26223 } 26224 26225 TEST_F(VkPositiveLayerTest, ClearColorImageWithValidRange) { 26226 TEST_DESCRIPTION("Record clear color with a valid VkImageSubresourceRange"); 26227 26228 ASSERT_NO_FATAL_FAILURE(Init()); 26229 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 26230 26231 VkImageObj image(m_device); 26232 image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL); 26233 ASSERT_TRUE(image.create_info().arrayLayers == 1); 26234 ASSERT_TRUE(image.initialized()); 26235 image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); 26236 26237 const VkClearColorValue clear_color = {{0.0f, 0.0f, 0.0f, 1.0f}}; 26238 26239 m_commandBuffer->begin(); 26240 const auto cb_handle = m_commandBuffer->handle(); 26241 26242 // Try good case 26243 { 26244 m_errorMonitor->ExpectSuccess(); 26245 VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; 26246 vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range); 26247 m_errorMonitor->VerifyNotFound(); 26248 } 26249 26250 // Try good case with VK_REMAINING 26251 { 26252 m_errorMonitor->ExpectSuccess(); 26253 VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS}; 26254 vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range); 26255 m_errorMonitor->VerifyNotFound(); 26256 } 26257 } 26258 26259 TEST_F(VkPositiveLayerTest, ClearDepthStencilWithValidRange) { 26260 TEST_DESCRIPTION("Record clear depth with a valid VkImageSubresourceRange"); 26261 26262 ASSERT_NO_FATAL_FAILURE(Init()); 26263 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 26264 26265 auto depth_format = FindSupportedDepthStencilFormat(gpu()); 26266 if (!depth_format) { 26267 printf(" No Depth + Stencil format found. Skipped.\n"); 26268 return; 26269 } 26270 26271 VkImageObj image(m_device); 26272 image.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL); 26273 ASSERT_TRUE(image.create_info().arrayLayers == 1); 26274 ASSERT_TRUE(image.initialized()); 26275 const VkImageAspectFlags ds_aspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 26276 image.SetLayout(ds_aspect, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); 26277 26278 const VkClearDepthStencilValue clear_value = {}; 26279 26280 m_commandBuffer->begin(); 26281 const auto cb_handle = m_commandBuffer->handle(); 26282 26283 // Try good case 26284 { 26285 m_errorMonitor->ExpectSuccess(); 26286 VkImageSubresourceRange range = {ds_aspect, 0, 1, 0, 1}; 26287 vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range); 26288 m_errorMonitor->VerifyNotFound(); 26289 } 26290 26291 // Try good case with VK_REMAINING 26292 { 26293 m_errorMonitor->ExpectSuccess(); 26294 VkImageSubresourceRange range = {ds_aspect, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS}; 26295 vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range); 26296 m_errorMonitor->VerifyNotFound(); 26297 } 26298 } 26299 26300 TEST_F(VkPositiveLayerTest, CreateGraphicsPipelineWithIgnoredPointers) { 26301 TEST_DESCRIPTION("Create Graphics Pipeline with pointers that must be ignored by layers"); 26302 26303 ASSERT_NO_FATAL_FAILURE(Init()); 26304 26305 m_depth_stencil_fmt = FindSupportedDepthStencilFormat(gpu()); 26306 ASSERT_TRUE(m_depth_stencil_fmt != 0); 26307 26308 m_depthStencil->Init(m_device, static_cast<int32_t>(m_width), static_cast<int32_t>(m_height), m_depth_stencil_fmt); 26309 26310 ASSERT_NO_FATAL_FAILURE(InitRenderTarget(m_depthStencil->BindInfo())); 26311 26312 const uint64_t fake_address_64 = 0xCDCDCDCDCDCDCDCD; 26313 const uint64_t fake_address_32 = 0xCDCDCDCD; 26314 void *hopefully_undereferencable_pointer = 26315 sizeof(void *) == 8 ? reinterpret_cast<void *>(fake_address_64) : reinterpret_cast<void *>(fake_address_32); 26316 26317 VkShaderObj vs(m_device, "#version 450\nvoid main(){gl_Position = vec4(0.0, 0.0, 0.0, 1.0);}\n", VK_SHADER_STAGE_VERTEX_BIT, 26318 this); 26319 26320 const VkPipelineVertexInputStateCreateInfo pipeline_vertex_input_state_create_info{ 26321 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, 26322 nullptr, // pNext 26323 0, // flags 26324 0, 26325 nullptr, // bindings 26326 0, 26327 nullptr // attributes 26328 }; 26329 26330 const VkPipelineInputAssemblyStateCreateInfo pipeline_input_assembly_state_create_info{ 26331 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, 26332 nullptr, // pNext 26333 0, // flags 26334 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 26335 VK_FALSE // primitive restart 26336 }; 26337 26338 const VkPipelineRasterizationStateCreateInfo pipeline_rasterization_state_create_info_template{ 26339 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, 26340 nullptr, // pNext 26341 0, // flags 26342 VK_FALSE, // depthClamp 26343 VK_FALSE, // rasterizerDiscardEnable 26344 VK_POLYGON_MODE_FILL, 26345 VK_CULL_MODE_NONE, 26346 VK_FRONT_FACE_COUNTER_CLOCKWISE, 26347 VK_FALSE, // depthBias 26348 0.0f, 26349 0.0f, 26350 0.0f, // depthBias params 26351 1.0f // lineWidth 26352 }; 26353 26354 VkPipelineLayout pipeline_layout; 26355 { 26356 VkPipelineLayoutCreateInfo pipeline_layout_create_info{ 26357 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, 26358 nullptr, // pNext 26359 0, // flags 26360 0, 26361 nullptr, // layouts 26362 0, 26363 nullptr // push constants 26364 }; 26365 26366 VkResult err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_create_info, nullptr, &pipeline_layout); 26367 ASSERT_VK_SUCCESS(err); 26368 } 26369 26370 // try disabled rasterizer and no tessellation 26371 { 26372 m_errorMonitor->ExpectSuccess(); 26373 26374 VkPipelineRasterizationStateCreateInfo pipeline_rasterization_state_create_info = 26375 pipeline_rasterization_state_create_info_template; 26376 pipeline_rasterization_state_create_info.rasterizerDiscardEnable = VK_TRUE; 26377 26378 VkGraphicsPipelineCreateInfo graphics_pipeline_create_info{ 26379 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, 26380 nullptr, // pNext 26381 0, // flags 26382 1, // stageCount 26383 &vs.GetStageCreateInfo(), 26384 &pipeline_vertex_input_state_create_info, 26385 &pipeline_input_assembly_state_create_info, 26386 reinterpret_cast<const VkPipelineTessellationStateCreateInfo *>(hopefully_undereferencable_pointer), 26387 reinterpret_cast<const VkPipelineViewportStateCreateInfo *>(hopefully_undereferencable_pointer), 26388 &pipeline_rasterization_state_create_info, 26389 reinterpret_cast<const VkPipelineMultisampleStateCreateInfo *>(hopefully_undereferencable_pointer), 26390 reinterpret_cast<const VkPipelineDepthStencilStateCreateInfo *>(hopefully_undereferencable_pointer), 26391 reinterpret_cast<const VkPipelineColorBlendStateCreateInfo *>(hopefully_undereferencable_pointer), 26392 nullptr, // dynamic states 26393 pipeline_layout, 26394 m_renderPass, 26395 0, // subpass 26396 VK_NULL_HANDLE, 26397 0}; 26398 26399 VkPipeline pipeline; 26400 vkCreateGraphicsPipelines(m_device->handle(), VK_NULL_HANDLE, 1, &graphics_pipeline_create_info, nullptr, &pipeline); 26401 26402 m_errorMonitor->VerifyNotFound(); 26403 26404 vkDestroyPipeline(m_device->handle(), pipeline, nullptr); 26405 } 26406 26407 const VkPipelineMultisampleStateCreateInfo pipeline_multisample_state_create_info{ 26408 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, 26409 nullptr, // pNext 26410 0, // flags 26411 VK_SAMPLE_COUNT_1_BIT, 26412 VK_FALSE, // sample shading 26413 0.0f, // minSampleShading 26414 nullptr, // pSampleMask 26415 VK_FALSE, // alphaToCoverageEnable 26416 VK_FALSE // alphaToOneEnable 26417 }; 26418 26419 // try enabled rasterizer but no subpass attachments 26420 { 26421 m_errorMonitor->ExpectSuccess(); 26422 26423 VkPipelineRasterizationStateCreateInfo pipeline_rasterization_state_create_info = 26424 pipeline_rasterization_state_create_info_template; 26425 pipeline_rasterization_state_create_info.rasterizerDiscardEnable = VK_FALSE; 26426 26427 VkViewport viewport = {0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f}; 26428 VkRect2D scissor = {{0, 0}, {static_cast<uint32_t>(m_width), static_cast<uint32_t>(m_height)}}; 26429 26430 const VkPipelineViewportStateCreateInfo pipeline_viewport_state_create_info{ 26431 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, 26432 nullptr, // pNext 26433 0, // flags 26434 1, 26435 &viewport, 26436 1, 26437 &scissor}; 26438 26439 VkRenderPass render_pass; 26440 { 26441 VkSubpassDescription subpass_desc = {}; 26442 26443 VkRenderPassCreateInfo render_pass_create_info{ 26444 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, 26445 nullptr, // pNext 26446 0, // flags 26447 0, 26448 nullptr, // attachments 26449 1, 26450 &subpass_desc, 26451 0, 26452 nullptr // subpass dependencies 26453 }; 26454 26455 VkResult err = vkCreateRenderPass(m_device->handle(), &render_pass_create_info, nullptr, &render_pass); 26456 ASSERT_VK_SUCCESS(err); 26457 } 26458 26459 VkGraphicsPipelineCreateInfo graphics_pipeline_create_info{ 26460 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, 26461 nullptr, // pNext 26462 0, // flags 26463 1, // stageCount 26464 &vs.GetStageCreateInfo(), 26465 &pipeline_vertex_input_state_create_info, 26466 &pipeline_input_assembly_state_create_info, 26467 nullptr, 26468 &pipeline_viewport_state_create_info, 26469 &pipeline_rasterization_state_create_info, 26470 &pipeline_multisample_state_create_info, 26471 reinterpret_cast<const VkPipelineDepthStencilStateCreateInfo *>(hopefully_undereferencable_pointer), 26472 reinterpret_cast<const VkPipelineColorBlendStateCreateInfo *>(hopefully_undereferencable_pointer), 26473 nullptr, // dynamic states 26474 pipeline_layout, 26475 render_pass, 26476 0, // subpass 26477 VK_NULL_HANDLE, 26478 0}; 26479 26480 VkPipeline pipeline; 26481 vkCreateGraphicsPipelines(m_device->handle(), VK_NULL_HANDLE, 1, &graphics_pipeline_create_info, nullptr, &pipeline); 26482 26483 m_errorMonitor->VerifyNotFound(); 26484 26485 vkDestroyPipeline(m_device->handle(), pipeline, nullptr); 26486 vkDestroyRenderPass(m_device->handle(), render_pass, nullptr); 26487 } 26488 26489 // try dynamic viewport and scissor 26490 { 26491 m_errorMonitor->ExpectSuccess(); 26492 26493 VkPipelineRasterizationStateCreateInfo pipeline_rasterization_state_create_info = 26494 pipeline_rasterization_state_create_info_template; 26495 pipeline_rasterization_state_create_info.rasterizerDiscardEnable = VK_FALSE; 26496 26497 const VkPipelineViewportStateCreateInfo pipeline_viewport_state_create_info{ 26498 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, 26499 nullptr, // pNext 26500 0, // flags 26501 1, 26502 reinterpret_cast<const VkViewport *>(hopefully_undereferencable_pointer), 26503 1, 26504 reinterpret_cast<const VkRect2D *>(hopefully_undereferencable_pointer)}; 26505 26506 const VkPipelineDepthStencilStateCreateInfo pipeline_depth_stencil_state_create_info{ 26507 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, 26508 nullptr, // pNext 26509 0, // flags 26510 }; 26511 26512 const VkPipelineColorBlendAttachmentState pipeline_color_blend_attachment_state = {}; 26513 26514 const VkPipelineColorBlendStateCreateInfo pipeline_color_blend_state_create_info{ 26515 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, 26516 nullptr, // pNext 26517 0, // flags 26518 VK_FALSE, 26519 VK_LOGIC_OP_CLEAR, 26520 1, 26521 &pipeline_color_blend_attachment_state, 26522 {0.0f, 0.0f, 0.0f, 0.0f}}; 26523 26524 const VkDynamicState dynamic_states[2] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR}; 26525 26526 const VkPipelineDynamicStateCreateInfo pipeline_dynamic_state_create_info{ 26527 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, 26528 nullptr, // pNext 26529 0, // flags 26530 2, dynamic_states}; 26531 26532 VkGraphicsPipelineCreateInfo graphics_pipeline_create_info{VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, 26533 nullptr, // pNext 26534 0, // flags 26535 1, // stageCount 26536 &vs.GetStageCreateInfo(), 26537 &pipeline_vertex_input_state_create_info, 26538 &pipeline_input_assembly_state_create_info, 26539 nullptr, 26540 &pipeline_viewport_state_create_info, 26541 &pipeline_rasterization_state_create_info, 26542 &pipeline_multisample_state_create_info, 26543 &pipeline_depth_stencil_state_create_info, 26544 &pipeline_color_blend_state_create_info, 26545 &pipeline_dynamic_state_create_info, // dynamic states 26546 pipeline_layout, 26547 m_renderPass, 26548 0, // subpass 26549 VK_NULL_HANDLE, 26550 0}; 26551 26552 VkPipeline pipeline; 26553 vkCreateGraphicsPipelines(m_device->handle(), VK_NULL_HANDLE, 1, &graphics_pipeline_create_info, nullptr, &pipeline); 26554 26555 m_errorMonitor->VerifyNotFound(); 26556 26557 vkDestroyPipeline(m_device->handle(), pipeline, nullptr); 26558 } 26559 26560 vkDestroyPipelineLayout(m_device->handle(), pipeline_layout, nullptr); 26561 } 26562 26563 TEST_F(VkPositiveLayerTest, ExternalMemory) { 26564 TEST_DESCRIPTION("Perform a copy through a pair of buffers linked by external memory"); 26565 26566 #ifdef _WIN32 26567 const auto extension_name = VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME; 26568 const auto handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR; 26569 #else 26570 const auto extension_name = VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME; 26571 const auto handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR; 26572 #endif 26573 26574 // Check for external memory instance extensions 26575 if (InstanceExtensionSupported(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME)) { 26576 m_instance_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME); 26577 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 26578 } else { 26579 printf(" External memory extension not supported, skipping test\n"); 26580 return; 26581 } 26582 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 26583 26584 // Check for import/export capability 26585 VkPhysicalDeviceExternalBufferInfoKHR ebi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR, nullptr, 0, 26586 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, handle_type}; 26587 VkExternalBufferPropertiesKHR ebp = {VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR, nullptr, {0, 0, 0}}; 26588 auto vkGetPhysicalDeviceExternalBufferPropertiesKHR = (PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR)vkGetInstanceProcAddr( 26589 instance(), "vkGetPhysicalDeviceExternalBufferPropertiesKHR"); 26590 ASSERT_TRUE(vkGetPhysicalDeviceExternalBufferPropertiesKHR != nullptr); 26591 vkGetPhysicalDeviceExternalBufferPropertiesKHR(gpu(), &ebi, &ebp); 26592 if (!(ebp.externalMemoryProperties.compatibleHandleTypes & handle_type) || 26593 !(ebp.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR) || 26594 !(ebp.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR)) { 26595 printf(" External buffer does not support importing and exporting, skipping test\n"); 26596 return; 26597 } 26598 26599 // Check if dedicated allocation is required 26600 bool dedicated_allocation = 26601 ebp.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR; 26602 if (dedicated_allocation) { 26603 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME)) { 26604 m_device_extension_names.push_back(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); 26605 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); 26606 } else { 26607 printf(" Dedicated allocation extension not supported, skipping test\n"); 26608 return; 26609 } 26610 } 26611 26612 // Check for external memory device extensions 26613 if (DeviceExtensionSupported(gpu(), nullptr, extension_name)) { 26614 m_device_extension_names.push_back(extension_name); 26615 m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME); 26616 } else { 26617 printf(" External memory extension not supported, skipping test\n"); 26618 return; 26619 } 26620 ASSERT_NO_FATAL_FAILURE(InitState()); 26621 26622 m_errorMonitor->ExpectSuccess(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT); 26623 26624 VkMemoryPropertyFlags mem_flags = 0; 26625 const VkDeviceSize buffer_size = 1024; 26626 26627 // Create export and import buffers 26628 const VkExternalMemoryBufferCreateInfoKHR external_buffer_info = {VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR, 26629 nullptr, handle_type}; 26630 auto buffer_info = 26631 vk_testing::Buffer::create_info(buffer_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT); 26632 buffer_info.pNext = &external_buffer_info; 26633 vk_testing::Buffer buffer_export; 26634 buffer_export.init_no_mem(*m_device, buffer_info); 26635 vk_testing::Buffer buffer_import; 26636 buffer_import.init_no_mem(*m_device, buffer_info); 26637 26638 // Allocation info 26639 auto alloc_info = vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, buffer_export.memory_requirements(), mem_flags); 26640 26641 // Add export allocation info to pNext chain 26642 VkExportMemoryAllocateInfoKHR export_info = {VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR, nullptr, handle_type}; 26643 alloc_info.pNext = &export_info; 26644 26645 // Add dedicated allocation info to pNext chain if required 26646 VkMemoryDedicatedAllocateInfoKHR dedicated_info = {VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR, nullptr, 26647 VK_NULL_HANDLE, buffer_export.handle()}; 26648 if (dedicated_allocation) { 26649 export_info.pNext = &dedicated_info; 26650 } 26651 26652 // Allocate memory to be exported 26653 vk_testing::DeviceMemory memory_export; 26654 memory_export.init(*m_device, alloc_info); 26655 26656 // Bind exported memory 26657 buffer_export.bind_memory(memory_export, 0); 26658 26659 #ifdef _WIN32 26660 // Export memory to handle 26661 auto vkGetMemoryWin32HandleKHR = (PFN_vkGetMemoryWin32HandleKHR)vkGetInstanceProcAddr(instance(), "vkGetMemoryWin32HandleKHR"); 26662 ASSERT_TRUE(vkGetMemoryWin32HandleKHR != nullptr); 26663 VkMemoryGetWin32HandleInfoKHR mghi = {VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR, nullptr, memory_export.handle(), 26664 handle_type}; 26665 HANDLE handle; 26666 ASSERT_VK_SUCCESS(vkGetMemoryWin32HandleKHR(m_device->device(), &mghi, &handle)); 26667 26668 VkImportMemoryWin32HandleInfoKHR import_info = {VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR, nullptr, handle_type, 26669 handle}; 26670 #else 26671 // Export memory to fd 26672 auto vkGetMemoryFdKHR = (PFN_vkGetMemoryFdKHR)vkGetInstanceProcAddr(instance(), "vkGetMemoryFdKHR"); 26673 ASSERT_TRUE(vkGetMemoryFdKHR != nullptr); 26674 VkMemoryGetFdInfoKHR mgfi = {VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR, nullptr, memory_export.handle(), handle_type}; 26675 int fd; 26676 ASSERT_VK_SUCCESS(vkGetMemoryFdKHR(m_device->device(), &mgfi, &fd)); 26677 26678 VkImportMemoryFdInfoKHR import_info = {VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, nullptr, handle_type, fd}; 26679 #endif 26680 26681 // Import memory 26682 alloc_info = vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, buffer_import.memory_requirements(), mem_flags); 26683 alloc_info.pNext = &import_info; 26684 vk_testing::DeviceMemory memory_import; 26685 memory_import.init(*m_device, alloc_info); 26686 26687 // Bind imported memory 26688 buffer_import.bind_memory(memory_import, 0); 26689 26690 // Create test buffers and fill input buffer 26691 VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; 26692 vk_testing::Buffer buffer_input; 26693 buffer_input.init_as_src_and_dst(*m_device, buffer_size, mem_prop); 26694 auto input_mem = (uint8_t *)buffer_input.memory().map(); 26695 for (uint32_t i = 0; i < buffer_size; i++) { 26696 input_mem[i] = (i & 0xFF); 26697 } 26698 buffer_input.memory().unmap(); 26699 vk_testing::Buffer buffer_output; 26700 buffer_output.init_as_src_and_dst(*m_device, buffer_size, mem_prop); 26701 26702 // Copy from input buffer to output buffer through the exported/imported memory 26703 m_commandBuffer->begin(); 26704 VkBufferCopy copy_info = {0, 0, buffer_size}; 26705 vkCmdCopyBuffer(m_commandBuffer->handle(), buffer_input.handle(), buffer_export.handle(), 1, ©_info); 26706 // Insert memory barrier to guarantee copy order 26707 VkMemoryBarrier mem_barrier = {VK_STRUCTURE_TYPE_MEMORY_BARRIER, nullptr, VK_ACCESS_TRANSFER_WRITE_BIT, 26708 VK_ACCESS_TRANSFER_READ_BIT}; 26709 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, 26710 &mem_barrier, 0, nullptr, 0, nullptr); 26711 vkCmdCopyBuffer(m_commandBuffer->handle(), buffer_import.handle(), buffer_output.handle(), 1, ©_info); 26712 m_commandBuffer->end(); 26713 m_commandBuffer->QueueCommandBuffer(); 26714 26715 m_errorMonitor->VerifyNotFound(); 26716 } 26717 26718 TEST_F(VkLayerTest, AMDMixedAttachmentSamplesValidateRenderPass) { 26719 TEST_DESCRIPTION("Verify error messages for supported and unsupported sample counts in render pass attachments."); 26720 26721 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 26722 if (DeviceExtensionSupported(gpu(), nullptr, VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME)) { 26723 m_device_extension_names.push_back(VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME); 26724 } else { 26725 return; 26726 } 26727 ASSERT_NO_FATAL_FAILURE(InitState()); 26728 26729 m_errorMonitor->ExpectSuccess(); 26730 26731 std::vector<VkAttachmentDescription> attachments; 26732 26733 { 26734 VkAttachmentDescription att = {}; 26735 att.format = VK_FORMAT_R8G8B8A8_UNORM; 26736 att.samples = VK_SAMPLE_COUNT_1_BIT; 26737 att.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 26738 att.storeOp = VK_ATTACHMENT_STORE_OP_STORE; 26739 att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; 26740 att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; 26741 att.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 26742 att.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 26743 26744 attachments.push_back(att); 26745 26746 att.format = VK_FORMAT_D16_UNORM; 26747 att.samples = VK_SAMPLE_COUNT_4_BIT; 26748 att.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 26749 att.storeOp = VK_ATTACHMENT_STORE_OP_STORE; 26750 att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 26751 att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; 26752 att.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 26753 att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 26754 26755 attachments.push_back(att); 26756 } 26757 26758 VkAttachmentReference color_ref = {}; 26759 color_ref.attachment = 0; 26760 color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 26761 26762 VkAttachmentReference depth_ref = {}; 26763 depth_ref.attachment = 1; 26764 depth_ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 26765 26766 VkSubpassDescription subpass = {}; 26767 subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; 26768 subpass.colorAttachmentCount = 1; 26769 subpass.pColorAttachments = &color_ref; 26770 subpass.pDepthStencilAttachment = &depth_ref; 26771 26772 VkRenderPassCreateInfo rp_info = {}; 26773 rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 26774 rp_info.attachmentCount = attachments.size(); 26775 rp_info.pAttachments = attachments.data(); 26776 rp_info.subpassCount = 1; 26777 rp_info.pSubpasses = &subpass; 26778 26779 vkCreateRenderPass(device(), &rp_info, NULL, &m_renderPass); 26780 m_errorMonitor->VerifyNotFound(); 26781 26782 // Expect an error message for invalid sample counts 26783 26784 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_14000bc4); 26785 26786 attachments[0].samples = VK_SAMPLE_COUNT_4_BIT; 26787 attachments[1].samples = VK_SAMPLE_COUNT_1_BIT; 26788 26789 { 26790 VkRenderPass render_pass; 26791 VkResult err = vkCreateRenderPass(device(), &rp_info, NULL, &render_pass); 26792 m_errorMonitor->VerifyFound(); 26793 ASSERT_NE(err, VK_SUCCESS); 26794 } 26795 } 26796 26797 TEST_F(VkLayerTest, AMDMixedAttachmentSamplesValidateGraphicsPipeline) { 26798 TEST_DESCRIPTION("Verify an error message for an incorrect graphics pipeline rasterization sample count."); 26799 26800 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 26801 if (DeviceExtensionSupported(gpu(), nullptr, VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME)) { 26802 m_device_extension_names.push_back(VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME); 26803 } else { 26804 return; 26805 } 26806 ASSERT_NO_FATAL_FAILURE(InitState()); 26807 26808 VkRenderpassObj render_pass(m_device); 26809 26810 const VkPipelineLayoutObj pipeline_layout(m_device); 26811 26812 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 26813 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 26814 26815 // Set a mismatched sample count 26816 26817 VkPipelineMultisampleStateCreateInfo ms_state_ci = {}; 26818 ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 26819 ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT; 26820 26821 VkPipelineObj pipe(m_device); 26822 pipe.AddShader(&vs); 26823 pipe.AddShader(&fs); 26824 pipe.AddDefaultColorAttachment(); 26825 pipe.SetMSAA(&ms_state_ci); 26826 26827 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_09600bc2); 26828 26829 pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle()); 26830 26831 m_errorMonitor->VerifyFound(); 26832 } 26833 26834 TEST_F(VkPositiveLayerTest, ParameterLayerFeatures2Capture) { 26835 TEST_DESCRIPTION("Ensure parameter_validation_layer correctly captures physical device features"); 26836 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { 26837 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 26838 } else { 26839 printf(" Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n"); 26840 return; 26841 } 26842 26843 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 26844 26845 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR = 26846 (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR"); 26847 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr); 26848 26849 VkResult err; 26850 m_errorMonitor->ExpectSuccess(); 26851 26852 VkPhysicalDeviceFeatures2KHR features2; 26853 features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; 26854 features2.pNext = nullptr; 26855 26856 vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2); 26857 26858 // We're not creating a valid m_device, but the phy wrapper is useful 26859 vk_testing::PhysicalDevice physical_device(gpu()); 26860 vk_testing::QueueCreateInfoArray queue_info(physical_device.queue_properties()); 26861 // Only request creation with queuefamilies that have at least one queue 26862 std::vector<VkDeviceQueueCreateInfo> create_queue_infos; 26863 auto qci = queue_info.data(); 26864 for (uint32_t i = 0; i < queue_info.size(); ++i) { 26865 if (qci[i].queueCount) { 26866 create_queue_infos.push_back(qci[i]); 26867 } 26868 } 26869 26870 VkDeviceCreateInfo dev_info = {}; 26871 dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; 26872 dev_info.pNext = &features2; 26873 dev_info.flags = 0; 26874 dev_info.queueCreateInfoCount = create_queue_infos.size(); 26875 dev_info.pQueueCreateInfos = create_queue_infos.data(); 26876 dev_info.enabledLayerCount = 0; 26877 dev_info.ppEnabledLayerNames = nullptr; 26878 dev_info.enabledExtensionCount = 0; 26879 dev_info.ppEnabledExtensionNames = nullptr; 26880 dev_info.pEnabledFeatures = nullptr; 26881 26882 VkDevice device; 26883 err = vkCreateDevice(gpu(), &dev_info, nullptr, &device); 26884 ASSERT_VK_SUCCESS(err); 26885 26886 if (features2.features.samplerAnisotropy) { 26887 // Test that the parameter layer is caching the features correctly using CreateSampler 26888 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo(); 26889 // If the features were not captured correctly, this should cause an error 26890 sampler_ci.anisotropyEnable = VK_TRUE; 26891 sampler_ci.maxAnisotropy = physical_device.properties().limits.maxSamplerAnisotropy; 26892 26893 VkSampler sampler = VK_NULL_HANDLE; 26894 err = vkCreateSampler(device, &sampler_ci, nullptr, &sampler); 26895 ASSERT_VK_SUCCESS(err); 26896 vkDestroySampler(device, sampler, nullptr); 26897 } else { 26898 printf(" Feature samplerAnisotropy not enabled; parameter_layer check skipped.\n"); 26899 } 26900 26901 // Verify the core validation layer has captured the physical device features by creating a a query pool. 26902 if (features2.features.pipelineStatisticsQuery) { 26903 VkQueryPool query_pool; 26904 VkQueryPoolCreateInfo qpci{}; 26905 qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; 26906 qpci.queryType = VK_QUERY_TYPE_PIPELINE_STATISTICS; 26907 qpci.queryCount = 1; 26908 err = vkCreateQueryPool(device, &qpci, nullptr, &query_pool); 26909 ASSERT_VK_SUCCESS(err); 26910 26911 vkDestroyQueryPool(device, query_pool, nullptr); 26912 } else { 26913 printf(" Feature pipelineStatisticsQuery not enabled; core_validation_layer check skipped.\n"); 26914 } 26915 26916 vkDestroyDevice(device, nullptr); 26917 26918 m_errorMonitor->VerifyNotFound(); 26919 } 26920 26921 TEST_F(VkPositiveLayerTest, GetMemoryRequirements2) { 26922 TEST_DESCRIPTION( 26923 "Get memory requirements with VK_KHR_get_memory_requirements2 instead of core entry points and verify layers do not emit " 26924 "errors when objects are bound and used"); 26925 26926 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 26927 26928 // Check for VK_KHR_get_memory_requirementes2 extensions 26929 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME)) { 26930 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); 26931 } else { 26932 printf(" %s not supported, skipping test\n", VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); 26933 return; 26934 } 26935 26936 ASSERT_NO_FATAL_FAILURE(InitState()); 26937 26938 m_errorMonitor->ExpectSuccess(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT); 26939 26940 // Create a test buffer 26941 vk_testing::Buffer buffer; 26942 buffer.init_no_mem(*m_device, 26943 vk_testing::Buffer::create_info(1024, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT)); 26944 26945 // Use extension to get buffer memory reqirements 26946 auto vkGetBufferMemoryRequirements2KHR = reinterpret_cast<PFN_vkGetBufferMemoryRequirements2KHR>( 26947 vkGetDeviceProcAddr(m_device->device(), "vkGetBufferMemoryRequirements2KHR")); 26948 ASSERT_TRUE(vkGetBufferMemoryRequirements2KHR != nullptr); 26949 VkBufferMemoryRequirementsInfo2KHR buffer_info = {VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR, nullptr, 26950 buffer.handle()}; 26951 VkMemoryRequirements2KHR buffer_reqs = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR}; 26952 vkGetBufferMemoryRequirements2KHR(m_device->device(), &buffer_info, &buffer_reqs); 26953 26954 // Allocate and bind buffer memory 26955 vk_testing::DeviceMemory buffer_memory; 26956 buffer_memory.init(*m_device, vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, buffer_reqs.memoryRequirements, 0)); 26957 vkBindBufferMemory(m_device->device(), buffer.handle(), buffer_memory.handle(), 0); 26958 26959 // Create a test image 26960 auto image_ci = vk_testing::Image::create_info(); 26961 image_ci.imageType = VK_IMAGE_TYPE_2D; 26962 image_ci.extent.width = 32; 26963 image_ci.extent.height = 32; 26964 image_ci.format = VK_FORMAT_R8G8B8A8_UNORM; 26965 image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; 26966 image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; 26967 vk_testing::Image image; 26968 image.init_no_mem(*m_device, image_ci); 26969 26970 // Use extension to get image memory requirements 26971 auto vkGetImageMemoryRequirements2KHR = reinterpret_cast<PFN_vkGetImageMemoryRequirements2KHR>( 26972 vkGetDeviceProcAddr(m_device->device(), "vkGetImageMemoryRequirements2KHR")); 26973 ASSERT_TRUE(vkGetImageMemoryRequirements2KHR != nullptr); 26974 VkImageMemoryRequirementsInfo2KHR image_info = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR, nullptr, 26975 image.handle()}; 26976 VkMemoryRequirements2KHR image_reqs = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR}; 26977 vkGetImageMemoryRequirements2KHR(m_device->device(), &image_info, &image_reqs); 26978 26979 // Allocate and bind image memory 26980 vk_testing::DeviceMemory image_memory; 26981 image_memory.init(*m_device, vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, image_reqs.memoryRequirements, 0)); 26982 vkBindImageMemory(m_device->device(), image.handle(), image_memory.handle(), 0); 26983 26984 // Now execute arbitrary commands that use the test buffer and image 26985 m_commandBuffer->begin(); 26986 26987 // Fill buffer with 0 26988 vkCmdFillBuffer(m_commandBuffer->handle(), buffer.handle(), 0, VK_WHOLE_SIZE, 0); 26989 26990 // Transition and clear image 26991 const auto subresource_range = image.subresource_range(VK_IMAGE_ASPECT_COLOR_BIT); 26992 const auto barrier = image.image_memory_barrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, 26993 VK_IMAGE_LAYOUT_GENERAL, subresource_range); 26994 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 26995 nullptr, 0, nullptr, 1, &barrier); 26996 const VkClearColorValue color = {}; 26997 vkCmdClearColorImage(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, &color, 1, &subresource_range); 26998 26999 // Submit and verify no validation errors 27000 m_commandBuffer->end(); 27001 m_commandBuffer->QueueCommandBuffer(); 27002 m_errorMonitor->VerifyNotFound(); 27003 } 27004 27005 TEST_F(VkPositiveLayerTest, BindMemory2) { 27006 TEST_DESCRIPTION( 27007 "Bind memory with VK_KHR_bind_memory2 instead of core entry points and verify layers do not emit errors when objects are " 27008 "used"); 27009 27010 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor)); 27011 27012 // Check for VK_KHR_get_memory_requirementes2 extensions 27013 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME)) { 27014 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME); 27015 } else { 27016 printf(" %s not supported, skipping test\n", VK_KHR_BIND_MEMORY_2_EXTENSION_NAME); 27017 return; 27018 } 27019 27020 ASSERT_NO_FATAL_FAILURE(InitState()); 27021 27022 m_errorMonitor->ExpectSuccess(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT); 27023 27024 // Create a test buffer 27025 vk_testing::Buffer buffer; 27026 buffer.init_no_mem(*m_device, vk_testing::Buffer::create_info(1024, VK_BUFFER_USAGE_TRANSFER_DST_BIT)); 27027 27028 // Allocate buffer memory 27029 vk_testing::DeviceMemory buffer_memory; 27030 buffer_memory.init(*m_device, vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, buffer.memory_requirements(), 0)); 27031 27032 // Bind buffer memory with extension 27033 auto vkBindBufferMemory2KHR = 27034 reinterpret_cast<PFN_vkBindBufferMemory2KHR>(vkGetDeviceProcAddr(m_device->device(), "vkBindBufferMemory2KHR")); 27035 ASSERT_TRUE(vkBindBufferMemory2KHR != nullptr); 27036 VkBindBufferMemoryInfoKHR buffer_bind_info = {VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR, nullptr, buffer.handle(), 27037 buffer_memory.handle(), 0}; 27038 vkBindBufferMemory2KHR(m_device->device(), 1, &buffer_bind_info); 27039 27040 // Create a test image 27041 auto image_ci = vk_testing::Image::create_info(); 27042 image_ci.imageType = VK_IMAGE_TYPE_2D; 27043 image_ci.extent.width = 32; 27044 image_ci.extent.height = 32; 27045 image_ci.format = VK_FORMAT_R8G8B8A8_UNORM; 27046 image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; 27047 image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; 27048 vk_testing::Image image; 27049 image.init_no_mem(*m_device, image_ci); 27050 27051 // Allocate image memory 27052 vk_testing::DeviceMemory image_memory; 27053 image_memory.init(*m_device, vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, image.memory_requirements(), 0)); 27054 27055 // Bind image memory with extension 27056 auto vkBindImageMemory2KHR = 27057 reinterpret_cast<PFN_vkBindImageMemory2KHR>(vkGetDeviceProcAddr(m_device->device(), "vkBindImageMemory2KHR")); 27058 ASSERT_TRUE(vkBindImageMemory2KHR != nullptr); 27059 VkBindImageMemoryInfoKHR image_bind_info = {VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR, nullptr, image.handle(), 27060 image_memory.handle(), 0}; 27061 vkBindImageMemory2KHR(m_device->device(), 1, &image_bind_info); 27062 27063 // Now execute arbitrary commands that use the test buffer and image 27064 m_commandBuffer->begin(); 27065 27066 // Fill buffer with 0 27067 vkCmdFillBuffer(m_commandBuffer->handle(), buffer.handle(), 0, VK_WHOLE_SIZE, 0); 27068 27069 // Transition and clear image 27070 const auto subresource_range = image.subresource_range(VK_IMAGE_ASPECT_COLOR_BIT); 27071 const auto barrier = image.image_memory_barrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, 27072 VK_IMAGE_LAYOUT_GENERAL, subresource_range); 27073 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 27074 nullptr, 0, nullptr, 1, &barrier); 27075 const VkClearColorValue color = {}; 27076 vkCmdClearColorImage(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, &color, 1, &subresource_range); 27077 27078 // Submit and verify no validation errors 27079 m_commandBuffer->end(); 27080 m_commandBuffer->QueueCommandBuffer(); 27081 m_errorMonitor->VerifyNotFound(); 27082 } 27083 27084 #if defined(ANDROID) && defined(VALIDATION_APK) 27085 const char *appTag = "VulkanLayerValidationTests"; 27086 static bool initialized = false; 27087 static bool active = false; 27088 27089 // Convert Intents to argv 27090 // Ported from Hologram sample, only difference is flexible key 27091 std::vector<std::string> get_args(android_app &app, const char *intent_extra_data_key) { 27092 std::vector<std::string> args; 27093 JavaVM &vm = *app.activity->vm; 27094 JNIEnv *p_env; 27095 if (vm.AttachCurrentThread(&p_env, nullptr) != JNI_OK) return args; 27096 27097 JNIEnv &env = *p_env; 27098 jobject activity = app.activity->clazz; 27099 jmethodID get_intent_method = env.GetMethodID(env.GetObjectClass(activity), "getIntent", "()Landroid/content/Intent;"); 27100 jobject intent = env.CallObjectMethod(activity, get_intent_method); 27101 jmethodID get_string_extra_method = 27102 env.GetMethodID(env.GetObjectClass(intent), "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;"); 27103 jvalue get_string_extra_args; 27104 get_string_extra_args.l = env.NewStringUTF(intent_extra_data_key); 27105 jstring extra_str = static_cast<jstring>(env.CallObjectMethodA(intent, get_string_extra_method, &get_string_extra_args)); 27106 27107 std::string args_str; 27108 if (extra_str) { 27109 const char *extra_utf = env.GetStringUTFChars(extra_str, nullptr); 27110 args_str = extra_utf; 27111 env.ReleaseStringUTFChars(extra_str, extra_utf); 27112 env.DeleteLocalRef(extra_str); 27113 } 27114 27115 env.DeleteLocalRef(get_string_extra_args.l); 27116 env.DeleteLocalRef(intent); 27117 vm.DetachCurrentThread(); 27118 27119 // split args_str 27120 std::stringstream ss(args_str); 27121 std::string arg; 27122 while (std::getline(ss, arg, ' ')) { 27123 if (!arg.empty()) args.push_back(arg); 27124 } 27125 27126 return args; 27127 } 27128 27129 void addFullTestCommentIfPresent(const ::testing::TestInfo &test_info, std::string &error_message) { 27130 const char *const type_param = test_info.type_param(); 27131 const char *const value_param = test_info.value_param(); 27132 27133 if (type_param != NULL || value_param != NULL) { 27134 error_message.append(", where "); 27135 if (type_param != NULL) { 27136 error_message.append("TypeParam = ").append(type_param); 27137 if (value_param != NULL) error_message.append(" and "); 27138 } 27139 if (value_param != NULL) { 27140 error_message.append("GetParam() = ").append(value_param); 27141 } 27142 } 27143 } 27144 27145 // Inspired by https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md 27146 class LogcatPrinter : public ::testing::EmptyTestEventListener { 27147 // Called before a test starts. 27148 virtual void OnTestStart(const ::testing::TestInfo &test_info) { 27149 __android_log_print(ANDROID_LOG_INFO, appTag, "[ RUN ] %s.%s", test_info.test_case_name(), test_info.name()); 27150 } 27151 27152 // Called after a failed assertion or a SUCCEED() invocation. 27153 virtual void OnTestPartResult(const ::testing::TestPartResult &result) { 27154 // If the test part succeeded, we don't need to do anything. 27155 if (result.type() == ::testing::TestPartResult::kSuccess) return; 27156 27157 __android_log_print(ANDROID_LOG_INFO, appTag, "%s in %s:%d %s", result.failed() ? "*** Failure" : "Success", 27158 result.file_name(), result.line_number(), result.summary()); 27159 } 27160 27161 // Called after a test ends. 27162 virtual void OnTestEnd(const ::testing::TestInfo &info) { 27163 std::string result; 27164 if (info.result()->Passed()) { 27165 result.append("[ OK ]"); 27166 } else { 27167 result.append("[ FAILED ]"); 27168 } 27169 result.append(info.test_case_name()).append(".").append(info.name()); 27170 if (info.result()->Failed()) addFullTestCommentIfPresent(info, result); 27171 27172 if (::testing::GTEST_FLAG(print_time)) { 27173 std::ostringstream os; 27174 os << info.result()->elapsed_time(); 27175 result.append(" (").append(os.str()).append(" ms)"); 27176 } 27177 27178 __android_log_print(ANDROID_LOG_INFO, appTag, "%s", result.c_str()); 27179 }; 27180 }; 27181 27182 static int32_t processInput(struct android_app *app, AInputEvent *event) { return 0; } 27183 27184 static void processCommand(struct android_app *app, int32_t cmd) { 27185 switch (cmd) { 27186 case APP_CMD_INIT_WINDOW: { 27187 if (app->window) { 27188 initialized = true; 27189 } 27190 break; 27191 } 27192 case APP_CMD_GAINED_FOCUS: { 27193 active = true; 27194 break; 27195 } 27196 case APP_CMD_LOST_FOCUS: { 27197 active = false; 27198 break; 27199 } 27200 } 27201 } 27202 27203 void android_main(struct android_app *app) { 27204 int vulkanSupport = InitVulkan(); 27205 if (vulkanSupport == 0) { 27206 __android_log_print(ANDROID_LOG_INFO, appTag, "==== FAILED ==== No Vulkan support found"); 27207 return; 27208 } 27209 27210 app->onAppCmd = processCommand; 27211 app->onInputEvent = processInput; 27212 27213 while (1) { 27214 int events; 27215 struct android_poll_source *source; 27216 while (ALooper_pollAll(active ? 0 : -1, NULL, &events, (void **)&source) >= 0) { 27217 if (source) { 27218 source->process(app, source); 27219 } 27220 27221 if (app->destroyRequested != 0) { 27222 VkTestFramework::Finish(); 27223 return; 27224 } 27225 } 27226 27227 if (initialized && active) { 27228 // Use the following key to send arguments to gtest, i.e. 27229 // --es args "--gtest_filter=-VkLayerTest.foo" 27230 const char key[] = "args"; 27231 std::vector<std::string> args = get_args(*app, key); 27232 27233 std::string filter = ""; 27234 if (args.size() > 0) { 27235 __android_log_print(ANDROID_LOG_INFO, appTag, "Intent args = %s", args[0].c_str()); 27236 filter += args[0]; 27237 } else { 27238 __android_log_print(ANDROID_LOG_INFO, appTag, "No Intent args detected"); 27239 } 27240 27241 int argc = 2; 27242 char *argv[] = {(char *)"foo", (char *)filter.c_str()}; 27243 __android_log_print(ANDROID_LOG_DEBUG, appTag, "filter = %s", argv[1]); 27244 27245 // Route output to files until we can override the gtest output 27246 freopen("/sdcard/Android/data/com.example.VulkanLayerValidationTests/files/out.txt", "w", stdout); 27247 freopen("/sdcard/Android/data/com.example.VulkanLayerValidationTests/files/err.txt", "w", stderr); 27248 27249 ::testing::InitGoogleTest(&argc, argv); 27250 27251 ::testing::TestEventListeners &listeners = ::testing::UnitTest::GetInstance()->listeners(); 27252 listeners.Append(new LogcatPrinter); 27253 27254 VkTestFramework::InitArgs(&argc, argv); 27255 ::testing::AddGlobalTestEnvironment(new TestEnvironment); 27256 27257 int result = RUN_ALL_TESTS(); 27258 27259 if (result != 0) { 27260 __android_log_print(ANDROID_LOG_INFO, appTag, "==== Tests FAILED ===="); 27261 } else { 27262 __android_log_print(ANDROID_LOG_INFO, appTag, "==== Tests PASSED ===="); 27263 } 27264 27265 VkTestFramework::Finish(); 27266 27267 fclose(stdout); 27268 fclose(stderr); 27269 27270 ANativeActivity_finish(app->activity); 27271 return; 27272 } 27273 } 27274 } 27275 #endif 27276 27277 #if defined(_WIN32) && !defined(NDEBUG) 27278 #include <crtdbg.h> 27279 #endif 27280 27281 int main(int argc, char **argv) { 27282 int result; 27283 27284 #ifdef ANDROID 27285 int vulkanSupport = InitVulkan(); 27286 if (vulkanSupport == 0) return 1; 27287 #endif 27288 27289 #if defined(_WIN32) && !defined(NDEBUG) 27290 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); 27291 _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); 27292 #endif 27293 27294 ::testing::InitGoogleTest(&argc, argv); 27295 VkTestFramework::InitArgs(&argc, argv); 27296 27297 ::testing::AddGlobalTestEnvironment(new TestEnvironment); 27298 27299 result = RUN_ALL_TESTS(); 27300 27301 VkTestFramework::Finish(); 27302 return result; 27303 } 27304