1 /* 2 * Copyright (c) 2015-2016 The Khronos Group Inc. 3 * Copyright (c) 2015-2016 Valve Corporation 4 * Copyright (c) 2015-2016 LunarG, Inc. 5 * Copyright (c) 2015-2016 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 */ 22 23 #ifdef ANDROID 24 #include "vulkan_wrapper.h" 25 #else 26 #include <vulkan/vulkan.h> 27 #endif 28 29 #if defined(ANDROID) && defined(VALIDATION_APK) 30 #include <android/log.h> 31 #include <android_native_app_glue.h> 32 #endif 33 34 #include "icd-spv.h" 35 #include "test_common.h" 36 #include "vk_layer_config.h" 37 #include "vkrenderframework.h" 38 #include <unordered_set> 39 #include "vk_validation_error_messages.h" 40 41 #define GLM_FORCE_RADIANS 42 #include "glm/glm.hpp" 43 #include <glm/gtc/matrix_transform.hpp> 44 45 #define PARAMETER_VALIDATION_TESTS 1 46 #define MEM_TRACKER_TESTS 1 47 #define OBJ_TRACKER_TESTS 1 48 #define DRAW_STATE_TESTS 1 49 #define THREADING_TESTS 1 50 #define SHADER_CHECKER_TESTS 1 51 #define DEVICE_LIMITS_TESTS 1 52 #define IMAGE_TESTS 1 53 54 //-------------------------------------------------------------------------------------- 55 // Mesh and VertexFormat Data 56 //-------------------------------------------------------------------------------------- 57 struct Vertex { 58 float posX, posY, posZ, posW; // Position data 59 float r, g, b, a; // Color 60 }; 61 62 #define XYZ1(_x_, _y_, _z_) (_x_), (_y_), (_z_), 1.f 63 64 typedef enum _BsoFailSelect { 65 BsoFailNone = 0x00000000, 66 BsoFailLineWidth = 0x00000001, 67 BsoFailDepthBias = 0x00000002, 68 BsoFailViewport = 0x00000004, 69 BsoFailScissor = 0x00000008, 70 BsoFailBlend = 0x00000010, 71 BsoFailDepthBounds = 0x00000020, 72 BsoFailStencilReadMask = 0x00000040, 73 BsoFailStencilWriteMask = 0x00000080, 74 BsoFailStencilReference = 0x00000100, 75 BsoFailCmdClearAttachments = 0x00000200, 76 BsoFailIndexBuffer = 0x00000400, 77 } BsoFailSelect; 78 79 struct vktriangle_vs_uniform { 80 // Must start with MVP 81 float mvp[4][4]; 82 float position[3][4]; 83 float color[3][4]; 84 }; 85 86 static const char bindStateVertShaderText[] = "#version 450\n" 87 "vec2 vertices[3];\n" 88 "out gl_PerVertex {\n" 89 " vec4 gl_Position;\n" 90 "};\n" 91 "void main() {\n" 92 " vertices[0] = vec2(-1.0, -1.0);\n" 93 " vertices[1] = vec2( 1.0, -1.0);\n" 94 " vertices[2] = vec2( 0.0, 1.0);\n" 95 " gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0);\n" 96 "}\n"; 97 98 static const char bindStateFragShaderText[] = "#version 450\n" 99 "\n" 100 "layout(location = 0) out vec4 uFragColor;\n" 101 "void main(){\n" 102 " uFragColor = vec4(0,1,0,1);\n" 103 "}\n"; 104 105 static VKAPI_ATTR VkBool32 VKAPI_CALL myDbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, 106 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg, 107 void *pUserData); 108 109 // ErrorMonitor Usage: 110 // 111 // Call SetDesiredFailureMsg with: a string to be compared against all 112 // encountered log messages, or a validation error enum identifying 113 // desired error message. Passing NULL or VALIDATION_ERROR_MAX_ENUM 114 // will match all log messages. logMsg will return true for skipCall 115 // only if msg is matched or NULL. 116 // 117 // Call DesiredMsgFound to determine if the desired failure message 118 // was encountered. 119 class ErrorMonitor { 120 public: 121 ErrorMonitor() { 122 test_platform_thread_create_mutex(&m_mutex); 123 test_platform_thread_lock_mutex(&m_mutex); 124 m_msgFlags = VK_DEBUG_REPORT_ERROR_BIT_EXT; 125 m_bailout = NULL; 126 test_platform_thread_unlock_mutex(&m_mutex); 127 } 128 129 ~ErrorMonitor() { test_platform_thread_delete_mutex(&m_mutex); } 130 131 // ErrorMonitor will look for an error message containing the specified string 132 void SetDesiredFailureMsg(VkFlags msgFlags, const char *msgString) { 133 // Also discard all collected messages to this point 134 test_platform_thread_lock_mutex(&m_mutex); 135 m_failure_message_strings.clear(); 136 // If we are looking for a matching string, ignore any IDs 137 m_desired_message_ids.clear(); 138 m_otherMsgs.clear(); 139 m_desired_message_strings.insert(msgString); 140 m_msgFound = VK_FALSE; 141 m_msgFlags = msgFlags; 142 test_platform_thread_unlock_mutex(&m_mutex); 143 } 144 145 // ErrorMonitor will look for a message ID matching the specified one 146 void SetDesiredFailureMsg(VkFlags msgFlags, UNIQUE_VALIDATION_ERROR_CODE msg_id) { 147 // Also discard all collected messages to this point 148 test_platform_thread_lock_mutex(&m_mutex); 149 m_failure_message_strings.clear(); 150 // If we are looking for IDs don't look for strings 151 m_desired_message_strings.clear(); 152 m_otherMsgs.clear(); 153 m_desired_message_ids.insert(msg_id); 154 m_msgFound = VK_FALSE; 155 m_msgFlags = msgFlags; 156 test_platform_thread_unlock_mutex(&m_mutex); 157 } 158 159 VkBool32 CheckForDesiredMsg(uint32_t message_code, const char *msgString) { 160 VkBool32 result = VK_FALSE; 161 test_platform_thread_lock_mutex(&m_mutex); 162 if (m_bailout != NULL) { 163 *m_bailout = true; 164 } 165 string errorString(msgString); 166 bool found_expected = false; 167 168 for (auto desired_msg : m_desired_message_strings) { 169 if (desired_msg.length() == 0) { 170 // An empty desired_msg string "" indicates a positive test - not expecting an error. 171 // Return true to avoid calling layers/driver with this error. 172 // And don't erase the "" string, so it remains if another error is found. 173 result = VK_TRUE; 174 } else if (errorString.find(desired_msg) != string::npos) { 175 found_expected = true; 176 m_failure_message_strings.insert(errorString); 177 m_msgFound = VK_TRUE; 178 result = VK_TRUE; 179 // We only want one match for each expected error so remove from set here 180 // Since we're about the break the loop it's ok to remove from set we're iterating over 181 m_desired_message_strings.erase(desired_msg); 182 break; 183 } 184 } 185 for (auto desired_id : m_desired_message_ids) { 186 if (desired_id == VALIDATION_ERROR_MAX_ENUM) { 187 // A message ID set to MAX_ENUM indicates a positive test - not expecting an error. 188 // Return true to avoid calling layers/driver with this error. 189 result = VK_TRUE; 190 } else if (desired_id == message_code) { 191 // Double-check that the string matches the error enum 192 if (errorString.find(validation_error_map[desired_id]) != string::npos) { 193 found_expected = true; 194 result = VK_TRUE; 195 m_msgFound = VK_TRUE; 196 m_desired_message_ids.erase(desired_id); 197 break; 198 } else { 199 // Treat this message as a regular unexpected error, but print a warning jic 200 printf("Message (%s) from MessageID %d does not correspond to expected message from error Database (%s)\n", 201 errorString.c_str(), desired_id, validation_error_map[desired_id]); 202 } 203 } 204 } 205 206 if (!found_expected) { 207 printf("Unexpected: %s\n", msgString); 208 m_otherMsgs.push_back(errorString); 209 } 210 test_platform_thread_unlock_mutex(&m_mutex); 211 return result; 212 } 213 214 vector<string> GetOtherFailureMsgs(void) { return m_otherMsgs; } 215 216 VkDebugReportFlagsEXT GetMessageFlags(void) { return m_msgFlags; } 217 218 VkBool32 DesiredMsgFound(void) { return m_msgFound; } 219 220 void SetBailout(bool *bailout) { m_bailout = bailout; } 221 222 void DumpFailureMsgs(void) { 223 vector<string> otherMsgs = GetOtherFailureMsgs(); 224 cout << "Other error messages logged for this test were:" << endl; 225 for (auto iter = otherMsgs.begin(); iter != otherMsgs.end(); iter++) { 226 cout << " " << *iter << endl; 227 } 228 } 229 230 // Helpers 231 232 // ExpectSuccess now takes an optional argument allowing a custom combination of debug flags 233 void ExpectSuccess(VkDebugReportFlagsEXT message_flag_mask = VK_DEBUG_REPORT_ERROR_BIT_EXT) { 234 m_msgFlags = message_flag_mask; 235 // Match ANY message matching specified type 236 SetDesiredFailureMsg(message_flag_mask, ""); 237 } 238 239 void VerifyFound() { 240 // Not seeing the desired message is a failure. /Before/ throwing, dump any other messages. 241 if (!DesiredMsgFound()) { 242 DumpFailureMsgs(); 243 for (auto desired_msg : m_desired_message_strings) { 244 FAIL() << "Did not receive expected error '" << desired_msg << "'"; 245 } 246 } 247 } 248 249 void VerifyNotFound() { 250 // ExpectSuccess() configured us to match anything. Any error is a failure. 251 if (DesiredMsgFound()) { 252 DumpFailureMsgs(); 253 for (auto msg : m_failure_message_strings) { 254 FAIL() << "Expected to succeed but got error: " << msg; 255 } 256 } 257 } 258 259 private: 260 VkFlags m_msgFlags; 261 std::unordered_set<uint32_t>m_desired_message_ids; 262 std::unordered_set<string> m_desired_message_strings; 263 std::unordered_set<string> m_failure_message_strings; 264 vector<string> m_otherMsgs; 265 test_platform_thread_mutex m_mutex; 266 bool *m_bailout; 267 VkBool32 m_msgFound; 268 }; 269 270 static VKAPI_ATTR VkBool32 VKAPI_CALL myDbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, 271 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg, 272 void *pUserData) { 273 ErrorMonitor *errMonitor = (ErrorMonitor *)pUserData; 274 if (msgFlags & errMonitor->GetMessageFlags()) { 275 return errMonitor->CheckForDesiredMsg(msgCode, pMsg); 276 } 277 return false; 278 } 279 280 class VkLayerTest : public VkRenderFramework { 281 public: 282 VkResult BeginCommandBuffer(VkCommandBufferObj &commandBuffer); 283 VkResult EndCommandBuffer(VkCommandBufferObj &commandBuffer); 284 void VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask); 285 void GenericDrawPreparation(VkCommandBufferObj *commandBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, 286 BsoFailSelect failMask); 287 void GenericDrawPreparation(VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask) { 288 GenericDrawPreparation(m_commandBuffer, pipelineobj, descriptorSet, failMask); 289 } 290 291 /* Convenience functions that use built-in command buffer */ 292 VkResult BeginCommandBuffer() { return BeginCommandBuffer(*m_commandBuffer); } 293 VkResult EndCommandBuffer() { return EndCommandBuffer(*m_commandBuffer); } 294 void Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) { 295 m_commandBuffer->Draw(vertexCount, instanceCount, firstVertex, firstInstance); 296 } 297 void DrawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, 298 uint32_t firstInstance) { 299 m_commandBuffer->DrawIndexed(indexCount, instanceCount, firstIndex, vertexOffset, firstInstance); 300 } 301 void QueueCommandBuffer(bool checkSuccess = true) { m_commandBuffer->QueueCommandBuffer(checkSuccess); } 302 void QueueCommandBuffer(const VkFence &fence) { m_commandBuffer->QueueCommandBuffer(fence); } 303 void BindVertexBuffer(VkConstantBufferObj *vertexBuffer, VkDeviceSize offset, uint32_t binding) { 304 m_commandBuffer->BindVertexBuffer(vertexBuffer, offset, binding); 305 } 306 void BindIndexBuffer(VkIndexBufferObj *indexBuffer, VkDeviceSize offset) { 307 m_commandBuffer->BindIndexBuffer(indexBuffer, offset); 308 } 309 310 protected: 311 ErrorMonitor *m_errorMonitor; 312 bool m_enableWSI; 313 314 virtual void SetUp() { 315 std::vector<const char *> instance_layer_names; 316 std::vector<const char *> instance_extension_names; 317 std::vector<const char *> device_extension_names; 318 319 instance_extension_names.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); 320 /* 321 * Since CreateDbgMsgCallback is an instance level extension call 322 * any extension / layer that utilizes that feature also needs 323 * to be enabled at create instance time. 324 */ 325 // Use Threading layer first to protect others from 326 // ThreadCommandBufferCollision test 327 instance_layer_names.push_back("VK_LAYER_GOOGLE_threading"); 328 instance_layer_names.push_back("VK_LAYER_LUNARG_parameter_validation"); 329 instance_layer_names.push_back("VK_LAYER_LUNARG_object_tracker"); 330 instance_layer_names.push_back("VK_LAYER_LUNARG_core_validation"); 331 instance_layer_names.push_back("VK_LAYER_LUNARG_image"); 332 instance_layer_names.push_back("VK_LAYER_LUNARG_swapchain"); 333 instance_layer_names.push_back("VK_LAYER_GOOGLE_unique_objects"); 334 335 if (m_enableWSI) { 336 instance_extension_names.push_back(VK_KHR_SURFACE_EXTENSION_NAME); 337 device_extension_names.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); 338 #ifdef NEED_TO_TEST_THIS_ON_PLATFORM 339 #if defined(VK_USE_PLATFORM_ANDROID_KHR) 340 instance_extension_names.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); 341 #endif // VK_USE_PLATFORM_ANDROID_KHR 342 #if defined(VK_USE_PLATFORM_MIR_KHR) 343 instance_extension_names.push_back(VK_KHR_MIR_SURFACE_EXTENSION_NAME); 344 #endif // VK_USE_PLATFORM_MIR_KHR 345 #if defined(VK_USE_PLATFORM_WAYLAND_KHR) 346 instance_extension_names.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); 347 #endif // VK_USE_PLATFORM_WAYLAND_KHR 348 #if defined(VK_USE_PLATFORM_WIN32_KHR) 349 instance_extension_names.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); 350 #endif // VK_USE_PLATFORM_WIN32_KHR 351 #endif // NEED_TO_TEST_THIS_ON_PLATFORM 352 #if defined(VK_USE_PLATFORM_XCB_KHR) 353 instance_extension_names.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); 354 #elif defined(VK_USE_PLATFORM_XLIB_KHR) 355 instance_extension_names.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); 356 #endif // VK_USE_PLATFORM_XLIB_KHR 357 } 358 359 this->app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; 360 this->app_info.pNext = NULL; 361 this->app_info.pApplicationName = "layer_tests"; 362 this->app_info.applicationVersion = 1; 363 this->app_info.pEngineName = "unittest"; 364 this->app_info.engineVersion = 1; 365 this->app_info.apiVersion = VK_API_VERSION_1_0; 366 367 m_errorMonitor = new ErrorMonitor; 368 InitFramework(instance_layer_names, instance_extension_names, device_extension_names, myDbgFunc, m_errorMonitor); 369 } 370 371 virtual void TearDown() { 372 // Clean up resources before we reset 373 ShutdownFramework(); 374 delete m_errorMonitor; 375 } 376 377 VkLayerTest() { m_enableWSI = false; } 378 }; 379 380 VkResult VkLayerTest::BeginCommandBuffer(VkCommandBufferObj &commandBuffer) { 381 VkResult result; 382 383 result = commandBuffer.BeginCommandBuffer(); 384 385 /* 386 * For render test all drawing happens in a single render pass 387 * on a single command buffer. 388 */ 389 if (VK_SUCCESS == result && renderPass()) { 390 commandBuffer.BeginRenderPass(renderPassBeginInfo()); 391 } 392 393 return result; 394 } 395 396 VkResult VkLayerTest::EndCommandBuffer(VkCommandBufferObj &commandBuffer) { 397 VkResult result; 398 399 if (renderPass()) { 400 commandBuffer.EndRenderPass(); 401 } 402 403 result = commandBuffer.EndCommandBuffer(); 404 405 return result; 406 } 407 408 void VkLayerTest::VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask) { 409 // Create identity matrix 410 int i; 411 struct vktriangle_vs_uniform data; 412 413 glm::mat4 Projection = glm::mat4(1.0f); 414 glm::mat4 View = glm::mat4(1.0f); 415 glm::mat4 Model = glm::mat4(1.0f); 416 glm::mat4 MVP = Projection * View * Model; 417 const int matrixSize = sizeof(MVP); 418 const int bufSize = sizeof(vktriangle_vs_uniform) / sizeof(float); 419 420 memcpy(&data.mvp, &MVP[0][0], matrixSize); 421 422 static const Vertex tri_data[] = { 423 {XYZ1(-1, -1, 0), XYZ1(1.f, 0.f, 0.f)}, {XYZ1(1, -1, 0), XYZ1(0.f, 1.f, 0.f)}, {XYZ1(0, 1, 0), XYZ1(0.f, 0.f, 1.f)}, 424 }; 425 426 for (i = 0; i < 3; i++) { 427 data.position[i][0] = tri_data[i].posX; 428 data.position[i][1] = tri_data[i].posY; 429 data.position[i][2] = tri_data[i].posZ; 430 data.position[i][3] = tri_data[i].posW; 431 data.color[i][0] = tri_data[i].r; 432 data.color[i][1] = tri_data[i].g; 433 data.color[i][2] = tri_data[i].b; 434 data.color[i][3] = tri_data[i].a; 435 } 436 437 ASSERT_NO_FATAL_FAILURE(InitViewport()); 438 439 VkConstantBufferObj constantBuffer(m_device, bufSize * 2, sizeof(float), (const void *)&data, 440 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); 441 442 VkShaderObj vs(m_device, vertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 443 VkShaderObj ps(m_device, fragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 444 445 VkPipelineObj pipelineobj(m_device); 446 pipelineobj.AddColorAttachment(); 447 pipelineobj.AddShader(&vs); 448 pipelineobj.AddShader(&ps); 449 if (failMask & BsoFailLineWidth) { 450 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_LINE_WIDTH); 451 VkPipelineInputAssemblyStateCreateInfo ia_state = {}; 452 ia_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 453 ia_state.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST; 454 pipelineobj.SetInputAssembly(&ia_state); 455 } 456 if (failMask & BsoFailDepthBias) { 457 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_DEPTH_BIAS); 458 VkPipelineRasterizationStateCreateInfo rs_state = {}; 459 rs_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 460 rs_state.depthBiasEnable = VK_TRUE; 461 rs_state.lineWidth = 1.0f; 462 pipelineobj.SetRasterization(&rs_state); 463 } 464 // Viewport and scissors must stay in synch or other errors will occur than 465 // the ones we want 466 if (failMask & BsoFailViewport) { 467 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_VIEWPORT); 468 } 469 if (failMask & BsoFailScissor) { 470 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_SCISSOR); 471 } 472 if (failMask & BsoFailBlend) { 473 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_BLEND_CONSTANTS); 474 VkPipelineColorBlendAttachmentState att_state = {}; 475 att_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR; 476 att_state.blendEnable = VK_TRUE; 477 pipelineobj.AddColorAttachment(0, &att_state); 478 } 479 if (failMask & BsoFailDepthBounds) { 480 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_DEPTH_BOUNDS); 481 } 482 if (failMask & BsoFailStencilReadMask) { 483 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK); 484 } 485 if (failMask & BsoFailStencilWriteMask) { 486 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK); 487 } 488 if (failMask & BsoFailStencilReference) { 489 pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_STENCIL_REFERENCE); 490 } 491 492 VkDescriptorSetObj descriptorSet(m_device); 493 descriptorSet.AppendBuffer(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, constantBuffer); 494 495 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 496 ASSERT_VK_SUCCESS(BeginCommandBuffer()); 497 498 GenericDrawPreparation(pipelineobj, descriptorSet, failMask); 499 500 // render triangle 501 if (failMask & BsoFailIndexBuffer) { 502 // Use DrawIndexed w/o an index buffer bound 503 DrawIndexed(3, 1, 0, 0, 0); 504 } else { 505 Draw(3, 1, 0, 0); 506 } 507 508 if (failMask & BsoFailCmdClearAttachments) { 509 VkClearAttachment color_attachment = {}; 510 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 511 color_attachment.colorAttachment = 1; // Someone who knew what they were doing would use 0 for the index; 512 VkClearRect clear_rect = {{{0, 0}, {static_cast<uint32_t>(m_width), static_cast<uint32_t>(m_height)}}, 0, 0}; 513 514 vkCmdClearAttachments(m_commandBuffer->GetBufferHandle(), 1, &color_attachment, 1, &clear_rect); 515 } 516 517 // finalize recording of the command buffer 518 EndCommandBuffer(); 519 520 QueueCommandBuffer(); 521 } 522 523 void VkLayerTest::GenericDrawPreparation(VkCommandBufferObj *commandBuffer, VkPipelineObj &pipelineobj, 524 VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask) { 525 if (m_depthStencil->Initialized()) { 526 commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, m_depthStencil); 527 } else { 528 commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL); 529 } 530 531 commandBuffer->PrepareAttachments(); 532 // Make sure depthWriteEnable is set so that Depth fail test will work 533 // correctly 534 // Make sure stencilTestEnable is set so that Stencil fail test will work 535 // correctly 536 VkStencilOpState stencil = {}; 537 stencil.failOp = VK_STENCIL_OP_KEEP; 538 stencil.passOp = VK_STENCIL_OP_KEEP; 539 stencil.depthFailOp = VK_STENCIL_OP_KEEP; 540 stencil.compareOp = VK_COMPARE_OP_NEVER; 541 542 VkPipelineDepthStencilStateCreateInfo ds_ci = {}; 543 ds_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; 544 ds_ci.pNext = NULL; 545 ds_ci.depthTestEnable = VK_FALSE; 546 ds_ci.depthWriteEnable = VK_TRUE; 547 ds_ci.depthCompareOp = VK_COMPARE_OP_NEVER; 548 ds_ci.depthBoundsTestEnable = VK_FALSE; 549 if (failMask & BsoFailDepthBounds) { 550 ds_ci.depthBoundsTestEnable = VK_TRUE; 551 ds_ci.maxDepthBounds = 0.0f; 552 ds_ci.minDepthBounds = 0.0f; 553 } 554 ds_ci.stencilTestEnable = VK_TRUE; 555 ds_ci.front = stencil; 556 ds_ci.back = stencil; 557 558 pipelineobj.SetDepthStencil(&ds_ci); 559 pipelineobj.SetViewport(m_viewports); 560 pipelineobj.SetScissor(m_scissors); 561 descriptorSet.CreateVKDescriptorSet(commandBuffer); 562 VkResult err = pipelineobj.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 563 ASSERT_VK_SUCCESS(err); 564 commandBuffer->BindPipeline(pipelineobj); 565 commandBuffer->BindDescriptorSet(descriptorSet); 566 } 567 568 class VkPositiveLayerTest : public VkLayerTest { 569 public: 570 protected: 571 }; 572 573 class VkWsiEnabledLayerTest : public VkLayerTest { 574 public: 575 protected: 576 VkWsiEnabledLayerTest() { m_enableWSI = true; } 577 }; 578 579 class VkBufferTest { 580 public: 581 enum eTestEnFlags { 582 eDoubleDelete, 583 eInvalidDeviceOffset, 584 eInvalidMemoryOffset, 585 eBindNullBuffer, 586 eFreeInvalidHandle, 587 eNone, 588 }; 589 590 enum eTestConditions { eOffsetAlignment = 1 }; 591 592 static bool GetTestConditionValid(VkDeviceObj *aVulkanDevice, eTestEnFlags aTestFlag, VkBufferUsageFlags aBufferUsage = 0) { 593 if (eInvalidDeviceOffset != aTestFlag && eInvalidMemoryOffset != aTestFlag) { 594 return true; 595 } 596 VkDeviceSize offset_limit = 0; 597 if (eInvalidMemoryOffset == aTestFlag) { 598 VkBuffer vulkanBuffer; 599 VkBufferCreateInfo buffer_create_info = {}; 600 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 601 buffer_create_info.size = 32; 602 buffer_create_info.usage = aBufferUsage; 603 604 vkCreateBuffer(aVulkanDevice->device(), &buffer_create_info, nullptr, &vulkanBuffer); 605 VkMemoryRequirements memory_reqs = {}; 606 607 vkGetBufferMemoryRequirements(aVulkanDevice->device(), vulkanBuffer, &memory_reqs); 608 vkDestroyBuffer(aVulkanDevice->device(), vulkanBuffer, nullptr); 609 offset_limit = memory_reqs.alignment; 610 } else if ((VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) & aBufferUsage) { 611 offset_limit = aVulkanDevice->props.limits.minTexelBufferOffsetAlignment; 612 } else if (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT & aBufferUsage) { 613 offset_limit = aVulkanDevice->props.limits.minUniformBufferOffsetAlignment; 614 } else if (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT & aBufferUsage) { 615 offset_limit = aVulkanDevice->props.limits.minStorageBufferOffsetAlignment; 616 } 617 if (eOffsetAlignment < offset_limit) { 618 return true; 619 } 620 return false; 621 } 622 623 // A constructor which performs validation tests within construction. 624 VkBufferTest(VkDeviceObj *aVulkanDevice, VkBufferUsageFlags aBufferUsage, eTestEnFlags aTestFlag = eNone) 625 : AllocateCurrent(false), BoundCurrent(false), CreateCurrent(false), VulkanDevice(aVulkanDevice->device()) { 626 627 if (eBindNullBuffer == aTestFlag) { 628 VulkanMemory = 0; 629 vkBindBufferMemory(VulkanDevice, VulkanBuffer, VulkanMemory, 0); 630 } else { 631 VkBufferCreateInfo buffer_create_info = {}; 632 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 633 buffer_create_info.size = 32; 634 buffer_create_info.usage = aBufferUsage; 635 636 vkCreateBuffer(VulkanDevice, &buffer_create_info, nullptr, &VulkanBuffer); 637 638 CreateCurrent = true; 639 640 VkMemoryRequirements memory_requirements; 641 vkGetBufferMemoryRequirements(VulkanDevice, VulkanBuffer, &memory_requirements); 642 643 VkMemoryAllocateInfo memory_allocate_info = {}; 644 memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 645 memory_allocate_info.allocationSize = memory_requirements.size; 646 bool pass = aVulkanDevice->phy().set_memory_type(memory_requirements.memoryTypeBits, &memory_allocate_info, 647 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); 648 if (!pass) { 649 vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr); 650 return; 651 } 652 653 vkAllocateMemory(VulkanDevice, &memory_allocate_info, NULL, &VulkanMemory); 654 AllocateCurrent = true; 655 // NB: 1 is intentionally an invalid offset value 656 const bool offset_en = eInvalidDeviceOffset == aTestFlag || eInvalidMemoryOffset == aTestFlag; 657 vkBindBufferMemory(VulkanDevice, VulkanBuffer, VulkanMemory, offset_en ? eOffsetAlignment : 0); 658 BoundCurrent = true; 659 660 InvalidDeleteEn = (eFreeInvalidHandle == aTestFlag); 661 } 662 } 663 664 ~VkBufferTest() { 665 if (CreateCurrent) { 666 vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr); 667 } 668 if (AllocateCurrent) { 669 if (InvalidDeleteEn) { 670 union { 671 VkDeviceMemory device_memory; 672 unsigned long long index_access; 673 } bad_index; 674 675 bad_index.device_memory = VulkanMemory; 676 bad_index.index_access++; 677 678 vkFreeMemory(VulkanDevice, bad_index.device_memory, nullptr); 679 } 680 vkFreeMemory(VulkanDevice, VulkanMemory, nullptr); 681 } 682 } 683 684 bool GetBufferCurrent() { return AllocateCurrent && BoundCurrent && CreateCurrent; } 685 686 const VkBuffer &GetBuffer() { return VulkanBuffer; } 687 688 void TestDoubleDestroy() { 689 // Destroy the buffer but leave the flag set, which will cause 690 // the buffer to be destroyed again in the destructor. 691 vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr); 692 } 693 694 protected: 695 bool AllocateCurrent; 696 bool BoundCurrent; 697 bool CreateCurrent; 698 bool InvalidDeleteEn; 699 700 VkBuffer VulkanBuffer; 701 VkDevice VulkanDevice; 702 VkDeviceMemory VulkanMemory; 703 }; 704 705 class VkVerticesObj { 706 public: 707 VkVerticesObj(VkDeviceObj *aVulkanDevice, unsigned aAttributeCount, unsigned aBindingCount, unsigned aByteStride, 708 VkDeviceSize aVertexCount, const float *aVerticies) 709 : BoundCurrent(false), AttributeCount(aAttributeCount), BindingCount(aBindingCount), BindId(BindIdGenerator), 710 PipelineVertexInputStateCreateInfo(), 711 VulkanMemoryBuffer(aVulkanDevice, 1, static_cast<int>(aByteStride * aVertexCount), 712 reinterpret_cast<const void *>(aVerticies), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) { 713 BindIdGenerator++; // NB: This can wrap w/misuse 714 715 VertexInputAttributeDescription = new VkVertexInputAttributeDescription[AttributeCount]; 716 VertexInputBindingDescription = new VkVertexInputBindingDescription[BindingCount]; 717 718 PipelineVertexInputStateCreateInfo.pVertexAttributeDescriptions = VertexInputAttributeDescription; 719 PipelineVertexInputStateCreateInfo.vertexAttributeDescriptionCount = AttributeCount; 720 PipelineVertexInputStateCreateInfo.pVertexBindingDescriptions = VertexInputBindingDescription; 721 PipelineVertexInputStateCreateInfo.vertexBindingDescriptionCount = BindingCount; 722 PipelineVertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 723 724 unsigned i = 0; 725 do { 726 VertexInputAttributeDescription[i].binding = BindId; 727 VertexInputAttributeDescription[i].location = i; 728 VertexInputAttributeDescription[i].format = VK_FORMAT_R32G32B32_SFLOAT; 729 VertexInputAttributeDescription[i].offset = sizeof(float) * aByteStride; 730 i++; 731 } while (AttributeCount < i); 732 733 i = 0; 734 do { 735 VertexInputBindingDescription[i].binding = BindId; 736 VertexInputBindingDescription[i].stride = aByteStride; 737 VertexInputBindingDescription[i].inputRate = VK_VERTEX_INPUT_RATE_VERTEX; 738 i++; 739 } while (BindingCount < i); 740 } 741 742 ~VkVerticesObj() { 743 if (VertexInputAttributeDescription) { 744 delete[] VertexInputAttributeDescription; 745 } 746 if (VertexInputBindingDescription) { 747 delete[] VertexInputBindingDescription; 748 } 749 } 750 751 bool AddVertexInputToPipe(VkPipelineObj &aPipelineObj) { 752 aPipelineObj.AddVertexInputAttribs(VertexInputAttributeDescription, AttributeCount); 753 aPipelineObj.AddVertexInputBindings(VertexInputBindingDescription, BindingCount); 754 return true; 755 } 756 757 void BindVertexBuffers(VkCommandBuffer aCommandBuffer, unsigned aOffsetCount = 0, VkDeviceSize *aOffsetList = nullptr) { 758 VkDeviceSize *offsetList; 759 unsigned offsetCount; 760 761 if (aOffsetCount) { 762 offsetList = aOffsetList; 763 offsetCount = aOffsetCount; 764 } else { 765 offsetList = new VkDeviceSize[1](); 766 offsetCount = 1; 767 } 768 769 vkCmdBindVertexBuffers(aCommandBuffer, BindId, offsetCount, &VulkanMemoryBuffer.handle(), offsetList); 770 BoundCurrent = true; 771 772 if (!aOffsetCount) { 773 delete[] offsetList; 774 } 775 } 776 777 protected: 778 static uint32_t BindIdGenerator; 779 780 bool BoundCurrent; 781 unsigned AttributeCount; 782 unsigned BindingCount; 783 uint32_t BindId; 784 785 VkPipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo; 786 VkVertexInputAttributeDescription *VertexInputAttributeDescription; 787 VkVertexInputBindingDescription *VertexInputBindingDescription; 788 VkConstantBufferObj VulkanMemoryBuffer; 789 }; 790 791 uint32_t VkVerticesObj::BindIdGenerator; 792 // ******************************************************************************************************************** 793 // ******************************************************************************************************************** 794 // ******************************************************************************************************************** 795 // ******************************************************************************************************************** 796 #if PARAMETER_VALIDATION_TESTS 797 TEST_F(VkLayerTest, RequiredParameter) { 798 TEST_DESCRIPTION("Specify VK_NULL_HANDLE, NULL, and 0 for required handle, " 799 "pointer, array, and array count parameters"); 800 801 ASSERT_NO_FATAL_FAILURE(InitState()); 802 803 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pFeatures specified as NULL"); 804 // Specify NULL for a pointer to a handle 805 // Expected to trigger an error with 806 // parameter_validation::validate_required_pointer 807 vkGetPhysicalDeviceFeatures(gpu(), NULL); 808 m_errorMonitor->VerifyFound(); 809 810 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 811 "required parameter pQueueFamilyPropertyCount specified as NULL"); 812 // Specify NULL for pointer to array count 813 // Expected to trigger an error with parameter_validation::validate_array 814 vkGetPhysicalDeviceQueueFamilyProperties(gpu(), NULL, NULL); 815 m_errorMonitor->VerifyFound(); 816 817 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter viewportCount must be greater than 0"); 818 // Specify 0 for a required array count 819 // Expected to trigger an error with parameter_validation::validate_array 820 VkViewport view_port = {}; 821 m_commandBuffer->SetViewport(0, 0, &view_port); 822 m_errorMonitor->VerifyFound(); 823 824 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pViewports specified as NULL"); 825 // Specify NULL for a required array 826 // Expected to trigger an error with parameter_validation::validate_array 827 m_commandBuffer->SetViewport(0, 1, NULL); 828 m_errorMonitor->VerifyFound(); 829 830 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter memory specified as VK_NULL_HANDLE"); 831 // Specify VK_NULL_HANDLE for a required handle 832 // Expected to trigger an error with 833 // parameter_validation::validate_required_handle 834 vkUnmapMemory(device(), VK_NULL_HANDLE); 835 m_errorMonitor->VerifyFound(); 836 837 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 838 "required parameter pFences[0] specified as VK_NULL_HANDLE"); 839 // Specify VK_NULL_HANDLE for a required handle array entry 840 // Expected to trigger an error with 841 // parameter_validation::validate_required_handle_array 842 VkFence fence = VK_NULL_HANDLE; 843 vkResetFences(device(), 1, &fence); 844 m_errorMonitor->VerifyFound(); 845 846 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pAllocateInfo specified as NULL"); 847 // Specify NULL for a required struct pointer 848 // Expected to trigger an error with 849 // parameter_validation::validate_struct_type 850 VkDeviceMemory memory = VK_NULL_HANDLE; 851 vkAllocateMemory(device(), NULL, NULL, &memory); 852 m_errorMonitor->VerifyFound(); 853 854 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "value of faceMask must not be 0"); 855 // Specify 0 for a required VkFlags parameter 856 // Expected to trigger an error with parameter_validation::validate_flags 857 m_commandBuffer->SetStencilReference(0, 0); 858 m_errorMonitor->VerifyFound(); 859 860 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "value of pSubmits[0].pWaitDstStageMask[0] must not be 0"); 861 // Specify 0 for a required VkFlags array entry 862 // Expected to trigger an error with 863 // parameter_validation::validate_flags_array 864 VkSemaphore semaphore = VK_NULL_HANDLE; 865 VkPipelineStageFlags stageFlags = 0; 866 VkSubmitInfo submitInfo = {}; 867 submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 868 submitInfo.waitSemaphoreCount = 1; 869 submitInfo.pWaitSemaphores = &semaphore; 870 submitInfo.pWaitDstStageMask = &stageFlags; 871 vkQueueSubmit(m_device->m_queue, 1, &submitInfo, VK_NULL_HANDLE); 872 m_errorMonitor->VerifyFound(); 873 } 874 875 TEST_F(VkLayerTest, ReservedParameter) { 876 TEST_DESCRIPTION("Specify a non-zero value for a reserved parameter"); 877 878 ASSERT_NO_FATAL_FAILURE(InitState()); 879 880 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " must be 0"); 881 // Specify 0 for a reserved VkFlags parameter 882 // Expected to trigger an error with 883 // parameter_validation::validate_reserved_flags 884 VkEvent event_handle = VK_NULL_HANDLE; 885 VkEventCreateInfo event_info = {}; 886 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 887 event_info.flags = 1; 888 vkCreateEvent(device(), &event_info, NULL, &event_handle); 889 m_errorMonitor->VerifyFound(); 890 } 891 892 TEST_F(VkLayerTest, InvalidStructSType) { 893 TEST_DESCRIPTION("Specify an invalid VkStructureType for a Vulkan " 894 "structure's sType field"); 895 896 ASSERT_NO_FATAL_FAILURE(InitState()); 897 898 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pAllocateInfo->sType must be"); 899 // Zero struct memory, effectively setting sType to 900 // VK_STRUCTURE_TYPE_APPLICATION_INFO 901 // Expected to trigger an error with 902 // parameter_validation::validate_struct_type 903 VkMemoryAllocateInfo alloc_info = {}; 904 VkDeviceMemory memory = VK_NULL_HANDLE; 905 vkAllocateMemory(device(), &alloc_info, NULL, &memory); 906 m_errorMonitor->VerifyFound(); 907 908 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pSubmits[0].sType must be"); 909 // Zero struct memory, effectively setting sType to 910 // VK_STRUCTURE_TYPE_APPLICATION_INFO 911 // Expected to trigger an error with 912 // parameter_validation::validate_struct_type_array 913 VkSubmitInfo submit_info = {}; 914 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 915 m_errorMonitor->VerifyFound(); 916 } 917 918 TEST_F(VkLayerTest, InvalidStructPNext) { 919 TEST_DESCRIPTION("Specify an invalid value for a Vulkan structure's pNext field"); 920 921 ASSERT_NO_FATAL_FAILURE(InitState()); 922 923 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "value of pCreateInfo->pNext must be NULL"); 924 // Set VkMemoryAllocateInfo::pNext to a non-NULL value, when pNext must be NULL. 925 // Need to pick a function that has no allowed pNext structure types. 926 // Expected to trigger an error with parameter_validation::validate_struct_pnext 927 VkEvent event = VK_NULL_HANDLE; 928 VkEventCreateInfo event_alloc_info = {}; 929 // Zero-initialization will provide the correct sType 930 VkApplicationInfo app_info = {}; 931 event_alloc_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 932 event_alloc_info.pNext = &app_info; 933 vkCreateEvent(device(), &event_alloc_info, NULL, &event); 934 m_errorMonitor->VerifyFound(); 935 936 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, 937 " chain includes a structure with unexpected VkStructureType "); 938 // Set VkMemoryAllocateInfo::pNext to a non-NULL value, but use 939 // a function that has allowed pNext structure types and specify 940 // a structure type that is not allowed. 941 // Expected to trigger an error with parameter_validation::validate_struct_pnext 942 VkDeviceMemory memory = VK_NULL_HANDLE; 943 VkMemoryAllocateInfo memory_alloc_info = {}; 944 memory_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 945 memory_alloc_info.pNext = &app_info; 946 vkAllocateMemory(device(), &memory_alloc_info, NULL, &memory); 947 m_errorMonitor->VerifyFound(); 948 } 949 950 TEST_F(VkLayerTest, UnrecognizedValue) { 951 TEST_DESCRIPTION("Specify unrecognized Vulkan enumeration, flags, and VkBool32 values"); 952 953 ASSERT_NO_FATAL_FAILURE(InitState()); 954 955 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "does not fall within the begin..end " 956 "range of the core VkFormat " 957 "enumeration tokens"); 958 // Specify an invalid VkFormat value 959 // Expected to trigger an error with 960 // parameter_validation::validate_ranged_enum 961 VkFormatProperties format_properties; 962 vkGetPhysicalDeviceFormatProperties(gpu(), static_cast<VkFormat>(8000), &format_properties); 963 m_errorMonitor->VerifyFound(); 964 965 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "contains flag bits that are not recognized members of"); 966 // Specify an invalid VkFlags bitmask value 967 // Expected to trigger an error with parameter_validation::validate_flags 968 VkImageFormatProperties image_format_properties; 969 vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, 970 static_cast<VkImageUsageFlags>(1 << 25), 0, &image_format_properties); 971 m_errorMonitor->VerifyFound(); 972 973 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "contains flag bits that are not recognized members of"); 974 // Specify an invalid VkFlags array entry 975 // Expected to trigger an error with 976 // parameter_validation::validate_flags_array 977 VkSemaphore semaphore = VK_NULL_HANDLE; 978 VkPipelineStageFlags stage_flags = static_cast<VkPipelineStageFlags>(1 << 25); 979 VkSubmitInfo submit_info = {}; 980 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 981 submit_info.waitSemaphoreCount = 1; 982 submit_info.pWaitSemaphores = &semaphore; 983 submit_info.pWaitDstStageMask = &stage_flags; 984 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 985 m_errorMonitor->VerifyFound(); 986 987 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "is neither VK_TRUE nor VK_FALSE"); 988 // Specify an invalid VkBool32 value 989 // Expected to trigger a warning with 990 // parameter_validation::validate_bool32 991 VkSampler sampler = VK_NULL_HANDLE; 992 VkSamplerCreateInfo sampler_info = {}; 993 sampler_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; 994 sampler_info.pNext = NULL; 995 sampler_info.magFilter = VK_FILTER_NEAREST; 996 sampler_info.minFilter = VK_FILTER_NEAREST; 997 sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; 998 sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 999 sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 1000 sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 1001 sampler_info.mipLodBias = 1.0; 1002 sampler_info.maxAnisotropy = 1; 1003 sampler_info.compareEnable = VK_FALSE; 1004 sampler_info.compareOp = VK_COMPARE_OP_NEVER; 1005 sampler_info.minLod = 1.0; 1006 sampler_info.maxLod = 1.0; 1007 sampler_info.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; 1008 sampler_info.unnormalizedCoordinates = VK_FALSE; 1009 // Not VK_TRUE or VK_FALSE 1010 sampler_info.anisotropyEnable = 3; 1011 vkCreateSampler(m_device->device(), &sampler_info, NULL, &sampler); 1012 m_errorMonitor->VerifyFound(); 1013 } 1014 1015 TEST_F(VkLayerTest, FailedReturnValue) { 1016 TEST_DESCRIPTION("Check for a message describing a VkResult failure code"); 1017 1018 ASSERT_NO_FATAL_FAILURE(InitState()); 1019 1020 // Find an unsupported image format 1021 VkFormat unsupported = VK_FORMAT_UNDEFINED; 1022 for (int f = VK_FORMAT_BEGIN_RANGE; f <= VK_FORMAT_END_RANGE; f++) { 1023 VkFormat format = static_cast<VkFormat>(f); 1024 VkFormatProperties fProps = m_device->format_properties(format); 1025 if (format != VK_FORMAT_UNDEFINED && fProps.linearTilingFeatures == 0 && fProps.optimalTilingFeatures == 0) { 1026 unsupported = format; 1027 break; 1028 } 1029 } 1030 1031 if (unsupported != VK_FORMAT_UNDEFINED) { 1032 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, 1033 "the requested format is not supported on this device"); 1034 // Specify an unsupported VkFormat value to generate a 1035 // VK_ERROR_FORMAT_NOT_SUPPORTED return code 1036 // Expected to trigger a warning from 1037 // parameter_validation::validate_result 1038 VkImageFormatProperties image_format_properties; 1039 VkResult err = vkGetPhysicalDeviceImageFormatProperties(gpu(), unsupported, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, 1040 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0, &image_format_properties); 1041 ASSERT_TRUE(err == VK_ERROR_FORMAT_NOT_SUPPORTED); 1042 m_errorMonitor->VerifyFound(); 1043 } 1044 } 1045 1046 TEST_F(VkLayerTest, UpdateBufferAlignment) { 1047 TEST_DESCRIPTION("Check alignment parameters for vkCmdUpdateBuffer"); 1048 uint32_t updateData[] = {1, 2, 3, 4, 5, 6, 7, 8}; 1049 1050 ASSERT_NO_FATAL_FAILURE(InitState()); 1051 1052 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; 1053 vk_testing::Buffer buffer; 1054 buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs); 1055 1056 BeginCommandBuffer(); 1057 // Introduce failure by using dstOffset that is not multiple of 4 1058 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4"); 1059 m_commandBuffer->UpdateBuffer(buffer.handle(), 1, 4, updateData); 1060 m_errorMonitor->VerifyFound(); 1061 1062 // Introduce failure by using dataSize that is not multiple of 4 1063 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4"); 1064 m_commandBuffer->UpdateBuffer(buffer.handle(), 0, 6, updateData); 1065 m_errorMonitor->VerifyFound(); 1066 1067 // Introduce failure by using dataSize that is < 0 1068 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 1069 "must be greater than zero and less than or equal to 65536"); 1070 m_commandBuffer->UpdateBuffer(buffer.handle(), 0, -44, updateData); 1071 m_errorMonitor->VerifyFound(); 1072 1073 // Introduce failure by using dataSize that is > 65536 1074 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 1075 "must be greater than zero and less than or equal to 65536"); 1076 m_commandBuffer->UpdateBuffer(buffer.handle(), 0, 80000, updateData); 1077 m_errorMonitor->VerifyFound(); 1078 1079 EndCommandBuffer(); 1080 } 1081 1082 TEST_F(VkLayerTest, FillBufferAlignment) { 1083 TEST_DESCRIPTION("Check alignment parameters for vkCmdFillBuffer"); 1084 1085 ASSERT_NO_FATAL_FAILURE(InitState()); 1086 1087 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; 1088 vk_testing::Buffer buffer; 1089 buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs); 1090 1091 BeginCommandBuffer(); 1092 1093 // Introduce failure by using dstOffset that is not multiple of 4 1094 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4"); 1095 m_commandBuffer->FillBuffer(buffer.handle(), 1, 4, 0x11111111); 1096 m_errorMonitor->VerifyFound(); 1097 1098 // Introduce failure by using size that is not multiple of 4 1099 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is not a multiple of 4"); 1100 m_commandBuffer->FillBuffer(buffer.handle(), 0, 6, 0x11111111); 1101 m_errorMonitor->VerifyFound(); 1102 1103 // Introduce failure by using size that is zero 1104 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must be greater than zero"); 1105 m_commandBuffer->FillBuffer(buffer.handle(), 0, 0, 0x11111111); 1106 m_errorMonitor->VerifyFound(); 1107 1108 EndCommandBuffer(); 1109 } 1110 1111 TEST_F(VkLayerTest, PSOPolygonModeInvalid) { 1112 VkResult err; 1113 1114 TEST_DESCRIPTION("Attempt to use a non-solid polygon fill mode in a " 1115 "pipeline when this feature is not enabled."); 1116 1117 ASSERT_NO_FATAL_FAILURE(InitState()); 1118 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 1119 1120 std::vector<const char *> device_extension_names; 1121 auto features = m_device->phy().features(); 1122 // Artificially disable support for non-solid fill modes 1123 features.fillModeNonSolid = false; 1124 // The sacrificial device object 1125 VkDeviceObj test_device(0, gpu(), device_extension_names, &features); 1126 1127 VkRenderpassObj render_pass(&test_device); 1128 1129 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 1130 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 1131 pipeline_layout_ci.setLayoutCount = 0; 1132 pipeline_layout_ci.pSetLayouts = NULL; 1133 1134 VkPipelineLayout pipeline_layout; 1135 err = vkCreatePipelineLayout(test_device.device(), &pipeline_layout_ci, NULL, &pipeline_layout); 1136 ASSERT_VK_SUCCESS(err); 1137 1138 VkPipelineRasterizationStateCreateInfo rs_ci = {}; 1139 rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 1140 rs_ci.pNext = nullptr; 1141 rs_ci.lineWidth = 1.0f; 1142 rs_ci.rasterizerDiscardEnable = true; 1143 1144 VkShaderObj vs(&test_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 1145 VkShaderObj fs(&test_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 1146 1147 // Set polygonMode to unsupported value POINT, should fail 1148 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 1149 "polygonMode cannot be VK_POLYGON_MODE_POINT or VK_POLYGON_MODE_LINE"); 1150 { 1151 VkPipelineObj pipe(&test_device); 1152 pipe.AddShader(&vs); 1153 pipe.AddShader(&fs); 1154 pipe.AddColorAttachment(); 1155 // Introduce failure by setting unsupported polygon mode 1156 rs_ci.polygonMode = VK_POLYGON_MODE_POINT; 1157 pipe.SetRasterization(&rs_ci); 1158 pipe.CreateVKPipeline(pipeline_layout, render_pass.handle()); 1159 } 1160 m_errorMonitor->VerifyFound(); 1161 1162 // Try again with polygonMode=LINE, should fail 1163 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 1164 "polygonMode cannot be VK_POLYGON_MODE_POINT or VK_POLYGON_MODE_LINE"); 1165 { 1166 VkPipelineObj pipe(&test_device); 1167 pipe.AddShader(&vs); 1168 pipe.AddShader(&fs); 1169 pipe.AddColorAttachment(); 1170 // Introduce failure by setting unsupported polygon mode 1171 rs_ci.polygonMode = VK_POLYGON_MODE_LINE; 1172 pipe.SetRasterization(&rs_ci); 1173 pipe.CreateVKPipeline(pipeline_layout, render_pass.handle()); 1174 } 1175 m_errorMonitor->VerifyFound(); 1176 1177 vkDestroyPipelineLayout(test_device.device(), pipeline_layout, NULL); 1178 } 1179 1180 #endif // PARAMETER_VALIDATION_TESTS 1181 1182 #if MEM_TRACKER_TESTS 1183 #if 0 1184 TEST_F(VkLayerTest, CallResetCommandBufferBeforeCompletion) 1185 { 1186 vk_testing::Fence testFence; 1187 VkFenceCreateInfo fenceInfo = {}; 1188 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 1189 fenceInfo.pNext = NULL; 1190 fenceInfo.flags = 0; 1191 1192 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Resetting command buffer"); 1193 1194 ASSERT_NO_FATAL_FAILURE(InitState()); 1195 1196 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; 1197 vk_testing::Buffer buffer; 1198 buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs); 1199 1200 BeginCommandBuffer(); 1201 m_commandBuffer->FillBuffer(buffer.handle(), 0, 4, 0x11111111); 1202 EndCommandBuffer(); 1203 1204 testFence.init(*m_device, fenceInfo); 1205 1206 // Bypass framework since it does the waits automatically 1207 VkResult err = VK_SUCCESS; 1208 VkSubmitInfo submit_info; 1209 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 1210 submit_info.pNext = NULL; 1211 submit_info.waitSemaphoreCount = 0; 1212 submit_info.pWaitSemaphores = NULL; 1213 submit_info.pWaitDstStageMask = NULL; 1214 submit_info.commandBufferCount = 1; 1215 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 1216 submit_info.signalSemaphoreCount = 0; 1217 submit_info.pSignalSemaphores = NULL; 1218 1219 err = vkQueueSubmit( m_device->m_queue, 1, &submit_info, testFence.handle()); 1220 ASSERT_VK_SUCCESS( err ); 1221 1222 // Introduce failure by calling begin again before checking fence 1223 vkResetCommandBuffer(m_commandBuffer->handle(), 0); 1224 1225 m_errorMonitor->VerifyFound(); 1226 } 1227 1228 TEST_F(VkLayerTest, CallBeginCommandBufferBeforeCompletion) 1229 { 1230 vk_testing::Fence testFence; 1231 VkFenceCreateInfo fenceInfo = {}; 1232 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 1233 fenceInfo.pNext = NULL; 1234 fenceInfo.flags = 0; 1235 1236 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Calling vkBeginCommandBuffer() on active command buffer"); 1237 1238 ASSERT_NO_FATAL_FAILURE(InitState()); 1239 ASSERT_NO_FATAL_FAILURE(InitViewport()); 1240 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 1241 1242 BeginCommandBuffer(); 1243 m_commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL); 1244 EndCommandBuffer(); 1245 1246 testFence.init(*m_device, fenceInfo); 1247 1248 // Bypass framework since it does the waits automatically 1249 VkResult err = VK_SUCCESS; 1250 VkSubmitInfo submit_info; 1251 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 1252 submit_info.pNext = NULL; 1253 submit_info.waitSemaphoreCount = 0; 1254 submit_info.pWaitSemaphores = NULL; 1255 submit_info.pWaitDstStageMask = NULL; 1256 submit_info.commandBufferCount = 1; 1257 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 1258 submit_info.signalSemaphoreCount = 0; 1259 submit_info.pSignalSemaphores = NULL; 1260 1261 err = vkQueueSubmit( m_device->m_queue, 1, &submit_info, testFence.handle()); 1262 ASSERT_VK_SUCCESS( err ); 1263 1264 VkCommandBufferInheritanceInfo hinfo = {}; 1265 VkCommandBufferBeginInfo info = {}; 1266 info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; 1267 info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 1268 info.renderPass = VK_NULL_HANDLE; 1269 info.subpass = 0; 1270 info.framebuffer = VK_NULL_HANDLE; 1271 info.occlusionQueryEnable = VK_FALSE; 1272 info.queryFlags = 0; 1273 info.pipelineStatistics = 0; 1274 1275 // Introduce failure by calling BCB again before checking fence 1276 vkBeginCommandBuffer(m_commandBuffer->handle(), &info); 1277 1278 m_errorMonitor->VerifyFound(); 1279 } 1280 #endif 1281 1282 TEST_F(VkLayerTest, InvalidMemoryAliasing) { 1283 TEST_DESCRIPTION("Create a buffer and image, allocate memory, and bind the " 1284 "buffer and image to memory such that they will alias."); 1285 VkResult err; 1286 bool pass; 1287 ASSERT_NO_FATAL_FAILURE(InitState()); 1288 1289 VkBuffer buffer, buffer2; 1290 VkImage image; 1291 VkImage image2; 1292 VkDeviceMemory mem; // buffer will be bound first 1293 VkDeviceMemory mem_img; // image bound first 1294 VkMemoryRequirements buff_mem_reqs, img_mem_reqs; 1295 1296 VkBufferCreateInfo buf_info = {}; 1297 buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 1298 buf_info.pNext = NULL; 1299 buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 1300 buf_info.size = 256; 1301 buf_info.queueFamilyIndexCount = 0; 1302 buf_info.pQueueFamilyIndices = NULL; 1303 buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 1304 buf_info.flags = 0; 1305 err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer); 1306 ASSERT_VK_SUCCESS(err); 1307 1308 vkGetBufferMemoryRequirements(m_device->device(), buffer, &buff_mem_reqs); 1309 1310 VkImageCreateInfo image_create_info = {}; 1311 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 1312 image_create_info.pNext = NULL; 1313 image_create_info.imageType = VK_IMAGE_TYPE_2D; 1314 image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM; 1315 image_create_info.extent.width = 64; 1316 image_create_info.extent.height = 64; 1317 image_create_info.extent.depth = 1; 1318 image_create_info.mipLevels = 1; 1319 image_create_info.arrayLayers = 1; 1320 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 1321 // Image tiling must be optimal to trigger error when aliasing linear buffer 1322 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 1323 image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; 1324 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 1325 image_create_info.queueFamilyIndexCount = 0; 1326 image_create_info.pQueueFamilyIndices = NULL; 1327 image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 1328 image_create_info.flags = 0; 1329 1330 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 1331 ASSERT_VK_SUCCESS(err); 1332 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image2); 1333 ASSERT_VK_SUCCESS(err); 1334 1335 vkGetImageMemoryRequirements(m_device->device(), image, &img_mem_reqs); 1336 1337 VkMemoryAllocateInfo alloc_info = {}; 1338 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 1339 alloc_info.pNext = NULL; 1340 alloc_info.memoryTypeIndex = 0; 1341 // Ensure memory is big enough for both bindings 1342 alloc_info.allocationSize = buff_mem_reqs.size + img_mem_reqs.size; 1343 pass = m_device->phy().set_memory_type(buff_mem_reqs.memoryTypeBits & img_mem_reqs.memoryTypeBits, &alloc_info, 1344 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); 1345 if (!pass) { 1346 vkDestroyBuffer(m_device->device(), buffer, NULL); 1347 vkDestroyImage(m_device->device(), image, NULL); 1348 return; 1349 } 1350 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem); 1351 ASSERT_VK_SUCCESS(err); 1352 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0); 1353 ASSERT_VK_SUCCESS(err); 1354 1355 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is aliased with linear buffer 0x"); 1356 // VALIDATION FAILURE due to image mapping overlapping buffer mapping 1357 err = vkBindImageMemory(m_device->device(), image, mem, 0); 1358 m_errorMonitor->VerifyFound(); 1359 1360 // Now correctly bind image2 to second mem allocation before incorrectly 1361 // aliasing buffer2 1362 err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer2); 1363 ASSERT_VK_SUCCESS(err); 1364 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem_img); 1365 ASSERT_VK_SUCCESS(err); 1366 err = vkBindImageMemory(m_device->device(), image2, mem_img, 0); 1367 ASSERT_VK_SUCCESS(err); 1368 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is aliased with non-linear image 0x"); 1369 err = vkBindBufferMemory(m_device->device(), buffer2, mem_img, 0); 1370 m_errorMonitor->VerifyFound(); 1371 1372 vkDestroyBuffer(m_device->device(), buffer, NULL); 1373 vkDestroyBuffer(m_device->device(), buffer2, NULL); 1374 vkDestroyImage(m_device->device(), image, NULL); 1375 vkDestroyImage(m_device->device(), image2, NULL); 1376 vkFreeMemory(m_device->device(), mem, NULL); 1377 vkFreeMemory(m_device->device(), mem_img, NULL); 1378 } 1379 1380 TEST_F(VkLayerTest, InvalidMemoryMapping) { 1381 TEST_DESCRIPTION("Attempt to map memory in a number of incorrect ways"); 1382 VkResult err; 1383 bool pass; 1384 ASSERT_NO_FATAL_FAILURE(InitState()); 1385 1386 VkBuffer buffer; 1387 VkDeviceMemory mem; 1388 VkMemoryRequirements mem_reqs; 1389 1390 VkBufferCreateInfo buf_info = {}; 1391 buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 1392 buf_info.pNext = NULL; 1393 buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 1394 buf_info.size = 256; 1395 buf_info.queueFamilyIndexCount = 0; 1396 buf_info.pQueueFamilyIndices = NULL; 1397 buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 1398 buf_info.flags = 0; 1399 err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer); 1400 ASSERT_VK_SUCCESS(err); 1401 1402 vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs); 1403 VkMemoryAllocateInfo alloc_info = {}; 1404 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 1405 alloc_info.pNext = NULL; 1406 alloc_info.memoryTypeIndex = 0; 1407 1408 // Ensure memory is big enough for both bindings 1409 static const VkDeviceSize allocation_size = 0x10000; 1410 alloc_info.allocationSize = allocation_size; 1411 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); 1412 if (!pass) { 1413 vkDestroyBuffer(m_device->device(), buffer, NULL); 1414 return; 1415 } 1416 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem); 1417 ASSERT_VK_SUCCESS(err); 1418 1419 uint8_t *pData; 1420 // Attempt to map memory size 0 is invalid 1421 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VkMapMemory: Attempting to map memory range of size zero"); 1422 err = vkMapMemory(m_device->device(), mem, 0, 0, 0, (void **)&pData); 1423 m_errorMonitor->VerifyFound(); 1424 // Map memory twice 1425 err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData); 1426 ASSERT_VK_SUCCESS(err); 1427 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 1428 "VkMapMemory: Attempting to map memory on an already-mapped object "); 1429 err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData); 1430 m_errorMonitor->VerifyFound(); 1431 1432 // Unmap the memory to avoid re-map error 1433 vkUnmapMemory(m_device->device(), mem); 1434 // overstep allocation with VK_WHOLE_SIZE 1435 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 1436 " with size of VK_WHOLE_SIZE oversteps total array size 0x"); 1437 err = vkMapMemory(m_device->device(), mem, allocation_size + 1, VK_WHOLE_SIZE, 0, (void **)&pData); 1438 m_errorMonitor->VerifyFound(); 1439 // overstep allocation w/o VK_WHOLE_SIZE 1440 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " oversteps total array size 0x"); 1441 err = vkMapMemory(m_device->device(), mem, 1, allocation_size, 0, (void **)&pData); 1442 m_errorMonitor->VerifyFound(); 1443 // Now error due to unmapping memory that's not mapped 1444 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Unmapping Memory without memory being mapped: "); 1445 vkUnmapMemory(m_device->device(), mem); 1446 m_errorMonitor->VerifyFound(); 1447 // Now map memory and cause errors due to flushing invalid ranges 1448 err = vkMapMemory(m_device->device(), mem, 16, VK_WHOLE_SIZE, 0, (void **)&pData); 1449 ASSERT_VK_SUCCESS(err); 1450 VkMappedMemoryRange mmr = {}; 1451 mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; 1452 mmr.memory = mem; 1453 mmr.offset = 15; // Error b/c offset less than offset of mapped mem 1454 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, ") is less than Memory Object's offset ("); 1455 vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr); 1456 m_errorMonitor->VerifyFound(); 1457 // Now flush range that oversteps mapped range 1458 vkUnmapMemory(m_device->device(), mem); 1459 err = vkMapMemory(m_device->device(), mem, 0, 256, 0, (void **)&pData); 1460 ASSERT_VK_SUCCESS(err); 1461 mmr.offset = 16; 1462 mmr.size = 256; // flushing bounds (272) exceed mapped bounds (256) 1463 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, ") exceeds the Memory Object's upper-bound ("); 1464 vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr); 1465 m_errorMonitor->VerifyFound(); 1466 1467 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 1468 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); 1469 if (!pass) { 1470 vkFreeMemory(m_device->device(), mem, NULL); 1471 vkDestroyBuffer(m_device->device(), buffer, NULL); 1472 return; 1473 } 1474 // TODO : If we can get HOST_VISIBLE w/o HOST_COHERENT we can test cases of 1475 // MEMTRACK_INVALID_MAP in validateAndCopyNoncoherentMemoryToDriver() 1476 1477 vkDestroyBuffer(m_device->device(), buffer, NULL); 1478 vkFreeMemory(m_device->device(), mem, NULL); 1479 } 1480 1481 TEST_F(VkLayerTest, EnableWsiBeforeUse) { 1482 VkResult err; 1483 bool pass; 1484 1485 // FIXME: After we turn on this code for non-Linux platforms, uncomment the 1486 // following declaration (which is temporarily being moved below): 1487 // VkSurfaceKHR surface = VK_NULL_HANDLE; 1488 VkSwapchainKHR swapchain = VK_NULL_HANDLE; 1489 VkSwapchainCreateInfoKHR swapchain_create_info = {}; 1490 uint32_t swapchain_image_count = 0; 1491 // VkImage swapchain_images[1] = {VK_NULL_HANDLE}; 1492 uint32_t image_index = 0; 1493 // VkPresentInfoKHR present_info = {}; 1494 1495 ASSERT_NO_FATAL_FAILURE(InitState()); 1496 1497 #ifdef NEED_TO_TEST_THIS_ON_PLATFORM 1498 #if defined(VK_USE_PLATFORM_ANDROID_KHR) 1499 // Use the functions from the VK_KHR_android_surface extension without 1500 // enabling that extension: 1501 1502 // Create a surface: 1503 VkAndroidSurfaceCreateInfoKHR android_create_info = {}; 1504 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this"); 1505 err = vkCreateAndroidSurfaceKHR(instance(), &android_create_info, NULL, &surface); 1506 pass = (err != VK_SUCCESS); 1507 ASSERT_TRUE(pass); 1508 m_errorMonitor->VerifyFound(); 1509 #endif // VK_USE_PLATFORM_ANDROID_KHR 1510 1511 #if defined(VK_USE_PLATFORM_MIR_KHR) 1512 // Use the functions from the VK_KHR_mir_surface extension without enabling 1513 // that extension: 1514 1515 // Create a surface: 1516 VkMirSurfaceCreateInfoKHR mir_create_info = {}; 1517 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this"); 1518 err = vkCreateMirSurfaceKHR(instance(), &mir_create_info, NULL, &surface); 1519 pass = (err != VK_SUCCESS); 1520 ASSERT_TRUE(pass); 1521 m_errorMonitor->VerifyFound(); 1522 1523 // Tell whether an mir_connection supports presentation: 1524 MirConnection *mir_connection = NULL; 1525 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this"); 1526 vkGetPhysicalDeviceMirPresentationSupportKHR(gpu(), 0, mir_connection, visual_id); 1527 m_errorMonitor->VerifyFound(); 1528 #endif // VK_USE_PLATFORM_MIR_KHR 1529 1530 #if defined(VK_USE_PLATFORM_WAYLAND_KHR) 1531 // Use the functions from the VK_KHR_wayland_surface extension without 1532 // enabling that extension: 1533 1534 // Create a surface: 1535 VkWaylandSurfaceCreateInfoKHR wayland_create_info = {}; 1536 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this"); 1537 err = vkCreateWaylandSurfaceKHR(instance(), &wayland_create_info, NULL, &surface); 1538 pass = (err != VK_SUCCESS); 1539 ASSERT_TRUE(pass); 1540 m_errorMonitor->VerifyFound(); 1541 1542 // Tell whether an wayland_display supports presentation: 1543 struct wl_display wayland_display = {}; 1544 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this"); 1545 vkGetPhysicalDeviceWaylandPresentationSupportKHR(gpu(), 0, &wayland_display); 1546 m_errorMonitor->VerifyFound(); 1547 #endif // VK_USE_PLATFORM_WAYLAND_KHR 1548 #endif // NEED_TO_TEST_THIS_ON_PLATFORM 1549 1550 #if defined(VK_USE_PLATFORM_WIN32_KHR) 1551 // FIXME: REMOVE THIS HERE, AND UNCOMMENT ABOVE, WHEN THIS TEST HAS BEEN PORTED 1552 // TO NON-LINUX PLATFORMS: 1553 VkSurfaceKHR surface = VK_NULL_HANDLE; 1554 // Use the functions from the VK_KHR_win32_surface extension without 1555 // enabling that extension: 1556 1557 // Create a surface: 1558 VkWin32SurfaceCreateInfoKHR win32_create_info = {}; 1559 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this"); 1560 err = vkCreateWin32SurfaceKHR(instance(), &win32_create_info, NULL, &surface); 1561 pass = (err != VK_SUCCESS); 1562 ASSERT_TRUE(pass); 1563 m_errorMonitor->VerifyFound(); 1564 1565 // Tell whether win32 supports presentation: 1566 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this"); 1567 vkGetPhysicalDeviceWin32PresentationSupportKHR(gpu(), 0); 1568 m_errorMonitor->VerifyFound(); 1569 // Set this (for now, until all platforms are supported and tested): 1570 #define NEED_TO_TEST_THIS_ON_PLATFORM 1571 #endif // VK_USE_PLATFORM_WIN32_KHR 1572 1573 #if defined(VK_USE_PLATFORM_XCB_KHR) 1574 // FIXME: REMOVE THIS HERE, AND UNCOMMENT ABOVE, WHEN THIS TEST HAS BEEN PORTED 1575 // TO NON-LINUX PLATFORMS: 1576 VkSurfaceKHR surface = VK_NULL_HANDLE; 1577 // Use the functions from the VK_KHR_xcb_surface extension without enabling 1578 // that extension: 1579 1580 // Create a surface: 1581 VkXcbSurfaceCreateInfoKHR xcb_create_info = {}; 1582 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this"); 1583 err = vkCreateXcbSurfaceKHR(instance(), &xcb_create_info, NULL, &surface); 1584 pass = (err != VK_SUCCESS); 1585 ASSERT_TRUE(pass); 1586 m_errorMonitor->VerifyFound(); 1587 1588 // Tell whether an xcb_visualid_t supports presentation: 1589 xcb_connection_t *xcb_connection = NULL; 1590 xcb_visualid_t visual_id = 0; 1591 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this"); 1592 vkGetPhysicalDeviceXcbPresentationSupportKHR(gpu(), 0, xcb_connection, visual_id); 1593 m_errorMonitor->VerifyFound(); 1594 // Set this (for now, until all platforms are supported and tested): 1595 #define NEED_TO_TEST_THIS_ON_PLATFORM 1596 #endif // VK_USE_PLATFORM_XCB_KHR 1597 1598 #if defined(VK_USE_PLATFORM_XLIB_KHR) 1599 // Use the functions from the VK_KHR_xlib_surface extension without enabling 1600 // that extension: 1601 1602 // Create a surface: 1603 VkXlibSurfaceCreateInfoKHR xlib_create_info = {}; 1604 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this"); 1605 err = vkCreateXlibSurfaceKHR(instance(), &xlib_create_info, NULL, &surface); 1606 pass = (err != VK_SUCCESS); 1607 ASSERT_TRUE(pass); 1608 m_errorMonitor->VerifyFound(); 1609 1610 // Tell whether an Xlib VisualID supports presentation: 1611 Display *dpy = NULL; 1612 VisualID visual = 0; 1613 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this"); 1614 vkGetPhysicalDeviceXlibPresentationSupportKHR(gpu(), 0, dpy, visual); 1615 m_errorMonitor->VerifyFound(); 1616 // Set this (for now, until all platforms are supported and tested): 1617 #define NEED_TO_TEST_THIS_ON_PLATFORM 1618 #endif // VK_USE_PLATFORM_XLIB_KHR 1619 1620 // Use the functions from the VK_KHR_surface extension without enabling 1621 // that extension: 1622 1623 #ifdef NEED_TO_TEST_THIS_ON_PLATFORM 1624 // Destroy a surface: 1625 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this"); 1626 vkDestroySurfaceKHR(instance(), surface, NULL); 1627 m_errorMonitor->VerifyFound(); 1628 1629 // Check if surface supports presentation: 1630 VkBool32 supported = false; 1631 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this"); 1632 err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu(), 0, surface, &supported); 1633 pass = (err != VK_SUCCESS); 1634 ASSERT_TRUE(pass); 1635 m_errorMonitor->VerifyFound(); 1636 1637 // Check surface capabilities: 1638 VkSurfaceCapabilitiesKHR capabilities = {}; 1639 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this"); 1640 err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu(), surface, &capabilities); 1641 pass = (err != VK_SUCCESS); 1642 ASSERT_TRUE(pass); 1643 m_errorMonitor->VerifyFound(); 1644 1645 // Check surface formats: 1646 uint32_t format_count = 0; 1647 VkSurfaceFormatKHR *formats = NULL; 1648 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this"); 1649 err = vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &format_count, formats); 1650 pass = (err != VK_SUCCESS); 1651 ASSERT_TRUE(pass); 1652 m_errorMonitor->VerifyFound(); 1653 1654 // Check surface present modes: 1655 uint32_t present_mode_count = 0; 1656 VkSurfaceFormatKHR *present_modes = NULL; 1657 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this"); 1658 err = vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &present_mode_count, present_modes); 1659 pass = (err != VK_SUCCESS); 1660 ASSERT_TRUE(pass); 1661 m_errorMonitor->VerifyFound(); 1662 #endif // NEED_TO_TEST_THIS_ON_PLATFORM 1663 1664 // Use the functions from the VK_KHR_swapchain extension without enabling 1665 // that extension: 1666 1667 // Create a swapchain: 1668 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this"); 1669 swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; 1670 swapchain_create_info.pNext = NULL; 1671 err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain); 1672 pass = (err != VK_SUCCESS); 1673 ASSERT_TRUE(pass); 1674 m_errorMonitor->VerifyFound(); 1675 1676 // Get the images from the swapchain: 1677 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this"); 1678 err = vkGetSwapchainImagesKHR(m_device->device(), swapchain, &swapchain_image_count, NULL); 1679 pass = (err != VK_SUCCESS); 1680 ASSERT_TRUE(pass); 1681 m_errorMonitor->VerifyFound(); 1682 1683 // Add a fence to avoid (justifiable) error about not providing fence OR semaphore 1684 VkFenceCreateInfo fci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 }; 1685 VkFence fence; 1686 err = vkCreateFence(m_device->device(), &fci, nullptr, &fence); 1687 1688 // Try to acquire an image: 1689 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this"); 1690 err = vkAcquireNextImageKHR(m_device->device(), swapchain, 0, VK_NULL_HANDLE, fence, &image_index); 1691 pass = (err != VK_SUCCESS); 1692 ASSERT_TRUE(pass); 1693 m_errorMonitor->VerifyFound(); 1694 1695 vkDestroyFence(m_device->device(), fence, nullptr); 1696 1697 // Try to present an image: 1698 // 1699 // NOTE: Currently can't test this because a real swapchain is needed (as 1700 // opposed to the fake one we created) in order for the layer to lookup the 1701 // VkDevice used to enable the extension: 1702 1703 // Destroy the swapchain: 1704 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this"); 1705 vkDestroySwapchainKHR(m_device->device(), swapchain, NULL); 1706 m_errorMonitor->VerifyFound(); 1707 } 1708 1709 TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit) { 1710 VkResult err; 1711 bool pass; 1712 1713 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 1714 "Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT"); 1715 1716 ASSERT_NO_FATAL_FAILURE(InitState()); 1717 1718 // Create an image, allocate memory, free it, and then try to bind it 1719 VkImage image; 1720 VkDeviceMemory mem; 1721 VkMemoryRequirements mem_reqs; 1722 1723 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 1724 const int32_t tex_width = 32; 1725 const int32_t tex_height = 32; 1726 1727 VkImageCreateInfo image_create_info = {}; 1728 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 1729 image_create_info.pNext = NULL; 1730 image_create_info.imageType = VK_IMAGE_TYPE_2D; 1731 image_create_info.format = tex_format; 1732 image_create_info.extent.width = tex_width; 1733 image_create_info.extent.height = tex_height; 1734 image_create_info.extent.depth = 1; 1735 image_create_info.mipLevels = 1; 1736 image_create_info.arrayLayers = 1; 1737 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 1738 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 1739 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 1740 image_create_info.flags = 0; 1741 image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; 1742 1743 VkMemoryAllocateInfo mem_alloc = {}; 1744 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 1745 mem_alloc.pNext = NULL; 1746 mem_alloc.allocationSize = 0; 1747 1748 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 1749 ASSERT_VK_SUCCESS(err); 1750 1751 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs); 1752 1753 mem_alloc.allocationSize = mem_reqs.size; 1754 1755 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); 1756 if (!pass) { // If we can't find any unmappable memory this test doesn't 1757 // make sense 1758 vkDestroyImage(m_device->device(), image, NULL); 1759 return; 1760 } 1761 1762 // allocate memory 1763 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem); 1764 ASSERT_VK_SUCCESS(err); 1765 1766 // Try to bind free memory that has been freed 1767 err = vkBindImageMemory(m_device->device(), image, mem, 0); 1768 ASSERT_VK_SUCCESS(err); 1769 1770 // Map memory as if to initialize the image 1771 void *mappedAddress = NULL; 1772 err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, &mappedAddress); 1773 1774 m_errorMonitor->VerifyFound(); 1775 1776 vkDestroyImage(m_device->device(), image, NULL); 1777 vkFreeMemory(m_device->device(), mem, NULL); 1778 } 1779 1780 TEST_F(VkLayerTest, RebindMemory) { 1781 VkResult err; 1782 bool pass; 1783 1784 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "which has already been bound to mem object"); 1785 1786 ASSERT_NO_FATAL_FAILURE(InitState()); 1787 1788 // Create an image, allocate memory, free it, and then try to bind it 1789 VkImage image; 1790 VkDeviceMemory mem1; 1791 VkDeviceMemory mem2; 1792 VkMemoryRequirements mem_reqs; 1793 1794 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 1795 const int32_t tex_width = 32; 1796 const int32_t tex_height = 32; 1797 1798 VkImageCreateInfo image_create_info = {}; 1799 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 1800 image_create_info.pNext = NULL; 1801 image_create_info.imageType = VK_IMAGE_TYPE_2D; 1802 image_create_info.format = tex_format; 1803 image_create_info.extent.width = tex_width; 1804 image_create_info.extent.height = tex_height; 1805 image_create_info.extent.depth = 1; 1806 image_create_info.mipLevels = 1; 1807 image_create_info.arrayLayers = 1; 1808 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 1809 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 1810 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 1811 image_create_info.flags = 0; 1812 1813 VkMemoryAllocateInfo mem_alloc = {}; 1814 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 1815 mem_alloc.pNext = NULL; 1816 mem_alloc.allocationSize = 0; 1817 mem_alloc.memoryTypeIndex = 0; 1818 1819 // Introduce failure, do NOT set memProps to 1820 // VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT 1821 mem_alloc.memoryTypeIndex = 1; 1822 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 1823 ASSERT_VK_SUCCESS(err); 1824 1825 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs); 1826 1827 mem_alloc.allocationSize = mem_reqs.size; 1828 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0); 1829 ASSERT_TRUE(pass); 1830 1831 // allocate 2 memory objects 1832 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem1); 1833 ASSERT_VK_SUCCESS(err); 1834 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem2); 1835 ASSERT_VK_SUCCESS(err); 1836 1837 // Bind first memory object to Image object 1838 err = vkBindImageMemory(m_device->device(), image, mem1, 0); 1839 ASSERT_VK_SUCCESS(err); 1840 1841 // Introduce validation failure, try to bind a different memory object to 1842 // the same image object 1843 err = vkBindImageMemory(m_device->device(), image, mem2, 0); 1844 1845 m_errorMonitor->VerifyFound(); 1846 1847 vkDestroyImage(m_device->device(), image, NULL); 1848 vkFreeMemory(m_device->device(), mem1, NULL); 1849 vkFreeMemory(m_device->device(), mem2, NULL); 1850 } 1851 1852 TEST_F(VkLayerTest, SubmitSignaledFence) { 1853 vk_testing::Fence testFence; 1854 1855 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "submitted in SIGNALED state. Fences " 1856 "must be reset before being submitted"); 1857 1858 VkFenceCreateInfo fenceInfo = {}; 1859 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 1860 fenceInfo.pNext = NULL; 1861 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; 1862 1863 ASSERT_NO_FATAL_FAILURE(InitState()); 1864 ASSERT_NO_FATAL_FAILURE(InitViewport()); 1865 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 1866 1867 BeginCommandBuffer(); 1868 m_commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL); 1869 EndCommandBuffer(); 1870 1871 testFence.init(*m_device, fenceInfo); 1872 1873 VkSubmitInfo submit_info; 1874 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 1875 submit_info.pNext = NULL; 1876 submit_info.waitSemaphoreCount = 0; 1877 submit_info.pWaitSemaphores = NULL; 1878 submit_info.pWaitDstStageMask = NULL; 1879 submit_info.commandBufferCount = 1; 1880 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 1881 submit_info.signalSemaphoreCount = 0; 1882 submit_info.pSignalSemaphores = NULL; 1883 1884 vkQueueSubmit(m_device->m_queue, 1, &submit_info, testFence.handle()); 1885 vkQueueWaitIdle(m_device->m_queue); 1886 1887 m_errorMonitor->VerifyFound(); 1888 } 1889 1890 TEST_F(VkLayerTest, InvalidUsageBits) { 1891 TEST_DESCRIPTION("Specify wrong usage for image then create conflicting view of image " 1892 "Initialize buffer with wrong usage then perform copy expecting errors " 1893 "from both the image and the buffer (2 calls)"); 1894 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid usage flag for image "); 1895 1896 ASSERT_NO_FATAL_FAILURE(InitState()); 1897 VkImageObj image(m_device); 1898 // Initialize image with USAGE_TRANSIENT_ATTACHMENT 1899 image.init(128, 128, VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 1900 ASSERT_TRUE(image.initialized()); 1901 1902 VkImageView dsv; 1903 VkImageViewCreateInfo dsvci = {}; 1904 dsvci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 1905 dsvci.image = image.handle(); 1906 dsvci.viewType = VK_IMAGE_VIEW_TYPE_2D; 1907 dsvci.format = VK_FORMAT_D32_SFLOAT_S8_UINT; 1908 dsvci.subresourceRange.layerCount = 1; 1909 dsvci.subresourceRange.baseMipLevel = 0; 1910 dsvci.subresourceRange.levelCount = 1; 1911 dsvci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 1912 1913 // Create a view with depth / stencil aspect for image with different usage 1914 vkCreateImageView(m_device->device(), &dsvci, NULL, &dsv); 1915 1916 m_errorMonitor->VerifyFound(); 1917 1918 // Initialize buffer with TRANSFER_DST usage 1919 vk_testing::Buffer buffer; 1920 VkMemoryPropertyFlags reqs = 0; 1921 buffer.init_as_dst(*m_device, 128 * 128, reqs); 1922 VkBufferImageCopy region = {}; 1923 region.bufferRowLength = 128; 1924 region.bufferImageHeight = 128; 1925 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 1926 region.imageSubresource.layerCount = 1; 1927 region.imageExtent.height = 16; 1928 region.imageExtent.width = 16; 1929 region.imageExtent.depth = 1; 1930 1931 // Buffer usage not set to TRANSFER_SRC and image usage not set to 1932 // TRANSFER_DST 1933 BeginCommandBuffer(); 1934 1935 // two separate errors from this call: 1936 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "image should have VK_IMAGE_USAGE_TRANSFER_DST_BIT"); 1937 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "buffer should have VK_BUFFER_USAGE_TRANSFER_SRC_BIT"); 1938 1939 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(), 1940 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); 1941 m_errorMonitor->VerifyFound(); 1942 } 1943 1944 1945 #endif // MEM_TRACKER_TESTS 1946 1947 #if OBJ_TRACKER_TESTS 1948 1949 TEST_F(VkLayerTest, LeakAnObject) { 1950 VkResult err; 1951 1952 TEST_DESCRIPTION("Create a fence and destroy its device without first destroying the fence."); 1953 1954 // Note that we have to create a new device since destroying the 1955 // framework's device causes Teardown() to fail and just calling Teardown 1956 // will destroy the errorMonitor. 1957 1958 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "has not been destroyed."); 1959 1960 ASSERT_NO_FATAL_FAILURE(InitState()); 1961 1962 const std::vector<VkQueueFamilyProperties> queue_props = m_device->queue_props; 1963 std::vector<VkDeviceQueueCreateInfo> queue_info; 1964 queue_info.reserve(queue_props.size()); 1965 std::vector<std::vector<float>> queue_priorities; 1966 for (uint32_t i = 0; i < (uint32_t)queue_props.size(); i++) { 1967 VkDeviceQueueCreateInfo qi = {}; 1968 qi.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 1969 qi.pNext = NULL; 1970 qi.queueFamilyIndex = i; 1971 qi.queueCount = queue_props[i].queueCount; 1972 queue_priorities.emplace_back(qi.queueCount, 0.0f); 1973 qi.pQueuePriorities = queue_priorities[i].data(); 1974 queue_info.push_back(qi); 1975 } 1976 1977 std::vector<const char *> device_extension_names; 1978 1979 // The sacrificial device object 1980 VkDevice testDevice; 1981 VkDeviceCreateInfo device_create_info = {}; 1982 auto features = m_device->phy().features(); 1983 device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; 1984 device_create_info.pNext = NULL; 1985 device_create_info.queueCreateInfoCount = queue_info.size(); 1986 device_create_info.pQueueCreateInfos = queue_info.data(); 1987 device_create_info.enabledLayerCount = 0; 1988 device_create_info.ppEnabledLayerNames = NULL; 1989 device_create_info.pEnabledFeatures = &features; 1990 err = vkCreateDevice(gpu(), &device_create_info, NULL, &testDevice); 1991 ASSERT_VK_SUCCESS(err); 1992 1993 VkFence fence; 1994 VkFenceCreateInfo fence_create_info = {}; 1995 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 1996 fence_create_info.pNext = NULL; 1997 fence_create_info.flags = 0; 1998 err = vkCreateFence(testDevice, &fence_create_info, NULL, &fence); 1999 ASSERT_VK_SUCCESS(err); 2000 2001 // Induce failure by not calling vkDestroyFence 2002 vkDestroyDevice(testDevice, NULL); 2003 m_errorMonitor->VerifyFound(); 2004 } 2005 2006 TEST_F(VkLayerTest, InvalidCommandPoolConsistency) { 2007 2008 TEST_DESCRIPTION("Allocate command buffers from one command pool and " 2009 "attempt to delete them from another."); 2010 2011 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "FreeCommandBuffers is attempting to free Command Buffer"); 2012 2013 ASSERT_NO_FATAL_FAILURE(InitState()); 2014 VkCommandPool command_pool_one; 2015 VkCommandPool command_pool_two; 2016 2017 VkCommandPoolCreateInfo pool_create_info{}; 2018 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 2019 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 2020 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 2021 2022 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_one); 2023 2024 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_two); 2025 2026 VkCommandBuffer command_buffer[9]; 2027 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 2028 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 2029 command_buffer_allocate_info.commandPool = command_pool_one; 2030 command_buffer_allocate_info.commandBufferCount = 9; 2031 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 2032 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer); 2033 2034 vkFreeCommandBuffers(m_device->device(), command_pool_two, 4, &command_buffer[3]); 2035 2036 m_errorMonitor->VerifyFound(); 2037 2038 vkDestroyCommandPool(m_device->device(), command_pool_one, NULL); 2039 vkDestroyCommandPool(m_device->device(), command_pool_two, NULL); 2040 } 2041 2042 TEST_F(VkLayerTest, InvalidDescriptorPoolConsistency) { 2043 VkResult err; 2044 2045 TEST_DESCRIPTION("Allocate descriptor sets from one DS pool and " 2046 "attempt to delete them from another."); 2047 2048 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "FreeDescriptorSets is attempting to free descriptorSet"); 2049 2050 ASSERT_NO_FATAL_FAILURE(InitState()); 2051 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 2052 2053 VkDescriptorPoolSize ds_type_count = {}; 2054 ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER; 2055 ds_type_count.descriptorCount = 1; 2056 2057 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 2058 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 2059 ds_pool_ci.pNext = NULL; 2060 ds_pool_ci.flags = 0; 2061 ds_pool_ci.maxSets = 1; 2062 ds_pool_ci.poolSizeCount = 1; 2063 ds_pool_ci.pPoolSizes = &ds_type_count; 2064 2065 VkDescriptorPool ds_pool_one; 2066 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool_one); 2067 ASSERT_VK_SUCCESS(err); 2068 2069 // Create a second descriptor pool 2070 VkDescriptorPool ds_pool_two; 2071 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool_two); 2072 ASSERT_VK_SUCCESS(err); 2073 2074 VkDescriptorSetLayoutBinding dsl_binding = {}; 2075 dsl_binding.binding = 0; 2076 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 2077 dsl_binding.descriptorCount = 1; 2078 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 2079 dsl_binding.pImmutableSamplers = NULL; 2080 2081 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 2082 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 2083 ds_layout_ci.pNext = NULL; 2084 ds_layout_ci.bindingCount = 1; 2085 ds_layout_ci.pBindings = &dsl_binding; 2086 2087 VkDescriptorSetLayout ds_layout; 2088 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 2089 ASSERT_VK_SUCCESS(err); 2090 2091 VkDescriptorSet descriptorSet; 2092 VkDescriptorSetAllocateInfo alloc_info = {}; 2093 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 2094 alloc_info.descriptorSetCount = 1; 2095 alloc_info.descriptorPool = ds_pool_one; 2096 alloc_info.pSetLayouts = &ds_layout; 2097 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 2098 ASSERT_VK_SUCCESS(err); 2099 2100 err = vkFreeDescriptorSets(m_device->device(), ds_pool_two, 1, &descriptorSet); 2101 2102 m_errorMonitor->VerifyFound(); 2103 2104 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 2105 vkDestroyDescriptorPool(m_device->device(), ds_pool_one, NULL); 2106 vkDestroyDescriptorPool(m_device->device(), ds_pool_two, NULL); 2107 } 2108 2109 TEST_F(VkLayerTest, CreateUnknownObject) { 2110 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Image Object "); 2111 2112 TEST_DESCRIPTION("Pass an invalid image object handle into a Vulkan API call."); 2113 2114 ASSERT_NO_FATAL_FAILURE(InitState()); 2115 2116 // Pass bogus handle into GetImageMemoryRequirements 2117 VkMemoryRequirements mem_reqs; 2118 uint64_t fakeImageHandle = 0xCADECADE; 2119 VkImage fauxImage = reinterpret_cast<VkImage &>(fakeImageHandle); 2120 2121 vkGetImageMemoryRequirements(m_device->device(), fauxImage, &mem_reqs); 2122 2123 m_errorMonitor->VerifyFound(); 2124 } 2125 2126 TEST_F(VkLayerTest, PipelineNotBound) { 2127 VkResult err; 2128 2129 TEST_DESCRIPTION("Pass in an invalid pipeline object handle into a Vulkan API call."); 2130 2131 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline Object "); 2132 2133 ASSERT_NO_FATAL_FAILURE(InitState()); 2134 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 2135 2136 VkDescriptorPoolSize ds_type_count = {}; 2137 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 2138 ds_type_count.descriptorCount = 1; 2139 2140 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 2141 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 2142 ds_pool_ci.pNext = NULL; 2143 ds_pool_ci.maxSets = 1; 2144 ds_pool_ci.poolSizeCount = 1; 2145 ds_pool_ci.pPoolSizes = &ds_type_count; 2146 2147 VkDescriptorPool ds_pool; 2148 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 2149 ASSERT_VK_SUCCESS(err); 2150 2151 VkDescriptorSetLayoutBinding dsl_binding = {}; 2152 dsl_binding.binding = 0; 2153 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 2154 dsl_binding.descriptorCount = 1; 2155 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 2156 dsl_binding.pImmutableSamplers = NULL; 2157 2158 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 2159 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 2160 ds_layout_ci.pNext = NULL; 2161 ds_layout_ci.bindingCount = 1; 2162 ds_layout_ci.pBindings = &dsl_binding; 2163 2164 VkDescriptorSetLayout ds_layout; 2165 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 2166 ASSERT_VK_SUCCESS(err); 2167 2168 VkDescriptorSet descriptorSet; 2169 VkDescriptorSetAllocateInfo alloc_info = {}; 2170 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 2171 alloc_info.descriptorSetCount = 1; 2172 alloc_info.descriptorPool = ds_pool; 2173 alloc_info.pSetLayouts = &ds_layout; 2174 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 2175 ASSERT_VK_SUCCESS(err); 2176 2177 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 2178 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 2179 pipeline_layout_ci.pNext = NULL; 2180 pipeline_layout_ci.setLayoutCount = 1; 2181 pipeline_layout_ci.pSetLayouts = &ds_layout; 2182 2183 VkPipelineLayout pipeline_layout; 2184 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 2185 ASSERT_VK_SUCCESS(err); 2186 2187 VkPipeline badPipeline = (VkPipeline)((size_t)0xbaadb1be); 2188 2189 BeginCommandBuffer(); 2190 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline); 2191 2192 m_errorMonitor->VerifyFound(); 2193 2194 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 2195 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 2196 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 2197 } 2198 2199 TEST_F(VkLayerTest, BindImageInvalidMemoryType) { 2200 VkResult err; 2201 2202 TEST_DESCRIPTION("Test validation check for an invalid memory type index " 2203 "during bind[Buffer|Image]Memory time"); 2204 2205 ASSERT_NO_FATAL_FAILURE(InitState()); 2206 2207 // Create an image, allocate memory, set a bad typeIndex and then try to 2208 // bind it 2209 VkImage image; 2210 VkDeviceMemory mem; 2211 VkMemoryRequirements mem_reqs; 2212 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 2213 const int32_t tex_width = 32; 2214 const int32_t tex_height = 32; 2215 2216 VkImageCreateInfo image_create_info = {}; 2217 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 2218 image_create_info.pNext = NULL; 2219 image_create_info.imageType = VK_IMAGE_TYPE_2D; 2220 image_create_info.format = tex_format; 2221 image_create_info.extent.width = tex_width; 2222 image_create_info.extent.height = tex_height; 2223 image_create_info.extent.depth = 1; 2224 image_create_info.mipLevels = 1; 2225 image_create_info.arrayLayers = 1; 2226 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 2227 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 2228 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 2229 image_create_info.flags = 0; 2230 2231 VkMemoryAllocateInfo mem_alloc = {}; 2232 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 2233 mem_alloc.pNext = NULL; 2234 mem_alloc.allocationSize = 0; 2235 mem_alloc.memoryTypeIndex = 0; 2236 2237 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 2238 ASSERT_VK_SUCCESS(err); 2239 2240 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs); 2241 mem_alloc.allocationSize = mem_reqs.size; 2242 2243 // Introduce Failure, select invalid TypeIndex 2244 VkPhysicalDeviceMemoryProperties memory_info; 2245 2246 vkGetPhysicalDeviceMemoryProperties(gpu(), &memory_info); 2247 unsigned int i; 2248 for (i = 0; i < memory_info.memoryTypeCount; i++) { 2249 if ((mem_reqs.memoryTypeBits & (1 << i)) == 0) { 2250 mem_alloc.memoryTypeIndex = i; 2251 break; 2252 } 2253 } 2254 if (i >= memory_info.memoryTypeCount) { 2255 printf("No invalid memory type index could be found; skipped.\n"); 2256 vkDestroyImage(m_device->device(), image, NULL); 2257 return; 2258 } 2259 2260 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "for this object type are not compatible with the memory"); 2261 2262 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem); 2263 ASSERT_VK_SUCCESS(err); 2264 2265 err = vkBindImageMemory(m_device->device(), image, mem, 0); 2266 (void)err; 2267 2268 m_errorMonitor->VerifyFound(); 2269 2270 vkDestroyImage(m_device->device(), image, NULL); 2271 vkFreeMemory(m_device->device(), mem, NULL); 2272 } 2273 2274 TEST_F(VkLayerTest, BindInvalidMemory) { 2275 VkResult err; 2276 bool pass; 2277 2278 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Device Memory Object "); 2279 2280 ASSERT_NO_FATAL_FAILURE(InitState()); 2281 2282 // Create an image, allocate memory, free it, and then try to bind it 2283 VkImage image; 2284 VkDeviceMemory mem; 2285 VkMemoryRequirements mem_reqs; 2286 2287 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 2288 const int32_t tex_width = 32; 2289 const int32_t tex_height = 32; 2290 2291 VkImageCreateInfo image_create_info = {}; 2292 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 2293 image_create_info.pNext = NULL; 2294 image_create_info.imageType = VK_IMAGE_TYPE_2D; 2295 image_create_info.format = tex_format; 2296 image_create_info.extent.width = tex_width; 2297 image_create_info.extent.height = tex_height; 2298 image_create_info.extent.depth = 1; 2299 image_create_info.mipLevels = 1; 2300 image_create_info.arrayLayers = 1; 2301 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 2302 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 2303 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 2304 image_create_info.flags = 0; 2305 2306 VkMemoryAllocateInfo mem_alloc = {}; 2307 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 2308 mem_alloc.pNext = NULL; 2309 mem_alloc.allocationSize = 0; 2310 mem_alloc.memoryTypeIndex = 0; 2311 2312 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 2313 ASSERT_VK_SUCCESS(err); 2314 2315 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs); 2316 2317 mem_alloc.allocationSize = mem_reqs.size; 2318 2319 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0); 2320 ASSERT_TRUE(pass); 2321 2322 // allocate memory 2323 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem); 2324 ASSERT_VK_SUCCESS(err); 2325 2326 // Introduce validation failure, free memory before binding 2327 vkFreeMemory(m_device->device(), mem, NULL); 2328 2329 // Try to bind free memory that has been freed 2330 err = vkBindImageMemory(m_device->device(), image, mem, 0); 2331 // This may very well return an error. 2332 (void)err; 2333 2334 m_errorMonitor->VerifyFound(); 2335 2336 vkDestroyImage(m_device->device(), image, NULL); 2337 } 2338 2339 TEST_F(VkLayerTest, BindMemoryToDestroyedObject) { 2340 VkResult err; 2341 bool pass; 2342 2343 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Image Object "); 2344 2345 ASSERT_NO_FATAL_FAILURE(InitState()); 2346 2347 // Create an image object, allocate memory, destroy the object and then try 2348 // to bind it 2349 VkImage image; 2350 VkDeviceMemory mem; 2351 VkMemoryRequirements mem_reqs; 2352 2353 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 2354 const int32_t tex_width = 32; 2355 const int32_t tex_height = 32; 2356 2357 VkImageCreateInfo image_create_info = {}; 2358 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 2359 image_create_info.pNext = NULL; 2360 image_create_info.imageType = VK_IMAGE_TYPE_2D; 2361 image_create_info.format = tex_format; 2362 image_create_info.extent.width = tex_width; 2363 image_create_info.extent.height = tex_height; 2364 image_create_info.extent.depth = 1; 2365 image_create_info.mipLevels = 1; 2366 image_create_info.arrayLayers = 1; 2367 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 2368 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 2369 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 2370 image_create_info.flags = 0; 2371 2372 VkMemoryAllocateInfo mem_alloc = {}; 2373 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 2374 mem_alloc.pNext = NULL; 2375 mem_alloc.allocationSize = 0; 2376 mem_alloc.memoryTypeIndex = 0; 2377 2378 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 2379 ASSERT_VK_SUCCESS(err); 2380 2381 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs); 2382 2383 mem_alloc.allocationSize = mem_reqs.size; 2384 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0); 2385 ASSERT_TRUE(pass); 2386 2387 // Allocate memory 2388 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem); 2389 ASSERT_VK_SUCCESS(err); 2390 2391 // Introduce validation failure, destroy Image object before binding 2392 vkDestroyImage(m_device->device(), image, NULL); 2393 ASSERT_VK_SUCCESS(err); 2394 2395 // Now Try to bind memory to this destroyed object 2396 err = vkBindImageMemory(m_device->device(), image, mem, 0); 2397 // This may very well return an error. 2398 (void)err; 2399 2400 m_errorMonitor->VerifyFound(); 2401 2402 vkFreeMemory(m_device->device(), mem, NULL); 2403 } 2404 2405 #endif // OBJ_TRACKER_TESTS 2406 2407 #if DRAW_STATE_TESTS 2408 2409 TEST_F(VkLayerTest, ImageSampleCounts) { 2410 2411 TEST_DESCRIPTION("Use bad sample counts in image transfer calls to trigger " 2412 "validation errors."); 2413 ASSERT_NO_FATAL_FAILURE(InitState()); 2414 2415 VkMemoryPropertyFlags reqs = 0; 2416 VkImageCreateInfo image_create_info = {}; 2417 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 2418 image_create_info.pNext = NULL; 2419 image_create_info.imageType = VK_IMAGE_TYPE_2D; 2420 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; 2421 image_create_info.extent.width = 256; 2422 image_create_info.extent.height = 256; 2423 image_create_info.extent.depth = 1; 2424 image_create_info.mipLevels = 1; 2425 image_create_info.arrayLayers = 1; 2426 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 2427 image_create_info.flags = 0; 2428 2429 VkImageBlit blit_region = {}; 2430 blit_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 2431 blit_region.srcSubresource.baseArrayLayer = 0; 2432 blit_region.srcSubresource.layerCount = 1; 2433 blit_region.srcSubresource.mipLevel = 0; 2434 blit_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 2435 blit_region.dstSubresource.baseArrayLayer = 0; 2436 blit_region.dstSubresource.layerCount = 1; 2437 blit_region.dstSubresource.mipLevel = 0; 2438 2439 // Create two images, the source with sampleCount = 2, and attempt to blit 2440 // between them 2441 { 2442 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT; 2443 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 2444 vk_testing::Image src_image; 2445 src_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs); 2446 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 2447 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 2448 vk_testing::Image dst_image; 2449 dst_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs); 2450 m_commandBuffer->BeginCommandBuffer(); 2451 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count " 2452 "of VK_SAMPLE_COUNT_2_BIT but " 2453 "must be VK_SAMPLE_COUNT_1_BIT"); 2454 vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), src_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 2455 dst_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, &blit_region, VK_FILTER_NEAREST); 2456 m_errorMonitor->VerifyFound(); 2457 m_commandBuffer->EndCommandBuffer(); 2458 } 2459 2460 // Create two images, the dest with sampleCount = 4, and attempt to blit 2461 // between them 2462 { 2463 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 2464 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 2465 vk_testing::Image src_image; 2466 src_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs); 2467 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; 2468 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 2469 vk_testing::Image dst_image; 2470 dst_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs); 2471 m_commandBuffer->BeginCommandBuffer(); 2472 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count " 2473 "of VK_SAMPLE_COUNT_4_BIT but " 2474 "must be VK_SAMPLE_COUNT_1_BIT"); 2475 vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), src_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 2476 dst_image.handle(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1, &blit_region, VK_FILTER_NEAREST); 2477 m_errorMonitor->VerifyFound(); 2478 m_commandBuffer->EndCommandBuffer(); 2479 } 2480 2481 VkBufferImageCopy copy_region = {}; 2482 copy_region.bufferRowLength = 128; 2483 copy_region.bufferImageHeight = 128; 2484 copy_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 2485 copy_region.imageSubresource.layerCount = 1; 2486 copy_region.imageExtent.height = 64; 2487 copy_region.imageExtent.width = 64; 2488 copy_region.imageExtent.depth = 1; 2489 2490 // Create src buffer and dst image with sampleCount = 4 and attempt to copy 2491 // buffer to image 2492 { 2493 vk_testing::Buffer src_buffer; 2494 VkMemoryPropertyFlags reqs = 0; 2495 src_buffer.init_as_src(*m_device, 128 * 128 * 4, reqs); 2496 image_create_info.samples = VK_SAMPLE_COUNT_8_BIT; 2497 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 2498 vk_testing::Image dst_image; 2499 dst_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs); 2500 m_commandBuffer->BeginCommandBuffer(); 2501 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count " 2502 "of VK_SAMPLE_COUNT_8_BIT but " 2503 "must be VK_SAMPLE_COUNT_1_BIT"); 2504 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), src_buffer.handle(), dst_image.handle(), 2505 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©_region); 2506 m_errorMonitor->VerifyFound(); 2507 m_commandBuffer->EndCommandBuffer(); 2508 } 2509 2510 // Create dst buffer and src image with sampleCount = 2 and attempt to copy 2511 // image to buffer 2512 { 2513 vk_testing::Buffer dst_buffer; 2514 dst_buffer.init_as_dst(*m_device, 128 * 128 * 4, reqs); 2515 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT; 2516 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 2517 vk_testing::Image src_image; 2518 src_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs); 2519 m_commandBuffer->BeginCommandBuffer(); 2520 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was created with a sample count " 2521 "of VK_SAMPLE_COUNT_2_BIT but " 2522 "must be VK_SAMPLE_COUNT_1_BIT"); 2523 vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), src_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 2524 dst_buffer.handle(), 1, ©_region); 2525 m_errorMonitor->VerifyFound(); 2526 m_commandBuffer->EndCommandBuffer(); 2527 } 2528 } 2529 2530 TEST_F(VkLayerTest, BlitImageFormats) { 2531 2532 // Image blit with mismatched formats 2533 const char * expected_message = 2534 "vkCmdBlitImage: If one of srcImage and dstImage images has signed/unsigned integer format," 2535 " the other one must also have signed/unsigned integer format"; 2536 2537 ASSERT_NO_FATAL_FAILURE(InitState()); 2538 2539 VkImageObj src_image(m_device); 2540 src_image.init(64, 64, VK_FORMAT_A2B10G10R10_UINT_PACK32, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_LINEAR, 0); 2541 VkImageObj dst_image(m_device); 2542 dst_image.init(64, 64, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_LINEAR, 0); 2543 VkImageObj dst_image2(m_device); 2544 dst_image2.init(64, 64, VK_FORMAT_R8G8B8A8_SINT, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_LINEAR, 0); 2545 2546 VkImageBlit blitRegion = {}; 2547 blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 2548 blitRegion.srcSubresource.baseArrayLayer = 0; 2549 blitRegion.srcSubresource.layerCount = 1; 2550 blitRegion.srcSubresource.mipLevel = 0; 2551 blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 2552 blitRegion.dstSubresource.baseArrayLayer = 0; 2553 blitRegion.dstSubresource.layerCount = 1; 2554 blitRegion.dstSubresource.mipLevel = 0; 2555 2556 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, expected_message); 2557 2558 // Unsigned int vs not an int 2559 BeginCommandBuffer(); 2560 vkCmdBlitImage(m_commandBuffer->handle(), src_image.image(), src_image.layout(), dst_image.image(), 2561 dst_image.layout(), 1, &blitRegion, VK_FILTER_NEAREST); 2562 2563 m_errorMonitor->VerifyFound(); 2564 2565 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, expected_message); 2566 2567 // Unsigned int vs signed int 2568 vkCmdBlitImage(m_commandBuffer->handle(), src_image.image(), src_image.layout(), dst_image2.image(), 2569 dst_image2.layout(), 1, &blitRegion, VK_FILTER_NEAREST); 2570 2571 m_errorMonitor->VerifyFound(); 2572 2573 EndCommandBuffer(); 2574 } 2575 2576 2577 TEST_F(VkLayerTest, DSImageTransferGranularityTests) { 2578 VkResult err; 2579 bool pass; 2580 2581 TEST_DESCRIPTION("Tests for validaiton of Queue Family property minImageTransferGranularity."); 2582 ASSERT_NO_FATAL_FAILURE(InitState()); 2583 2584 // If w/d/h granularity is 1, test is not meaningful 2585 // TODO: When virtual device limits are available, create a set of limits for this test that 2586 // will always have a granularity of > 1 for w, h, and d 2587 auto index = m_device->graphics_queue_node_index_; 2588 auto queue_family_properties = m_device->phy().queue_properties(); 2589 2590 if ((queue_family_properties[index].minImageTransferGranularity.depth < 4) || 2591 (queue_family_properties[index].minImageTransferGranularity.width < 4) || 2592 (queue_family_properties[index].minImageTransferGranularity.height < 4)) { 2593 return; 2594 } 2595 2596 // Create two images of different types and try to copy between them 2597 VkImage srcImage; 2598 VkImage dstImage; 2599 VkDeviceMemory srcMem; 2600 VkDeviceMemory destMem; 2601 VkMemoryRequirements memReqs; 2602 2603 VkImageCreateInfo image_create_info = {}; 2604 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 2605 image_create_info.pNext = NULL; 2606 image_create_info.imageType = VK_IMAGE_TYPE_2D; 2607 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; 2608 image_create_info.extent.width = 32; 2609 image_create_info.extent.height = 32; 2610 image_create_info.extent.depth = 1; 2611 image_create_info.mipLevels = 1; 2612 image_create_info.arrayLayers = 4; 2613 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 2614 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 2615 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 2616 image_create_info.flags = 0; 2617 2618 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage); 2619 ASSERT_VK_SUCCESS(err); 2620 2621 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage); 2622 ASSERT_VK_SUCCESS(err); 2623 2624 // Allocate memory 2625 VkMemoryAllocateInfo memAlloc = {}; 2626 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 2627 memAlloc.pNext = NULL; 2628 memAlloc.allocationSize = 0; 2629 memAlloc.memoryTypeIndex = 0; 2630 2631 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs); 2632 memAlloc.allocationSize = memReqs.size; 2633 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 2634 ASSERT_TRUE(pass); 2635 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem); 2636 ASSERT_VK_SUCCESS(err); 2637 2638 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs); 2639 memAlloc.allocationSize = memReqs.size; 2640 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 2641 ASSERT_VK_SUCCESS(err); 2642 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem); 2643 ASSERT_VK_SUCCESS(err); 2644 2645 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0); 2646 ASSERT_VK_SUCCESS(err); 2647 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0); 2648 ASSERT_VK_SUCCESS(err); 2649 2650 BeginCommandBuffer(); 2651 VkImageCopy copyRegion; 2652 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 2653 copyRegion.srcSubresource.mipLevel = 0; 2654 copyRegion.srcSubresource.baseArrayLayer = 0; 2655 copyRegion.srcSubresource.layerCount = 1; 2656 copyRegion.srcOffset.x = 0; 2657 copyRegion.srcOffset.y = 0; 2658 copyRegion.srcOffset.z = 0; 2659 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 2660 copyRegion.dstSubresource.mipLevel = 0; 2661 copyRegion.dstSubresource.baseArrayLayer = 0; 2662 copyRegion.dstSubresource.layerCount = 1; 2663 copyRegion.dstOffset.x = 0; 2664 copyRegion.dstOffset.y = 0; 2665 copyRegion.dstOffset.z = 0; 2666 copyRegion.extent.width = 1; 2667 copyRegion.extent.height = 1; 2668 copyRegion.extent.depth = 1; 2669 2670 // Introduce failure by setting srcOffset to a bad granularity value 2671 copyRegion.srcOffset.y = 3; 2672 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 2673 m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region); 2674 m_errorMonitor->VerifyFound(); 2675 2676 // Introduce failure by setting extent to a bad granularity value 2677 copyRegion.srcOffset.y = 0; 2678 copyRegion.extent.width = 3; 2679 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 2680 m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region); 2681 m_errorMonitor->VerifyFound(); 2682 2683 // Now do some buffer/image copies 2684 vk_testing::Buffer buffer; 2685 VkMemoryPropertyFlags reqs = 0; 2686 buffer.init_as_dst(*m_device, 128 * 128, reqs); 2687 VkBufferImageCopy region = {}; 2688 region.bufferOffset = 0; 2689 region.bufferRowLength = 3; 2690 region.bufferImageHeight = 128; 2691 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 2692 region.imageSubresource.layerCount = 1; 2693 region.imageExtent.height = 16; 2694 region.imageExtent.width = 16; 2695 region.imageExtent.depth = 1; 2696 region.imageOffset.x = 0; 2697 region.imageOffset.y = 0; 2698 region.imageOffset.z = 0; 2699 2700 // Introduce failure by setting bufferRowLength to a bad granularity value 2701 region.bufferRowLength = 3; 2702 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 2703 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 2704 ®ion); 2705 m_errorMonitor->VerifyFound(); 2706 region.bufferRowLength = 128; 2707 2708 // Introduce failure by setting bufferOffset to a bad granularity value 2709 region.bufferOffset = 3; 2710 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 2711 vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1, 2712 ®ion); 2713 m_errorMonitor->VerifyFound(); 2714 region.bufferOffset = 0; 2715 2716 // Introduce failure by setting bufferImageHeight to a bad granularity value 2717 region.bufferImageHeight = 3; 2718 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 2719 vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1, 2720 ®ion); 2721 m_errorMonitor->VerifyFound(); 2722 region.bufferImageHeight = 128; 2723 2724 // Introduce failure by setting imageExtent to a bad granularity value 2725 region.imageExtent.width = 3; 2726 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 2727 vkCmdCopyImageToBuffer(m_commandBuffer->GetBufferHandle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, buffer.handle(), 1, 2728 ®ion); 2729 m_errorMonitor->VerifyFound(); 2730 region.imageExtent.width = 16; 2731 2732 // Introduce failure by setting imageOffset to a bad granularity value 2733 region.imageOffset.z = 3; 2734 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "queue family image transfer granularity"); 2735 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), srcImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 2736 ®ion); 2737 m_errorMonitor->VerifyFound(); 2738 2739 EndCommandBuffer(); 2740 2741 vkDestroyImage(m_device->device(), srcImage, NULL); 2742 vkDestroyImage(m_device->device(), dstImage, NULL); 2743 vkFreeMemory(m_device->device(), srcMem, NULL); 2744 vkFreeMemory(m_device->device(), destMem, NULL); 2745 } 2746 2747 TEST_F(VkLayerTest, MismatchedQueueFamiliesOnSubmit) { 2748 TEST_DESCRIPTION("Submit command buffer created using one queue family and " 2749 "attempt to submit them on a queue created in a different " 2750 "queue family."); 2751 2752 ASSERT_NO_FATAL_FAILURE(InitState()); 2753 // This test is meaningless unless we have multiple queue families 2754 auto queue_family_properties = m_device->phy().queue_properties(); 2755 if (queue_family_properties.size() < 2) { 2756 return; 2757 } 2758 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is being submitted on queue "); 2759 // Get safe index of another queue family 2760 uint32_t other_queue_family = (m_device->graphics_queue_node_index_ == 0) ? 1 : 0; 2761 ASSERT_NO_FATAL_FAILURE(InitState()); 2762 // Create a second queue using a different queue family 2763 VkQueue other_queue; 2764 vkGetDeviceQueue(m_device->device(), other_queue_family, 0, &other_queue); 2765 2766 // Record an empty cmd buffer 2767 VkCommandBufferBeginInfo cmdBufBeginDesc = {}; 2768 cmdBufBeginDesc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 2769 vkBeginCommandBuffer(m_commandBuffer->handle(), &cmdBufBeginDesc); 2770 vkEndCommandBuffer(m_commandBuffer->handle()); 2771 2772 // And submit on the wrong queue 2773 VkSubmitInfo submit_info = {}; 2774 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 2775 submit_info.commandBufferCount = 1; 2776 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 2777 vkQueueSubmit(other_queue, 1, &submit_info, VK_NULL_HANDLE); 2778 2779 m_errorMonitor->VerifyFound(); 2780 } 2781 2782 TEST_F(VkLayerTest, RenderPassPipelineSubpassMismatch) { 2783 TEST_DESCRIPTION("Use a pipeline for the wrong subpass in a render pass instance"); 2784 ASSERT_NO_FATAL_FAILURE(InitState()); 2785 2786 // A renderpass with two subpasses, both writing the same attachment. 2787 VkAttachmentDescription attach[] = { 2788 { 0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, 2789 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 2790 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 2791 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL 2792 }, 2793 }; 2794 VkAttachmentReference ref = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; 2795 VkSubpassDescription subpasses[] = { 2796 { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 2797 1, &ref, nullptr, nullptr, 0, nullptr }, 2798 { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 2799 1, &ref, nullptr, nullptr, 0, nullptr }, 2800 }; 2801 VkSubpassDependency dep = { 2802 0, 1, 2803 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 2804 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 2805 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 2806 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 2807 VK_DEPENDENCY_BY_REGION_BIT 2808 }; 2809 VkRenderPassCreateInfo rpci = { 2810 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 2811 0, 1, attach, 2, subpasses, 1, &dep 2812 }; 2813 VkRenderPass rp; 2814 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 2815 ASSERT_VK_SUCCESS(err); 2816 2817 VkImageObj image(m_device); 2818 image.init_no_layout(32, 32, VK_FORMAT_R8G8B8A8_UNORM, 2819 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 2820 VK_IMAGE_TILING_OPTIMAL, 0); 2821 VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM); 2822 2823 VkFramebufferCreateInfo fbci = { 2824 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 2825 0, rp, 1, &imageView, 32, 32, 1 2826 }; 2827 VkFramebuffer fb; 2828 err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb); 2829 ASSERT_VK_SUCCESS(err); 2830 2831 char const *vsSource = 2832 "#version 450\n" 2833 "void main() { gl_Position = vec4(1); }\n"; 2834 char const *fsSource = 2835 "#version 450\n" 2836 "layout(location=0) out vec4 color;\n" 2837 "void main() { color = vec4(1); }\n"; 2838 2839 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 2840 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 2841 VkPipelineObj pipe(m_device); 2842 pipe.AddColorAttachment(); 2843 pipe.AddShader(&vs); 2844 pipe.AddShader(&fs); 2845 VkViewport view_port = {}; 2846 m_viewports.push_back(view_port); 2847 pipe.SetViewport(m_viewports); 2848 VkRect2D rect = {}; 2849 m_scissors.push_back(rect); 2850 pipe.SetScissor(m_scissors); 2851 2852 VkPipelineLayoutCreateInfo plci = { 2853 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 2854 0, 0, nullptr, 0, nullptr 2855 }; 2856 VkPipelineLayout pl; 2857 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl); 2858 ASSERT_VK_SUCCESS(err); 2859 pipe.CreateVKPipeline(pl, rp); 2860 2861 BeginCommandBuffer(); 2862 2863 VkRenderPassBeginInfo rpbi = { 2864 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, 2865 rp, fb, { { 0, 0, }, { 32, 32 } }, 0, nullptr 2866 }; 2867 2868 // subtest 1: bind in the wrong subpass 2869 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); 2870 vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE); 2871 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 2872 "built for subpass 0 but used in subpass 1"); 2873 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 2874 vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); 2875 m_errorMonitor->VerifyFound(); 2876 2877 vkCmdEndRenderPass(m_commandBuffer->handle()); 2878 2879 // subtest 2: bind in correct subpass, then transition to next subpass 2880 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); 2881 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 2882 vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE); 2883 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 2884 "built for subpass 0 but used in subpass 1"); 2885 vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); 2886 m_errorMonitor->VerifyFound(); 2887 2888 vkCmdEndRenderPass(m_commandBuffer->handle()); 2889 2890 EndCommandBuffer(); 2891 2892 vkDestroyPipelineLayout(m_device->device(), pl, nullptr); 2893 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 2894 vkDestroyRenderPass(m_device->device(), rp, nullptr); 2895 } 2896 2897 TEST_F(VkLayerTest, RenderPassInvalidRenderArea) { 2898 TEST_DESCRIPTION("Generate INVALID_RENDER_AREA error by beginning renderpass" 2899 "with extent outside of framebuffer"); 2900 ASSERT_NO_FATAL_FAILURE(InitState()); 2901 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 2902 2903 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot execute a render pass with renderArea " 2904 "not within the bound of the framebuffer."); 2905 2906 // Framebuffer for render target is 256x256, exceed that for INVALID_RENDER_AREA 2907 m_renderPassBeginInfo.renderArea.extent.width = 257; 2908 m_renderPassBeginInfo.renderArea.extent.height = 257; 2909 BeginCommandBuffer(); 2910 m_errorMonitor->VerifyFound(); 2911 } 2912 2913 TEST_F(VkLayerTest, DisabledIndependentBlend) { 2914 TEST_DESCRIPTION("Generate INDEPENDENT_BLEND by disabling independent " 2915 "blend and then specifying different blend states for two " 2916 "attachements"); 2917 VkPhysicalDeviceFeatures features = {}; 2918 features.independentBlend = VK_FALSE; 2919 ASSERT_NO_FATAL_FAILURE(InitState(&features)); 2920 2921 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 2922 "Invalid Pipeline CreateInfo: If independent blend feature not " 2923 "enabled, all elements of pAttachments must be identical"); 2924 2925 VkDescriptorSetObj descriptorSet(m_device); 2926 descriptorSet.AppendDummy(); 2927 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 2928 2929 VkPipelineObj pipeline(m_device); 2930 VkRenderpassObj renderpass(m_device); 2931 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 2932 pipeline.AddShader(&vs); 2933 2934 VkPipelineColorBlendAttachmentState att_state1 = {}, att_state2 = {}; 2935 att_state1.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR; 2936 att_state1.blendEnable = VK_TRUE; 2937 att_state2.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR; 2938 att_state2.blendEnable = VK_FALSE; 2939 pipeline.AddColorAttachment(0, &att_state1); 2940 pipeline.AddColorAttachment(1, &att_state2); 2941 pipeline.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderpass.handle()); 2942 m_errorMonitor->VerifyFound(); 2943 } 2944 2945 TEST_F(VkLayerTest, RenderPassDepthStencilAttachmentUnused) { 2946 TEST_DESCRIPTION("Specify no depth attachement in renderpass then specify " 2947 "depth attachments in subpass"); 2948 ASSERT_NO_FATAL_FAILURE(InitState()); 2949 2950 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 2951 "vkCreateRenderPass has no depth/stencil attachment, yet subpass"); 2952 2953 // Create a renderPass with a single color attachment 2954 VkAttachmentReference attach = {}; 2955 attach.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 2956 VkSubpassDescription subpass = {}; 2957 VkRenderPassCreateInfo rpci = {}; 2958 rpci.subpassCount = 1; 2959 rpci.pSubpasses = &subpass; 2960 rpci.attachmentCount = 1; 2961 VkAttachmentDescription attach_desc = {}; 2962 attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM; 2963 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; 2964 rpci.pAttachments = &attach_desc; 2965 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 2966 VkRenderPass rp; 2967 subpass.pDepthStencilAttachment = &attach; 2968 subpass.pColorAttachments = NULL; 2969 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 2970 m_errorMonitor->VerifyFound(); 2971 } 2972 2973 TEST_F(VkLayerTest, UnusedPreserveAttachment) { 2974 TEST_DESCRIPTION("Create a framebuffer where a subpass has a preserve " 2975 "attachment reference of VK_ATTACHMENT_UNUSED"); 2976 2977 ASSERT_NO_FATAL_FAILURE(InitState()); 2978 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 2979 2980 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must not be VK_ATTACHMENT_UNUSED"); 2981 2982 VkAttachmentReference color_attach = {}; 2983 color_attach.layout = VK_IMAGE_LAYOUT_GENERAL; 2984 color_attach.attachment = 0; 2985 uint32_t preserve_attachment = VK_ATTACHMENT_UNUSED; 2986 VkSubpassDescription subpass = {}; 2987 subpass.colorAttachmentCount = 1; 2988 subpass.pColorAttachments = &color_attach; 2989 subpass.preserveAttachmentCount = 1; 2990 subpass.pPreserveAttachments = &preserve_attachment; 2991 2992 VkRenderPassCreateInfo rpci = {}; 2993 rpci.subpassCount = 1; 2994 rpci.pSubpasses = &subpass; 2995 rpci.attachmentCount = 1; 2996 VkAttachmentDescription attach_desc = {}; 2997 attach_desc.format = VK_FORMAT_UNDEFINED; 2998 rpci.pAttachments = &attach_desc; 2999 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 3000 VkRenderPass rp; 3001 VkResult result = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 3002 3003 m_errorMonitor->VerifyFound(); 3004 3005 if (result == VK_SUCCESS) { 3006 vkDestroyRenderPass(m_device->device(), rp, NULL); 3007 } 3008 } 3009 3010 TEST_F(VkLayerTest, CreateRenderPassResolveRequiresColorMsaa) { 3011 TEST_DESCRIPTION("Ensure that CreateRenderPass produces a validation error " 3012 "when the source of a subpass multisample resolve " 3013 "does not have multiple samples."); 3014 3015 ASSERT_NO_FATAL_FAILURE(InitState()); 3016 3017 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 3018 "Subpass 0 requests multisample resolve from attachment 0 which has " 3019 "VK_SAMPLE_COUNT_1_BIT"); 3020 3021 VkAttachmentDescription attachments[] = { 3022 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 3023 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 3024 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 3025 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 3026 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 3027 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 3028 }; 3029 3030 VkAttachmentReference color = { 3031 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 3032 }; 3033 3034 VkAttachmentReference resolve = { 3035 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 3036 }; 3037 3038 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &color, &resolve, nullptr, 0, nullptr}; 3039 3040 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr}; 3041 3042 VkRenderPass rp; 3043 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 3044 3045 m_errorMonitor->VerifyFound(); 3046 3047 if (err == VK_SUCCESS) 3048 vkDestroyRenderPass(m_device->device(), rp, nullptr); 3049 } 3050 3051 TEST_F(VkLayerTest, CreateRenderPassResolveRequiresSingleSampleDest) { 3052 TEST_DESCRIPTION("Ensure CreateRenderPass produces a validation error " 3053 "when a subpass multisample resolve operation is " 3054 "requested, and the destination of that resolve has " 3055 "multiple samples."); 3056 3057 ASSERT_NO_FATAL_FAILURE(InitState()); 3058 3059 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 3060 "Subpass 0 requests multisample resolve into attachment 1, which " 3061 "must have VK_SAMPLE_COUNT_1_BIT but has VK_SAMPLE_COUNT_4_BIT"); 3062 3063 VkAttachmentDescription attachments[] = { 3064 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 3065 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 3066 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 3067 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 3068 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 3069 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 3070 }; 3071 3072 VkAttachmentReference color = { 3073 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 3074 }; 3075 3076 VkAttachmentReference resolve = { 3077 1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 3078 }; 3079 3080 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &color, &resolve, nullptr, 0, nullptr}; 3081 3082 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr}; 3083 3084 VkRenderPass rp; 3085 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 3086 3087 m_errorMonitor->VerifyFound(); 3088 3089 if (err == VK_SUCCESS) 3090 vkDestroyRenderPass(m_device->device(), rp, nullptr); 3091 } 3092 3093 TEST_F(VkLayerTest, CreateRenderPassSubpassSampleCountConsistency) { 3094 TEST_DESCRIPTION("Ensure CreateRenderPass produces a validation error " 3095 "when the color and depth attachments used by a subpass " 3096 "have inconsistent sample counts"); 3097 3098 ASSERT_NO_FATAL_FAILURE(InitState()); 3099 3100 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 3101 "Subpass 0 attempts to render to attachments with inconsistent sample counts"); 3102 3103 VkAttachmentDescription attachments[] = { 3104 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 3105 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 3106 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 3107 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 3108 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 3109 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 3110 }; 3111 3112 VkAttachmentReference color[] = { 3113 { 3114 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 3115 }, 3116 { 3117 1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 3118 }, 3119 }; 3120 3121 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 2, color, nullptr, nullptr, 0, nullptr}; 3122 3123 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 0, nullptr}; 3124 3125 VkRenderPass rp; 3126 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 3127 3128 m_errorMonitor->VerifyFound(); 3129 3130 if (err == VK_SUCCESS) 3131 vkDestroyRenderPass(m_device->device(), rp, nullptr); 3132 } 3133 3134 TEST_F(VkLayerTest, FramebufferCreateErrors) { 3135 TEST_DESCRIPTION("Hit errors when attempting to create a framebuffer :\n" 3136 " 1. Mismatch between framebuffer & renderPass attachmentCount\n" 3137 " 2. Use a color image as depthStencil attachment\n" 3138 " 3. Mismatch framebuffer & renderPass attachment formats\n" 3139 " 4. Mismatch framebuffer & renderPass attachment #samples\n" 3140 " 5. Framebuffer attachment w/ non-1 mip-levels\n" 3141 " 6. Framebuffer attachment where dimensions don't match\n" 3142 " 7. Framebuffer attachment w/o identity swizzle\n" 3143 " 8. framebuffer dimensions exceed physical device limits\n"); 3144 3145 ASSERT_NO_FATAL_FAILURE(InitState()); 3146 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 3147 3148 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 3149 "vkCreateFramebuffer(): VkFramebufferCreateInfo attachmentCount of 2 " 3150 "does not match attachmentCount of 1 of "); 3151 3152 // Create a renderPass with a single color attachment 3153 VkAttachmentReference attach = {}; 3154 attach.layout = VK_IMAGE_LAYOUT_GENERAL; 3155 VkSubpassDescription subpass = {}; 3156 subpass.pColorAttachments = &attach; 3157 VkRenderPassCreateInfo rpci = {}; 3158 rpci.subpassCount = 1; 3159 rpci.pSubpasses = &subpass; 3160 rpci.attachmentCount = 1; 3161 VkAttachmentDescription attach_desc = {}; 3162 attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM; 3163 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; 3164 rpci.pAttachments = &attach_desc; 3165 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 3166 VkRenderPass rp; 3167 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 3168 ASSERT_VK_SUCCESS(err); 3169 3170 VkImageView ivs[2]; 3171 ivs[0] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM); 3172 ivs[1] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM); 3173 VkFramebufferCreateInfo fb_info = {}; 3174 fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; 3175 fb_info.pNext = NULL; 3176 fb_info.renderPass = rp; 3177 // Set mis-matching attachmentCount 3178 fb_info.attachmentCount = 2; 3179 fb_info.pAttachments = ivs; 3180 fb_info.width = 100; 3181 fb_info.height = 100; 3182 fb_info.layers = 1; 3183 3184 VkFramebuffer fb; 3185 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 3186 3187 m_errorMonitor->VerifyFound(); 3188 if (err == VK_SUCCESS) { 3189 vkDestroyFramebuffer(m_device->device(), fb, NULL); 3190 } 3191 vkDestroyRenderPass(m_device->device(), rp, NULL); 3192 3193 // Create a renderPass with a depth-stencil attachment created with 3194 // IMAGE_USAGE_COLOR_ATTACHMENT 3195 // Add our color attachment to pDepthStencilAttachment 3196 subpass.pDepthStencilAttachment = &attach; 3197 subpass.pColorAttachments = NULL; 3198 VkRenderPass rp_ds; 3199 err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_ds); 3200 ASSERT_VK_SUCCESS(err); 3201 // Set correct attachment count, but attachment has COLOR usage bit set 3202 fb_info.attachmentCount = 1; 3203 fb_info.renderPass = rp_ds; 3204 3205 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " conflicts with the image's IMAGE_USAGE flags "); 3206 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 3207 3208 m_errorMonitor->VerifyFound(); 3209 if (err == VK_SUCCESS) { 3210 vkDestroyFramebuffer(m_device->device(), fb, NULL); 3211 } 3212 vkDestroyRenderPass(m_device->device(), rp_ds, NULL); 3213 3214 // Create new renderpass with alternate attachment format from fb 3215 attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM; 3216 subpass.pDepthStencilAttachment = NULL; 3217 subpass.pColorAttachments = &attach; 3218 err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 3219 ASSERT_VK_SUCCESS(err); 3220 3221 // Cause error due to mis-matched formats between rp & fb 3222 // rp attachment 0 now has RGBA8 but corresponding fb attach is BGRA8 3223 fb_info.renderPass = rp; 3224 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 3225 " has format of VK_FORMAT_B8G8R8A8_UNORM that does not match "); 3226 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 3227 3228 m_errorMonitor->VerifyFound(); 3229 if (err == VK_SUCCESS) { 3230 vkDestroyFramebuffer(m_device->device(), fb, NULL); 3231 } 3232 vkDestroyRenderPass(m_device->device(), rp, NULL); 3233 3234 // Create new renderpass with alternate sample count from fb 3235 attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM; 3236 attach_desc.samples = VK_SAMPLE_COUNT_4_BIT; 3237 err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 3238 ASSERT_VK_SUCCESS(err); 3239 3240 // Cause error due to mis-matched sample count between rp & fb 3241 fb_info.renderPass = rp; 3242 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has VK_SAMPLE_COUNT_1_BIT samples " 3243 "that do not match the " 3244 "VK_SAMPLE_COUNT_4_BIT "); 3245 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 3246 3247 m_errorMonitor->VerifyFound(); 3248 if (err == VK_SUCCESS) { 3249 vkDestroyFramebuffer(m_device->device(), fb, NULL); 3250 } 3251 3252 vkDestroyRenderPass(m_device->device(), rp, NULL); 3253 3254 // Create a custom imageView with non-1 mip levels 3255 VkImageObj image(m_device); 3256 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 3257 ASSERT_TRUE(image.initialized()); 3258 3259 VkImageView view; 3260 VkImageViewCreateInfo ivci = {}; 3261 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 3262 ivci.image = image.handle(); 3263 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; 3264 ivci.format = VK_FORMAT_B8G8R8A8_UNORM; 3265 ivci.subresourceRange.layerCount = 1; 3266 ivci.subresourceRange.baseMipLevel = 0; 3267 // Set level count 2 (only 1 is allowed for FB attachment) 3268 ivci.subresourceRange.levelCount = 2; 3269 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3270 err = vkCreateImageView(m_device->device(), &ivci, NULL, &view); 3271 ASSERT_VK_SUCCESS(err); 3272 // Re-create renderpass to have matching sample count 3273 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; 3274 err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 3275 ASSERT_VK_SUCCESS(err); 3276 3277 fb_info.renderPass = rp; 3278 fb_info.pAttachments = &view; 3279 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has mip levelCount of 2 but only "); 3280 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 3281 3282 m_errorMonitor->VerifyFound(); 3283 if (err == VK_SUCCESS) { 3284 vkDestroyFramebuffer(m_device->device(), fb, NULL); 3285 } 3286 vkDestroyImageView(m_device->device(), view, NULL); 3287 // Update view to original color buffer and grow FB dimensions too big 3288 fb_info.pAttachments = ivs; 3289 fb_info.height = 1024; 3290 fb_info.width = 1024; 3291 fb_info.layers = 2; 3292 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " Attachment dimensions must be at " 3293 "least as large. "); 3294 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 3295 3296 m_errorMonitor->VerifyFound(); 3297 if (err == VK_SUCCESS) { 3298 vkDestroyFramebuffer(m_device->device(), fb, NULL); 3299 } 3300 // Create view attachment with non-identity swizzle 3301 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 3302 ivci.image = image.handle(); 3303 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; 3304 ivci.format = VK_FORMAT_B8G8R8A8_UNORM; 3305 ivci.subresourceRange.layerCount = 1; 3306 ivci.subresourceRange.baseMipLevel = 0; 3307 ivci.subresourceRange.levelCount = 1; 3308 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3309 ivci.components.r = VK_COMPONENT_SWIZZLE_G; 3310 ivci.components.g = VK_COMPONENT_SWIZZLE_R; 3311 ivci.components.b = VK_COMPONENT_SWIZZLE_A; 3312 ivci.components.a = VK_COMPONENT_SWIZZLE_B; 3313 err = vkCreateImageView(m_device->device(), &ivci, NULL, &view); 3314 ASSERT_VK_SUCCESS(err); 3315 3316 fb_info.pAttachments = &view; 3317 fb_info.height = 100; 3318 fb_info.width = 100; 3319 fb_info.layers = 1; 3320 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has non-identy swizzle. All " 3321 "framebuffer attachments must have " 3322 "been created with the identity " 3323 "swizzle. "); 3324 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 3325 3326 m_errorMonitor->VerifyFound(); 3327 if (err == VK_SUCCESS) { 3328 vkDestroyFramebuffer(m_device->device(), fb, NULL); 3329 } 3330 vkDestroyImageView(m_device->device(), view, NULL); 3331 // Request fb that exceeds max dimensions 3332 // reset attachment to color attachment 3333 fb_info.pAttachments = ivs; 3334 fb_info.width = m_device->props.limits.maxFramebufferWidth + 1; 3335 fb_info.height = m_device->props.limits.maxFramebufferHeight + 1; 3336 fb_info.layers = m_device->props.limits.maxFramebufferLayers + 1; 3337 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " Requested VkFramebufferCreateInfo " 3338 "dimensions exceed physical device " 3339 "limits. "); 3340 err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 3341 3342 m_errorMonitor->VerifyFound(); 3343 if (err == VK_SUCCESS) { 3344 vkDestroyFramebuffer(m_device->device(), fb, NULL); 3345 } 3346 3347 vkDestroyRenderPass(m_device->device(), rp, NULL); 3348 } 3349 3350 TEST_F(VkLayerTest, DynamicDepthBiasNotBound) { 3351 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Depth Bias dynamic " 3352 "state is required but not correctly bound."); 3353 3354 ASSERT_NO_FATAL_FAILURE(InitState()); 3355 // Dynamic depth bias 3356 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic depth bias state not set for this command buffer"); 3357 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthBias); 3358 m_errorMonitor->VerifyFound(); 3359 } 3360 3361 TEST_F(VkLayerTest, DynamicLineWidthNotBound) { 3362 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Line Width dynamic " 3363 "state is required but not correctly bound."); 3364 3365 ASSERT_NO_FATAL_FAILURE(InitState()); 3366 // Dynamic line width 3367 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic line width state not set for this command buffer"); 3368 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailLineWidth); 3369 m_errorMonitor->VerifyFound(); 3370 } 3371 3372 TEST_F(VkLayerTest, DynamicViewportNotBound) { 3373 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Viewport dynamic " 3374 "state is required but not correctly bound."); 3375 3376 ASSERT_NO_FATAL_FAILURE(InitState()); 3377 // Dynamic viewport state 3378 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic viewport(s) 0 are used by pipeline state object, but were not provided"); 3379 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport); 3380 m_errorMonitor->VerifyFound(); 3381 } 3382 3383 TEST_F(VkLayerTest, DynamicScissorNotBound) { 3384 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Scissor dynamic " 3385 "state is required but not correctly bound."); 3386 3387 ASSERT_NO_FATAL_FAILURE(InitState()); 3388 // Dynamic scissor state 3389 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic scissor(s) 0 are used by pipeline state object, but were not provided"); 3390 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailScissor); 3391 m_errorMonitor->VerifyFound(); 3392 } 3393 3394 TEST_F(VkLayerTest, DynamicBlendConstantsNotBound) { 3395 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Blend Constants " 3396 "dynamic state is required but not correctly bound."); 3397 3398 ASSERT_NO_FATAL_FAILURE(InitState()); 3399 // Dynamic blend constant state 3400 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 3401 "Dynamic blend constants state not set for this command buffer"); 3402 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailBlend); 3403 m_errorMonitor->VerifyFound(); 3404 } 3405 3406 TEST_F(VkLayerTest, DynamicDepthBoundsNotBound) { 3407 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Depth Bounds dynamic " 3408 "state is required but not correctly bound."); 3409 3410 ASSERT_NO_FATAL_FAILURE(InitState()); 3411 if (!m_device->phy().features().depthBounds) { 3412 printf("Device does not support depthBounds test; skipped.\n"); 3413 return; 3414 } 3415 // Dynamic depth bounds 3416 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 3417 "Dynamic depth bounds state not set for this command buffer"); 3418 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthBounds); 3419 m_errorMonitor->VerifyFound(); 3420 } 3421 3422 TEST_F(VkLayerTest, DynamicStencilReadNotBound) { 3423 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Stencil Read dynamic " 3424 "state is required but not correctly bound."); 3425 3426 ASSERT_NO_FATAL_FAILURE(InitState()); 3427 // Dynamic stencil read mask 3428 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 3429 "Dynamic stencil read mask state not set for this command buffer"); 3430 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailStencilReadMask); 3431 m_errorMonitor->VerifyFound(); 3432 } 3433 3434 TEST_F(VkLayerTest, DynamicStencilWriteNotBound) { 3435 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Stencil Write dynamic" 3436 " state is required but not correctly bound."); 3437 3438 ASSERT_NO_FATAL_FAILURE(InitState()); 3439 // Dynamic stencil write mask 3440 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 3441 "Dynamic stencil write mask state not set for this command buffer"); 3442 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailStencilWriteMask); 3443 m_errorMonitor->VerifyFound(); 3444 } 3445 3446 TEST_F(VkLayerTest, DynamicStencilRefNotBound) { 3447 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Stencil Ref dynamic " 3448 "state is required but not correctly bound."); 3449 3450 ASSERT_NO_FATAL_FAILURE(InitState()); 3451 // Dynamic stencil reference 3452 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 3453 "Dynamic stencil reference state not set for this command buffer"); 3454 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailStencilReference); 3455 m_errorMonitor->VerifyFound(); 3456 } 3457 3458 TEST_F(VkLayerTest, IndexBufferNotBound) { 3459 TEST_DESCRIPTION("Run an indexed draw call without an index buffer bound."); 3460 3461 ASSERT_NO_FATAL_FAILURE(InitState()); 3462 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 3463 "Index buffer object not bound to this command buffer when Indexed "); 3464 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailIndexBuffer); 3465 m_errorMonitor->VerifyFound(); 3466 } 3467 3468 TEST_F(VkLayerTest, CommandBufferTwoSubmits) { 3469 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 3470 "was begun w/ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has " 3471 "been submitted"); 3472 3473 ASSERT_NO_FATAL_FAILURE(InitState()); 3474 ASSERT_NO_FATAL_FAILURE(InitViewport()); 3475 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 3476 3477 // We luck out b/c by default the framework creates CB w/ the 3478 // VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set 3479 BeginCommandBuffer(); 3480 m_commandBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL); 3481 EndCommandBuffer(); 3482 3483 // Bypass framework since it does the waits automatically 3484 VkResult err = VK_SUCCESS; 3485 VkSubmitInfo submit_info; 3486 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 3487 submit_info.pNext = NULL; 3488 submit_info.waitSemaphoreCount = 0; 3489 submit_info.pWaitSemaphores = NULL; 3490 submit_info.pWaitDstStageMask = NULL; 3491 submit_info.commandBufferCount = 1; 3492 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 3493 submit_info.signalSemaphoreCount = 0; 3494 submit_info.pSignalSemaphores = NULL; 3495 3496 err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 3497 ASSERT_VK_SUCCESS(err); 3498 3499 // Cause validation error by re-submitting cmd buffer that should only be 3500 // submitted once 3501 err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 3502 3503 m_errorMonitor->VerifyFound(); 3504 } 3505 3506 TEST_F(VkLayerTest, AllocDescriptorFromEmptyPool) { 3507 // Initiate Draw w/o a PSO bound 3508 VkResult err; 3509 3510 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Unable to allocate 1 descriptors of " 3511 "type " 3512 "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER "); 3513 3514 ASSERT_NO_FATAL_FAILURE(InitState()); 3515 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 3516 3517 // Create Pool w/ 1 Sampler descriptor, but try to alloc Uniform Buffer 3518 // descriptor from it 3519 VkDescriptorPoolSize ds_type_count = {}; 3520 ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER; 3521 ds_type_count.descriptorCount = 1; 3522 3523 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 3524 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 3525 ds_pool_ci.pNext = NULL; 3526 ds_pool_ci.flags = 0; 3527 ds_pool_ci.maxSets = 1; 3528 ds_pool_ci.poolSizeCount = 1; 3529 ds_pool_ci.pPoolSizes = &ds_type_count; 3530 3531 VkDescriptorPool ds_pool; 3532 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 3533 ASSERT_VK_SUCCESS(err); 3534 3535 VkDescriptorSetLayoutBinding dsl_binding = {}; 3536 dsl_binding.binding = 0; 3537 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 3538 dsl_binding.descriptorCount = 1; 3539 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 3540 dsl_binding.pImmutableSamplers = NULL; 3541 3542 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 3543 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 3544 ds_layout_ci.pNext = NULL; 3545 ds_layout_ci.bindingCount = 1; 3546 ds_layout_ci.pBindings = &dsl_binding; 3547 3548 VkDescriptorSetLayout ds_layout; 3549 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 3550 ASSERT_VK_SUCCESS(err); 3551 3552 VkDescriptorSet descriptorSet; 3553 VkDescriptorSetAllocateInfo alloc_info = {}; 3554 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 3555 alloc_info.descriptorSetCount = 1; 3556 alloc_info.descriptorPool = ds_pool; 3557 alloc_info.pSetLayouts = &ds_layout; 3558 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 3559 3560 m_errorMonitor->VerifyFound(); 3561 3562 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 3563 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 3564 } 3565 3566 TEST_F(VkLayerTest, FreeDescriptorFromOneShotPool) { 3567 VkResult err; 3568 3569 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 3570 "It is invalid to call vkFreeDescriptorSets() with a pool created " 3571 "without setting VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT."); 3572 3573 ASSERT_NO_FATAL_FAILURE(InitState()); 3574 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 3575 3576 VkDescriptorPoolSize ds_type_count = {}; 3577 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 3578 ds_type_count.descriptorCount = 1; 3579 3580 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 3581 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 3582 ds_pool_ci.pNext = NULL; 3583 ds_pool_ci.maxSets = 1; 3584 ds_pool_ci.poolSizeCount = 1; 3585 ds_pool_ci.flags = 0; 3586 // Not specifying VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT means 3587 // app can only call vkResetDescriptorPool on this pool.; 3588 ds_pool_ci.pPoolSizes = &ds_type_count; 3589 3590 VkDescriptorPool ds_pool; 3591 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 3592 ASSERT_VK_SUCCESS(err); 3593 3594 VkDescriptorSetLayoutBinding dsl_binding = {}; 3595 dsl_binding.binding = 0; 3596 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 3597 dsl_binding.descriptorCount = 1; 3598 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 3599 dsl_binding.pImmutableSamplers = NULL; 3600 3601 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 3602 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 3603 ds_layout_ci.pNext = NULL; 3604 ds_layout_ci.bindingCount = 1; 3605 ds_layout_ci.pBindings = &dsl_binding; 3606 3607 VkDescriptorSetLayout ds_layout; 3608 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 3609 ASSERT_VK_SUCCESS(err); 3610 3611 VkDescriptorSet descriptorSet; 3612 VkDescriptorSetAllocateInfo alloc_info = {}; 3613 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 3614 alloc_info.descriptorSetCount = 1; 3615 alloc_info.descriptorPool = ds_pool; 3616 alloc_info.pSetLayouts = &ds_layout; 3617 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 3618 ASSERT_VK_SUCCESS(err); 3619 3620 err = vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptorSet); 3621 m_errorMonitor->VerifyFound(); 3622 3623 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 3624 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 3625 } 3626 3627 TEST_F(VkLayerTest, InvalidDescriptorPool) { 3628 // Attempt to clear Descriptor Pool with bad object. 3629 // ObjectTracker should catch this. 3630 3631 ASSERT_NO_FATAL_FAILURE(InitState()); 3632 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Descriptor Pool Object 0xbaad6001"); 3633 uint64_t fake_pool_handle = 0xbaad6001; 3634 VkDescriptorPool bad_pool = reinterpret_cast<VkDescriptorPool &>(fake_pool_handle); 3635 vkResetDescriptorPool(device(), bad_pool, 0); 3636 m_errorMonitor->VerifyFound(); 3637 } 3638 3639 TEST_F(VkPositiveLayerTest, InvalidDescriptorSet) { 3640 // Attempt to bind an invalid Descriptor Set to a valid Command Buffer 3641 // ObjectTracker should catch this. 3642 // Create a valid cmd buffer 3643 // call vkCmdBindDescriptorSets w/ false Descriptor Set 3644 3645 uint64_t fake_set_handle = 0xbaad6001; 3646 VkDescriptorSet bad_set = reinterpret_cast<VkDescriptorSet &>(fake_set_handle); 3647 VkResult err; 3648 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Descriptor Set Object 0xbaad6001"); 3649 3650 ASSERT_NO_FATAL_FAILURE(InitState()); 3651 3652 VkDescriptorSetLayoutBinding layout_bindings[1] = {}; 3653 layout_bindings[0].binding = 0; 3654 layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 3655 layout_bindings[0].descriptorCount = 1; 3656 layout_bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; 3657 layout_bindings[0].pImmutableSamplers = NULL; 3658 3659 VkDescriptorSetLayout descriptor_set_layout; 3660 VkDescriptorSetLayoutCreateInfo dslci = {}; 3661 dslci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 3662 dslci.pNext = NULL; 3663 dslci.bindingCount = 1; 3664 dslci.pBindings = layout_bindings; 3665 err = vkCreateDescriptorSetLayout(device(), &dslci, NULL, &descriptor_set_layout); 3666 ASSERT_VK_SUCCESS(err); 3667 3668 VkPipelineLayout pipeline_layout; 3669 VkPipelineLayoutCreateInfo plci = {}; 3670 plci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 3671 plci.pNext = NULL; 3672 plci.setLayoutCount = 1; 3673 plci.pSetLayouts = &descriptor_set_layout; 3674 err = vkCreatePipelineLayout(device(), &plci, NULL, &pipeline_layout); 3675 ASSERT_VK_SUCCESS(err); 3676 3677 BeginCommandBuffer(); 3678 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &bad_set, 0, 3679 NULL); 3680 m_errorMonitor->VerifyFound(); 3681 EndCommandBuffer(); 3682 vkDestroyPipelineLayout(device(), pipeline_layout, NULL); 3683 vkDestroyDescriptorSetLayout(device(), descriptor_set_layout, NULL); 3684 } 3685 3686 TEST_F(VkLayerTest, InvalidDescriptorSetLayout) { 3687 // Attempt to create a Pipeline Layout with an invalid Descriptor Set Layout. 3688 // ObjectTracker should catch this. 3689 uint64_t fake_layout_handle = 0xbaad6001; 3690 VkDescriptorSetLayout bad_layout = reinterpret_cast<VkDescriptorSetLayout &>(fake_layout_handle); 3691 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Descriptor Set Layout Object 0xbaad6001"); 3692 ASSERT_NO_FATAL_FAILURE(InitState()); 3693 VkPipelineLayout pipeline_layout; 3694 VkPipelineLayoutCreateInfo plci = {}; 3695 plci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 3696 plci.pNext = NULL; 3697 plci.setLayoutCount = 1; 3698 plci.pSetLayouts = &bad_layout; 3699 vkCreatePipelineLayout(device(), &plci, NULL, &pipeline_layout); 3700 3701 m_errorMonitor->VerifyFound(); 3702 } 3703 3704 TEST_F(VkLayerTest, WriteDescriptorSetIntegrityCheck) { 3705 TEST_DESCRIPTION("This test verifies some requirements of chapter 13.2.3 of the Vulkan Spec " 3706 "1) A uniform buffer update must have a valid buffer index." 3707 "2) When using an array of descriptors in a single WriteDescriptor," 3708 " the descriptor types and stageflags must all be the same." 3709 "3) Immutable Sampler state must match across descriptors"); 3710 3711 const char *invalid_BufferInfo_ErrorMessage = 3712 "vkUpdateDescriptorSets: if pDescriptorWrites[0].descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, " 3713 "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or " 3714 "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, pDescriptorWrites[0].pBufferInfo must not be NULL"; 3715 const char *stateFlag_ErrorMessage = "Attempting write update to descriptor set "; 3716 const char *immutable_ErrorMessage = "Attempting write update to descriptor set "; 3717 3718 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_BufferInfo_ErrorMessage); 3719 3720 ASSERT_NO_FATAL_FAILURE(InitState()); 3721 VkDescriptorPoolSize ds_type_count[4] = {}; 3722 ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 3723 ds_type_count[0].descriptorCount = 1; 3724 ds_type_count[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 3725 ds_type_count[1].descriptorCount = 1; 3726 ds_type_count[2].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 3727 ds_type_count[2].descriptorCount = 1; 3728 ds_type_count[3].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; 3729 ds_type_count[3].descriptorCount = 1; 3730 3731 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 3732 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 3733 ds_pool_ci.maxSets = 1; 3734 ds_pool_ci.poolSizeCount = sizeof(ds_type_count) / sizeof(VkDescriptorPoolSize); 3735 ds_pool_ci.pPoolSizes = ds_type_count; 3736 3737 VkDescriptorPool ds_pool; 3738 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 3739 ASSERT_VK_SUCCESS(err); 3740 3741 VkDescriptorSetLayoutBinding layout_binding[3] = {}; 3742 layout_binding[0].binding = 0; 3743 layout_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 3744 layout_binding[0].descriptorCount = 1; 3745 layout_binding[0].stageFlags = VK_SHADER_STAGE_ALL; 3746 layout_binding[0].pImmutableSamplers = NULL; 3747 3748 layout_binding[1].binding = 1; 3749 layout_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 3750 layout_binding[1].descriptorCount = 1; 3751 layout_binding[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 3752 layout_binding[1].pImmutableSamplers = NULL; 3753 3754 VkSamplerCreateInfo sampler_ci = {}; 3755 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; 3756 sampler_ci.pNext = NULL; 3757 sampler_ci.magFilter = VK_FILTER_NEAREST; 3758 sampler_ci.minFilter = VK_FILTER_NEAREST; 3759 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; 3760 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 3761 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 3762 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 3763 sampler_ci.mipLodBias = 1.0; 3764 sampler_ci.anisotropyEnable = VK_FALSE; 3765 sampler_ci.maxAnisotropy = 1; 3766 sampler_ci.compareEnable = VK_FALSE; 3767 sampler_ci.compareOp = VK_COMPARE_OP_NEVER; 3768 sampler_ci.minLod = 1.0; 3769 sampler_ci.maxLod = 1.0; 3770 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; 3771 sampler_ci.unnormalizedCoordinates = VK_FALSE; 3772 VkSampler sampler; 3773 3774 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 3775 ASSERT_VK_SUCCESS(err); 3776 3777 layout_binding[2].binding = 2; 3778 layout_binding[2].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 3779 layout_binding[2].descriptorCount = 1; 3780 layout_binding[2].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 3781 layout_binding[2].pImmutableSamplers = static_cast<VkSampler *>(&sampler); 3782 3783 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 3784 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 3785 ds_layout_ci.bindingCount = sizeof(layout_binding) / sizeof(VkDescriptorSetLayoutBinding); 3786 ds_layout_ci.pBindings = layout_binding; 3787 VkDescriptorSetLayout ds_layout; 3788 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 3789 ASSERT_VK_SUCCESS(err); 3790 3791 VkDescriptorSetAllocateInfo alloc_info = {}; 3792 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 3793 alloc_info.descriptorSetCount = 1; 3794 alloc_info.descriptorPool = ds_pool; 3795 alloc_info.pSetLayouts = &ds_layout; 3796 VkDescriptorSet descriptorSet; 3797 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 3798 ASSERT_VK_SUCCESS(err); 3799 3800 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 3801 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 3802 pipeline_layout_ci.pNext = NULL; 3803 pipeline_layout_ci.setLayoutCount = 1; 3804 pipeline_layout_ci.pSetLayouts = &ds_layout; 3805 3806 VkPipelineLayout pipeline_layout; 3807 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 3808 ASSERT_VK_SUCCESS(err); 3809 3810 VkWriteDescriptorSet descriptor_write = {}; 3811 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 3812 descriptor_write.dstSet = descriptorSet; 3813 descriptor_write.dstBinding = 0; 3814 descriptor_write.descriptorCount = 1; 3815 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 3816 3817 // 1) The uniform buffer is intentionally invalid here 3818 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 3819 m_errorMonitor->VerifyFound(); 3820 3821 // Create a buffer to update the descriptor with 3822 uint32_t qfi = 0; 3823 VkBufferCreateInfo buffCI = {}; 3824 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 3825 buffCI.size = 1024; 3826 buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 3827 buffCI.queueFamilyIndexCount = 1; 3828 buffCI.pQueueFamilyIndices = &qfi; 3829 3830 VkBuffer dyub; 3831 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub); 3832 ASSERT_VK_SUCCESS(err); 3833 VkDescriptorBufferInfo buffInfo = {}; 3834 buffInfo.buffer = dyub; 3835 buffInfo.offset = 0; 3836 buffInfo.range = 1024; 3837 3838 descriptor_write.pBufferInfo = &buffInfo; 3839 descriptor_write.descriptorCount = 2; 3840 3841 // 2) The stateFlags don't match between the first and second descriptor 3842 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, stateFlag_ErrorMessage); 3843 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 3844 m_errorMonitor->VerifyFound(); 3845 3846 // 3) The second descriptor has a null_ptr pImmutableSamplers and 3847 // the third descriptor contains an immutable sampler 3848 descriptor_write.dstBinding = 1; 3849 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 3850 3851 // Make pImageInfo index non-null to avoid complaints of it missing 3852 VkDescriptorImageInfo imageInfo = {}; 3853 imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 3854 descriptor_write.pImageInfo = &imageInfo; 3855 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, immutable_ErrorMessage); 3856 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 3857 m_errorMonitor->VerifyFound(); 3858 3859 vkDestroyBuffer(m_device->device(), dyub, NULL); 3860 vkDestroySampler(m_device->device(), sampler, NULL); 3861 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 3862 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 3863 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 3864 } 3865 3866 TEST_F(VkLayerTest, InvalidCmdBufferBufferDestroyed) { 3867 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid " 3868 "due to a buffer dependency being destroyed."); 3869 ASSERT_NO_FATAL_FAILURE(InitState()); 3870 3871 VkBuffer buffer; 3872 VkDeviceMemory mem; 3873 VkMemoryRequirements mem_reqs; 3874 3875 VkBufferCreateInfo buf_info = {}; 3876 buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 3877 buf_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT; 3878 buf_info.size = 256; 3879 buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 3880 VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer); 3881 ASSERT_VK_SUCCESS(err); 3882 3883 vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs); 3884 3885 VkMemoryAllocateInfo alloc_info = {}; 3886 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 3887 alloc_info.allocationSize = 256; 3888 bool pass = false; 3889 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); 3890 if (!pass) { 3891 vkDestroyBuffer(m_device->device(), buffer, NULL); 3892 return; 3893 } 3894 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem); 3895 ASSERT_VK_SUCCESS(err); 3896 3897 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0); 3898 ASSERT_VK_SUCCESS(err); 3899 3900 m_commandBuffer->BeginCommandBuffer(); 3901 vkCmdFillBuffer(m_commandBuffer->GetBufferHandle(), buffer, 0, VK_WHOLE_SIZE, 0); 3902 m_commandBuffer->EndCommandBuffer(); 3903 3904 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound buffer "); 3905 // Destroy buffer dependency prior to submit to cause ERROR 3906 vkDestroyBuffer(m_device->device(), buffer, NULL); 3907 3908 VkSubmitInfo submit_info = {}; 3909 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 3910 submit_info.commandBufferCount = 1; 3911 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 3912 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 3913 3914 m_errorMonitor->VerifyFound(); 3915 vkFreeMemory(m_device->handle(), mem, NULL); 3916 } 3917 3918 TEST_F(VkLayerTest, InvalidCmdBufferBufferViewDestroyed) { 3919 TEST_DESCRIPTION("Delete bufferView bound to cmd buffer, then attempt to submit cmd buffer."); 3920 3921 ASSERT_NO_FATAL_FAILURE(InitState()); 3922 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 3923 3924 VkDescriptorPoolSize ds_type_count; 3925 ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 3926 ds_type_count.descriptorCount = 1; 3927 3928 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 3929 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 3930 ds_pool_ci.maxSets = 1; 3931 ds_pool_ci.poolSizeCount = 1; 3932 ds_pool_ci.pPoolSizes = &ds_type_count; 3933 3934 VkDescriptorPool ds_pool; 3935 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 3936 ASSERT_VK_SUCCESS(err); 3937 3938 VkDescriptorSetLayoutBinding layout_binding; 3939 layout_binding.binding = 0; 3940 layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 3941 layout_binding.descriptorCount = 1; 3942 layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 3943 layout_binding.pImmutableSamplers = NULL; 3944 3945 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 3946 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 3947 ds_layout_ci.bindingCount = 1; 3948 ds_layout_ci.pBindings = &layout_binding; 3949 VkDescriptorSetLayout ds_layout; 3950 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 3951 ASSERT_VK_SUCCESS(err); 3952 3953 VkDescriptorSetAllocateInfo alloc_info = {}; 3954 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 3955 alloc_info.descriptorSetCount = 1; 3956 alloc_info.descriptorPool = ds_pool; 3957 alloc_info.pSetLayouts = &ds_layout; 3958 VkDescriptorSet descriptor_set; 3959 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set); 3960 ASSERT_VK_SUCCESS(err); 3961 3962 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 3963 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 3964 pipeline_layout_ci.pNext = NULL; 3965 pipeline_layout_ci.setLayoutCount = 1; 3966 pipeline_layout_ci.pSetLayouts = &ds_layout; 3967 3968 VkPipelineLayout pipeline_layout; 3969 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 3970 ASSERT_VK_SUCCESS(err); 3971 3972 VkBuffer buffer; 3973 uint32_t queue_family_index = 0; 3974 VkBufferCreateInfo buffer_create_info = {}; 3975 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 3976 buffer_create_info.size = 1024; 3977 buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; 3978 buffer_create_info.queueFamilyIndexCount = 1; 3979 buffer_create_info.pQueueFamilyIndices = &queue_family_index; 3980 3981 err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer); 3982 ASSERT_VK_SUCCESS(err); 3983 3984 VkMemoryRequirements memory_reqs; 3985 VkDeviceMemory buffer_memory; 3986 3987 VkMemoryAllocateInfo memory_info = {}; 3988 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 3989 memory_info.allocationSize = 0; 3990 memory_info.memoryTypeIndex = 0; 3991 3992 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs); 3993 memory_info.allocationSize = memory_reqs.size; 3994 bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 3995 ASSERT_TRUE(pass); 3996 3997 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory); 3998 ASSERT_VK_SUCCESS(err); 3999 err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0); 4000 ASSERT_VK_SUCCESS(err); 4001 4002 VkBufferView view; 4003 VkBufferViewCreateInfo bvci = {}; 4004 bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; 4005 bvci.buffer = buffer; 4006 bvci.format = VK_FORMAT_R8_UNORM; 4007 bvci.range = VK_WHOLE_SIZE; 4008 4009 err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view); 4010 ASSERT_VK_SUCCESS(err); 4011 4012 VkWriteDescriptorSet descriptor_write = {}; 4013 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 4014 descriptor_write.dstSet = descriptor_set; 4015 descriptor_write.dstBinding = 0; 4016 descriptor_write.descriptorCount = 1; 4017 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 4018 descriptor_write.pTexelBufferView = &view; 4019 4020 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 4021 4022 char const *vsSource = "#version 450\n" 4023 "\n" 4024 "out gl_PerVertex { \n" 4025 " vec4 gl_Position;\n" 4026 "};\n" 4027 "void main(){\n" 4028 " gl_Position = vec4(1);\n" 4029 "}\n"; 4030 char const *fsSource = "#version 450\n" 4031 "\n" 4032 "layout(set=0, binding=0, r8) uniform imageBuffer s;\n" 4033 "layout(location=0) out vec4 x;\n" 4034 "void main(){\n" 4035 " x = imageLoad(s, 0);\n" 4036 "}\n"; 4037 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 4038 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 4039 VkPipelineObj pipe(m_device); 4040 pipe.AddShader(&vs); 4041 pipe.AddShader(&fs); 4042 pipe.AddColorAttachment(); 4043 pipe.CreateVKPipeline(pipeline_layout, renderPass()); 4044 4045 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot submit cmd buffer using deleted buffer view "); 4046 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound buffer view "); 4047 4048 BeginCommandBuffer(); 4049 VkViewport viewport = {0, 0, 16, 16, 0, 1}; 4050 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 4051 VkRect2D scissor = {{0, 0}, {16, 16}}; 4052 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 4053 // Bind pipeline to cmd buffer 4054 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 4055 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, 4056 &descriptor_set, 0, nullptr); 4057 Draw(1, 0, 0, 0); 4058 EndCommandBuffer(); 4059 4060 // Delete BufferView in order to invalidate cmd buffer 4061 vkDestroyBufferView(m_device->device(), view, NULL); 4062 // Now attempt submit of cmd buffer 4063 VkSubmitInfo submit_info = {}; 4064 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 4065 submit_info.commandBufferCount = 1; 4066 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 4067 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 4068 m_errorMonitor->VerifyFound(); 4069 4070 // Clean-up 4071 vkDestroyBuffer(m_device->device(), buffer, NULL); 4072 vkFreeMemory(m_device->device(), buffer_memory, NULL); 4073 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 4074 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 4075 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 4076 } 4077 4078 TEST_F(VkLayerTest, InvalidCmdBufferImageDestroyed) { 4079 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid " 4080 "due to an image dependency being destroyed."); 4081 ASSERT_NO_FATAL_FAILURE(InitState()); 4082 4083 VkImage image; 4084 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 4085 VkImageCreateInfo image_create_info = {}; 4086 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 4087 image_create_info.pNext = NULL; 4088 image_create_info.imageType = VK_IMAGE_TYPE_2D; 4089 image_create_info.format = tex_format; 4090 image_create_info.extent.width = 32; 4091 image_create_info.extent.height = 32; 4092 image_create_info.extent.depth = 1; 4093 image_create_info.mipLevels = 1; 4094 image_create_info.arrayLayers = 1; 4095 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 4096 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 4097 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 4098 image_create_info.flags = 0; 4099 VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 4100 ASSERT_VK_SUCCESS(err); 4101 // Have to bind memory to image before recording cmd in cmd buffer using it 4102 VkMemoryRequirements mem_reqs; 4103 VkDeviceMemory image_mem; 4104 bool pass; 4105 VkMemoryAllocateInfo mem_alloc = {}; 4106 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 4107 mem_alloc.pNext = NULL; 4108 mem_alloc.memoryTypeIndex = 0; 4109 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs); 4110 mem_alloc.allocationSize = mem_reqs.size; 4111 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0); 4112 ASSERT_TRUE(pass); 4113 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem); 4114 ASSERT_VK_SUCCESS(err); 4115 err = vkBindImageMemory(m_device->device(), image, image_mem, 0); 4116 ASSERT_VK_SUCCESS(err); 4117 4118 m_commandBuffer->BeginCommandBuffer(); 4119 VkClearColorValue ccv; 4120 ccv.float32[0] = 1.0f; 4121 ccv.float32[1] = 1.0f; 4122 ccv.float32[2] = 1.0f; 4123 ccv.float32[3] = 1.0f; 4124 VkImageSubresourceRange isr = {}; 4125 isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 4126 isr.baseArrayLayer = 0; 4127 isr.baseMipLevel = 0; 4128 isr.layerCount = 1; 4129 isr.levelCount = 1; 4130 vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), image, VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &isr); 4131 m_commandBuffer->EndCommandBuffer(); 4132 4133 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound image "); 4134 // Destroy image dependency prior to submit to cause ERROR 4135 vkDestroyImage(m_device->device(), image, NULL); 4136 4137 VkSubmitInfo submit_info = {}; 4138 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 4139 submit_info.commandBufferCount = 1; 4140 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 4141 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 4142 4143 m_errorMonitor->VerifyFound(); 4144 vkFreeMemory(m_device->device(), image_mem, nullptr); 4145 } 4146 4147 TEST_F(VkLayerTest, InvalidCmdBufferFramebufferImageDestroyed) { 4148 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid " 4149 "due to a framebuffer image dependency being destroyed."); 4150 VkFormatProperties format_properties; 4151 VkResult err = VK_SUCCESS; 4152 vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties); 4153 if (!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { 4154 return; 4155 } 4156 4157 ASSERT_NO_FATAL_FAILURE(InitState()); 4158 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 4159 4160 VkImageCreateInfo image_ci = {}; 4161 image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 4162 image_ci.pNext = NULL; 4163 image_ci.imageType = VK_IMAGE_TYPE_2D; 4164 image_ci.format = VK_FORMAT_B8G8R8A8_UNORM; 4165 image_ci.extent.width = 32; 4166 image_ci.extent.height = 32; 4167 image_ci.extent.depth = 1; 4168 image_ci.mipLevels = 1; 4169 image_ci.arrayLayers = 1; 4170 image_ci.samples = VK_SAMPLE_COUNT_1_BIT; 4171 image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; 4172 image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; 4173 image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 4174 image_ci.flags = 0; 4175 VkImage image; 4176 ASSERT_VK_SUCCESS(vkCreateImage(m_device->handle(), &image_ci, NULL, &image)); 4177 4178 VkMemoryRequirements memory_reqs; 4179 VkDeviceMemory image_memory; 4180 bool pass; 4181 VkMemoryAllocateInfo memory_info = {}; 4182 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 4183 memory_info.pNext = NULL; 4184 memory_info.allocationSize = 0; 4185 memory_info.memoryTypeIndex = 0; 4186 vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs); 4187 memory_info.allocationSize = memory_reqs.size; 4188 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 4189 ASSERT_TRUE(pass); 4190 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory); 4191 ASSERT_VK_SUCCESS(err); 4192 err = vkBindImageMemory(m_device->device(), image, image_memory, 0); 4193 ASSERT_VK_SUCCESS(err); 4194 4195 VkImageViewCreateInfo ivci = { 4196 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 4197 nullptr, 4198 0, 4199 image, 4200 VK_IMAGE_VIEW_TYPE_2D, 4201 VK_FORMAT_B8G8R8A8_UNORM, 4202 {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A}, 4203 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}, 4204 }; 4205 VkImageView view; 4206 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view); 4207 ASSERT_VK_SUCCESS(err); 4208 4209 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 32, 32, 1}; 4210 VkFramebuffer fb; 4211 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); 4212 ASSERT_VK_SUCCESS(err); 4213 4214 // Just use default renderpass with our framebuffer 4215 m_renderPassBeginInfo.framebuffer = fb; 4216 // Create Null cmd buffer for submit 4217 BeginCommandBuffer(); 4218 EndCommandBuffer(); 4219 // Destroy image attached to framebuffer to invalidate cmd buffer 4220 vkDestroyImage(m_device->device(), image, NULL); 4221 // Now attempt to submit cmd buffer and verify error 4222 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound image "); 4223 QueueCommandBuffer(false); 4224 m_errorMonitor->VerifyFound(); 4225 4226 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 4227 vkDestroyImageView(m_device->device(), view, nullptr); 4228 vkFreeMemory(m_device->device(), image_memory, nullptr); 4229 } 4230 4231 TEST_F(VkLayerTest, FramebufferInUseDestroyedSignaled) { 4232 TEST_DESCRIPTION("Delete in-use framebuffer."); 4233 VkFormatProperties format_properties; 4234 VkResult err = VK_SUCCESS; 4235 vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties); 4236 4237 ASSERT_NO_FATAL_FAILURE(InitState()); 4238 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 4239 4240 VkImageObj image(m_device); 4241 image.init(256, 256, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 4242 ASSERT_TRUE(image.initialized()); 4243 VkImageView view = image.targetView(VK_FORMAT_B8G8R8A8_UNORM); 4244 4245 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 256, 256, 1}; 4246 VkFramebuffer fb; 4247 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); 4248 ASSERT_VK_SUCCESS(err); 4249 4250 // Just use default renderpass with our framebuffer 4251 m_renderPassBeginInfo.framebuffer = fb; 4252 // Create Null cmd buffer for submit 4253 BeginCommandBuffer(); 4254 EndCommandBuffer(); 4255 // Submit cmd buffer to put it in-flight 4256 VkSubmitInfo submit_info = {}; 4257 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 4258 submit_info.commandBufferCount = 1; 4259 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 4260 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 4261 // Destroy framebuffer while in-flight 4262 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete framebuffer 0x"); 4263 vkDestroyFramebuffer(m_device->device(), fb, NULL); 4264 m_errorMonitor->VerifyFound(); 4265 // Wait for queue to complete so we can safely destroy everything 4266 vkQueueWaitIdle(m_device->m_queue); 4267 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 4268 } 4269 4270 TEST_F(VkLayerTest, FramebufferImageInUseDestroyedSignaled) { 4271 TEST_DESCRIPTION("Delete in-use image that's child of framebuffer."); 4272 VkFormatProperties format_properties; 4273 VkResult err = VK_SUCCESS; 4274 vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties); 4275 4276 ASSERT_NO_FATAL_FAILURE(InitState()); 4277 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 4278 4279 VkImageCreateInfo image_ci = {}; 4280 image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 4281 image_ci.pNext = NULL; 4282 image_ci.imageType = VK_IMAGE_TYPE_2D; 4283 image_ci.format = VK_FORMAT_B8G8R8A8_UNORM; 4284 image_ci.extent.width = 256; 4285 image_ci.extent.height = 256; 4286 image_ci.extent.depth = 1; 4287 image_ci.mipLevels = 1; 4288 image_ci.arrayLayers = 1; 4289 image_ci.samples = VK_SAMPLE_COUNT_1_BIT; 4290 image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; 4291 image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 4292 image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 4293 image_ci.flags = 0; 4294 VkImage image; 4295 ASSERT_VK_SUCCESS(vkCreateImage(m_device->handle(), &image_ci, NULL, &image)); 4296 4297 VkMemoryRequirements memory_reqs; 4298 VkDeviceMemory image_memory; 4299 bool pass; 4300 VkMemoryAllocateInfo memory_info = {}; 4301 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 4302 memory_info.pNext = NULL; 4303 memory_info.allocationSize = 0; 4304 memory_info.memoryTypeIndex = 0; 4305 vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs); 4306 memory_info.allocationSize = memory_reqs.size; 4307 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 4308 ASSERT_TRUE(pass); 4309 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory); 4310 ASSERT_VK_SUCCESS(err); 4311 err = vkBindImageMemory(m_device->device(), image, image_memory, 0); 4312 ASSERT_VK_SUCCESS(err); 4313 4314 VkImageViewCreateInfo ivci = { 4315 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 4316 nullptr, 4317 0, 4318 image, 4319 VK_IMAGE_VIEW_TYPE_2D, 4320 VK_FORMAT_B8G8R8A8_UNORM, 4321 {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A}, 4322 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}, 4323 }; 4324 VkImageView view; 4325 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view); 4326 ASSERT_VK_SUCCESS(err); 4327 4328 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 256, 256, 1}; 4329 VkFramebuffer fb; 4330 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); 4331 ASSERT_VK_SUCCESS(err); 4332 4333 // Just use default renderpass with our framebuffer 4334 m_renderPassBeginInfo.framebuffer = fb; 4335 // Create Null cmd buffer for submit 4336 BeginCommandBuffer(); 4337 EndCommandBuffer(); 4338 // Submit cmd buffer to put it (and attached imageView) in-flight 4339 VkSubmitInfo submit_info = {}; 4340 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 4341 submit_info.commandBufferCount = 1; 4342 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 4343 // Submit cmd buffer to put framebuffer and children in-flight 4344 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 4345 // Destroy image attached to framebuffer while in-flight 4346 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete image 0x"); 4347 vkDestroyImage(m_device->device(), image, NULL); 4348 m_errorMonitor->VerifyFound(); 4349 // Wait for queue to complete so we can safely destroy image and other objects 4350 vkQueueWaitIdle(m_device->m_queue); 4351 vkDestroyImage(m_device->device(), image, NULL); 4352 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 4353 vkDestroyImageView(m_device->device(), view, nullptr); 4354 vkFreeMemory(m_device->device(), image_memory, nullptr); 4355 } 4356 4357 TEST_F(VkLayerTest, ImageMemoryNotBound) { 4358 TEST_DESCRIPTION("Attempt to draw with an image which has not had memory bound to it."); 4359 ASSERT_NO_FATAL_FAILURE(InitState()); 4360 4361 VkImage image; 4362 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 4363 VkImageCreateInfo image_create_info = {}; 4364 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 4365 image_create_info.pNext = NULL; 4366 image_create_info.imageType = VK_IMAGE_TYPE_2D; 4367 image_create_info.format = tex_format; 4368 image_create_info.extent.width = 32; 4369 image_create_info.extent.height = 32; 4370 image_create_info.extent.depth = 1; 4371 image_create_info.mipLevels = 1; 4372 image_create_info.arrayLayers = 1; 4373 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 4374 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 4375 image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 4376 image_create_info.flags = 0; 4377 VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 4378 ASSERT_VK_SUCCESS(err); 4379 // Have to bind memory to image before recording cmd in cmd buffer using it 4380 VkMemoryRequirements mem_reqs; 4381 VkDeviceMemory image_mem; 4382 bool pass; 4383 VkMemoryAllocateInfo mem_alloc = {}; 4384 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 4385 mem_alloc.pNext = NULL; 4386 mem_alloc.memoryTypeIndex = 0; 4387 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs); 4388 mem_alloc.allocationSize = mem_reqs.size; 4389 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0); 4390 ASSERT_TRUE(pass); 4391 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem); 4392 ASSERT_VK_SUCCESS(err); 4393 4394 // Introduce error, do not call vkBindImageMemory(m_device->device(), image, image_mem, 0); 4395 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 4396 " used with no memory bound. Memory should be bound by calling vkBindImageMemory()."); 4397 4398 m_commandBuffer->BeginCommandBuffer(); 4399 VkClearColorValue ccv; 4400 ccv.float32[0] = 1.0f; 4401 ccv.float32[1] = 1.0f; 4402 ccv.float32[2] = 1.0f; 4403 ccv.float32[3] = 1.0f; 4404 VkImageSubresourceRange isr = {}; 4405 isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 4406 isr.baseArrayLayer = 0; 4407 isr.baseMipLevel = 0; 4408 isr.layerCount = 1; 4409 isr.levelCount = 1; 4410 vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), image, VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &isr); 4411 m_commandBuffer->EndCommandBuffer(); 4412 4413 m_errorMonitor->VerifyFound(); 4414 vkDestroyImage(m_device->device(), image, NULL); 4415 vkFreeMemory(m_device->device(), image_mem, nullptr); 4416 } 4417 4418 TEST_F(VkLayerTest, BufferMemoryNotBound) { 4419 TEST_DESCRIPTION("Attempt to copy from a buffer which has not had memory bound to it."); 4420 ASSERT_NO_FATAL_FAILURE(InitState()); 4421 4422 VkImageObj image(m_device); 4423 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 4424 VK_IMAGE_TILING_OPTIMAL, 0); 4425 ASSERT_TRUE(image.initialized()); 4426 4427 VkBuffer buffer; 4428 VkDeviceMemory mem; 4429 VkMemoryRequirements mem_reqs; 4430 4431 VkBufferCreateInfo buf_info = {}; 4432 buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 4433 buf_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; 4434 buf_info.size = 256; 4435 buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 4436 VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer); 4437 ASSERT_VK_SUCCESS(err); 4438 4439 vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs); 4440 4441 VkMemoryAllocateInfo alloc_info = {}; 4442 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 4443 alloc_info.allocationSize = 256; 4444 bool pass = false; 4445 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); 4446 if (!pass) { 4447 vkDestroyBuffer(m_device->device(), buffer, NULL); 4448 return; 4449 } 4450 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem); 4451 ASSERT_VK_SUCCESS(err); 4452 4453 // Introduce failure by not calling vkBindBufferMemory(m_device->device(), buffer, mem, 0); 4454 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 4455 " used with no memory bound. Memory should be bound by calling vkBindBufferMemory()."); 4456 VkBufferImageCopy region = {}; 4457 region.bufferRowLength = 128; 4458 region.bufferImageHeight = 128; 4459 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 4460 4461 region.imageSubresource.layerCount = 1; 4462 region.imageExtent.height = 4; 4463 region.imageExtent.width = 4; 4464 region.imageExtent.depth = 1; 4465 m_commandBuffer->BeginCommandBuffer(); 4466 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer, image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, 4467 ®ion); 4468 m_commandBuffer->EndCommandBuffer(); 4469 4470 m_errorMonitor->VerifyFound(); 4471 4472 vkDestroyBuffer(m_device->device(), buffer, NULL); 4473 vkFreeMemory(m_device->handle(), mem, NULL); 4474 } 4475 4476 TEST_F(VkLayerTest, InvalidCmdBufferEventDestroyed) { 4477 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid " 4478 "due to an event dependency being destroyed."); 4479 ASSERT_NO_FATAL_FAILURE(InitState()); 4480 4481 VkEvent event; 4482 VkEventCreateInfo evci = {}; 4483 evci.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 4484 VkResult result = vkCreateEvent(m_device->device(), &evci, NULL, &event); 4485 ASSERT_VK_SUCCESS(result); 4486 4487 m_commandBuffer->BeginCommandBuffer(); 4488 vkCmdSetEvent(m_commandBuffer->GetBufferHandle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); 4489 m_commandBuffer->EndCommandBuffer(); 4490 4491 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound event "); 4492 // Destroy event dependency prior to submit to cause ERROR 4493 vkDestroyEvent(m_device->device(), event, NULL); 4494 4495 VkSubmitInfo submit_info = {}; 4496 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 4497 submit_info.commandBufferCount = 1; 4498 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 4499 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 4500 4501 m_errorMonitor->VerifyFound(); 4502 } 4503 4504 TEST_F(VkLayerTest, InvalidCmdBufferQueryPoolDestroyed) { 4505 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid " 4506 "due to a query pool dependency being destroyed."); 4507 ASSERT_NO_FATAL_FAILURE(InitState()); 4508 4509 VkQueryPool query_pool; 4510 VkQueryPoolCreateInfo qpci{}; 4511 qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; 4512 qpci.queryType = VK_QUERY_TYPE_TIMESTAMP; 4513 qpci.queryCount = 1; 4514 VkResult result = vkCreateQueryPool(m_device->device(), &qpci, nullptr, &query_pool); 4515 ASSERT_VK_SUCCESS(result); 4516 4517 m_commandBuffer->BeginCommandBuffer(); 4518 vkCmdResetQueryPool(m_commandBuffer->GetBufferHandle(), query_pool, 0, 1); 4519 m_commandBuffer->EndCommandBuffer(); 4520 4521 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound query pool "); 4522 // Destroy query pool dependency prior to submit to cause ERROR 4523 vkDestroyQueryPool(m_device->device(), query_pool, NULL); 4524 4525 VkSubmitInfo submit_info = {}; 4526 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 4527 submit_info.commandBufferCount = 1; 4528 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 4529 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 4530 4531 m_errorMonitor->VerifyFound(); 4532 } 4533 4534 TEST_F(VkLayerTest, InvalidCmdBufferPipelineDestroyed) { 4535 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid " 4536 "due to a pipeline dependency being destroyed."); 4537 ASSERT_NO_FATAL_FAILURE(InitState()); 4538 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 4539 4540 VkResult err; 4541 4542 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 4543 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 4544 4545 VkPipelineLayout pipeline_layout; 4546 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 4547 ASSERT_VK_SUCCESS(err); 4548 4549 VkPipelineViewportStateCreateInfo vp_state_ci = {}; 4550 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 4551 vp_state_ci.viewportCount = 1; 4552 VkViewport vp = {}; // Just need dummy vp to point to 4553 vp_state_ci.pViewports = &vp; 4554 vp_state_ci.scissorCount = 1; 4555 VkRect2D scissors = {}; // Dummy scissors to point to 4556 vp_state_ci.pScissors = &scissors; 4557 4558 VkPipelineShaderStageCreateInfo shaderStages[2]; 4559 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo)); 4560 4561 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 4562 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader 4563 // but add it to be able to run on more devices 4564 shaderStages[0] = vs.GetStageCreateInfo(); 4565 shaderStages[1] = fs.GetStageCreateInfo(); 4566 4567 VkPipelineVertexInputStateCreateInfo vi_ci = {}; 4568 vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 4569 4570 VkPipelineInputAssemblyStateCreateInfo ia_ci = {}; 4571 ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 4572 ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 4573 4574 VkPipelineRasterizationStateCreateInfo rs_ci = {}; 4575 rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 4576 rs_ci.rasterizerDiscardEnable = true; 4577 rs_ci.lineWidth = 1.0f; 4578 4579 VkPipelineColorBlendAttachmentState att = {}; 4580 att.blendEnable = VK_FALSE; 4581 att.colorWriteMask = 0xf; 4582 4583 VkPipelineColorBlendStateCreateInfo cb_ci = {}; 4584 cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; 4585 cb_ci.attachmentCount = 1; 4586 cb_ci.pAttachments = &att; 4587 4588 VkGraphicsPipelineCreateInfo gp_ci = {}; 4589 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 4590 gp_ci.stageCount = 2; 4591 gp_ci.pStages = shaderStages; 4592 gp_ci.pVertexInputState = &vi_ci; 4593 gp_ci.pInputAssemblyState = &ia_ci; 4594 gp_ci.pViewportState = &vp_state_ci; 4595 gp_ci.pRasterizationState = &rs_ci; 4596 gp_ci.pColorBlendState = &cb_ci; 4597 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; 4598 gp_ci.layout = pipeline_layout; 4599 gp_ci.renderPass = renderPass(); 4600 4601 VkPipelineCacheCreateInfo pc_ci = {}; 4602 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 4603 4604 VkPipeline pipeline; 4605 VkPipelineCache pipelineCache; 4606 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache); 4607 ASSERT_VK_SUCCESS(err); 4608 4609 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline); 4610 ASSERT_VK_SUCCESS(err); 4611 4612 m_commandBuffer->BeginCommandBuffer(); 4613 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); 4614 m_commandBuffer->EndCommandBuffer(); 4615 // Now destroy pipeline in order to cause error when submitting 4616 vkDestroyPipeline(m_device->device(), pipeline, nullptr); 4617 4618 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound pipeline "); 4619 4620 VkSubmitInfo submit_info = {}; 4621 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 4622 submit_info.commandBufferCount = 1; 4623 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 4624 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 4625 4626 m_errorMonitor->VerifyFound(); 4627 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL); 4628 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 4629 } 4630 4631 TEST_F(VkLayerTest, InvalidCmdBufferDescriptorSetBufferDestroyed) { 4632 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid " 4633 "due to a bound descriptor set with a buffer dependency " 4634 "being destroyed."); 4635 ASSERT_NO_FATAL_FAILURE(InitState()); 4636 ASSERT_NO_FATAL_FAILURE(InitViewport()); 4637 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 4638 4639 VkDescriptorPoolSize ds_type_count = {}; 4640 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 4641 ds_type_count.descriptorCount = 1; 4642 4643 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 4644 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 4645 ds_pool_ci.pNext = NULL; 4646 ds_pool_ci.maxSets = 1; 4647 ds_pool_ci.poolSizeCount = 1; 4648 ds_pool_ci.pPoolSizes = &ds_type_count; 4649 4650 VkDescriptorPool ds_pool; 4651 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 4652 ASSERT_VK_SUCCESS(err); 4653 4654 VkDescriptorSetLayoutBinding dsl_binding = {}; 4655 dsl_binding.binding = 0; 4656 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 4657 dsl_binding.descriptorCount = 1; 4658 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 4659 dsl_binding.pImmutableSamplers = NULL; 4660 4661 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 4662 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 4663 ds_layout_ci.pNext = NULL; 4664 ds_layout_ci.bindingCount = 1; 4665 ds_layout_ci.pBindings = &dsl_binding; 4666 VkDescriptorSetLayout ds_layout; 4667 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 4668 ASSERT_VK_SUCCESS(err); 4669 4670 VkDescriptorSet descriptorSet; 4671 VkDescriptorSetAllocateInfo alloc_info = {}; 4672 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 4673 alloc_info.descriptorSetCount = 1; 4674 alloc_info.descriptorPool = ds_pool; 4675 alloc_info.pSetLayouts = &ds_layout; 4676 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 4677 ASSERT_VK_SUCCESS(err); 4678 4679 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 4680 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 4681 pipeline_layout_ci.pNext = NULL; 4682 pipeline_layout_ci.setLayoutCount = 1; 4683 pipeline_layout_ci.pSetLayouts = &ds_layout; 4684 4685 VkPipelineLayout pipeline_layout; 4686 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 4687 ASSERT_VK_SUCCESS(err); 4688 4689 // Create a buffer to update the descriptor with 4690 uint32_t qfi = 0; 4691 VkBufferCreateInfo buffCI = {}; 4692 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 4693 buffCI.size = 1024; 4694 buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 4695 buffCI.queueFamilyIndexCount = 1; 4696 buffCI.pQueueFamilyIndices = &qfi; 4697 4698 VkBuffer buffer; 4699 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &buffer); 4700 ASSERT_VK_SUCCESS(err); 4701 // Allocate memory and bind to buffer so we can make it to the appropriate 4702 // error 4703 VkMemoryAllocateInfo mem_alloc = {}; 4704 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 4705 mem_alloc.pNext = NULL; 4706 mem_alloc.allocationSize = 1024; 4707 mem_alloc.memoryTypeIndex = 0; 4708 4709 VkMemoryRequirements memReqs; 4710 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs); 4711 bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0); 4712 if (!pass) { 4713 vkDestroyBuffer(m_device->device(), buffer, NULL); 4714 return; 4715 } 4716 4717 VkDeviceMemory mem; 4718 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem); 4719 ASSERT_VK_SUCCESS(err); 4720 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0); 4721 ASSERT_VK_SUCCESS(err); 4722 // Correctly update descriptor to avoid "NOT_UPDATED" error 4723 VkDescriptorBufferInfo buffInfo = {}; 4724 buffInfo.buffer = buffer; 4725 buffInfo.offset = 0; 4726 buffInfo.range = 1024; 4727 4728 VkWriteDescriptorSet descriptor_write; 4729 memset(&descriptor_write, 0, sizeof(descriptor_write)); 4730 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 4731 descriptor_write.dstSet = descriptorSet; 4732 descriptor_write.dstBinding = 0; 4733 descriptor_write.descriptorCount = 1; 4734 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 4735 descriptor_write.pBufferInfo = &buffInfo; 4736 4737 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 4738 4739 // Create PSO to be used for draw-time errors below 4740 char const *vsSource = "#version 450\n" 4741 "\n" 4742 "out gl_PerVertex { \n" 4743 " vec4 gl_Position;\n" 4744 "};\n" 4745 "void main(){\n" 4746 " gl_Position = vec4(1);\n" 4747 "}\n"; 4748 char const *fsSource = "#version 450\n" 4749 "\n" 4750 "layout(location=0) out vec4 x;\n" 4751 "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n" 4752 "void main(){\n" 4753 " x = vec4(bar.y);\n" 4754 "}\n"; 4755 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 4756 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 4757 VkPipelineObj pipe(m_device); 4758 pipe.AddShader(&vs); 4759 pipe.AddShader(&fs); 4760 pipe.AddColorAttachment(); 4761 pipe.CreateVKPipeline(pipeline_layout, renderPass()); 4762 4763 BeginCommandBuffer(); 4764 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 4765 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, 4766 &descriptorSet, 0, NULL); 4767 Draw(1, 0, 0, 0); 4768 EndCommandBuffer(); 4769 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound buffer "); 4770 // Destroy buffer should invalidate the cmd buffer, causing error on submit 4771 vkDestroyBuffer(m_device->device(), buffer, NULL); 4772 // Attempt to submit cmd buffer 4773 VkSubmitInfo submit_info = {}; 4774 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 4775 submit_info.commandBufferCount = 1; 4776 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 4777 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 4778 m_errorMonitor->VerifyFound(); 4779 // Cleanup 4780 vkFreeMemory(m_device->device(), mem, NULL); 4781 4782 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 4783 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 4784 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 4785 } 4786 4787 TEST_F(VkLayerTest, InvalidCmdBufferDescriptorSetImageSamplerDestroyed) { 4788 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid " 4789 "due to a bound descriptor sets with a combined image " 4790 "sampler having their image, sampler, and descriptor set " 4791 "each respectively destroyed and then attempting to " 4792 "submit associated cmd buffers. Attempt to destroy a " 4793 "DescriptorSet that is in use."); 4794 ASSERT_NO_FATAL_FAILURE(InitState()); 4795 ASSERT_NO_FATAL_FAILURE(InitViewport()); 4796 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 4797 4798 VkDescriptorPoolSize ds_type_count = {}; 4799 ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 4800 ds_type_count.descriptorCount = 1; 4801 4802 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 4803 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 4804 ds_pool_ci.pNext = NULL; 4805 ds_pool_ci.maxSets = 1; 4806 ds_pool_ci.poolSizeCount = 1; 4807 ds_pool_ci.pPoolSizes = &ds_type_count; 4808 4809 VkDescriptorPool ds_pool; 4810 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 4811 ASSERT_VK_SUCCESS(err); 4812 4813 VkDescriptorSetLayoutBinding dsl_binding = {}; 4814 dsl_binding.binding = 0; 4815 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 4816 dsl_binding.descriptorCount = 1; 4817 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 4818 dsl_binding.pImmutableSamplers = NULL; 4819 4820 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 4821 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 4822 ds_layout_ci.pNext = NULL; 4823 ds_layout_ci.bindingCount = 1; 4824 ds_layout_ci.pBindings = &dsl_binding; 4825 VkDescriptorSetLayout ds_layout; 4826 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 4827 ASSERT_VK_SUCCESS(err); 4828 4829 VkDescriptorSet descriptorSet; 4830 VkDescriptorSetAllocateInfo alloc_info = {}; 4831 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 4832 alloc_info.descriptorSetCount = 1; 4833 alloc_info.descriptorPool = ds_pool; 4834 alloc_info.pSetLayouts = &ds_layout; 4835 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 4836 ASSERT_VK_SUCCESS(err); 4837 4838 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 4839 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 4840 pipeline_layout_ci.pNext = NULL; 4841 pipeline_layout_ci.setLayoutCount = 1; 4842 pipeline_layout_ci.pSetLayouts = &ds_layout; 4843 4844 VkPipelineLayout pipeline_layout; 4845 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 4846 ASSERT_VK_SUCCESS(err); 4847 4848 // Create images to update the descriptor with 4849 VkImage image; 4850 VkImage image2; 4851 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 4852 const int32_t tex_width = 32; 4853 const int32_t tex_height = 32; 4854 VkImageCreateInfo image_create_info = {}; 4855 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 4856 image_create_info.pNext = NULL; 4857 image_create_info.imageType = VK_IMAGE_TYPE_2D; 4858 image_create_info.format = tex_format; 4859 image_create_info.extent.width = tex_width; 4860 image_create_info.extent.height = tex_height; 4861 image_create_info.extent.depth = 1; 4862 image_create_info.mipLevels = 1; 4863 image_create_info.arrayLayers = 1; 4864 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 4865 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 4866 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 4867 image_create_info.flags = 0; 4868 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 4869 ASSERT_VK_SUCCESS(err); 4870 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image2); 4871 ASSERT_VK_SUCCESS(err); 4872 4873 VkMemoryRequirements memory_reqs; 4874 VkDeviceMemory image_memory; 4875 bool pass; 4876 VkMemoryAllocateInfo memory_info = {}; 4877 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 4878 memory_info.pNext = NULL; 4879 memory_info.allocationSize = 0; 4880 memory_info.memoryTypeIndex = 0; 4881 vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs); 4882 // Allocate enough memory for both images 4883 memory_info.allocationSize = memory_reqs.size * 2; 4884 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 4885 ASSERT_TRUE(pass); 4886 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory); 4887 ASSERT_VK_SUCCESS(err); 4888 err = vkBindImageMemory(m_device->device(), image, image_memory, 0); 4889 ASSERT_VK_SUCCESS(err); 4890 // Bind second image to memory right after first image 4891 err = vkBindImageMemory(m_device->device(), image2, image_memory, memory_reqs.size); 4892 ASSERT_VK_SUCCESS(err); 4893 4894 VkImageViewCreateInfo image_view_create_info = {}; 4895 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 4896 image_view_create_info.image = image; 4897 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; 4898 image_view_create_info.format = tex_format; 4899 image_view_create_info.subresourceRange.layerCount = 1; 4900 image_view_create_info.subresourceRange.baseMipLevel = 0; 4901 image_view_create_info.subresourceRange.levelCount = 1; 4902 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 4903 4904 VkImageView view; 4905 VkImageView view2; 4906 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view); 4907 ASSERT_VK_SUCCESS(err); 4908 image_view_create_info.image = image2; 4909 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view2); 4910 ASSERT_VK_SUCCESS(err); 4911 // Create Samplers 4912 VkSamplerCreateInfo sampler_ci = {}; 4913 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; 4914 sampler_ci.pNext = NULL; 4915 sampler_ci.magFilter = VK_FILTER_NEAREST; 4916 sampler_ci.minFilter = VK_FILTER_NEAREST; 4917 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; 4918 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 4919 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 4920 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 4921 sampler_ci.mipLodBias = 1.0; 4922 sampler_ci.anisotropyEnable = VK_FALSE; 4923 sampler_ci.maxAnisotropy = 1; 4924 sampler_ci.compareEnable = VK_FALSE; 4925 sampler_ci.compareOp = VK_COMPARE_OP_NEVER; 4926 sampler_ci.minLod = 1.0; 4927 sampler_ci.maxLod = 1.0; 4928 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; 4929 sampler_ci.unnormalizedCoordinates = VK_FALSE; 4930 VkSampler sampler; 4931 VkSampler sampler2; 4932 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 4933 ASSERT_VK_SUCCESS(err); 4934 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler2); 4935 ASSERT_VK_SUCCESS(err); 4936 // Update descriptor with image and sampler 4937 VkDescriptorImageInfo img_info = {}; 4938 img_info.sampler = sampler; 4939 img_info.imageView = view; 4940 img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 4941 4942 VkWriteDescriptorSet descriptor_write; 4943 memset(&descriptor_write, 0, sizeof(descriptor_write)); 4944 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 4945 descriptor_write.dstSet = descriptorSet; 4946 descriptor_write.dstBinding = 0; 4947 descriptor_write.descriptorCount = 1; 4948 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 4949 descriptor_write.pImageInfo = &img_info; 4950 4951 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 4952 4953 // Create PSO to be used for draw-time errors below 4954 char const *vsSource = "#version 450\n" 4955 "\n" 4956 "out gl_PerVertex { \n" 4957 " vec4 gl_Position;\n" 4958 "};\n" 4959 "void main(){\n" 4960 " gl_Position = vec4(1);\n" 4961 "}\n"; 4962 char const *fsSource = "#version 450\n" 4963 "\n" 4964 "layout(set=0, binding=0) uniform sampler2D s;\n" 4965 "layout(location=0) out vec4 x;\n" 4966 "void main(){\n" 4967 " x = texture(s, vec2(1));\n" 4968 "}\n"; 4969 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 4970 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 4971 VkPipelineObj pipe(m_device); 4972 pipe.AddShader(&vs); 4973 pipe.AddShader(&fs); 4974 pipe.AddColorAttachment(); 4975 pipe.CreateVKPipeline(pipeline_layout, renderPass()); 4976 4977 // First error case is destroying sampler prior to cmd buffer submission 4978 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot submit cmd buffer using deleted sampler "); 4979 BeginCommandBuffer(); 4980 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 4981 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, 4982 &descriptorSet, 0, NULL); 4983 Draw(1, 0, 0, 0); 4984 EndCommandBuffer(); 4985 // Destroy sampler invalidates the cmd buffer, causing error on submit 4986 vkDestroySampler(m_device->device(), sampler, NULL); 4987 // Attempt to submit cmd buffer 4988 VkSubmitInfo submit_info = {}; 4989 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 4990 submit_info.commandBufferCount = 1; 4991 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 4992 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 4993 m_errorMonitor->VerifyFound(); 4994 // Now re-update descriptor with valid sampler and delete image 4995 img_info.sampler = sampler2; 4996 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 4997 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound image "); 4998 BeginCommandBuffer(); 4999 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 5000 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, 5001 &descriptorSet, 0, NULL); 5002 Draw(1, 0, 0, 0); 5003 EndCommandBuffer(); 5004 // Destroy image invalidates the cmd buffer, causing error on submit 5005 vkDestroyImage(m_device->device(), image, NULL); 5006 // Attempt to submit cmd buffer 5007 submit_info = {}; 5008 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 5009 submit_info.commandBufferCount = 1; 5010 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 5011 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 5012 m_errorMonitor->VerifyFound(); 5013 // Now update descriptor to be valid, but then free descriptor 5014 img_info.imageView = view2; 5015 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 5016 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound descriptor set "); 5017 BeginCommandBuffer(); 5018 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 5019 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, 5020 &descriptorSet, 0, NULL); 5021 Draw(1, 0, 0, 0); 5022 EndCommandBuffer(); 5023 // Destroy descriptor set invalidates the cb, causing error on submit 5024 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot call vkFreeDescriptorSets() on descriptor set 0x"); 5025 vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptorSet); 5026 m_errorMonitor->VerifyFound(); 5027 // Attempt to submit cmd buffer 5028 submit_info = {}; 5029 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 5030 submit_info.commandBufferCount = 1; 5031 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 5032 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 5033 m_errorMonitor->VerifyFound(); 5034 // Cleanup 5035 vkFreeMemory(m_device->device(), image_memory, NULL); 5036 vkDestroySampler(m_device->device(), sampler2, NULL); 5037 vkDestroyImage(m_device->device(), image2, NULL); 5038 vkDestroyImageView(m_device->device(), view, NULL); 5039 vkDestroyImageView(m_device->device(), view2, NULL); 5040 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 5041 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 5042 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 5043 } 5044 5045 TEST_F(VkLayerTest, DescriptorPoolInUseDestroyedSignaled) { 5046 TEST_DESCRIPTION("Delete a DescriptorPool with a DescriptorSet that is in use."); 5047 ASSERT_NO_FATAL_FAILURE(InitState()); 5048 ASSERT_NO_FATAL_FAILURE(InitViewport()); 5049 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 5050 5051 VkDescriptorPoolSize ds_type_count = {}; 5052 ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 5053 ds_type_count.descriptorCount = 1; 5054 5055 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 5056 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 5057 ds_pool_ci.pNext = NULL; 5058 ds_pool_ci.maxSets = 1; 5059 ds_pool_ci.poolSizeCount = 1; 5060 ds_pool_ci.pPoolSizes = &ds_type_count; 5061 5062 VkDescriptorPool ds_pool; 5063 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 5064 ASSERT_VK_SUCCESS(err); 5065 5066 VkDescriptorSetLayoutBinding dsl_binding = {}; 5067 dsl_binding.binding = 0; 5068 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 5069 dsl_binding.descriptorCount = 1; 5070 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 5071 dsl_binding.pImmutableSamplers = NULL; 5072 5073 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 5074 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 5075 ds_layout_ci.pNext = NULL; 5076 ds_layout_ci.bindingCount = 1; 5077 ds_layout_ci.pBindings = &dsl_binding; 5078 VkDescriptorSetLayout ds_layout; 5079 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 5080 ASSERT_VK_SUCCESS(err); 5081 5082 VkDescriptorSet descriptor_set; 5083 VkDescriptorSetAllocateInfo alloc_info = {}; 5084 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 5085 alloc_info.descriptorSetCount = 1; 5086 alloc_info.descriptorPool = ds_pool; 5087 alloc_info.pSetLayouts = &ds_layout; 5088 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set); 5089 ASSERT_VK_SUCCESS(err); 5090 5091 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 5092 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 5093 pipeline_layout_ci.pNext = NULL; 5094 pipeline_layout_ci.setLayoutCount = 1; 5095 pipeline_layout_ci.pSetLayouts = &ds_layout; 5096 5097 VkPipelineLayout pipeline_layout; 5098 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 5099 ASSERT_VK_SUCCESS(err); 5100 5101 // Create image to update the descriptor with 5102 VkImageObj image(m_device); 5103 image.init(32, 32, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 5104 ASSERT_TRUE(image.initialized()); 5105 5106 VkImageView view = image.targetView(VK_FORMAT_B8G8R8A8_UNORM); 5107 // Create Sampler 5108 VkSamplerCreateInfo sampler_ci = {}; 5109 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; 5110 sampler_ci.pNext = NULL; 5111 sampler_ci.magFilter = VK_FILTER_NEAREST; 5112 sampler_ci.minFilter = VK_FILTER_NEAREST; 5113 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; 5114 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 5115 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 5116 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 5117 sampler_ci.mipLodBias = 1.0; 5118 sampler_ci.anisotropyEnable = VK_FALSE; 5119 sampler_ci.maxAnisotropy = 1; 5120 sampler_ci.compareEnable = VK_FALSE; 5121 sampler_ci.compareOp = VK_COMPARE_OP_NEVER; 5122 sampler_ci.minLod = 1.0; 5123 sampler_ci.maxLod = 1.0; 5124 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; 5125 sampler_ci.unnormalizedCoordinates = VK_FALSE; 5126 VkSampler sampler; 5127 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 5128 ASSERT_VK_SUCCESS(err); 5129 // Update descriptor with image and sampler 5130 VkDescriptorImageInfo img_info = {}; 5131 img_info.sampler = sampler; 5132 img_info.imageView = view; 5133 img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 5134 5135 VkWriteDescriptorSet descriptor_write; 5136 memset(&descriptor_write, 0, sizeof(descriptor_write)); 5137 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 5138 descriptor_write.dstSet = descriptor_set; 5139 descriptor_write.dstBinding = 0; 5140 descriptor_write.descriptorCount = 1; 5141 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 5142 descriptor_write.pImageInfo = &img_info; 5143 5144 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 5145 5146 // Create PSO to be used for draw-time errors below 5147 char const *vsSource = "#version 450\n" 5148 "\n" 5149 "out gl_PerVertex { \n" 5150 " vec4 gl_Position;\n" 5151 "};\n" 5152 "void main(){\n" 5153 " gl_Position = vec4(1);\n" 5154 "}\n"; 5155 char const *fsSource = "#version 450\n" 5156 "\n" 5157 "layout(set=0, binding=0) uniform sampler2D s;\n" 5158 "layout(location=0) out vec4 x;\n" 5159 "void main(){\n" 5160 " x = texture(s, vec2(1));\n" 5161 "}\n"; 5162 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 5163 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 5164 VkPipelineObj pipe(m_device); 5165 pipe.AddShader(&vs); 5166 pipe.AddShader(&fs); 5167 pipe.AddColorAttachment(); 5168 pipe.CreateVKPipeline(pipeline_layout, renderPass()); 5169 5170 BeginCommandBuffer(); 5171 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 5172 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, 5173 &descriptor_set, 0, NULL); 5174 Draw(1, 0, 0, 0); 5175 EndCommandBuffer(); 5176 // Submit cmd buffer to put pool in-flight 5177 VkSubmitInfo submit_info = {}; 5178 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 5179 submit_info.commandBufferCount = 1; 5180 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 5181 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 5182 // Destroy pool while in-flight, causing error 5183 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete descriptor pool "); 5184 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 5185 m_errorMonitor->VerifyFound(); 5186 vkQueueWaitIdle(m_device->m_queue); 5187 // Cleanup 5188 vkDestroySampler(m_device->device(), sampler, NULL); 5189 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 5190 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 5191 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 5192 } 5193 5194 TEST_F(VkLayerTest, DescriptorImageUpdateNoMemoryBound) { 5195 TEST_DESCRIPTION("Attempt an image descriptor set update where image's bound memory has been freed."); 5196 ASSERT_NO_FATAL_FAILURE(InitState()); 5197 ASSERT_NO_FATAL_FAILURE(InitViewport()); 5198 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 5199 5200 VkDescriptorPoolSize ds_type_count = {}; 5201 ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 5202 ds_type_count.descriptorCount = 1; 5203 5204 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 5205 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 5206 ds_pool_ci.pNext = NULL; 5207 ds_pool_ci.maxSets = 1; 5208 ds_pool_ci.poolSizeCount = 1; 5209 ds_pool_ci.pPoolSizes = &ds_type_count; 5210 5211 VkDescriptorPool ds_pool; 5212 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 5213 ASSERT_VK_SUCCESS(err); 5214 5215 VkDescriptorSetLayoutBinding dsl_binding = {}; 5216 dsl_binding.binding = 0; 5217 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 5218 dsl_binding.descriptorCount = 1; 5219 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 5220 dsl_binding.pImmutableSamplers = NULL; 5221 5222 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 5223 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 5224 ds_layout_ci.pNext = NULL; 5225 ds_layout_ci.bindingCount = 1; 5226 ds_layout_ci.pBindings = &dsl_binding; 5227 VkDescriptorSetLayout ds_layout; 5228 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 5229 ASSERT_VK_SUCCESS(err); 5230 5231 VkDescriptorSet descriptorSet; 5232 VkDescriptorSetAllocateInfo alloc_info = {}; 5233 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 5234 alloc_info.descriptorSetCount = 1; 5235 alloc_info.descriptorPool = ds_pool; 5236 alloc_info.pSetLayouts = &ds_layout; 5237 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 5238 ASSERT_VK_SUCCESS(err); 5239 5240 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 5241 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 5242 pipeline_layout_ci.pNext = NULL; 5243 pipeline_layout_ci.setLayoutCount = 1; 5244 pipeline_layout_ci.pSetLayouts = &ds_layout; 5245 5246 VkPipelineLayout pipeline_layout; 5247 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 5248 ASSERT_VK_SUCCESS(err); 5249 5250 // Create images to update the descriptor with 5251 VkImage image; 5252 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 5253 const int32_t tex_width = 32; 5254 const int32_t tex_height = 32; 5255 VkImageCreateInfo image_create_info = {}; 5256 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 5257 image_create_info.pNext = NULL; 5258 image_create_info.imageType = VK_IMAGE_TYPE_2D; 5259 image_create_info.format = tex_format; 5260 image_create_info.extent.width = tex_width; 5261 image_create_info.extent.height = tex_height; 5262 image_create_info.extent.depth = 1; 5263 image_create_info.mipLevels = 1; 5264 image_create_info.arrayLayers = 1; 5265 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 5266 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 5267 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 5268 image_create_info.flags = 0; 5269 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 5270 ASSERT_VK_SUCCESS(err); 5271 // Initially bind memory to avoid error at bind view time. We'll break binding before update. 5272 VkMemoryRequirements memory_reqs; 5273 VkDeviceMemory image_memory; 5274 bool pass; 5275 VkMemoryAllocateInfo memory_info = {}; 5276 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 5277 memory_info.pNext = NULL; 5278 memory_info.allocationSize = 0; 5279 memory_info.memoryTypeIndex = 0; 5280 vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs); 5281 // Allocate enough memory for image 5282 memory_info.allocationSize = memory_reqs.size; 5283 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 5284 ASSERT_TRUE(pass); 5285 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory); 5286 ASSERT_VK_SUCCESS(err); 5287 err = vkBindImageMemory(m_device->device(), image, image_memory, 0); 5288 ASSERT_VK_SUCCESS(err); 5289 5290 VkImageViewCreateInfo image_view_create_info = {}; 5291 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 5292 image_view_create_info.image = image; 5293 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; 5294 image_view_create_info.format = tex_format; 5295 image_view_create_info.subresourceRange.layerCount = 1; 5296 image_view_create_info.subresourceRange.baseMipLevel = 0; 5297 image_view_create_info.subresourceRange.levelCount = 1; 5298 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 5299 5300 VkImageView view; 5301 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view); 5302 ASSERT_VK_SUCCESS(err); 5303 // Create Samplers 5304 VkSamplerCreateInfo sampler_ci = {}; 5305 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; 5306 sampler_ci.pNext = NULL; 5307 sampler_ci.magFilter = VK_FILTER_NEAREST; 5308 sampler_ci.minFilter = VK_FILTER_NEAREST; 5309 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; 5310 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 5311 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 5312 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 5313 sampler_ci.mipLodBias = 1.0; 5314 sampler_ci.anisotropyEnable = VK_FALSE; 5315 sampler_ci.maxAnisotropy = 1; 5316 sampler_ci.compareEnable = VK_FALSE; 5317 sampler_ci.compareOp = VK_COMPARE_OP_NEVER; 5318 sampler_ci.minLod = 1.0; 5319 sampler_ci.maxLod = 1.0; 5320 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; 5321 sampler_ci.unnormalizedCoordinates = VK_FALSE; 5322 VkSampler sampler; 5323 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 5324 ASSERT_VK_SUCCESS(err); 5325 // Update descriptor with image and sampler 5326 VkDescriptorImageInfo img_info = {}; 5327 img_info.sampler = sampler; 5328 img_info.imageView = view; 5329 img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 5330 5331 VkWriteDescriptorSet descriptor_write; 5332 memset(&descriptor_write, 0, sizeof(descriptor_write)); 5333 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 5334 descriptor_write.dstSet = descriptorSet; 5335 descriptor_write.dstBinding = 0; 5336 descriptor_write.descriptorCount = 1; 5337 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 5338 descriptor_write.pImageInfo = &img_info; 5339 // Break memory binding and attempt update 5340 vkFreeMemory(m_device->device(), image_memory, nullptr); 5341 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 5342 " previously bound memory was freed. Memory must not be freed prior to this operation."); 5343 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 5344 "vkUpdateDescriptorsSets() failed write update validation for Descriptor Set 0x"); 5345 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 5346 m_errorMonitor->VerifyFound(); 5347 // Cleanup 5348 vkDestroyImage(m_device->device(), image, NULL); 5349 vkDestroySampler(m_device->device(), sampler, NULL); 5350 vkDestroyImageView(m_device->device(), view, NULL); 5351 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 5352 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 5353 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 5354 } 5355 5356 TEST_F(VkLayerTest, InvalidPipeline) { 5357 // Attempt to bind an invalid Pipeline to a valid Command Buffer 5358 // ObjectTracker should catch this. 5359 // Create a valid cmd buffer 5360 // call vkCmdBindPipeline w/ false Pipeline 5361 uint64_t fake_pipeline_handle = 0xbaad6001; 5362 VkPipeline bad_pipeline = reinterpret_cast<VkPipeline &>(fake_pipeline_handle); 5363 ASSERT_NO_FATAL_FAILURE(InitState()); 5364 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 5365 5366 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline Object 0xbaad6001"); 5367 BeginCommandBuffer(); 5368 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, bad_pipeline); 5369 m_errorMonitor->VerifyFound(); 5370 5371 // Now issue a draw call with no pipeline bound 5372 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "At Draw/Dispatch time no valid VkPipeline is bound!"); 5373 Draw(1, 0, 0, 0); 5374 m_errorMonitor->VerifyFound(); 5375 5376 // Finally same check once more but with Dispatch/Compute 5377 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "At Draw/Dispatch time no valid VkPipeline is bound!"); 5378 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); // must be outside renderpass 5379 vkCmdDispatch(m_commandBuffer->GetBufferHandle(), 0, 0, 0); 5380 m_errorMonitor->VerifyFound(); 5381 } 5382 5383 TEST_F(VkLayerTest, DescriptorSetNotUpdated) { 5384 TEST_DESCRIPTION("Bind a descriptor set that hasn't been updated."); 5385 VkResult err; 5386 5387 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, " bound but it was never updated. "); 5388 5389 ASSERT_NO_FATAL_FAILURE(InitState()); 5390 ASSERT_NO_FATAL_FAILURE(InitViewport()); 5391 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 5392 VkDescriptorPoolSize ds_type_count = {}; 5393 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 5394 ds_type_count.descriptorCount = 1; 5395 5396 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 5397 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 5398 ds_pool_ci.pNext = NULL; 5399 ds_pool_ci.maxSets = 1; 5400 ds_pool_ci.poolSizeCount = 1; 5401 ds_pool_ci.pPoolSizes = &ds_type_count; 5402 5403 VkDescriptorPool ds_pool; 5404 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 5405 ASSERT_VK_SUCCESS(err); 5406 5407 VkDescriptorSetLayoutBinding dsl_binding = {}; 5408 dsl_binding.binding = 0; 5409 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 5410 dsl_binding.descriptorCount = 1; 5411 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 5412 dsl_binding.pImmutableSamplers = NULL; 5413 5414 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 5415 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 5416 ds_layout_ci.pNext = NULL; 5417 ds_layout_ci.bindingCount = 1; 5418 ds_layout_ci.pBindings = &dsl_binding; 5419 VkDescriptorSetLayout ds_layout; 5420 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 5421 ASSERT_VK_SUCCESS(err); 5422 5423 VkDescriptorSet descriptorSet; 5424 VkDescriptorSetAllocateInfo alloc_info = {}; 5425 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 5426 alloc_info.descriptorSetCount = 1; 5427 alloc_info.descriptorPool = ds_pool; 5428 alloc_info.pSetLayouts = &ds_layout; 5429 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 5430 ASSERT_VK_SUCCESS(err); 5431 5432 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 5433 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 5434 pipeline_layout_ci.pNext = NULL; 5435 pipeline_layout_ci.setLayoutCount = 1; 5436 pipeline_layout_ci.pSetLayouts = &ds_layout; 5437 5438 VkPipelineLayout pipeline_layout; 5439 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 5440 ASSERT_VK_SUCCESS(err); 5441 5442 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 5443 // We shouldn't need a fragment shader but add it to be able to run 5444 // on more devices 5445 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 5446 5447 VkPipelineObj pipe(m_device); 5448 pipe.AddShader(&vs); 5449 pipe.AddShader(&fs); 5450 pipe.AddColorAttachment(); 5451 pipe.CreateVKPipeline(pipeline_layout, renderPass()); 5452 5453 BeginCommandBuffer(); 5454 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 5455 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, 5456 &descriptorSet, 0, NULL); 5457 5458 m_errorMonitor->VerifyFound(); 5459 5460 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 5461 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 5462 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 5463 } 5464 5465 TEST_F(VkLayerTest, InvalidBufferViewObject) { 5466 // Create a single TEXEL_BUFFER descriptor and send it an invalid bufferView 5467 VkResult err; 5468 5469 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempted write update to texel buffer " 5470 "descriptor with invalid buffer view"); 5471 5472 ASSERT_NO_FATAL_FAILURE(InitState()); 5473 VkDescriptorPoolSize ds_type_count = {}; 5474 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; 5475 ds_type_count.descriptorCount = 1; 5476 5477 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 5478 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 5479 ds_pool_ci.pNext = NULL; 5480 ds_pool_ci.maxSets = 1; 5481 ds_pool_ci.poolSizeCount = 1; 5482 ds_pool_ci.pPoolSizes = &ds_type_count; 5483 5484 VkDescriptorPool ds_pool; 5485 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 5486 ASSERT_VK_SUCCESS(err); 5487 5488 VkDescriptorSetLayoutBinding dsl_binding = {}; 5489 dsl_binding.binding = 0; 5490 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; 5491 dsl_binding.descriptorCount = 1; 5492 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 5493 dsl_binding.pImmutableSamplers = NULL; 5494 5495 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 5496 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 5497 ds_layout_ci.pNext = NULL; 5498 ds_layout_ci.bindingCount = 1; 5499 ds_layout_ci.pBindings = &dsl_binding; 5500 VkDescriptorSetLayout ds_layout; 5501 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 5502 ASSERT_VK_SUCCESS(err); 5503 5504 VkDescriptorSet descriptorSet; 5505 VkDescriptorSetAllocateInfo alloc_info = {}; 5506 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 5507 alloc_info.descriptorSetCount = 1; 5508 alloc_info.descriptorPool = ds_pool; 5509 alloc_info.pSetLayouts = &ds_layout; 5510 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 5511 ASSERT_VK_SUCCESS(err); 5512 5513 VkBufferView view = (VkBufferView)((size_t)0xbaadbeef); // invalid bufferView object 5514 VkWriteDescriptorSet descriptor_write; 5515 memset(&descriptor_write, 0, sizeof(descriptor_write)); 5516 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 5517 descriptor_write.dstSet = descriptorSet; 5518 descriptor_write.dstBinding = 0; 5519 descriptor_write.descriptorCount = 1; 5520 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; 5521 descriptor_write.pTexelBufferView = &view; 5522 5523 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 5524 5525 m_errorMonitor->VerifyFound(); 5526 5527 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 5528 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 5529 } 5530 5531 TEST_F(VkLayerTest, CreateBufferViewNoMemoryBoundToBuffer) { 5532 TEST_DESCRIPTION("Attempt to create a buffer view with a buffer that has no memory bound to it."); 5533 5534 VkResult err; 5535 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 5536 " used with no memory bound. Memory should be bound by calling vkBindBufferMemory()."); 5537 5538 ASSERT_NO_FATAL_FAILURE(InitState()); 5539 5540 // Create a buffer with no bound memory and then attempt to create 5541 // a buffer view. 5542 VkBufferCreateInfo buff_ci = {}; 5543 buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 5544 buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT; 5545 buff_ci.size = 256; 5546 buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 5547 VkBuffer buffer; 5548 err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer); 5549 ASSERT_VK_SUCCESS(err); 5550 5551 VkBufferViewCreateInfo buff_view_ci = {}; 5552 buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; 5553 buff_view_ci.buffer = buffer; 5554 buff_view_ci.format = VK_FORMAT_R8_UNORM; 5555 buff_view_ci.range = VK_WHOLE_SIZE; 5556 VkBufferView buff_view; 5557 err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buff_view); 5558 5559 m_errorMonitor->VerifyFound(); 5560 vkDestroyBuffer(m_device->device(), buffer, NULL); 5561 // If last error is success, it still created the view, so delete it. 5562 if (err == VK_SUCCESS) { 5563 vkDestroyBufferView(m_device->device(), buff_view, NULL); 5564 } 5565 } 5566 5567 TEST_F(VkLayerTest, InvalidDynamicOffsetCases) { 5568 // Create a descriptorSet w/ dynamic descriptor and then hit 3 offset error 5569 // cases: 5570 // 1. No dynamicOffset supplied 5571 // 2. Too many dynamicOffsets supplied 5572 // 3. Dynamic offset oversteps buffer being updated 5573 VkResult err; 5574 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " requires 1 dynamicOffsets, but only " 5575 "0 dynamicOffsets are left in " 5576 "pDynamicOffsets "); 5577 5578 ASSERT_NO_FATAL_FAILURE(InitState()); 5579 ASSERT_NO_FATAL_FAILURE(InitViewport()); 5580 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 5581 5582 VkDescriptorPoolSize ds_type_count = {}; 5583 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 5584 ds_type_count.descriptorCount = 1; 5585 5586 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 5587 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 5588 ds_pool_ci.pNext = NULL; 5589 ds_pool_ci.maxSets = 1; 5590 ds_pool_ci.poolSizeCount = 1; 5591 ds_pool_ci.pPoolSizes = &ds_type_count; 5592 5593 VkDescriptorPool ds_pool; 5594 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 5595 ASSERT_VK_SUCCESS(err); 5596 5597 VkDescriptorSetLayoutBinding dsl_binding = {}; 5598 dsl_binding.binding = 0; 5599 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 5600 dsl_binding.descriptorCount = 1; 5601 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 5602 dsl_binding.pImmutableSamplers = NULL; 5603 5604 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 5605 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 5606 ds_layout_ci.pNext = NULL; 5607 ds_layout_ci.bindingCount = 1; 5608 ds_layout_ci.pBindings = &dsl_binding; 5609 VkDescriptorSetLayout ds_layout; 5610 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 5611 ASSERT_VK_SUCCESS(err); 5612 5613 VkDescriptorSet descriptorSet; 5614 VkDescriptorSetAllocateInfo alloc_info = {}; 5615 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 5616 alloc_info.descriptorSetCount = 1; 5617 alloc_info.descriptorPool = ds_pool; 5618 alloc_info.pSetLayouts = &ds_layout; 5619 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 5620 ASSERT_VK_SUCCESS(err); 5621 5622 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 5623 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 5624 pipeline_layout_ci.pNext = NULL; 5625 pipeline_layout_ci.setLayoutCount = 1; 5626 pipeline_layout_ci.pSetLayouts = &ds_layout; 5627 5628 VkPipelineLayout pipeline_layout; 5629 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 5630 ASSERT_VK_SUCCESS(err); 5631 5632 // Create a buffer to update the descriptor with 5633 uint32_t qfi = 0; 5634 VkBufferCreateInfo buffCI = {}; 5635 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 5636 buffCI.size = 1024; 5637 buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 5638 buffCI.queueFamilyIndexCount = 1; 5639 buffCI.pQueueFamilyIndices = &qfi; 5640 5641 VkBuffer dyub; 5642 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub); 5643 ASSERT_VK_SUCCESS(err); 5644 // Allocate memory and bind to buffer so we can make it to the appropriate 5645 // error 5646 VkMemoryAllocateInfo mem_alloc = {}; 5647 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 5648 mem_alloc.pNext = NULL; 5649 mem_alloc.allocationSize = 1024; 5650 mem_alloc.memoryTypeIndex = 0; 5651 5652 VkMemoryRequirements memReqs; 5653 vkGetBufferMemoryRequirements(m_device->device(), dyub, &memReqs); 5654 bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0); 5655 if (!pass) { 5656 vkDestroyBuffer(m_device->device(), dyub, NULL); 5657 return; 5658 } 5659 5660 VkDeviceMemory mem; 5661 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem); 5662 ASSERT_VK_SUCCESS(err); 5663 err = vkBindBufferMemory(m_device->device(), dyub, mem, 0); 5664 ASSERT_VK_SUCCESS(err); 5665 // Correctly update descriptor to avoid "NOT_UPDATED" error 5666 VkDescriptorBufferInfo buffInfo = {}; 5667 buffInfo.buffer = dyub; 5668 buffInfo.offset = 0; 5669 buffInfo.range = 1024; 5670 5671 VkWriteDescriptorSet descriptor_write; 5672 memset(&descriptor_write, 0, sizeof(descriptor_write)); 5673 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 5674 descriptor_write.dstSet = descriptorSet; 5675 descriptor_write.dstBinding = 0; 5676 descriptor_write.descriptorCount = 1; 5677 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 5678 descriptor_write.pBufferInfo = &buffInfo; 5679 5680 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 5681 5682 BeginCommandBuffer(); 5683 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, 5684 &descriptorSet, 0, NULL); 5685 m_errorMonitor->VerifyFound(); 5686 uint32_t pDynOff[2] = {512, 756}; 5687 // Now cause error b/c too many dynOffsets in array for # of dyn descriptors 5688 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 5689 "Attempting to bind 1 descriptorSets with 1 dynamic descriptors, but "); 5690 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, 5691 &descriptorSet, 2, pDynOff); 5692 m_errorMonitor->VerifyFound(); 5693 // Finally cause error due to dynamicOffset being too big 5694 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " dynamic offset 512 combined with " 5695 "offset 0 and range 1024 that " 5696 "oversteps the buffer size of 1024"); 5697 // Create PSO to be used for draw-time errors below 5698 char const *vsSource = "#version 450\n" 5699 "\n" 5700 "out gl_PerVertex { \n" 5701 " vec4 gl_Position;\n" 5702 "};\n" 5703 "void main(){\n" 5704 " gl_Position = vec4(1);\n" 5705 "}\n"; 5706 char const *fsSource = "#version 450\n" 5707 "\n" 5708 "layout(location=0) out vec4 x;\n" 5709 "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n" 5710 "void main(){\n" 5711 " x = vec4(bar.y);\n" 5712 "}\n"; 5713 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 5714 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 5715 VkPipelineObj pipe(m_device); 5716 pipe.AddShader(&vs); 5717 pipe.AddShader(&fs); 5718 pipe.AddColorAttachment(); 5719 pipe.CreateVKPipeline(pipeline_layout, renderPass()); 5720 5721 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 5722 // This update should succeed, but offset size of 512 will overstep buffer 5723 // /w range 1024 & size 1024 5724 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, 5725 &descriptorSet, 1, pDynOff); 5726 Draw(1, 0, 0, 0); 5727 m_errorMonitor->VerifyFound(); 5728 5729 vkDestroyBuffer(m_device->device(), dyub, NULL); 5730 vkFreeMemory(m_device->device(), mem, NULL); 5731 5732 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 5733 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 5734 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 5735 } 5736 5737 TEST_F(VkLayerTest, DescriptorBufferUpdateNoMemoryBound) { 5738 TEST_DESCRIPTION("Attempt to update a descriptor with a non-sparse buffer " 5739 "that doesn't have memory bound"); 5740 VkResult err; 5741 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 5742 " used with no memory bound. Memory should be bound by calling vkBindBufferMemory()."); 5743 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 5744 "vkUpdateDescriptorsSets() failed write update validation for Descriptor Set 0x"); 5745 5746 ASSERT_NO_FATAL_FAILURE(InitState()); 5747 ASSERT_NO_FATAL_FAILURE(InitViewport()); 5748 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 5749 5750 VkDescriptorPoolSize ds_type_count = {}; 5751 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 5752 ds_type_count.descriptorCount = 1; 5753 5754 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 5755 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 5756 ds_pool_ci.pNext = NULL; 5757 ds_pool_ci.maxSets = 1; 5758 ds_pool_ci.poolSizeCount = 1; 5759 ds_pool_ci.pPoolSizes = &ds_type_count; 5760 5761 VkDescriptorPool ds_pool; 5762 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 5763 ASSERT_VK_SUCCESS(err); 5764 5765 VkDescriptorSetLayoutBinding dsl_binding = {}; 5766 dsl_binding.binding = 0; 5767 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 5768 dsl_binding.descriptorCount = 1; 5769 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 5770 dsl_binding.pImmutableSamplers = NULL; 5771 5772 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 5773 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 5774 ds_layout_ci.pNext = NULL; 5775 ds_layout_ci.bindingCount = 1; 5776 ds_layout_ci.pBindings = &dsl_binding; 5777 VkDescriptorSetLayout ds_layout; 5778 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 5779 ASSERT_VK_SUCCESS(err); 5780 5781 VkDescriptorSet descriptorSet; 5782 VkDescriptorSetAllocateInfo alloc_info = {}; 5783 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 5784 alloc_info.descriptorSetCount = 1; 5785 alloc_info.descriptorPool = ds_pool; 5786 alloc_info.pSetLayouts = &ds_layout; 5787 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 5788 ASSERT_VK_SUCCESS(err); 5789 5790 // Create a buffer to update the descriptor with 5791 uint32_t qfi = 0; 5792 VkBufferCreateInfo buffCI = {}; 5793 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 5794 buffCI.size = 1024; 5795 buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 5796 buffCI.queueFamilyIndexCount = 1; 5797 buffCI.pQueueFamilyIndices = &qfi; 5798 5799 VkBuffer dyub; 5800 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub); 5801 ASSERT_VK_SUCCESS(err); 5802 5803 // Attempt to update descriptor without binding memory to it 5804 VkDescriptorBufferInfo buffInfo = {}; 5805 buffInfo.buffer = dyub; 5806 buffInfo.offset = 0; 5807 buffInfo.range = 1024; 5808 5809 VkWriteDescriptorSet descriptor_write; 5810 memset(&descriptor_write, 0, sizeof(descriptor_write)); 5811 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 5812 descriptor_write.dstSet = descriptorSet; 5813 descriptor_write.dstBinding = 0; 5814 descriptor_write.descriptorCount = 1; 5815 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 5816 descriptor_write.pBufferInfo = &buffInfo; 5817 5818 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 5819 m_errorMonitor->VerifyFound(); 5820 5821 vkDestroyBuffer(m_device->device(), dyub, NULL); 5822 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 5823 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 5824 } 5825 5826 TEST_F(VkLayerTest, InvalidPushConstants) { 5827 VkResult err; 5828 ASSERT_NO_FATAL_FAILURE(InitState()); 5829 ASSERT_NO_FATAL_FAILURE(InitViewport()); 5830 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 5831 5832 VkPipelineLayout pipeline_layout; 5833 VkPushConstantRange pc_range = {}; 5834 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 5835 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 5836 pipeline_layout_ci.pushConstantRangeCount = 1; 5837 pipeline_layout_ci.pPushConstantRanges = &pc_range; 5838 5839 // 5840 // Check for invalid push constant ranges in pipeline layouts. 5841 // 5842 struct PipelineLayoutTestCase { 5843 VkPushConstantRange const range; 5844 char const *msg; 5845 }; 5846 5847 const uint32_t too_big = m_device->props.limits.maxPushConstantsSize + 0x4; 5848 const std::array<PipelineLayoutTestCase, 10> range_tests = {{ 5849 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 0}, 5850 "vkCreatePipelineLayout() call has push constants index 0 with " 5851 "size 0."}, 5852 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 1}, 5853 "vkCreatePipelineLayout() call has push constants index 0 with " 5854 "size 1."}, 5855 {{VK_SHADER_STAGE_VERTEX_BIT, 4, 1}, 5856 "vkCreatePipelineLayout() call has push constants index 0 with " 5857 "size 1."}, 5858 {{VK_SHADER_STAGE_VERTEX_BIT, 4, 0}, 5859 "vkCreatePipelineLayout() call has push constants index 0 with " 5860 "size 0."}, 5861 {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4}, 5862 "vkCreatePipelineLayout() call has push constants index 0 with " 5863 "offset 1. Offset must"}, 5864 {{VK_SHADER_STAGE_VERTEX_BIT, 0, too_big}, 5865 "vkCreatePipelineLayout() call has push constants index 0 " 5866 "with offset "}, 5867 {{VK_SHADER_STAGE_VERTEX_BIT, too_big, too_big}, 5868 "vkCreatePipelineLayout() call has push constants " 5869 "index 0 with offset "}, 5870 {{VK_SHADER_STAGE_VERTEX_BIT, too_big, 4}, 5871 "vkCreatePipelineLayout() call has push constants index 0 " 5872 "with offset "}, 5873 {{VK_SHADER_STAGE_VERTEX_BIT, 0xFFFFFFF0, 0x00000020}, 5874 "vkCreatePipelineLayout() call has push " 5875 "constants index 0 with offset "}, 5876 {{VK_SHADER_STAGE_VERTEX_BIT, 0x00000020, 0xFFFFFFF0}, 5877 "vkCreatePipelineLayout() call has push " 5878 "constants index 0 with offset "}, 5879 }}; 5880 5881 // Check for invalid offset and size 5882 for (const auto &iter : range_tests) { 5883 pc_range = iter.range; 5884 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg); 5885 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 5886 m_errorMonitor->VerifyFound(); 5887 if (VK_SUCCESS == err) { 5888 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 5889 } 5890 } 5891 5892 // Check for invalid stage flag 5893 pc_range.offset = 0; 5894 pc_range.size = 16; 5895 pc_range.stageFlags = 0; 5896 m_errorMonitor->SetDesiredFailureMsg( 5897 VK_DEBUG_REPORT_ERROR_BIT_EXT, 5898 "vkCreatePipelineLayout: value of pCreateInfo->pPushConstantRanges[0].stageFlags must not be 0"); 5899 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 5900 m_errorMonitor->VerifyFound(); 5901 if (VK_SUCCESS == err) { 5902 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 5903 } 5904 5905 // Check for overlapping ranges 5906 const uint32_t ranges_per_test = 5; 5907 struct OverlappingRangeTestCase { 5908 VkPushConstantRange const ranges[ranges_per_test]; 5909 char const *msg; 5910 }; 5911 5912 const std::array<OverlappingRangeTestCase, 5> overlapping_range_tests = { 5913 {{{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, 5914 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, 5915 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, 5916 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, 5917 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}}, 5918 "vkCreatePipelineLayout() call has push constants with overlapping ranges:"}, 5919 { 5920 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, 5921 {VK_SHADER_STAGE_VERTEX_BIT, 4, 4}, 5922 {VK_SHADER_STAGE_VERTEX_BIT, 8, 4}, 5923 {VK_SHADER_STAGE_VERTEX_BIT, 12, 8}, 5924 {VK_SHADER_STAGE_VERTEX_BIT, 16, 4}}, 5925 "vkCreatePipelineLayout() call has push constants with overlapping ranges: 3:[12, 20), 4:[16, 20)", 5926 }, 5927 { 5928 {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4}, 5929 {VK_SHADER_STAGE_VERTEX_BIT, 12, 8}, 5930 {VK_SHADER_STAGE_VERTEX_BIT, 8, 4}, 5931 {VK_SHADER_STAGE_VERTEX_BIT, 4, 4}, 5932 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}}, 5933 "vkCreatePipelineLayout() call has push constants with overlapping ranges: 0:[16, 20), 1:[12, 20)", 5934 }, 5935 { 5936 {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4}, 5937 {VK_SHADER_STAGE_VERTEX_BIT, 8, 4}, 5938 {VK_SHADER_STAGE_VERTEX_BIT, 4, 4}, 5939 {VK_SHADER_STAGE_VERTEX_BIT, 12, 8}, 5940 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}}, 5941 "vkCreatePipelineLayout() call has push constants with overlapping ranges: 0:[16, 20), 3:[12, 20)", 5942 }, 5943 { 5944 {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4}, 5945 {VK_SHADER_STAGE_VERTEX_BIT, 32, 4}, 5946 {VK_SHADER_STAGE_VERTEX_BIT, 4, 96}, 5947 {VK_SHADER_STAGE_VERTEX_BIT, 40, 8}, 5948 {VK_SHADER_STAGE_VERTEX_BIT, 52, 4}}, 5949 "vkCreatePipelineLayout() call has push constants with overlapping ranges:", 5950 }}}; 5951 5952 for (const auto &iter : overlapping_range_tests) { 5953 pipeline_layout_ci.pPushConstantRanges = iter.ranges; 5954 pipeline_layout_ci.pushConstantRangeCount = ranges_per_test; 5955 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, iter.msg); 5956 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 5957 m_errorMonitor->VerifyFound(); 5958 if (VK_SUCCESS == err) { 5959 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 5960 } 5961 } 5962 5963 // 5964 // CmdPushConstants tests 5965 // 5966 const uint8_t dummy_values[100] = {}; 5967 5968 // Check for invalid offset and size and if range is within layout range(s) 5969 const std::array<PipelineLayoutTestCase, 11> cmd_range_tests = {{ 5970 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 0}, "vkCmdPushConstants: parameter size must be greater than 0"}, 5971 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 1}, 5972 "vkCmdPushConstants() call has push constants with size 1. Size " 5973 "must be greater than zero and a multiple of 4."}, 5974 {{VK_SHADER_STAGE_VERTEX_BIT, 4, 1}, 5975 "vkCmdPushConstants() call has push constants with size 1. Size " 5976 "must be greater than zero and a multiple of 4."}, 5977 {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4}, 5978 "vkCmdPushConstants() call has push constants with offset 1. " 5979 "Offset must be a multiple of 4."}, 5980 {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4}, 5981 "vkCmdPushConstants() call has push constants with offset 1. " 5982 "Offset must be a multiple of 4."}, 5983 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 20}, 5984 "vkCmdPushConstants() Push constant range [0, 20) with stageFlags = " 5985 "0x1 not within flag-matching ranges in pipeline layout"}, 5986 {{VK_SHADER_STAGE_VERTEX_BIT, 60, 8}, 5987 "vkCmdPushConstants() Push constant range [60, 68) with stageFlags = " 5988 "0x1 not within flag-matching ranges in pipeline layout"}, 5989 {{VK_SHADER_STAGE_VERTEX_BIT, 76, 8}, 5990 "vkCmdPushConstants() Push constant range [76, 84) with stageFlags = " 5991 "0x1 not within flag-matching ranges in pipeline layout"}, 5992 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 80}, 5993 "vkCmdPushConstants() Push constant range [0, 80) with stageFlags = " 5994 "0x1 not within flag-matching ranges in pipeline layout"}, 5995 {{VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0, 4}, 5996 "vkCmdPushConstants() stageFlags = 0x2 do not match the stageFlags in " 5997 "any of the ranges in pipeline layout"}, 5998 {{VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0, 16}, 5999 "vkCmdPushConstants() stageFlags = 0x3 do not match the stageFlags in " 6000 "any of the ranges in pipeline layout"}, 6001 }}; 6002 6003 BeginCommandBuffer(); 6004 6005 // Setup ranges: [0,16) [64,80) 6006 const VkPushConstantRange pc_range2[] = { 6007 {VK_SHADER_STAGE_VERTEX_BIT, 64, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 0, 16}, 6008 }; 6009 pipeline_layout_ci.pushConstantRangeCount = sizeof(pc_range2) / sizeof(VkPushConstantRange); 6010 pipeline_layout_ci.pPushConstantRanges = pc_range2; 6011 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 6012 ASSERT_VK_SUCCESS(err); 6013 for (const auto &iter : cmd_range_tests) { 6014 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg); 6015 vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset, 6016 iter.range.size, dummy_values); 6017 m_errorMonitor->VerifyFound(); 6018 } 6019 6020 // Check for invalid stage flag 6021 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdPushConstants: value of stageFlags must not be 0"); 6022 vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, 0, 0, 16, dummy_values); 6023 m_errorMonitor->VerifyFound(); 6024 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 6025 6026 // overlapping range tests with cmd 6027 const std::array<PipelineLayoutTestCase, 3> cmd_overlap_tests = {{ 6028 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 20}, 6029 "vkCmdPushConstants() Push constant range [0, 20) with stageFlags = " 6030 "0x1 not within flag-matching ranges in pipeline layout"}, 6031 {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4}, 6032 "vkCmdPushConstants() Push constant range [16, 20) with stageFlags = " 6033 "0x1 not within flag-matching ranges in pipeline layout"}, 6034 {{VK_SHADER_STAGE_VERTEX_BIT, 40, 16}, 6035 "vkCmdPushConstants() Push constant range [40, 56) with stageFlags = " 6036 "0x1 not within flag-matching ranges in pipeline layout"}, 6037 }}; 6038 // Setup ranges: [0,16), [20,36), [36,44), [44,52), [80,92) 6039 const VkPushConstantRange pc_range3[] = { 6040 {VK_SHADER_STAGE_VERTEX_BIT, 20, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 0, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 44, 8}, 6041 {VK_SHADER_STAGE_VERTEX_BIT, 80, 12}, {VK_SHADER_STAGE_VERTEX_BIT, 36, 8}, 6042 }; 6043 pipeline_layout_ci.pushConstantRangeCount = sizeof(pc_range3) / sizeof(VkPushConstantRange); 6044 pipeline_layout_ci.pPushConstantRanges = pc_range3; 6045 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 6046 ASSERT_VK_SUCCESS(err); 6047 for (const auto &iter : cmd_overlap_tests) { 6048 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg); 6049 vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset, 6050 iter.range.size, dummy_values); 6051 m_errorMonitor->VerifyFound(); 6052 } 6053 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 6054 6055 EndCommandBuffer(); 6056 } 6057 6058 TEST_F(VkLayerTest, DescriptorSetCompatibility) { 6059 // Test various desriptorSet errors with bad binding combinations 6060 VkResult err; 6061 6062 ASSERT_NO_FATAL_FAILURE(InitState()); 6063 ASSERT_NO_FATAL_FAILURE(InitViewport()); 6064 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 6065 6066 const VkFormat tex_format = VK_FORMAT_R8G8B8A8_UNORM; 6067 VkImageTiling tiling; 6068 VkFormatProperties format_properties; 6069 vkGetPhysicalDeviceFormatProperties(gpu(), tex_format, &format_properties); 6070 if (format_properties.linearTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) { 6071 tiling = VK_IMAGE_TILING_LINEAR; 6072 } else if (format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) { 6073 tiling = VK_IMAGE_TILING_OPTIMAL; 6074 } else { 6075 printf("Device does not support VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; " 6076 "skipped.\n"); 6077 return; 6078 } 6079 6080 static const uint32_t NUM_DESCRIPTOR_TYPES = 5; 6081 VkDescriptorPoolSize ds_type_count[NUM_DESCRIPTOR_TYPES] = {}; 6082 ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 6083 ds_type_count[0].descriptorCount = 10; 6084 ds_type_count[1].type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; 6085 ds_type_count[1].descriptorCount = 2; 6086 ds_type_count[2].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; 6087 ds_type_count[2].descriptorCount = 2; 6088 ds_type_count[3].type = VK_DESCRIPTOR_TYPE_SAMPLER; 6089 ds_type_count[3].descriptorCount = 5; 6090 // TODO : LunarG ILO driver currently asserts in desc.c w/ INPUT_ATTACHMENT 6091 // type 6092 // ds_type_count[4].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; 6093 ds_type_count[4].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 6094 ds_type_count[4].descriptorCount = 2; 6095 6096 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 6097 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 6098 ds_pool_ci.pNext = NULL; 6099 ds_pool_ci.maxSets = 5; 6100 ds_pool_ci.poolSizeCount = NUM_DESCRIPTOR_TYPES; 6101 ds_pool_ci.pPoolSizes = ds_type_count; 6102 6103 VkDescriptorPool ds_pool; 6104 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 6105 ASSERT_VK_SUCCESS(err); 6106 6107 static const uint32_t MAX_DS_TYPES_IN_LAYOUT = 2; 6108 VkDescriptorSetLayoutBinding dsl_binding[MAX_DS_TYPES_IN_LAYOUT] = {}; 6109 dsl_binding[0].binding = 0; 6110 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 6111 dsl_binding[0].descriptorCount = 5; 6112 dsl_binding[0].stageFlags = VK_SHADER_STAGE_ALL; 6113 dsl_binding[0].pImmutableSamplers = NULL; 6114 6115 // Create layout identical to set0 layout but w/ different stageFlags 6116 VkDescriptorSetLayoutBinding dsl_fs_stage_only = {}; 6117 dsl_fs_stage_only.binding = 0; 6118 dsl_fs_stage_only.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 6119 dsl_fs_stage_only.descriptorCount = 5; 6120 dsl_fs_stage_only.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; // Different stageFlags to cause error at 6121 // bind time 6122 dsl_fs_stage_only.pImmutableSamplers = NULL; 6123 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 6124 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 6125 ds_layout_ci.pNext = NULL; 6126 ds_layout_ci.bindingCount = 1; 6127 ds_layout_ci.pBindings = dsl_binding; 6128 static const uint32_t NUM_LAYOUTS = 4; 6129 VkDescriptorSetLayout ds_layout[NUM_LAYOUTS] = {}; 6130 VkDescriptorSetLayout ds_layout_fs_only = {}; 6131 // Create 4 unique layouts for full pipelineLayout, and 1 special fs-only 6132 // layout for error case 6133 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[0]); 6134 ASSERT_VK_SUCCESS(err); 6135 ds_layout_ci.pBindings = &dsl_fs_stage_only; 6136 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout_fs_only); 6137 ASSERT_VK_SUCCESS(err); 6138 dsl_binding[0].binding = 0; 6139 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; 6140 dsl_binding[0].descriptorCount = 2; 6141 dsl_binding[1].binding = 1; 6142 dsl_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; 6143 dsl_binding[1].descriptorCount = 2; 6144 dsl_binding[1].stageFlags = VK_SHADER_STAGE_ALL; 6145 dsl_binding[1].pImmutableSamplers = NULL; 6146 ds_layout_ci.pBindings = dsl_binding; 6147 ds_layout_ci.bindingCount = 2; 6148 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[1]); 6149 ASSERT_VK_SUCCESS(err); 6150 dsl_binding[0].binding = 0; 6151 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 6152 dsl_binding[0].descriptorCount = 5; 6153 ds_layout_ci.bindingCount = 1; 6154 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[2]); 6155 ASSERT_VK_SUCCESS(err); 6156 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 6157 dsl_binding[0].descriptorCount = 2; 6158 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout[3]); 6159 ASSERT_VK_SUCCESS(err); 6160 6161 static const uint32_t NUM_SETS = 4; 6162 VkDescriptorSet descriptorSet[NUM_SETS] = {}; 6163 VkDescriptorSetAllocateInfo alloc_info = {}; 6164 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 6165 alloc_info.descriptorSetCount = NUM_LAYOUTS; 6166 alloc_info.descriptorPool = ds_pool; 6167 alloc_info.pSetLayouts = ds_layout; 6168 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, descriptorSet); 6169 ASSERT_VK_SUCCESS(err); 6170 VkDescriptorSet ds0_fs_only = {}; 6171 alloc_info.descriptorSetCount = 1; 6172 alloc_info.pSetLayouts = &ds_layout_fs_only; 6173 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &ds0_fs_only); 6174 ASSERT_VK_SUCCESS(err); 6175 6176 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 6177 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 6178 pipeline_layout_ci.pNext = NULL; 6179 pipeline_layout_ci.setLayoutCount = NUM_LAYOUTS; 6180 pipeline_layout_ci.pSetLayouts = ds_layout; 6181 6182 VkPipelineLayout pipeline_layout; 6183 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 6184 ASSERT_VK_SUCCESS(err); 6185 // Create pipelineLayout with only one setLayout 6186 pipeline_layout_ci.setLayoutCount = 1; 6187 VkPipelineLayout single_pipe_layout; 6188 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &single_pipe_layout); 6189 ASSERT_VK_SUCCESS(err); 6190 // Create pipelineLayout with 2 descriptor setLayout at index 0 6191 pipeline_layout_ci.pSetLayouts = &ds_layout[3]; 6192 VkPipelineLayout pipe_layout_one_desc; 6193 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_one_desc); 6194 ASSERT_VK_SUCCESS(err); 6195 // Create pipelineLayout with 5 SAMPLER descriptor setLayout at index 0 6196 pipeline_layout_ci.pSetLayouts = &ds_layout[2]; 6197 VkPipelineLayout pipe_layout_five_samp; 6198 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_five_samp); 6199 ASSERT_VK_SUCCESS(err); 6200 // Create pipelineLayout with UB type, but stageFlags for FS only 6201 pipeline_layout_ci.pSetLayouts = &ds_layout_fs_only; 6202 VkPipelineLayout pipe_layout_fs_only; 6203 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_fs_only); 6204 ASSERT_VK_SUCCESS(err); 6205 // Create pipelineLayout w/ incompatible set0 layout, but set1 is fine 6206 VkDescriptorSetLayout