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 pl_bad_s0[2] = {}; 6207 pl_bad_s0[0] = ds_layout_fs_only; 6208 pl_bad_s0[1] = ds_layout[1]; 6209 pipeline_layout_ci.setLayoutCount = 2; 6210 pipeline_layout_ci.pSetLayouts = pl_bad_s0; 6211 VkPipelineLayout pipe_layout_bad_set0; 6212 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipe_layout_bad_set0); 6213 ASSERT_VK_SUCCESS(err); 6214 6215 // Create a buffer to update the descriptor with 6216 uint32_t qfi = 0; 6217 VkBufferCreateInfo buffCI = {}; 6218 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 6219 buffCI.size = 1024; 6220 buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 6221 buffCI.queueFamilyIndexCount = 1; 6222 buffCI.pQueueFamilyIndices = &qfi; 6223 6224 VkBuffer dyub; 6225 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub); 6226 ASSERT_VK_SUCCESS(err); 6227 // Correctly update descriptor to avoid "NOT_UPDATED" error 6228 static const uint32_t NUM_BUFFS = 5; 6229 VkDescriptorBufferInfo buffInfo[NUM_BUFFS] = {}; 6230 for (uint32_t i = 0; i < NUM_BUFFS; ++i) { 6231 buffInfo[i].buffer = dyub; 6232 buffInfo[i].offset = 0; 6233 buffInfo[i].range = 1024; 6234 } 6235 VkImage image; 6236 const int32_t tex_width = 32; 6237 const int32_t tex_height = 32; 6238 VkImageCreateInfo image_create_info = {}; 6239 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 6240 image_create_info.pNext = NULL; 6241 image_create_info.imageType = VK_IMAGE_TYPE_2D; 6242 image_create_info.format = tex_format; 6243 image_create_info.extent.width = tex_width; 6244 image_create_info.extent.height = tex_height; 6245 image_create_info.extent.depth = 1; 6246 image_create_info.mipLevels = 1; 6247 image_create_info.arrayLayers = 1; 6248 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 6249 image_create_info.tiling = tiling; 6250 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT; 6251 image_create_info.flags = 0; 6252 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 6253 ASSERT_VK_SUCCESS(err); 6254 6255 VkMemoryRequirements memReqs; 6256 VkDeviceMemory imageMem; 6257 bool pass; 6258 VkMemoryAllocateInfo memAlloc = {}; 6259 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 6260 memAlloc.pNext = NULL; 6261 memAlloc.allocationSize = 0; 6262 memAlloc.memoryTypeIndex = 0; 6263 vkGetImageMemoryRequirements(m_device->device(), image, &memReqs); 6264 memAlloc.allocationSize = memReqs.size; 6265 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 6266 ASSERT_TRUE(pass); 6267 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &imageMem); 6268 ASSERT_VK_SUCCESS(err); 6269 err = vkBindImageMemory(m_device->device(), image, imageMem, 0); 6270 ASSERT_VK_SUCCESS(err); 6271 6272 VkImageViewCreateInfo image_view_create_info = {}; 6273 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 6274 image_view_create_info.image = image; 6275 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; 6276 image_view_create_info.format = tex_format; 6277 image_view_create_info.subresourceRange.layerCount = 1; 6278 image_view_create_info.subresourceRange.baseMipLevel = 0; 6279 image_view_create_info.subresourceRange.levelCount = 1; 6280 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 6281 6282 VkImageView view; 6283 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view); 6284 ASSERT_VK_SUCCESS(err); 6285 VkDescriptorImageInfo imageInfo[4] = {}; 6286 imageInfo[0].imageView = view; 6287 imageInfo[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 6288 imageInfo[1].imageView = view; 6289 imageInfo[1].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 6290 imageInfo[2].imageView = view; 6291 imageInfo[2].imageLayout = VK_IMAGE_LAYOUT_GENERAL; 6292 imageInfo[3].imageView = view; 6293 imageInfo[3].imageLayout = VK_IMAGE_LAYOUT_GENERAL; 6294 6295 static const uint32_t NUM_SET_UPDATES = 3; 6296 VkWriteDescriptorSet descriptor_write[NUM_SET_UPDATES] = {}; 6297 descriptor_write[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 6298 descriptor_write[0].dstSet = descriptorSet[0]; 6299 descriptor_write[0].dstBinding = 0; 6300 descriptor_write[0].descriptorCount = 5; 6301 descriptor_write[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 6302 descriptor_write[0].pBufferInfo = buffInfo; 6303 descriptor_write[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 6304 descriptor_write[1].dstSet = descriptorSet[1]; 6305 descriptor_write[1].dstBinding = 0; 6306 descriptor_write[1].descriptorCount = 2; 6307 descriptor_write[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; 6308 descriptor_write[1].pImageInfo = imageInfo; 6309 descriptor_write[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 6310 descriptor_write[2].dstSet = descriptorSet[1]; 6311 descriptor_write[2].dstBinding = 1; 6312 descriptor_write[2].descriptorCount = 2; 6313 descriptor_write[2].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; 6314 descriptor_write[2].pImageInfo = &imageInfo[2]; 6315 6316 vkUpdateDescriptorSets(m_device->device(), 3, descriptor_write, 0, NULL); 6317 6318 // Create PSO to be used for draw-time errors below 6319 char const *vsSource = "#version 450\n" 6320 "\n" 6321 "out gl_PerVertex {\n" 6322 " vec4 gl_Position;\n" 6323 "};\n" 6324 "void main(){\n" 6325 " gl_Position = vec4(1);\n" 6326 "}\n"; 6327 char const *fsSource = "#version 450\n" 6328 "\n" 6329 "layout(location=0) out vec4 x;\n" 6330 "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n" 6331 "void main(){\n" 6332 " x = vec4(bar.y);\n" 6333 "}\n"; 6334 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 6335 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 6336 VkPipelineObj pipe(m_device); 6337 pipe.AddShader(&vs); 6338 pipe.AddShader(&fs); 6339 pipe.AddColorAttachment(); 6340 pipe.CreateVKPipeline(pipe_layout_fs_only, renderPass()); 6341 6342 BeginCommandBuffer(); 6343 6344 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 6345 // NOTE : I believe LunarG ilo driver has bug (LX#189) that requires binding 6346 // of PSO 6347 // here before binding DSs. Otherwise we assert in cmd_copy_dset_data() of 6348 // cmd_pipeline.c 6349 // due to the fact that cmd_alloc_dset_data() has not been called in 6350 // cmd_bind_graphics_pipeline() 6351 // TODO : Want to cause various binding incompatibility issues here to test 6352 // DrawState 6353 // First cause various verify_layout_compatibility() fails 6354 // Second disturb early and late sets and verify INFO msgs 6355 // verify_set_layout_compatibility fail cases: 6356 // 1. invalid VkPipelineLayout (layout) passed into vkCmdBindDescriptorSets 6357 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline Layout Object "); 6358 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, 6359 (VkPipelineLayout)((size_t)0xbaadb1be), 0, 1, &descriptorSet[0], 0, NULL); 6360 m_errorMonitor->VerifyFound(); 6361 6362 // 2. layoutIndex exceeds # of layouts in layout 6363 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " attempting to bind set to index 1"); 6364 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, single_pipe_layout, 0, 2, 6365 &descriptorSet[0], 0, NULL); 6366 m_errorMonitor->VerifyFound(); 6367 6368 vkDestroyPipelineLayout(m_device->device(), single_pipe_layout, NULL); 6369 // 3. Pipeline setLayout[0] has 2 descriptors, but set being bound has 5 6370 // descriptors 6371 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has 2 descriptors, but DescriptorSetLayout "); 6372 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_one_desc, 0, 1, 6373 &descriptorSet[0], 0, NULL); 6374 m_errorMonitor->VerifyFound(); 6375 6376 vkDestroyPipelineLayout(m_device->device(), pipe_layout_one_desc, NULL); 6377 // 4. same # of descriptors but mismatch in type 6378 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is type 'VK_DESCRIPTOR_TYPE_SAMPLER' but binding "); 6379 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_five_samp, 0, 1, 6380 &descriptorSet[0], 0, NULL); 6381 m_errorMonitor->VerifyFound(); 6382 6383 vkDestroyPipelineLayout(m_device->device(), pipe_layout_five_samp, NULL); 6384 // 5. same # of descriptors but mismatch in stageFlags 6385 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6386 " has stageFlags 16 but binding 0 for DescriptorSetLayout "); 6387 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_fs_only, 0, 1, 6388 &descriptorSet[0], 0, NULL); 6389 m_errorMonitor->VerifyFound(); 6390 6391 // Cause INFO messages due to disturbing previously bound Sets 6392 // First bind sets 0 & 1 6393 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2, 6394 &descriptorSet[0], 0, NULL); 6395 // 1. Disturb bound set0 by re-binding set1 w/ updated pipelineLayout 6396 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, " previously bound as set #0 was disturbed "); 6397 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_bad_set0, 1, 1, 6398 &descriptorSet[1], 0, NULL); 6399 m_errorMonitor->VerifyFound(); 6400 6401 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2, 6402 &descriptorSet[0], 0, NULL); 6403 // 2. Disturb set after last bound set 6404 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, " newly bound as set #0 so set #1 and " 6405 "any subsequent sets were disturbed "); 6406 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_fs_only, 0, 1, 6407 &ds0_fs_only, 0, NULL); 6408 m_errorMonitor->VerifyFound(); 6409 6410 // Now that we're done actively using the pipelineLayout that gfx pipeline 6411 // was created with, we should be able to delete it. Do that now to verify 6412 // that validation obeys pipelineLayout lifetime 6413 vkDestroyPipelineLayout(m_device->device(), pipe_layout_fs_only, NULL); 6414 6415 // Cause draw-time errors due to PSO incompatibilities 6416 // 1. Error due to not binding required set (we actually use same code as 6417 // above to disturb set0) 6418 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2, 6419 &descriptorSet[0], 0, NULL); 6420 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout_bad_set0, 1, 1, 6421 &descriptorSet[1], 0, NULL); 6422 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " uses set #0 but that set is not bound."); 6423 Draw(1, 0, 0, 0); 6424 m_errorMonitor->VerifyFound(); 6425 6426 vkDestroyPipelineLayout(m_device->device(), pipe_layout_bad_set0, NULL); 6427 // 2. Error due to bound set not being compatible with PSO's 6428 // VkPipelineLayout (diff stageFlags in this case) 6429 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 2, 6430 &descriptorSet[0], 0, NULL); 6431 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " bound as set #0 is not compatible with "); 6432 Draw(1, 0, 0, 0); 6433 m_errorMonitor->VerifyFound(); 6434 6435 // Remaining clean-up 6436 for (uint32_t i = 0; i < NUM_LAYOUTS; ++i) { 6437 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout[i], NULL); 6438 } 6439 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout_fs_only, NULL); 6440 vkDestroyBuffer(m_device->device(), dyub, NULL); 6441 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 6442 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 6443 vkFreeMemory(m_device->device(), imageMem, NULL); 6444 vkDestroyImage(m_device->device(), image, NULL); 6445 vkDestroyImageView(m_device->device(), view, NULL); 6446 } 6447 6448 TEST_F(VkLayerTest, NoBeginCommandBuffer) { 6449 6450 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6451 "You must call vkBeginCommandBuffer() before this call to "); 6452 6453 ASSERT_NO_FATAL_FAILURE(InitState()); 6454 VkCommandBufferObj commandBuffer(m_device, m_commandPool); 6455 // Call EndCommandBuffer() w/o calling BeginCommandBuffer() 6456 vkEndCommandBuffer(commandBuffer.GetBufferHandle()); 6457 6458 m_errorMonitor->VerifyFound(); 6459 } 6460 6461 TEST_F(VkLayerTest, SecondaryCommandBufferNullRenderpass) { 6462 VkResult err; 6463 VkCommandBuffer draw_cmd; 6464 6465 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " must specify a valid renderpass parameter."); 6466 6467 ASSERT_NO_FATAL_FAILURE(InitState()); 6468 6469 VkCommandBufferAllocateInfo cmd = {}; 6470 cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 6471 cmd.pNext = NULL; 6472 cmd.commandPool = m_commandPool; 6473 cmd.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY; 6474 cmd.commandBufferCount = 1; 6475 6476 err = vkAllocateCommandBuffers(m_device->device(), &cmd, &draw_cmd); 6477 ASSERT_VK_SUCCESS(err); 6478 6479 // Force the failure by not setting the Renderpass and Framebuffer fields 6480 VkCommandBufferBeginInfo cmd_buf_info = {}; 6481 VkCommandBufferInheritanceInfo cmd_buf_hinfo = {}; 6482 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 6483 cmd_buf_info.pNext = NULL; 6484 cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; 6485 cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo; 6486 6487 // The error should be caught by validation of the BeginCommandBuffer call 6488 vkBeginCommandBuffer(draw_cmd, &cmd_buf_info); 6489 6490 m_errorMonitor->VerifyFound(); 6491 vkFreeCommandBuffers(m_device->device(), m_commandPool, 1, &draw_cmd); 6492 } 6493 6494 TEST_F(VkLayerTest, CommandBufferResetErrors) { 6495 // Cause error due to Begin while recording CB 6496 // Then cause 2 errors for attempting to reset CB w/o having 6497 // VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT set for the pool from 6498 // which CBs were allocated. Note that this bit is off by default. 6499 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot call Begin on command buffer"); 6500 6501 ASSERT_NO_FATAL_FAILURE(InitState()); 6502 6503 // Calls AllocateCommandBuffers 6504 VkCommandBufferObj commandBuffer(m_device, m_commandPool); 6505 6506 // Force the failure by setting the Renderpass and Framebuffer fields with 6507 // (fake) data 6508 VkCommandBufferBeginInfo cmd_buf_info = {}; 6509 VkCommandBufferInheritanceInfo cmd_buf_hinfo = {}; 6510 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 6511 cmd_buf_info.pNext = NULL; 6512 cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; 6513 cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo; 6514 6515 // Begin CB to transition to recording state 6516 vkBeginCommandBuffer(commandBuffer.GetBufferHandle(), &cmd_buf_info); 6517 // Can't re-begin. This should trigger error 6518 vkBeginCommandBuffer(commandBuffer.GetBufferHandle(), &cmd_buf_info); 6519 m_errorMonitor->VerifyFound(); 6520 6521 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to reset command buffer "); 6522 VkCommandBufferResetFlags flags = 0; // Don't care about flags for this test 6523 // Reset attempt will trigger error due to incorrect CommandPool state 6524 vkResetCommandBuffer(commandBuffer.GetBufferHandle(), flags); 6525 m_errorMonitor->VerifyFound(); 6526 6527 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " attempts to implicitly reset cmdBuffer created from "); 6528 // Transition CB to RECORDED state 6529 vkEndCommandBuffer(commandBuffer.GetBufferHandle()); 6530 // Now attempting to Begin will implicitly reset, which triggers error 6531 vkBeginCommandBuffer(commandBuffer.GetBufferHandle(), &cmd_buf_info); 6532 m_errorMonitor->VerifyFound(); 6533 } 6534 6535 TEST_F(VkLayerTest, InvalidPipelineCreateState) { 6536 // Attempt to Create Gfx Pipeline w/o a VS 6537 VkResult err; 6538 6539 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline CreateInfo State: Vertex Shader required"); 6540 6541 ASSERT_NO_FATAL_FAILURE(InitState()); 6542 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 6543 6544 VkDescriptorPoolSize ds_type_count = {}; 6545 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 6546 ds_type_count.descriptorCount = 1; 6547 6548 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 6549 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 6550 ds_pool_ci.pNext = NULL; 6551 ds_pool_ci.maxSets = 1; 6552 ds_pool_ci.poolSizeCount = 1; 6553 ds_pool_ci.pPoolSizes = &ds_type_count; 6554 6555 VkDescriptorPool ds_pool; 6556 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 6557 ASSERT_VK_SUCCESS(err); 6558 6559 VkDescriptorSetLayoutBinding dsl_binding = {}; 6560 dsl_binding.binding = 0; 6561 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 6562 dsl_binding.descriptorCount = 1; 6563 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 6564 dsl_binding.pImmutableSamplers = NULL; 6565 6566 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 6567 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 6568 ds_layout_ci.pNext = NULL; 6569 ds_layout_ci.bindingCount = 1; 6570 ds_layout_ci.pBindings = &dsl_binding; 6571 6572 VkDescriptorSetLayout ds_layout; 6573 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 6574 ASSERT_VK_SUCCESS(err); 6575 6576 VkDescriptorSet descriptorSet; 6577 VkDescriptorSetAllocateInfo alloc_info = {}; 6578 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 6579 alloc_info.descriptorSetCount = 1; 6580 alloc_info.descriptorPool = ds_pool; 6581 alloc_info.pSetLayouts = &ds_layout; 6582 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 6583 ASSERT_VK_SUCCESS(err); 6584 6585 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 6586 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 6587 pipeline_layout_ci.setLayoutCount = 1; 6588 pipeline_layout_ci.pSetLayouts = &ds_layout; 6589 6590 VkPipelineLayout pipeline_layout; 6591 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 6592 ASSERT_VK_SUCCESS(err); 6593 6594 VkViewport vp = {}; // Just need dummy vp to point to 6595 VkRect2D sc = {}; // dummy scissor to point to 6596 6597 VkPipelineViewportStateCreateInfo vp_state_ci = {}; 6598 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 6599 vp_state_ci.scissorCount = 1; 6600 vp_state_ci.pScissors = ≻ 6601 vp_state_ci.viewportCount = 1; 6602 vp_state_ci.pViewports = &vp; 6603 6604 VkPipelineRasterizationStateCreateInfo rs_state_ci = {}; 6605 rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 6606 rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL; 6607 rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT; 6608 rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; 6609 rs_state_ci.depthClampEnable = VK_FALSE; 6610 rs_state_ci.rasterizerDiscardEnable = VK_FALSE; 6611 rs_state_ci.depthBiasEnable = VK_FALSE; 6612 6613 VkGraphicsPipelineCreateInfo gp_ci = {}; 6614 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 6615 gp_ci.pViewportState = &vp_state_ci; 6616 gp_ci.pRasterizationState = &rs_state_ci; 6617 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; 6618 gp_ci.layout = pipeline_layout; 6619 gp_ci.renderPass = renderPass(); 6620 6621 VkPipelineCacheCreateInfo pc_ci = {}; 6622 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 6623 pc_ci.initialDataSize = 0; 6624 pc_ci.pInitialData = 0; 6625 6626 VkPipeline pipeline; 6627 VkPipelineCache pipelineCache; 6628 6629 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache); 6630 ASSERT_VK_SUCCESS(err); 6631 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline); 6632 6633 m_errorMonitor->VerifyFound(); 6634 6635 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL); 6636 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 6637 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 6638 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 6639 } 6640 /*// TODO : This test should be good, but needs Tess support in compiler to run 6641 TEST_F(VkLayerTest, InvalidPatchControlPoints) 6642 { 6643 // Attempt to Create Gfx Pipeline w/o a VS 6644 VkResult err; 6645 6646 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6647 "Invalid Pipeline CreateInfo State: VK_PRIMITIVE_TOPOLOGY_PATCH 6648 primitive "); 6649 6650 ASSERT_NO_FATAL_FAILURE(InitState()); 6651 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 6652 6653 VkDescriptorPoolSize ds_type_count = {}; 6654 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 6655 ds_type_count.descriptorCount = 1; 6656 6657 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 6658 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 6659 ds_pool_ci.pNext = NULL; 6660 ds_pool_ci.poolSizeCount = 1; 6661 ds_pool_ci.pPoolSizes = &ds_type_count; 6662 6663 VkDescriptorPool ds_pool; 6664 err = vkCreateDescriptorPool(m_device->device(), 6665 VK_DESCRIPTOR_POOL_USAGE_NON_FREE, 1, &ds_pool_ci, NULL, &ds_pool); 6666 ASSERT_VK_SUCCESS(err); 6667 6668 VkDescriptorSetLayoutBinding dsl_binding = {}; 6669 dsl_binding.binding = 0; 6670 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 6671 dsl_binding.descriptorCount = 1; 6672 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 6673 dsl_binding.pImmutableSamplers = NULL; 6674 6675 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 6676 ds_layout_ci.sType = 6677 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 6678 ds_layout_ci.pNext = NULL; 6679 ds_layout_ci.bindingCount = 1; 6680 ds_layout_ci.pBindings = &dsl_binding; 6681 6682 VkDescriptorSetLayout ds_layout; 6683 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, 6684 &ds_layout); 6685 ASSERT_VK_SUCCESS(err); 6686 6687 VkDescriptorSet descriptorSet; 6688 err = vkAllocateDescriptorSets(m_device->device(), ds_pool, 6689 VK_DESCRIPTOR_SET_USAGE_NON_FREE, 1, &ds_layout, &descriptorSet); 6690 ASSERT_VK_SUCCESS(err); 6691 6692 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 6693 pipeline_layout_ci.sType = 6694 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 6695 pipeline_layout_ci.pNext = NULL; 6696 pipeline_layout_ci.setLayoutCount = 1; 6697 pipeline_layout_ci.pSetLayouts = &ds_layout; 6698 6699 VkPipelineLayout pipeline_layout; 6700 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, 6701 &pipeline_layout); 6702 ASSERT_VK_SUCCESS(err); 6703 6704 VkPipelineShaderStageCreateInfo shaderStages[3]; 6705 memset(&shaderStages, 0, 3 * sizeof(VkPipelineShaderStageCreateInfo)); 6706 6707 VkShaderObj vs(m_device,bindStateVertShaderText,VK_SHADER_STAGE_VERTEX_BIT, 6708 this); 6709 // Just using VS txt for Tess shaders as we don't care about functionality 6710 VkShaderObj 6711 tc(m_device,bindStateVertShaderText,VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 6712 this); 6713 VkShaderObj 6714 te(m_device,bindStateVertShaderText,VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, 6715 this); 6716 6717 shaderStages[0].sType = 6718 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 6719 shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; 6720 shaderStages[0].shader = vs.handle(); 6721 shaderStages[1].sType = 6722 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 6723 shaderStages[1].stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; 6724 shaderStages[1].shader = tc.handle(); 6725 shaderStages[2].sType = 6726 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 6727 shaderStages[2].stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; 6728 shaderStages[2].shader = te.handle(); 6729 6730 VkPipelineInputAssemblyStateCreateInfo iaCI = {}; 6731 iaCI.sType = 6732 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 6733 iaCI.topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; 6734 6735 VkPipelineTessellationStateCreateInfo tsCI = {}; 6736 tsCI.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; 6737 tsCI.patchControlPoints = 0; // This will cause an error 6738 6739 VkGraphicsPipelineCreateInfo gp_ci = {}; 6740 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 6741 gp_ci.pNext = NULL; 6742 gp_ci.stageCount = 3; 6743 gp_ci.pStages = shaderStages; 6744 gp_ci.pVertexInputState = NULL; 6745 gp_ci.pInputAssemblyState = &iaCI; 6746 gp_ci.pTessellationState = &tsCI; 6747 gp_ci.pViewportState = NULL; 6748 gp_ci.pRasterizationState = NULL; 6749 gp_ci.pMultisampleState = NULL; 6750 gp_ci.pDepthStencilState = NULL; 6751 gp_ci.pColorBlendState = NULL; 6752 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; 6753 gp_ci.layout = pipeline_layout; 6754 gp_ci.renderPass = renderPass(); 6755 6756 VkPipelineCacheCreateInfo pc_ci = {}; 6757 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 6758 pc_ci.pNext = NULL; 6759 pc_ci.initialSize = 0; 6760 pc_ci.initialData = 0; 6761 pc_ci.maxSize = 0; 6762 6763 VkPipeline pipeline; 6764 VkPipelineCache pipelineCache; 6765 6766 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, 6767 &pipelineCache); 6768 ASSERT_VK_SUCCESS(err); 6769 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, 6770 &gp_ci, NULL, &pipeline); 6771 6772 m_errorMonitor->VerifyFound(); 6773 6774 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL); 6775 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 6776 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 6777 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 6778 } 6779 */ 6780 // Set scissor and viewport counts to different numbers 6781 TEST_F(VkLayerTest, PSOViewportScissorCountMismatch) { 6782 VkResult err; 6783 6784 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 6785 "Gfx Pipeline viewport count (1) must match scissor count (0)."); 6786 6787 ASSERT_NO_FATAL_FAILURE(InitState()); 6788 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 6789 6790 VkDescriptorPoolSize ds_type_count = {}; 6791 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 6792 ds_type_count.descriptorCount = 1; 6793 6794 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 6795 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 6796 ds_pool_ci.maxSets = 1; 6797 ds_pool_ci.poolSizeCount = 1; 6798 ds_pool_ci.pPoolSizes = &ds_type_count; 6799 6800 VkDescriptorPool ds_pool; 6801 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 6802 ASSERT_VK_SUCCESS(err); 6803 6804 VkDescriptorSetLayoutBinding dsl_binding = {}; 6805 dsl_binding.binding = 0; 6806 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 6807 dsl_binding.descriptorCount = 1; 6808 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 6809 6810 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 6811 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 6812 ds_layout_ci.bindingCount = 1; 6813 ds_layout_ci.pBindings = &dsl_binding; 6814 6815 VkDescriptorSetLayout ds_layout; 6816 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 6817 ASSERT_VK_SUCCESS(err); 6818 6819 VkDescriptorSet descriptorSet; 6820 VkDescriptorSetAllocateInfo alloc_info = {}; 6821 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 6822 alloc_info.descriptorSetCount = 1; 6823 alloc_info.descriptorPool = ds_pool; 6824 alloc_info.pSetLayouts = &ds_layout; 6825 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 6826 ASSERT_VK_SUCCESS(err); 6827 6828 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 6829 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 6830 pipeline_layout_ci.setLayoutCount = 1; 6831 pipeline_layout_ci.pSetLayouts = &ds_layout; 6832 6833 VkPipelineLayout pipeline_layout; 6834 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 6835 ASSERT_VK_SUCCESS(err); 6836 6837 VkViewport vp = {}; // Just need dummy vp to point to 6838 6839 VkPipelineViewportStateCreateInfo vp_state_ci = {}; 6840 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 6841 vp_state_ci.scissorCount = 0; 6842 vp_state_ci.viewportCount = 1; // Count mismatch should cause error 6843 vp_state_ci.pViewports = &vp; 6844 6845 VkPipelineRasterizationStateCreateInfo rs_state_ci = {}; 6846 rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 6847 rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL; 6848 rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT; 6849 rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; 6850 rs_state_ci.depthClampEnable = VK_FALSE; 6851 rs_state_ci.rasterizerDiscardEnable = VK_FALSE; 6852 rs_state_ci.depthBiasEnable = VK_FALSE; 6853 6854 VkPipelineShaderStageCreateInfo shaderStages[2]; 6855 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo)); 6856 6857 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 6858 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader 6859 // but add it to be able to run on more devices 6860 shaderStages[0] = vs.GetStageCreateInfo(); 6861 shaderStages[1] = fs.GetStageCreateInfo(); 6862 6863 VkGraphicsPipelineCreateInfo gp_ci = {}; 6864 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 6865 gp_ci.stageCount = 2; 6866 gp_ci.pStages = shaderStages; 6867 gp_ci.pViewportState = &vp_state_ci; 6868 gp_ci.pRasterizationState = &rs_state_ci; 6869 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; 6870 gp_ci.layout = pipeline_layout; 6871 gp_ci.renderPass = renderPass(); 6872 6873 VkPipelineCacheCreateInfo pc_ci = {}; 6874 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 6875 6876 VkPipeline pipeline; 6877 VkPipelineCache pipelineCache; 6878 6879 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache); 6880 ASSERT_VK_SUCCESS(err); 6881 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline); 6882 6883 m_errorMonitor->VerifyFound(); 6884 6885 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL); 6886 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 6887 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 6888 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 6889 } 6890 // Don't set viewport state in PSO. This is an error b/c we always need this 6891 // state 6892 // for the counts even if the data is going to be set dynamically. 6893 TEST_F(VkLayerTest, PSOViewportStateNotSet) { 6894 // Attempt to Create Gfx Pipeline w/o a VS 6895 VkResult err; 6896 6897 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Gfx Pipeline pViewportState is null. Even if "); 6898 6899 ASSERT_NO_FATAL_FAILURE(InitState()); 6900 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 6901 6902 VkDescriptorPoolSize ds_type_count = {}; 6903 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 6904 ds_type_count.descriptorCount = 1; 6905 6906 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 6907 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 6908 ds_pool_ci.maxSets = 1; 6909 ds_pool_ci.poolSizeCount = 1; 6910 ds_pool_ci.pPoolSizes = &ds_type_count; 6911 6912 VkDescriptorPool ds_pool; 6913 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 6914 ASSERT_VK_SUCCESS(err); 6915 6916 VkDescriptorSetLayoutBinding dsl_binding = {}; 6917 dsl_binding.binding = 0; 6918 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 6919 dsl_binding.descriptorCount = 1; 6920 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 6921 6922 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 6923 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 6924 ds_layout_ci.bindingCount = 1; 6925 ds_layout_ci.pBindings = &dsl_binding; 6926 6927 VkDescriptorSetLayout ds_layout; 6928 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 6929 ASSERT_VK_SUCCESS(err); 6930 6931 VkDescriptorSet descriptorSet; 6932 VkDescriptorSetAllocateInfo alloc_info = {}; 6933 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 6934 alloc_info.descriptorSetCount = 1; 6935 alloc_info.descriptorPool = ds_pool; 6936 alloc_info.pSetLayouts = &ds_layout; 6937 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 6938 ASSERT_VK_SUCCESS(err); 6939 6940 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 6941 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 6942 pipeline_layout_ci.setLayoutCount = 1; 6943 pipeline_layout_ci.pSetLayouts = &ds_layout; 6944 6945 VkPipelineLayout pipeline_layout; 6946 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 6947 ASSERT_VK_SUCCESS(err); 6948 6949 VkDynamicState sc_state = VK_DYNAMIC_STATE_SCISSOR; 6950 // Set scissor as dynamic to avoid second error 6951 VkPipelineDynamicStateCreateInfo dyn_state_ci = {}; 6952 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; 6953 dyn_state_ci.dynamicStateCount = 1; 6954 dyn_state_ci.pDynamicStates = &sc_state; 6955 6956 VkPipelineShaderStageCreateInfo shaderStages[2]; 6957 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo)); 6958 6959 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 6960 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader 6961 // but add it to be able to run on more devices 6962 shaderStages[0] = vs.GetStageCreateInfo(); 6963 shaderStages[1] = fs.GetStageCreateInfo(); 6964 6965 VkPipelineRasterizationStateCreateInfo rs_state_ci = {}; 6966 rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 6967 rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL; 6968 rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT; 6969 rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; 6970 rs_state_ci.depthClampEnable = VK_FALSE; 6971 rs_state_ci.rasterizerDiscardEnable = VK_FALSE; 6972 rs_state_ci.depthBiasEnable = VK_FALSE; 6973 6974 VkGraphicsPipelineCreateInfo gp_ci = {}; 6975 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 6976 gp_ci.stageCount = 2; 6977 gp_ci.pStages = shaderStages; 6978 gp_ci.pRasterizationState = &rs_state_ci; 6979 gp_ci.pViewportState = NULL; // Not setting VP state w/o dynamic vp state 6980 // should cause validation error 6981 gp_ci.pDynamicState = &dyn_state_ci; 6982 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; 6983 gp_ci.layout = pipeline_layout; 6984 gp_ci.renderPass = renderPass(); 6985 6986 VkPipelineCacheCreateInfo pc_ci = {}; 6987 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 6988 6989 VkPipeline pipeline; 6990 VkPipelineCache pipelineCache; 6991 6992 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache); 6993 ASSERT_VK_SUCCESS(err); 6994 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline); 6995 6996 m_errorMonitor->VerifyFound(); 6997 6998 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL); 6999 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 7000 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 7001 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 7002 } 7003 // Create PSO w/o non-zero viewportCount but no viewport data 7004 // Then run second test where dynamic scissor count doesn't match PSO scissor 7005 // count 7006 TEST_F(VkLayerTest, PSOViewportCountWithoutDataAndDynScissorMismatch) { 7007 VkResult err; 7008 7009 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 7010 "Gfx Pipeline viewportCount is 1, but pViewports is NULL. "); 7011 7012 ASSERT_NO_FATAL_FAILURE(InitState()); 7013 7014 if (!m_device->phy().features().multiViewport) { 7015 printf("Device does not support multiple viewports/scissors; skipped.\n"); 7016 return; 7017 } 7018 7019 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7020 7021 VkDescriptorPoolSize ds_type_count = {}; 7022 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 7023 ds_type_count.descriptorCount = 1; 7024 7025 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 7026 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 7027 ds_pool_ci.maxSets = 1; 7028 ds_pool_ci.poolSizeCount = 1; 7029 ds_pool_ci.pPoolSizes = &ds_type_count; 7030 7031 VkDescriptorPool ds_pool; 7032 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 7033 ASSERT_VK_SUCCESS(err); 7034 7035 VkDescriptorSetLayoutBinding dsl_binding = {}; 7036 dsl_binding.binding = 0; 7037 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 7038 dsl_binding.descriptorCount = 1; 7039 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 7040 7041 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 7042 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 7043 ds_layout_ci.bindingCount = 1; 7044 ds_layout_ci.pBindings = &dsl_binding; 7045 7046 VkDescriptorSetLayout ds_layout; 7047 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 7048 ASSERT_VK_SUCCESS(err); 7049 7050 VkDescriptorSet descriptorSet; 7051 VkDescriptorSetAllocateInfo alloc_info = {}; 7052 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 7053 alloc_info.descriptorSetCount = 1; 7054 alloc_info.descriptorPool = ds_pool; 7055 alloc_info.pSetLayouts = &ds_layout; 7056 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 7057 ASSERT_VK_SUCCESS(err); 7058 7059 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 7060 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 7061 pipeline_layout_ci.setLayoutCount = 1; 7062 pipeline_layout_ci.pSetLayouts = &ds_layout; 7063 7064 VkPipelineLayout pipeline_layout; 7065 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 7066 ASSERT_VK_SUCCESS(err); 7067 7068 VkPipelineViewportStateCreateInfo vp_state_ci = {}; 7069 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 7070 vp_state_ci.viewportCount = 1; 7071 vp_state_ci.pViewports = NULL; // Null vp w/ count of 1 should cause error 7072 vp_state_ci.scissorCount = 1; 7073 vp_state_ci.pScissors = NULL; // Scissor is dynamic (below) so this won't cause error 7074 7075 VkDynamicState sc_state = VK_DYNAMIC_STATE_SCISSOR; 7076 // Set scissor as dynamic to avoid that error 7077 VkPipelineDynamicStateCreateInfo dyn_state_ci = {}; 7078 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; 7079 dyn_state_ci.dynamicStateCount = 1; 7080 dyn_state_ci.pDynamicStates = &sc_state; 7081 7082 VkPipelineShaderStageCreateInfo shaderStages[2]; 7083 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo)); 7084 7085 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 7086 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader 7087 // but add it to be able to run on more devices 7088 shaderStages[0] = vs.GetStageCreateInfo(); 7089 shaderStages[1] = fs.GetStageCreateInfo(); 7090 7091 VkPipelineVertexInputStateCreateInfo vi_ci = {}; 7092 vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 7093 vi_ci.pNext = nullptr; 7094 vi_ci.vertexBindingDescriptionCount = 0; 7095 vi_ci.pVertexBindingDescriptions = nullptr; 7096 vi_ci.vertexAttributeDescriptionCount = 0; 7097 vi_ci.pVertexAttributeDescriptions = nullptr; 7098 7099 VkPipelineInputAssemblyStateCreateInfo ia_ci = {}; 7100 ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 7101 ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 7102 7103 VkPipelineRasterizationStateCreateInfo rs_ci = {}; 7104 rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 7105 rs_ci.pNext = nullptr; 7106 7107 VkPipelineColorBlendAttachmentState att = {}; 7108 att.blendEnable = VK_FALSE; 7109 att.colorWriteMask = 0xf; 7110 7111 VkPipelineColorBlendStateCreateInfo cb_ci = {}; 7112 cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; 7113 cb_ci.pNext = nullptr; 7114 cb_ci.attachmentCount = 1; 7115 cb_ci.pAttachments = &att; 7116 7117 VkGraphicsPipelineCreateInfo gp_ci = {}; 7118 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 7119 gp_ci.stageCount = 2; 7120 gp_ci.pStages = shaderStages; 7121 gp_ci.pVertexInputState = &vi_ci; 7122 gp_ci.pInputAssemblyState = &ia_ci; 7123 gp_ci.pViewportState = &vp_state_ci; 7124 gp_ci.pRasterizationState = &rs_ci; 7125 gp_ci.pColorBlendState = &cb_ci; 7126 gp_ci.pDynamicState = &dyn_state_ci; 7127 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; 7128 gp_ci.layout = pipeline_layout; 7129 gp_ci.renderPass = renderPass(); 7130 7131 VkPipelineCacheCreateInfo pc_ci = {}; 7132 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 7133 7134 VkPipeline pipeline; 7135 VkPipelineCache pipelineCache; 7136 7137 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache); 7138 ASSERT_VK_SUCCESS(err); 7139 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline); 7140 7141 m_errorMonitor->VerifyFound(); 7142 7143 // Now hit second fail case where we set scissor w/ different count than PSO 7144 // First need to successfully create the PSO from above by setting 7145 // pViewports 7146 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic scissor(s) 0 are used by pipeline state object, "); 7147 7148 VkViewport vp = {}; // Just need dummy vp to point to 7149 vp_state_ci.pViewports = &vp; 7150 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline); 7151 ASSERT_VK_SUCCESS(err); 7152 BeginCommandBuffer(); 7153 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); 7154 VkRect2D scissors[1] = {}; // don't care about data 7155 // Count of 2 doesn't match PSO count of 1 7156 vkCmdSetScissor(m_commandBuffer->GetBufferHandle(), 1, 1, scissors); 7157 Draw(1, 0, 0, 0); 7158 7159 m_errorMonitor->VerifyFound(); 7160 7161 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL); 7162 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 7163 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 7164 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 7165 vkDestroyPipeline(m_device->device(), pipeline, NULL); 7166 } 7167 // Create PSO w/o non-zero scissorCount but no scissor data 7168 // Then run second test where dynamic viewportCount doesn't match PSO 7169 // viewportCount 7170 TEST_F(VkLayerTest, PSOScissorCountWithoutDataAndDynViewportMismatch) { 7171 VkResult err; 7172 7173 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Gfx Pipeline scissorCount is 1, but pScissors is NULL. "); 7174 7175 ASSERT_NO_FATAL_FAILURE(InitState()); 7176 7177 if (!m_device->phy().features().multiViewport) { 7178 printf("Device does not support multiple viewports/scissors; skipped.\n"); 7179 return; 7180 } 7181 7182 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7183 7184 VkDescriptorPoolSize ds_type_count = {}; 7185 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 7186 ds_type_count.descriptorCount = 1; 7187 7188 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 7189 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 7190 ds_pool_ci.maxSets = 1; 7191 ds_pool_ci.poolSizeCount = 1; 7192 ds_pool_ci.pPoolSizes = &ds_type_count; 7193 7194 VkDescriptorPool ds_pool; 7195 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 7196 ASSERT_VK_SUCCESS(err); 7197 7198 VkDescriptorSetLayoutBinding dsl_binding = {}; 7199 dsl_binding.binding = 0; 7200 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 7201 dsl_binding.descriptorCount = 1; 7202 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 7203 7204 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 7205 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 7206 ds_layout_ci.bindingCount = 1; 7207 ds_layout_ci.pBindings = &dsl_binding; 7208 7209 VkDescriptorSetLayout ds_layout; 7210 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 7211 ASSERT_VK_SUCCESS(err); 7212 7213 VkDescriptorSet descriptorSet; 7214 VkDescriptorSetAllocateInfo alloc_info = {}; 7215 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 7216 alloc_info.descriptorSetCount = 1; 7217 alloc_info.descriptorPool = ds_pool; 7218 alloc_info.pSetLayouts = &ds_layout; 7219 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 7220 ASSERT_VK_SUCCESS(err); 7221 7222 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 7223 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 7224 pipeline_layout_ci.setLayoutCount = 1; 7225 pipeline_layout_ci.pSetLayouts = &ds_layout; 7226 7227 VkPipelineLayout pipeline_layout; 7228 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 7229 ASSERT_VK_SUCCESS(err); 7230 7231 VkPipelineViewportStateCreateInfo vp_state_ci = {}; 7232 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 7233 vp_state_ci.scissorCount = 1; 7234 vp_state_ci.pScissors = NULL; // Null scissor w/ count of 1 should cause error 7235 vp_state_ci.viewportCount = 1; 7236 vp_state_ci.pViewports = NULL; // vp is dynamic (below) so this won't cause error 7237 7238 VkDynamicState vp_state = VK_DYNAMIC_STATE_VIEWPORT; 7239 // Set scissor as dynamic to avoid that error 7240 VkPipelineDynamicStateCreateInfo dyn_state_ci = {}; 7241 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; 7242 dyn_state_ci.dynamicStateCount = 1; 7243 dyn_state_ci.pDynamicStates = &vp_state; 7244 7245 VkPipelineShaderStageCreateInfo shaderStages[2]; 7246 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo)); 7247 7248 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 7249 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader 7250 // but add it to be able to run on more devices 7251 shaderStages[0] = vs.GetStageCreateInfo(); 7252 shaderStages[1] = fs.GetStageCreateInfo(); 7253 7254 VkPipelineVertexInputStateCreateInfo vi_ci = {}; 7255 vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 7256 vi_ci.pNext = nullptr; 7257 vi_ci.vertexBindingDescriptionCount = 0; 7258 vi_ci.pVertexBindingDescriptions = nullptr; 7259 vi_ci.vertexAttributeDescriptionCount = 0; 7260 vi_ci.pVertexAttributeDescriptions = nullptr; 7261 7262 VkPipelineInputAssemblyStateCreateInfo ia_ci = {}; 7263 ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 7264 ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 7265 7266 VkPipelineRasterizationStateCreateInfo rs_ci = {}; 7267 rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 7268 rs_ci.pNext = nullptr; 7269 7270 VkPipelineColorBlendAttachmentState att = {}; 7271 att.blendEnable = VK_FALSE; 7272 att.colorWriteMask = 0xf; 7273 7274 VkPipelineColorBlendStateCreateInfo cb_ci = {}; 7275 cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; 7276 cb_ci.pNext = nullptr; 7277 cb_ci.attachmentCount = 1; 7278 cb_ci.pAttachments = &att; 7279 7280 VkGraphicsPipelineCreateInfo gp_ci = {}; 7281 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 7282 gp_ci.stageCount = 2; 7283 gp_ci.pStages = shaderStages; 7284 gp_ci.pVertexInputState = &vi_ci; 7285 gp_ci.pInputAssemblyState = &ia_ci; 7286 gp_ci.pViewportState = &vp_state_ci; 7287 gp_ci.pRasterizationState = &rs_ci; 7288 gp_ci.pColorBlendState = &cb_ci; 7289 gp_ci.pDynamicState = &dyn_state_ci; 7290 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; 7291 gp_ci.layout = pipeline_layout; 7292 gp_ci.renderPass = renderPass(); 7293 7294 VkPipelineCacheCreateInfo pc_ci = {}; 7295 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 7296 7297 VkPipeline pipeline; 7298 VkPipelineCache pipelineCache; 7299 7300 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache); 7301 ASSERT_VK_SUCCESS(err); 7302 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline); 7303 7304 m_errorMonitor->VerifyFound(); 7305 7306 // Now hit second fail case where we set scissor w/ different count than PSO 7307 // First need to successfully create the PSO from above by setting 7308 // pViewports 7309 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic viewport(s) 0 are used by pipeline state object, "); 7310 7311 VkRect2D sc = {}; // Just need dummy vp to point to 7312 vp_state_ci.pScissors = ≻ 7313 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline); 7314 ASSERT_VK_SUCCESS(err); 7315 BeginCommandBuffer(); 7316 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); 7317 VkViewport viewports[1] = {}; // don't care about data 7318 // Count of 2 doesn't match PSO count of 1 7319 vkCmdSetViewport(m_commandBuffer->GetBufferHandle(), 1, 1, viewports); 7320 Draw(1, 0, 0, 0); 7321 7322 m_errorMonitor->VerifyFound(); 7323 7324 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL); 7325 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 7326 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 7327 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 7328 vkDestroyPipeline(m_device->device(), pipeline, NULL); 7329 } 7330 7331 TEST_F(VkLayerTest, PSOLineWidthInvalid) { 7332 VkResult err; 7333 7334 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to -1"); 7335 7336 ASSERT_NO_FATAL_FAILURE(InitState()); 7337 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7338 7339 VkDescriptorPoolSize ds_type_count = {}; 7340 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 7341 ds_type_count.descriptorCount = 1; 7342 7343 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 7344 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 7345 ds_pool_ci.maxSets = 1; 7346 ds_pool_ci.poolSizeCount = 1; 7347 ds_pool_ci.pPoolSizes = &ds_type_count; 7348 7349 VkDescriptorPool ds_pool; 7350 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 7351 ASSERT_VK_SUCCESS(err); 7352 7353 VkDescriptorSetLayoutBinding dsl_binding = {}; 7354 dsl_binding.binding = 0; 7355 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 7356 dsl_binding.descriptorCount = 1; 7357 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 7358 7359 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 7360 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 7361 ds_layout_ci.bindingCount = 1; 7362 ds_layout_ci.pBindings = &dsl_binding; 7363 7364 VkDescriptorSetLayout ds_layout; 7365 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 7366 ASSERT_VK_SUCCESS(err); 7367 7368 VkDescriptorSet descriptorSet; 7369 VkDescriptorSetAllocateInfo alloc_info = {}; 7370 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 7371 alloc_info.descriptorSetCount = 1; 7372 alloc_info.descriptorPool = ds_pool; 7373 alloc_info.pSetLayouts = &ds_layout; 7374 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 7375 ASSERT_VK_SUCCESS(err); 7376 7377 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 7378 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 7379 pipeline_layout_ci.setLayoutCount = 1; 7380 pipeline_layout_ci.pSetLayouts = &ds_layout; 7381 7382 VkPipelineLayout pipeline_layout; 7383 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 7384 ASSERT_VK_SUCCESS(err); 7385 7386 VkPipelineViewportStateCreateInfo vp_state_ci = {}; 7387 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 7388 vp_state_ci.scissorCount = 1; 7389 vp_state_ci.pScissors = NULL; 7390 vp_state_ci.viewportCount = 1; 7391 vp_state_ci.pViewports = NULL; 7392 7393 VkDynamicState dynamic_states[3] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_LINE_WIDTH}; 7394 // Set scissor as dynamic to avoid that error 7395 VkPipelineDynamicStateCreateInfo dyn_state_ci = {}; 7396 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; 7397 dyn_state_ci.dynamicStateCount = 2; 7398 dyn_state_ci.pDynamicStates = dynamic_states; 7399 7400 VkPipelineShaderStageCreateInfo shaderStages[2]; 7401 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo)); 7402 7403 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 7404 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, 7405 this); // TODO - We shouldn't need a fragment shader 7406 // but add it to be able to run on more devices 7407 shaderStages[0] = vs.GetStageCreateInfo(); 7408 shaderStages[1] = fs.GetStageCreateInfo(); 7409 7410 VkPipelineVertexInputStateCreateInfo vi_ci = {}; 7411 vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 7412 vi_ci.pNext = nullptr; 7413 vi_ci.vertexBindingDescriptionCount = 0; 7414 vi_ci.pVertexBindingDescriptions = nullptr; 7415 vi_ci.vertexAttributeDescriptionCount = 0; 7416 vi_ci.pVertexAttributeDescriptions = nullptr; 7417 7418 VkPipelineInputAssemblyStateCreateInfo ia_ci = {}; 7419 ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 7420 ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 7421 7422 VkPipelineRasterizationStateCreateInfo rs_ci = {}; 7423 rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 7424 rs_ci.pNext = nullptr; 7425 7426 // Check too low (line width of -1.0f). 7427 rs_ci.lineWidth = -1.0f; 7428 7429 VkPipelineColorBlendAttachmentState att = {}; 7430 att.blendEnable = VK_FALSE; 7431 att.colorWriteMask = 0xf; 7432 7433 VkPipelineColorBlendStateCreateInfo cb_ci = {}; 7434 cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; 7435 cb_ci.pNext = nullptr; 7436 cb_ci.attachmentCount = 1; 7437 cb_ci.pAttachments = &att; 7438 7439 VkGraphicsPipelineCreateInfo gp_ci = {}; 7440 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 7441 gp_ci.stageCount = 2; 7442 gp_ci.pStages = shaderStages; 7443 gp_ci.pVertexInputState = &vi_ci; 7444 gp_ci.pInputAssemblyState = &ia_ci; 7445 gp_ci.pViewportState = &vp_state_ci; 7446 gp_ci.pRasterizationState = &rs_ci; 7447 gp_ci.pColorBlendState = &cb_ci; 7448 gp_ci.pDynamicState = &dyn_state_ci; 7449 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; 7450 gp_ci.layout = pipeline_layout; 7451 gp_ci.renderPass = renderPass(); 7452 7453 VkPipelineCacheCreateInfo pc_ci = {}; 7454 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 7455 7456 VkPipeline pipeline; 7457 VkPipelineCache pipelineCache; 7458 7459 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache); 7460 ASSERT_VK_SUCCESS(err); 7461 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline); 7462 7463 m_errorMonitor->VerifyFound(); 7464 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL); 7465 7466 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to 65536"); 7467 7468 // Check too high (line width of 65536.0f). 7469 rs_ci.lineWidth = 65536.0f; 7470 7471 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache); 7472 ASSERT_VK_SUCCESS(err); 7473 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline); 7474 7475 m_errorMonitor->VerifyFound(); 7476 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL); 7477 7478 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to -1"); 7479 7480 dyn_state_ci.dynamicStateCount = 3; 7481 7482 rs_ci.lineWidth = 1.0f; 7483 7484 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache); 7485 ASSERT_VK_SUCCESS(err); 7486 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline); 7487 BeginCommandBuffer(); 7488 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); 7489 7490 // Check too low with dynamic setting. 7491 vkCmdSetLineWidth(m_commandBuffer->GetBufferHandle(), -1.0f); 7492 m_errorMonitor->VerifyFound(); 7493 7494 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempt to set lineWidth to 65536"); 7495 7496 // Check too high with dynamic setting. 7497 vkCmdSetLineWidth(m_commandBuffer->GetBufferHandle(), 65536.0f); 7498 m_errorMonitor->VerifyFound(); 7499 EndCommandBuffer(); 7500 7501 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL); 7502 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 7503 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 7504 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 7505 vkDestroyPipeline(m_device->device(), pipeline, NULL); 7506 } 7507 7508 TEST_F(VkLayerTest, NullRenderPass) { 7509 // Bind a NULL RenderPass 7510 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 7511 "You cannot use a NULL RenderPass object in vkCmdBeginRenderPass()"); 7512 7513 ASSERT_NO_FATAL_FAILURE(InitState()); 7514 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7515 7516 BeginCommandBuffer(); 7517 // Don't care about RenderPass handle b/c error should be flagged before 7518 // that 7519 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), NULL, VK_SUBPASS_CONTENTS_INLINE); 7520 7521 m_errorMonitor->VerifyFound(); 7522 } 7523 7524 TEST_F(VkLayerTest, RenderPassWithinRenderPass) { 7525 // Bind a BeginRenderPass within an active RenderPass 7526 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 7527 "It is invalid to issue this call inside an active render pass"); 7528 7529 ASSERT_NO_FATAL_FAILURE(InitState()); 7530 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7531 7532 BeginCommandBuffer(); 7533 // Just create a dummy Renderpass that's non-NULL so we can get to the 7534 // proper error 7535 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 7536 7537 m_errorMonitor->VerifyFound(); 7538 } 7539 7540 TEST_F(VkLayerTest, RenderPassClearOpMismatch) { 7541 TEST_DESCRIPTION("Begin a renderPass where clearValueCount is less than" 7542 "the number of renderPass attachments that use loadOp" 7543 "VK_ATTACHMENT_LOAD_OP_CLEAR."); 7544 7545 ASSERT_NO_FATAL_FAILURE(InitState()); 7546 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7547 7548 // Create a renderPass with a single attachment that uses loadOp CLEAR 7549 VkAttachmentReference attach = {}; 7550 attach.layout = VK_IMAGE_LAYOUT_GENERAL; 7551 VkSubpassDescription subpass = {}; 7552 subpass.inputAttachmentCount = 1; 7553 subpass.pInputAttachments = &attach; 7554 VkRenderPassCreateInfo rpci = {}; 7555 rpci.subpassCount = 1; 7556 rpci.pSubpasses = &subpass; 7557 rpci.attachmentCount = 1; 7558 VkAttachmentDescription attach_desc = {}; 7559 attach_desc.format = VK_FORMAT_UNDEFINED; 7560 // Set loadOp to CLEAR 7561 attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 7562 rpci.pAttachments = &attach_desc; 7563 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 7564 VkRenderPass rp; 7565 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 7566 7567 VkCommandBufferInheritanceInfo hinfo = {}; 7568 hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; 7569 hinfo.renderPass = VK_NULL_HANDLE; 7570 hinfo.subpass = 0; 7571 hinfo.framebuffer = VK_NULL_HANDLE; 7572 hinfo.occlusionQueryEnable = VK_FALSE; 7573 hinfo.queryFlags = 0; 7574 hinfo.pipelineStatistics = 0; 7575 VkCommandBufferBeginInfo info = {}; 7576 info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; 7577 info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 7578 info.pInheritanceInfo = &hinfo; 7579 7580 vkBeginCommandBuffer(m_commandBuffer->handle(), &info); 7581 VkRenderPassBeginInfo rp_begin = {}; 7582 rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; 7583 rp_begin.pNext = NULL; 7584 rp_begin.renderPass = renderPass(); 7585 rp_begin.framebuffer = framebuffer(); 7586 rp_begin.clearValueCount = 0; // Should be 1 7587 7588 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " has a clearValueCount of 0 but " 7589 "there must be at least 1 entries in " 7590 "pClearValues array to account for "); 7591 7592 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &rp_begin, VK_SUBPASS_CONTENTS_INLINE); 7593 7594 m_errorMonitor->VerifyFound(); 7595 7596 vkDestroyRenderPass(m_device->device(), rp, NULL); 7597 } 7598 7599 TEST_F(VkLayerTest, EndCommandBufferWithinRenderPass) { 7600 7601 TEST_DESCRIPTION("End a command buffer with an active render pass"); 7602 7603 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 7604 "It is invalid to issue this call inside an active render pass"); 7605 7606 ASSERT_NO_FATAL_FAILURE(InitState()); 7607 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7608 7609 // The framework's BeginCommandBuffer calls CreateRenderPass 7610 BeginCommandBuffer(); 7611 7612 // Call directly into vkEndCommandBuffer instead of the 7613 // the framework's EndCommandBuffer, which inserts a 7614 // vkEndRenderPass 7615 vkEndCommandBuffer(m_commandBuffer->GetBufferHandle()); 7616 7617 m_errorMonitor->VerifyFound(); 7618 7619 // TODO: Add test for VK_COMMAND_BUFFER_LEVEL_SECONDARY 7620 // TODO: Add test for VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT 7621 } 7622 7623 TEST_F(VkLayerTest, FillBufferWithinRenderPass) { 7624 // Call CmdFillBuffer within an active renderpass 7625 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 7626 "It is invalid to issue this call inside an active render pass"); 7627 7628 ASSERT_NO_FATAL_FAILURE(InitState()); 7629 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7630 7631 // Renderpass is started here 7632 BeginCommandBuffer(); 7633 7634 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; 7635 vk_testing::Buffer dstBuffer; 7636 dstBuffer.init_as_dst(*m_device, (VkDeviceSize)1024, reqs); 7637 7638 m_commandBuffer->FillBuffer(dstBuffer.handle(), 0, 4, 0x11111111); 7639 7640 m_errorMonitor->VerifyFound(); 7641 } 7642 7643 TEST_F(VkLayerTest, UpdateBufferWithinRenderPass) { 7644 // Call CmdUpdateBuffer within an active renderpass 7645 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 7646 "It is invalid to issue this call inside an active render pass"); 7647 7648 ASSERT_NO_FATAL_FAILURE(InitState()); 7649 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7650 7651 // Renderpass is started here 7652 BeginCommandBuffer(); 7653 7654 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; 7655 vk_testing::Buffer dstBuffer; 7656 dstBuffer.init_as_dst(*m_device, (VkDeviceSize)1024, reqs); 7657 7658 VkDeviceSize dstOffset = 0; 7659 VkDeviceSize dataSize = 1024; 7660 const void *pData = NULL; 7661 7662 vkCmdUpdateBuffer(m_commandBuffer->GetBufferHandle(), dstBuffer.handle(), dstOffset, dataSize, pData); 7663 7664 m_errorMonitor->VerifyFound(); 7665 } 7666 7667 TEST_F(VkLayerTest, ClearColorImageWithinRenderPass) { 7668 // Call CmdClearColorImage within an active RenderPass 7669 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 7670 "It is invalid to issue this call inside an active render pass"); 7671 7672 ASSERT_NO_FATAL_FAILURE(InitState()); 7673 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7674 7675 // Renderpass is started here 7676 BeginCommandBuffer(); 7677 7678 VkClearColorValue clear_color; 7679 memset(clear_color.uint32, 0, sizeof(uint32_t) * 4); 7680 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; 7681 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 7682 const int32_t tex_width = 32; 7683 const int32_t tex_height = 32; 7684 VkImageCreateInfo image_create_info = {}; 7685 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 7686 image_create_info.pNext = NULL; 7687 image_create_info.imageType = VK_IMAGE_TYPE_2D; 7688 image_create_info.format = tex_format; 7689 image_create_info.extent.width = tex_width; 7690 image_create_info.extent.height = tex_height; 7691 image_create_info.extent.depth = 1; 7692 image_create_info.mipLevels = 1; 7693 image_create_info.arrayLayers = 1; 7694 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 7695 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 7696 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 7697 7698 vk_testing::Image dstImage; 7699 dstImage.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs); 7700 7701 const VkImageSubresourceRange range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT); 7702 7703 vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &range); 7704 7705 m_errorMonitor->VerifyFound(); 7706 } 7707 7708 TEST_F(VkLayerTest, ClearDepthStencilImageWithinRenderPass) { 7709 // Call CmdClearDepthStencilImage within an active RenderPass 7710 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 7711 "It is invalid to issue this call inside an active render pass"); 7712 7713 ASSERT_NO_FATAL_FAILURE(InitState()); 7714 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7715 7716 // Renderpass is started here 7717 BeginCommandBuffer(); 7718 7719 VkClearDepthStencilValue clear_value = {0}; 7720 VkMemoryPropertyFlags reqs = 0; 7721 VkImageCreateInfo image_create_info = vk_testing::Image::create_info(); 7722 image_create_info.imageType = VK_IMAGE_TYPE_2D; 7723 image_create_info.format = VK_FORMAT_D24_UNORM_S8_UINT; 7724 image_create_info.extent.width = 64; 7725 image_create_info.extent.height = 64; 7726 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 7727 image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; 7728 7729 vk_testing::Image dstImage; 7730 dstImage.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs); 7731 7732 const VkImageSubresourceRange range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT); 7733 7734 vkCmdClearDepthStencilImage(m_commandBuffer->GetBufferHandle(), dstImage.handle(), 7735 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, &clear_value, 1, &range); 7736 7737 m_errorMonitor->VerifyFound(); 7738 } 7739 7740 TEST_F(VkLayerTest, ClearColorAttachmentsOutsideRenderPass) { 7741 // Call CmdClearAttachmentss outside of an active RenderPass 7742 VkResult err; 7743 7744 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearAttachments(): This call " 7745 "must be issued inside an active " 7746 "render pass"); 7747 7748 ASSERT_NO_FATAL_FAILURE(InitState()); 7749 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7750 7751 // Start no RenderPass 7752 err = m_commandBuffer->BeginCommandBuffer(); 7753 ASSERT_VK_SUCCESS(err); 7754 7755 VkClearAttachment color_attachment; 7756 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 7757 color_attachment.clearValue.color.float32[0] = 0; 7758 color_attachment.clearValue.color.float32[1] = 0; 7759 color_attachment.clearValue.color.float32[2] = 0; 7760 color_attachment.clearValue.color.float32[3] = 0; 7761 color_attachment.colorAttachment = 0; 7762 VkClearRect clear_rect = {{{0, 0}, {32, 32}}}; 7763 vkCmdClearAttachments(m_commandBuffer->GetBufferHandle(), 1, &color_attachment, 1, &clear_rect); 7764 7765 m_errorMonitor->VerifyFound(); 7766 } 7767 7768 TEST_F(VkLayerTest, RenderPassExcessiveNextSubpass) { 7769 TEST_DESCRIPTION("Test that an error is produced when CmdNextSubpass is " 7770 "called too many times in a renderpass instance"); 7771 7772 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdNextSubpass(): Attempted to advance " 7773 "beyond final subpass"); 7774 7775 ASSERT_NO_FATAL_FAILURE(InitState()); 7776 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7777 7778 BeginCommandBuffer(); 7779 7780 // error here. 7781 vkCmdNextSubpass(m_commandBuffer->GetBufferHandle(), VK_SUBPASS_CONTENTS_INLINE); 7782 m_errorMonitor->VerifyFound(); 7783 7784 EndCommandBuffer(); 7785 } 7786 7787 TEST_F(VkLayerTest, RenderPassEndedBeforeFinalSubpass) { 7788 TEST_DESCRIPTION("Test that an error is produced when CmdEndRenderPass is " 7789 "called before the final subpass has been reached"); 7790 7791 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdEndRenderPass(): Called before reaching " 7792 "final subpass"); 7793 7794 ASSERT_NO_FATAL_FAILURE(InitState()); 7795 VkSubpassDescription sd[2] = {{0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}, 7796 {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr}}; 7797 7798 VkRenderPassCreateInfo rcpi = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 2, sd, 0, nullptr}; 7799 7800 VkRenderPass rp; 7801 VkResult err = vkCreateRenderPass(m_device->device(), &rcpi, nullptr, &rp); 7802 ASSERT_VK_SUCCESS(err); 7803 7804 VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 16, 16, 1}; 7805 7806 VkFramebuffer fb; 7807 err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb); 7808 ASSERT_VK_SUCCESS(err); 7809 7810 m_commandBuffer->BeginCommandBuffer(); // no implicit RP begin 7811 7812 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {16, 16}}, 0, nullptr}; 7813 7814 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); 7815 7816 // Error here. 7817 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); 7818 m_errorMonitor->VerifyFound(); 7819 7820 // Clean up. 7821 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 7822 vkDestroyRenderPass(m_device->device(), rp, nullptr); 7823 } 7824 7825 TEST_F(VkLayerTest, BufferMemoryBarrierNoBuffer) { 7826 // Try to add a buffer memory barrier with no buffer. 7827 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 7828 "required parameter pBufferMemoryBarriers[0].buffer specified as VK_NULL_HANDLE"); 7829 7830 ASSERT_NO_FATAL_FAILURE(InitState()); 7831 BeginCommandBuffer(); 7832 7833 VkBufferMemoryBarrier buf_barrier = {}; 7834 buf_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; 7835 buf_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; 7836 buf_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 7837 buf_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 7838 buf_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 7839 buf_barrier.buffer = VK_NULL_HANDLE; 7840 buf_barrier.offset = 0; 7841 buf_barrier.size = VK_WHOLE_SIZE; 7842 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, 7843 nullptr, 1, &buf_barrier, 0, nullptr); 7844 7845 m_errorMonitor->VerifyFound(); 7846 } 7847 7848 TEST_F(VkLayerTest, InvalidBarriers) { 7849 TEST_DESCRIPTION("A variety of ways to get VK_INVALID_BARRIER "); 7850 7851 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Barriers cannot be set during subpass"); 7852 7853 ASSERT_NO_FATAL_FAILURE(InitState()); 7854 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 7855 7856 VkMemoryBarrier mem_barrier = {}; 7857 mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; 7858 mem_barrier.pNext = NULL; 7859 mem_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; 7860 mem_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 7861 BeginCommandBuffer(); 7862 // BeginCommandBuffer() starts a render pass 7863 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 1, 7864 &mem_barrier, 0, nullptr, 0, nullptr); 7865 m_errorMonitor->VerifyFound(); 7866 7867 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image Layout cannot be transitioned to UNDEFINED"); 7868 VkImageObj image(m_device); 7869 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 7870 ASSERT_TRUE(image.initialized()); 7871 VkImageMemoryBarrier img_barrier = {}; 7872 img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 7873 img_barrier.pNext = NULL; 7874 img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; 7875 img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 7876 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 7877 // New layout can't be UNDEFINED 7878 img_barrier.newLayout = VK_IMAGE_LAYOUT_UNDEFINED; 7879 img_barrier.image = image.handle(); 7880 img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 7881 img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 7882 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 7883 img_barrier.subresourceRange.baseArrayLayer = 0; 7884 img_barrier.subresourceRange.baseMipLevel = 0; 7885 img_barrier.subresourceRange.layerCount = 1; 7886 img_barrier.subresourceRange.levelCount = 1; 7887 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, 7888 nullptr, 0, nullptr, 1, &img_barrier); 7889 m_errorMonitor->VerifyFound(); 7890 img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 7891 7892 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Subresource must have the sum of the " 7893 "baseArrayLayer"); 7894 // baseArrayLayer + layerCount must be <= image's arrayLayers 7895 img_barrier.subresourceRange.baseArrayLayer = 1; 7896 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, 7897 nullptr, 0, nullptr, 1, &img_barrier); 7898 m_errorMonitor->VerifyFound(); 7899 img_barrier.subresourceRange.baseArrayLayer = 0; 7900 7901 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Subresource must have the sum of the baseMipLevel"); 7902 // baseMipLevel + levelCount must be <= image's mipLevels 7903 img_barrier.subresourceRange.baseMipLevel = 1; 7904 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, 7905 nullptr, 0, nullptr, 1, &img_barrier); 7906 m_errorMonitor->VerifyFound(); 7907 img_barrier.subresourceRange.baseMipLevel = 0; 7908 7909 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Buffer Barriers cannot be used during a render pass"); 7910 vk_testing::Buffer buffer; 7911 buffer.init(*m_device, 256); 7912 VkBufferMemoryBarrier buf_barrier = {}; 7913 buf_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; 7914 buf_barrier.pNext = NULL; 7915 buf_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; 7916 buf_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 7917 buf_barrier.buffer = buffer.handle(); 7918 buf_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 7919 buf_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 7920 buf_barrier.offset = 0; 7921 buf_barrier.size = VK_WHOLE_SIZE; 7922 // Can't send buffer barrier during a render pass 7923 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, 7924 nullptr, 1, &buf_barrier, 0, nullptr); 7925 m_errorMonitor->VerifyFound(); 7926 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); 7927 7928 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "which is not less than total size"); 7929 buf_barrier.offset = 257; 7930 // Offset greater than total size 7931 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, 7932 nullptr, 1, &buf_barrier, 0, nullptr); 7933 m_errorMonitor->VerifyFound(); 7934 buf_barrier.offset = 0; 7935 7936 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "whose sum is greater than total size"); 7937 buf_barrier.size = 257; 7938 // Size greater than total size 7939 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, 7940 nullptr, 1, &buf_barrier, 0, nullptr); 7941 m_errorMonitor->VerifyFound(); 7942 7943 // Now exercise barrier aspect bit errors, first DS 7944 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a depth and stencil format and thus must " 7945 "have either one or both of VK_IMAGE_ASPECT_DEPTH_BIT and " 7946 "VK_IMAGE_ASPECT_STENCIL_BIT set."); 7947 VkDepthStencilObj ds_image(m_device); 7948 ds_image.Init(m_device, 128, 128, VK_FORMAT_D24_UNORM_S8_UINT); 7949 ASSERT_TRUE(ds_image.initialized()); 7950 img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 7951 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; 7952 img_barrier.image = ds_image.handle(); 7953 // Use of COLOR aspect on DS image is error 7954 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 7955 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, 7956 nullptr, 0, nullptr, 1, &img_barrier); 7957 m_errorMonitor->VerifyFound(); 7958 // Now test depth-only 7959 VkFormatProperties format_props; 7960 7961 vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D16_UNORM, &format_props); 7962 if (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) { 7963 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a depth-only format and thus must " 7964 "have VK_IMAGE_ASPECT_DEPTH_BIT set."); 7965 VkDepthStencilObj d_image(m_device); 7966 d_image.Init(m_device, 128, 128, VK_FORMAT_D16_UNORM); 7967 ASSERT_TRUE(d_image.initialized()); 7968 img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 7969 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; 7970 img_barrier.image = d_image.handle(); 7971 // Use of COLOR aspect on depth image is error 7972 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 7973 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 7974 0, nullptr, 0, nullptr, 1, &img_barrier); 7975 m_errorMonitor->VerifyFound(); 7976 } 7977 vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_S8_UINT, &format_props); 7978 if (format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) { 7979 // Now test stencil-only 7980 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a stencil-only format and thus must " 7981 "have VK_IMAGE_ASPECT_STENCIL_BIT set."); 7982 VkDepthStencilObj s_image(m_device); 7983 s_image.Init(m_device, 128, 128, VK_FORMAT_S8_UINT); 7984 ASSERT_TRUE(s_image.initialized()); 7985 img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 7986 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; 7987 img_barrier.image = s_image.handle(); 7988 // Use of COLOR aspect on depth image is error 7989 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 7990 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 7991 0, nullptr, 0, nullptr, 1, &img_barrier); 7992 m_errorMonitor->VerifyFound(); 7993 } 7994 // Finally test color 7995 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a color format and thus must " 7996 "have VK_IMAGE_ASPECT_COLOR_BIT set."); 7997 VkImageObj c_image(m_device); 7998 c_image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 7999 ASSERT_TRUE(c_image.initialized()); 8000 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 8001 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; 8002 img_barrier.image = c_image.handle(); 8003 // Set aspect to depth (non-color) 8004 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 8005 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, 8006 nullptr, 0, nullptr, 1, &img_barrier); 8007 m_errorMonitor->VerifyFound(); 8008 } 8009 8010 TEST_F(VkLayerTest, LayoutFromPresentWithoutAccessMemoryRead) { 8011 // Transition an image away from PRESENT_SRC_KHR without ACCESS_MEMORY_READ in srcAccessMask 8012 8013 m_errorMonitor->SetDesiredFailureMsg( 8014 VK_DEBUG_REPORT_WARNING_BIT_EXT, 8015 "must have required access bit"); 8016 ASSERT_NO_FATAL_FAILURE(InitState()); 8017 VkImageObj image(m_device); 8018 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 8019 ASSERT_TRUE(image.initialized()); 8020 8021 VkImageMemoryBarrier barrier = {}; 8022 VkImageSubresourceRange range; 8023 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 8024 barrier.srcAccessMask = 0; 8025 barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 8026 barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; 8027 barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 8028 barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; 8029 barrier.image = image.handle(); 8030 range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 8031 range.baseMipLevel = 0; 8032 range.levelCount = 1; 8033 range.baseArrayLayer = 0; 8034 range.layerCount = 1; 8035 barrier.subresourceRange = range; 8036 VkCommandBufferObj cmdbuf(m_device, m_commandPool); 8037 cmdbuf.BeginCommandBuffer(); 8038 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, 8039 &barrier); 8040 barrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; 8041 barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 8042 barrier.srcAccessMask = 0; 8043 barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 8044 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, 8045 &barrier); 8046 8047 m_errorMonitor->VerifyFound(); 8048 } 8049 8050 TEST_F(VkLayerTest, IdxBufferAlignmentError) { 8051 // Bind a BeginRenderPass within an active RenderPass 8052 VkResult err; 8053 8054 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdBindIndexBuffer() offset (0x7) does not fall on "); 8055 8056 ASSERT_NO_FATAL_FAILURE(InitState()); 8057 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 8058 uint32_t qfi = 0; 8059 VkBufferCreateInfo buffCI = {}; 8060 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 8061 buffCI.size = 1024; 8062 buffCI.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT; 8063 buffCI.queueFamilyIndexCount = 1; 8064 buffCI.pQueueFamilyIndices = &qfi; 8065 8066 VkBuffer ib; 8067 err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &ib); 8068 ASSERT_VK_SUCCESS(err); 8069 8070 BeginCommandBuffer(); 8071 ASSERT_VK_SUCCESS(err); 8072 // vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), 8073 // VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 8074 // Should error before calling to driver so don't care about actual data 8075 vkCmdBindIndexBuffer(m_commandBuffer->GetBufferHandle(), ib, 7, VK_INDEX_TYPE_UINT16); 8076 8077 m_errorMonitor->VerifyFound(); 8078 8079 vkDestroyBuffer(m_device->device(), ib, NULL); 8080 } 8081 8082 TEST_F(VkLayerTest, InvalidQueueFamilyIndex) { 8083 // Create an out-of-range queueFamilyIndex 8084 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 8085 "vkCreateBuffer: pCreateInfo->pQueueFamilyIndices[0] (777) must be one " 8086 "of the indices specified when the device was created, via the " 8087 "VkDeviceQueueCreateInfo structure."); 8088 8089 ASSERT_NO_FATAL_FAILURE(InitState()); 8090 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 8091 VkBufferCreateInfo buffCI = {}; 8092 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 8093 buffCI.size = 1024; 8094 buffCI.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT; 8095 buffCI.queueFamilyIndexCount = 1; 8096 // Introduce failure by specifying invalid queue_family_index 8097 uint32_t qfi = 777; 8098 buffCI.pQueueFamilyIndices = &qfi; 8099 buffCI.sharingMode = VK_SHARING_MODE_CONCURRENT; // qfi only matters in CONCURRENT mode 8100 8101 VkBuffer ib; 8102 vkCreateBuffer(m_device->device(), &buffCI, NULL, &ib); 8103 8104 m_errorMonitor->VerifyFound(); 8105 vkDestroyBuffer(m_device->device(), ib, NULL); 8106 } 8107 8108 TEST_F(VkLayerTest, ExecuteCommandsPrimaryCB) { 8109 TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a primary command buffer" 8110 " (should only be secondary)"); 8111 8112 ASSERT_NO_FATAL_FAILURE(InitState()); 8113 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 8114 8115 // An empty primary command buffer 8116 VkCommandBufferObj cb(m_device, m_commandPool); 8117 cb.BeginCommandBuffer(); 8118 cb.EndCommandBuffer(); 8119 8120 m_commandBuffer->BeginCommandBuffer(); 8121 vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); 8122 VkCommandBuffer handle = cb.handle(); 8123 8124 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdExecuteCommands() called w/ Primary Cmd Buffer "); 8125 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &handle); 8126 m_errorMonitor->VerifyFound(); 8127 } 8128 8129 TEST_F(VkLayerTest, DSUsageBitsErrors) { 8130 TEST_DESCRIPTION("Attempt to update descriptor sets for images and buffers " 8131 "that do not have correct usage bits sets."); 8132 VkResult err; 8133 8134 ASSERT_NO_FATAL_FAILURE(InitState()); 8135 VkDescriptorPoolSize ds_type_count[VK_DESCRIPTOR_TYPE_RANGE_SIZE] = {}; 8136 for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) { 8137 ds_type_count[i].type = VkDescriptorType(i); 8138 ds_type_count[i].descriptorCount = 1; 8139 } 8140 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 8141 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 8142 ds_pool_ci.pNext = NULL; 8143 ds_pool_ci.maxSets = VK_DESCRIPTOR_TYPE_RANGE_SIZE; 8144 ds_pool_ci.poolSizeCount = VK_DESCRIPTOR_TYPE_RANGE_SIZE; 8145 ds_pool_ci.pPoolSizes = ds_type_count; 8146 8147 VkDescriptorPool ds_pool; 8148 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 8149 ASSERT_VK_SUCCESS(err); 8150 8151 // Create 10 layouts where each has a single descriptor of different type 8152 VkDescriptorSetLayoutBinding dsl_binding[VK_DESCRIPTOR_TYPE_RANGE_SIZE] = {}; 8153 for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) { 8154 dsl_binding[i].binding = 0; 8155 dsl_binding[i].descriptorType = VkDescriptorType(i); 8156 dsl_binding[i].descriptorCount = 1; 8157 dsl_binding[i].stageFlags = VK_SHADER_STAGE_ALL; 8158 dsl_binding[i].pImmutableSamplers = NULL; 8159 } 8160 8161 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 8162 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 8163 ds_layout_ci.pNext = NULL; 8164 ds_layout_ci.bindingCount = 1; 8165 VkDescriptorSetLayout ds_layouts[VK_DESCRIPTOR_TYPE_RANGE_SIZE]; 8166 for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) { 8167 ds_layout_ci.pBindings = dsl_binding + i; 8168 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, ds_layouts + i); 8169 ASSERT_VK_SUCCESS(err); 8170 } 8171 VkDescriptorSet descriptor_sets[VK_DESCRIPTOR_TYPE_RANGE_SIZE] = {}; 8172 VkDescriptorSetAllocateInfo alloc_info = {}; 8173 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 8174 alloc_info.descriptorSetCount = VK_DESCRIPTOR_TYPE_RANGE_SIZE; 8175 alloc_info.descriptorPool = ds_pool; 8176 alloc_info.pSetLayouts = ds_layouts; 8177 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, descriptor_sets); 8178 ASSERT_VK_SUCCESS(err); 8179 8180 // Create a buffer & bufferView to be used for invalid updates 8181 VkBufferCreateInfo buff_ci = {}; 8182 buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 8183 // This usage is not valid for any descriptor type 8184 buff_ci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; 8185 buff_ci.size = 256; 8186 buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 8187 VkBuffer buffer; 8188 err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer); 8189 ASSERT_VK_SUCCESS(err); 8190 8191 VkBufferViewCreateInfo buff_view_ci = {}; 8192 buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; 8193 buff_view_ci.buffer = buffer; 8194 buff_view_ci.format = VK_FORMAT_R8_UNORM; 8195 buff_view_ci.range = VK_WHOLE_SIZE; 8196 VkBufferView buff_view; 8197 err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buff_view); 8198 ASSERT_VK_SUCCESS(err); 8199 8200 // Create an image to be used for invalid updates 8201 VkImageCreateInfo image_ci = {}; 8202 image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 8203 image_ci.imageType = VK_IMAGE_TYPE_2D; 8204 image_ci.format = VK_FORMAT_R8G8B8A8_UNORM; 8205 image_ci.extent.width = 64; 8206 image_ci.extent.height = 64; 8207 image_ci.extent.depth = 1; 8208 image_ci.mipLevels = 1; 8209 image_ci.arrayLayers = 1; 8210 image_ci.samples = VK_SAMPLE_COUNT_1_BIT; 8211 image_ci.tiling = VK_IMAGE_TILING_LINEAR; 8212 image_ci.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; 8213 // This usage is not valid for any descriptor type 8214 image_ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 8215 image_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 8216 VkImage image; 8217 err = vkCreateImage(m_device->device(), &image_ci, NULL, &image); 8218 ASSERT_VK_SUCCESS(err); 8219 // Bind memory to image 8220 VkMemoryRequirements mem_reqs; 8221 VkDeviceMemory image_mem; 8222 bool pass; 8223 VkMemoryAllocateInfo mem_alloc = {}; 8224 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 8225 mem_alloc.pNext = NULL; 8226 mem_alloc.allocationSize = 0; 8227 mem_alloc.memoryTypeIndex = 0; 8228 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs); 8229 mem_alloc.allocationSize = mem_reqs.size; 8230 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0); 8231 ASSERT_TRUE(pass); 8232 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem); 8233 ASSERT_VK_SUCCESS(err); 8234 err = vkBindImageMemory(m_device->device(), image, image_mem, 0); 8235 ASSERT_VK_SUCCESS(err); 8236 // Now create view for image 8237 VkImageViewCreateInfo image_view_ci = {}; 8238 image_view_ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 8239 image_view_ci.image = image; 8240 image_view_ci.format = VK_FORMAT_R8G8B8A8_UNORM; 8241 image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D; 8242 image_view_ci.subresourceRange.layerCount = 1; 8243 image_view_ci.subresourceRange.baseArrayLayer = 0; 8244 image_view_ci.subresourceRange.levelCount = 1; 8245 image_view_ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 8246 VkImageView image_view; 8247 err = vkCreateImageView(m_device->device(), &image_view_ci, NULL, &image_view); 8248 ASSERT_VK_SUCCESS(err); 8249 8250 VkDescriptorBufferInfo buff_info = {}; 8251 buff_info.buffer = buffer; 8252 VkDescriptorImageInfo img_info = {}; 8253 img_info.imageView = image_view; 8254 VkWriteDescriptorSet descriptor_write = {}; 8255 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 8256 descriptor_write.dstBinding = 0; 8257 descriptor_write.descriptorCount = 1; 8258 descriptor_write.pTexelBufferView = &buff_view; 8259 descriptor_write.pBufferInfo = &buff_info; 8260 descriptor_write.pImageInfo = &img_info; 8261 8262 // These error messages align with VkDescriptorType struct 8263 const char *error_msgs[] = {"", // placeholder, no error for SAMPLER descriptor 8264 " does not have VK_IMAGE_USAGE_SAMPLED_BIT set.", 8265 " does not have VK_IMAGE_USAGE_SAMPLED_BIT set.", 8266 " does not have VK_IMAGE_USAGE_STORAGE_BIT set.", 8267 " does not have VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT set.", 8268 " does not have VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT set.", 8269 " does not have VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT set.", 8270 " does not have VK_BUFFER_USAGE_STORAGE_BUFFER_BIT set.", 8271 " does not have VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT set.", 8272 " does not have VK_BUFFER_USAGE_STORAGE_BUFFER_BIT set.", 8273 " does not have VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set."}; 8274 // Start loop at 1 as SAMPLER desc type has no usage bit error 8275 for (uint32_t i = 1; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) { 8276 descriptor_write.descriptorType = VkDescriptorType(i); 8277 descriptor_write.dstSet = descriptor_sets[i]; 8278 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error_msgs[i]); 8279 8280 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 8281 8282 m_errorMonitor->VerifyFound(); 8283 vkDestroyDescriptorSetLayout(m_device->device(), ds_layouts[i], NULL); 8284 } 8285 vkDestroyDescriptorSetLayout(m_device->device(), ds_layouts[0], NULL); 8286 vkDestroyImage(m_device->device(), image, NULL); 8287 vkFreeMemory(m_device->device(), image_mem, NULL); 8288 vkDestroyImageView(m_device->device(), image_view, NULL); 8289 vkDestroyBuffer(m_device->device(), buffer, NULL); 8290 vkDestroyBufferView(m_device->device(), buff_view, NULL); 8291 vkFreeDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_TYPE_RANGE_SIZE, descriptor_sets); 8292 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 8293 } 8294 8295 TEST_F(VkLayerTest, DSBufferInfoErrors) { 8296 TEST_DESCRIPTION("Attempt to update buffer descriptor set that has incorrect " 8297 "parameters in VkDescriptorBufferInfo struct. This includes:\n" 8298 "1. offset value greater than buffer size\n" 8299 "2. range value of 0\n" 8300 "3. range value greater than buffer (size - offset)"); 8301 VkResult err; 8302 8303 ASSERT_NO_FATAL_FAILURE(InitState()); 8304 VkDescriptorPoolSize ds_type_count = {}; 8305 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 8306 ds_type_count.descriptorCount = 1; 8307 8308 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 8309 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 8310 ds_pool_ci.pNext = NULL; 8311 ds_pool_ci.maxSets = 1; 8312 ds_pool_ci.poolSizeCount = 1; 8313 ds_pool_ci.pPoolSizes = &ds_type_count; 8314 8315 VkDescriptorPool ds_pool; 8316 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 8317 ASSERT_VK_SUCCESS(err); 8318 8319 // Create layout with single uniform buffer descriptor 8320 VkDescriptorSetLayoutBinding dsl_binding = {}; 8321 dsl_binding.binding = 0; 8322 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 8323 dsl_binding.descriptorCount = 1; 8324 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 8325 dsl_binding.pImmutableSamplers = NULL; 8326 8327 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 8328 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 8329 ds_layout_ci.pNext = NULL; 8330 ds_layout_ci.bindingCount = 1; 8331 ds_layout_ci.pBindings = &dsl_binding; 8332 VkDescriptorSetLayout ds_layout; 8333 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 8334 ASSERT_VK_SUCCESS(err); 8335 8336 VkDescriptorSet descriptor_set = {}; 8337 VkDescriptorSetAllocateInfo alloc_info = {}; 8338 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 8339 alloc_info.descriptorSetCount = 1; 8340 alloc_info.descriptorPool = ds_pool; 8341 alloc_info.pSetLayouts = &ds_layout; 8342 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set); 8343 ASSERT_VK_SUCCESS(err); 8344 8345 // Create a buffer to be used for invalid updates 8346 VkBufferCreateInfo buff_ci = {}; 8347 buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 8348 buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 8349 buff_ci.size = 256; 8350 buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 8351 VkBuffer buffer; 8352 err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer); 8353 ASSERT_VK_SUCCESS(err); 8354 // Have to bind memory to buffer before descriptor update 8355 VkMemoryAllocateInfo mem_alloc = {}; 8356 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 8357 mem_alloc.pNext = NULL; 8358 mem_alloc.allocationSize = 256; 8359 mem_alloc.memoryTypeIndex = 0; 8360 8361 VkMemoryRequirements mem_reqs; 8362 vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs); 8363 bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0); 8364 if (!pass) { 8365 vkDestroyBuffer(m_device->device(), buffer, NULL); 8366 return; 8367 } 8368 8369 VkDeviceMemory mem; 8370 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem); 8371 ASSERT_VK_SUCCESS(err); 8372 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0); 8373 ASSERT_VK_SUCCESS(err); 8374 8375 VkDescriptorBufferInfo buff_info = {}; 8376 buff_info.buffer = buffer; 8377 // First make offset 1 larger than buffer size 8378 buff_info.offset = 257; 8379 buff_info.range = VK_WHOLE_SIZE; 8380 VkWriteDescriptorSet descriptor_write = {}; 8381 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 8382 descriptor_write.dstBinding = 0; 8383 descriptor_write.descriptorCount = 1; 8384 descriptor_write.pTexelBufferView = nullptr; 8385 descriptor_write.pBufferInfo = &buff_info; 8386 descriptor_write.pImageInfo = nullptr; 8387 8388 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 8389 descriptor_write.dstSet = descriptor_set; 8390 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " offset of 257 is greater than buffer "); 8391 8392 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 8393 8394 m_errorMonitor->VerifyFound(); 8395 // Now cause error due to range of 0 8396 buff_info.offset = 0; 8397 buff_info.range = 0; 8398 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 8399 " range is not VK_WHOLE_SIZE and is zero, which is not allowed."); 8400 8401 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 8402 8403 m_errorMonitor->VerifyFound(); 8404 // Now cause error due to range exceeding buffer size - offset 8405 buff_info.offset = 128; 8406 buff_info.range = 200; 8407 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " range is 200 which is greater than buffer size "); 8408 8409 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 8410 8411 m_errorMonitor->VerifyFound(); 8412 vkFreeMemory(m_device->device(), mem, NULL); 8413 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 8414 vkDestroyBuffer(m_device->device(), buffer, NULL); 8415 vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set); 8416 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 8417 } 8418 8419 TEST_F(VkLayerTest, DSAspectBitsErrors) { 8420 // TODO : Initially only catching case where DEPTH & STENCIL aspect bits 8421 // are set, but could expand this test to hit more cases. 8422 TEST_DESCRIPTION("Attempt to update descriptor sets for images " 8423 "that do not have correct aspect bits sets."); 8424 VkResult err; 8425 8426 ASSERT_NO_FATAL_FAILURE(InitState()); 8427 VkDescriptorPoolSize ds_type_count = {}; 8428 ds_type_count.type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; 8429 ds_type_count.descriptorCount = 1; 8430 8431 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 8432 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 8433 ds_pool_ci.pNext = NULL; 8434 ds_pool_ci.maxSets = 5; 8435 ds_pool_ci.poolSizeCount = 1; 8436 ds_pool_ci.pPoolSizes = &ds_type_count; 8437 8438 VkDescriptorPool ds_pool; 8439 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 8440 ASSERT_VK_SUCCESS(err); 8441 8442 VkDescriptorSetLayoutBinding dsl_binding = {}; 8443 dsl_binding.binding = 0; 8444 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; 8445 dsl_binding.descriptorCount = 1; 8446 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 8447 dsl_binding.pImmutableSamplers = NULL; 8448 8449 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 8450 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 8451 ds_layout_ci.pNext = NULL; 8452 ds_layout_ci.bindingCount = 1; 8453 ds_layout_ci.pBindings = &dsl_binding; 8454 VkDescriptorSetLayout ds_layout; 8455 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 8456 ASSERT_VK_SUCCESS(err); 8457 8458 VkDescriptorSet descriptor_set = {}; 8459 VkDescriptorSetAllocateInfo alloc_info = {}; 8460 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 8461 alloc_info.descriptorSetCount = 1; 8462 alloc_info.descriptorPool = ds_pool; 8463 alloc_info.pSetLayouts = &ds_layout; 8464 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set); 8465 ASSERT_VK_SUCCESS(err); 8466 8467 // Create an image to be used for invalid updates 8468 VkImageCreateInfo image_ci = {}; 8469 image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 8470 image_ci.imageType = VK_IMAGE_TYPE_2D; 8471 image_ci.format = VK_FORMAT_D24_UNORM_S8_UINT; 8472 image_ci.extent.width = 64; 8473 image_ci.extent.height = 64; 8474 image_ci.extent.depth = 1; 8475 image_ci.mipLevels = 1; 8476 image_ci.arrayLayers = 1; 8477 image_ci.samples = VK_SAMPLE_COUNT_1_BIT; 8478 image_ci.tiling = VK_IMAGE_TILING_LINEAR; 8479 image_ci.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; 8480 image_ci.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 8481 image_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 8482 VkImage image; 8483 err = vkCreateImage(m_device->device(), &image_ci, NULL, &image); 8484 ASSERT_VK_SUCCESS(err); 8485 // Bind memory to image 8486 VkMemoryRequirements mem_reqs; 8487 VkDeviceMemory image_mem; 8488 bool pass; 8489 VkMemoryAllocateInfo mem_alloc = {}; 8490 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 8491 mem_alloc.pNext = NULL; 8492 mem_alloc.allocationSize = 0; 8493 mem_alloc.memoryTypeIndex = 0; 8494 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs); 8495 mem_alloc.allocationSize = mem_reqs.size; 8496 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0); 8497 ASSERT_TRUE(pass); 8498 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem); 8499 ASSERT_VK_SUCCESS(err); 8500 err = vkBindImageMemory(m_device->device(), image, image_mem, 0); 8501 ASSERT_VK_SUCCESS(err); 8502 // Now create view for image 8503 VkImageViewCreateInfo image_view_ci = {}; 8504 image_view_ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 8505 image_view_ci.image = image; 8506 image_view_ci.format = VK_FORMAT_D24_UNORM_S8_UINT; 8507 image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D; 8508 image_view_ci.subresourceRange.layerCount = 1; 8509 image_view_ci.subresourceRange.baseArrayLayer = 0; 8510 image_view_ci.subresourceRange.levelCount = 1; 8511 // Setting both depth & stencil aspect bits is illegal for descriptor 8512 image_view_ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 8513 8514 VkImageView image_view; 8515 err = vkCreateImageView(m_device->device(), &image_view_ci, NULL, &image_view); 8516 ASSERT_VK_SUCCESS(err); 8517 8518 VkDescriptorImageInfo img_info = {}; 8519 img_info.imageView = image_view; 8520 VkWriteDescriptorSet descriptor_write = {}; 8521 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 8522 descriptor_write.dstBinding = 0; 8523 descriptor_write.descriptorCount = 1; 8524 descriptor_write.pTexelBufferView = NULL; 8525 descriptor_write.pBufferInfo = NULL; 8526 descriptor_write.pImageInfo = &img_info; 8527 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; 8528 descriptor_write.dstSet = descriptor_set; 8529 const char *error_msg = " please only set either VK_IMAGE_ASPECT_DEPTH_BIT " 8530 "or VK_IMAGE_ASPECT_STENCIL_BIT "; 8531 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, error_msg); 8532 8533 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 8534 8535 m_errorMonitor->VerifyFound(); 8536 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 8537 vkDestroyImage(m_device->device(), image, NULL); 8538 vkFreeMemory(m_device->device(), image_mem, NULL); 8539 vkDestroyImageView(m_device->device(), image_view, NULL); 8540 vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set); 8541 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 8542 } 8543 8544 TEST_F(VkLayerTest, DSTypeMismatch) { 8545 // Create DS w/ layout of one type and attempt Update w/ mis-matched type 8546 VkResult err; 8547 8548 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 8549 " binding #0 with type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER but update " 8550 "type is VK_DESCRIPTOR_TYPE_SAMPLER"); 8551 8552 ASSERT_NO_FATAL_FAILURE(InitState()); 8553 // VkDescriptorSetObj descriptorSet(m_device); 8554 VkDescriptorPoolSize ds_type_count = {}; 8555 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 8556 ds_type_count.descriptorCount = 1; 8557 8558 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 8559 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 8560 ds_pool_ci.pNext = NULL; 8561 ds_pool_ci.maxSets = 1; 8562 ds_pool_ci.poolSizeCount = 1; 8563 ds_pool_ci.pPoolSizes = &ds_type_count; 8564 8565 VkDescriptorPool ds_pool; 8566 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 8567 ASSERT_VK_SUCCESS(err); 8568 VkDescriptorSetLayoutBinding dsl_binding = {}; 8569 dsl_binding.binding = 0; 8570 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 8571 dsl_binding.descriptorCount = 1; 8572 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 8573 dsl_binding.pImmutableSamplers = NULL; 8574 8575 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 8576 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 8577 ds_layout_ci.pNext = NULL; 8578 ds_layout_ci.bindingCount = 1; 8579 ds_layout_ci.pBindings = &dsl_binding; 8580 8581 VkDescriptorSetLayout ds_layout; 8582 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 8583 ASSERT_VK_SUCCESS(err); 8584 8585 VkDescriptorSet descriptorSet; 8586 VkDescriptorSetAllocateInfo alloc_info = {}; 8587 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 8588 alloc_info.descriptorSetCount = 1; 8589 alloc_info.descriptorPool = ds_pool; 8590 alloc_info.pSetLayouts = &ds_layout; 8591 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 8592 ASSERT_VK_SUCCESS(err); 8593 8594 VkSamplerCreateInfo sampler_ci = {}; 8595 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; 8596 sampler_ci.pNext = NULL; 8597 sampler_ci.magFilter = VK_FILTER_NEAREST; 8598 sampler_ci.minFilter = VK_FILTER_NEAREST; 8599 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; 8600 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 8601 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 8602 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 8603 sampler_ci.mipLodBias = 1.0; 8604 sampler_ci.anisotropyEnable = VK_FALSE; 8605 sampler_ci.maxAnisotropy = 1; 8606 sampler_ci.compareEnable = VK_FALSE; 8607 sampler_ci.compareOp = VK_COMPARE_OP_NEVER; 8608 sampler_ci.minLod = 1.0; 8609 sampler_ci.maxLod = 1.0; 8610 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; 8611 sampler_ci.unnormalizedCoordinates = VK_FALSE; 8612 VkSampler sampler; 8613 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 8614 ASSERT_VK_SUCCESS(err); 8615 8616 VkDescriptorImageInfo info = {}; 8617 info.sampler = sampler; 8618 8619 VkWriteDescriptorSet descriptor_write; 8620 memset(&descriptor_write, 0, sizeof(descriptor_write)); 8621 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 8622 descriptor_write.dstSet = descriptorSet; 8623 descriptor_write.descriptorCount = 1; 8624 // This is a mismatched type for the layout which expects BUFFER 8625 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 8626 descriptor_write.pImageInfo = &info; 8627 8628 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 8629 8630 m_errorMonitor->VerifyFound(); 8631 8632 vkDestroySampler(m_device->device(), sampler, NULL); 8633 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 8634 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 8635 } 8636 8637 TEST_F(VkLayerTest, DSUpdateOutOfBounds) { 8638 // For overlapping Update, have arrayIndex exceed that of layout 8639 VkResult err; 8640 8641 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 8642 " binding #0 with 1 total descriptors but update of 1 descriptors " 8643 "starting at binding offset of 0 combined with update array element " 8644 "offset of 1 oversteps the size of this descriptor set."); 8645 8646 ASSERT_NO_FATAL_FAILURE(InitState()); 8647 // VkDescriptorSetObj descriptorSet(m_device); 8648 VkDescriptorPoolSize ds_type_count = {}; 8649 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 8650 ds_type_count.descriptorCount = 1; 8651 8652 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 8653 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 8654 ds_pool_ci.pNext = NULL; 8655 ds_pool_ci.maxSets = 1; 8656 ds_pool_ci.poolSizeCount = 1; 8657 ds_pool_ci.pPoolSizes = &ds_type_count; 8658 8659 VkDescriptorPool ds_pool; 8660 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 8661 ASSERT_VK_SUCCESS(err); 8662 8663 VkDescriptorSetLayoutBinding dsl_binding = {}; 8664 dsl_binding.binding = 0; 8665 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 8666 dsl_binding.descriptorCount = 1; 8667 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 8668 dsl_binding.pImmutableSamplers = NULL; 8669 8670 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 8671 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 8672 ds_layout_ci.pNext = NULL; 8673 ds_layout_ci.bindingCount = 1; 8674 ds_layout_ci.pBindings = &dsl_binding; 8675 8676 VkDescriptorSetLayout ds_layout; 8677 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 8678 ASSERT_VK_SUCCESS(err); 8679 8680 VkDescriptorSet descriptorSet; 8681 VkDescriptorSetAllocateInfo alloc_info = {}; 8682 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 8683 alloc_info.descriptorSetCount = 1; 8684 alloc_info.descriptorPool = ds_pool; 8685 alloc_info.pSetLayouts = &ds_layout; 8686 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 8687 ASSERT_VK_SUCCESS(err); 8688 8689 // Correctly update descriptor to avoid "NOT_UPDATED" error 8690 VkDescriptorBufferInfo buff_info = {}; 8691 buff_info.buffer = VkBuffer(0); // Don't care about buffer handle for this test 8692 buff_info.offset = 0; 8693 buff_info.range = 1024; 8694 8695 VkWriteDescriptorSet descriptor_write; 8696 memset(&descriptor_write, 0, sizeof(descriptor_write)); 8697 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 8698 descriptor_write.dstSet = descriptorSet; 8699 descriptor_write.dstArrayElement = 1; /* This index out of bounds for the update */ 8700 descriptor_write.descriptorCount = 1; 8701 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 8702 descriptor_write.pBufferInfo = &buff_info; 8703 8704 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 8705 8706 m_errorMonitor->VerifyFound(); 8707 8708 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 8709 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 8710 } 8711 8712 TEST_F(VkLayerTest, InvalidDSUpdateIndex) { 8713 // Create layout w/ count of 1 and attempt update to that layout w/ binding 8714 // index 2 8715 VkResult err; 8716 8717 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " does not have binding 2."); 8718 8719 ASSERT_NO_FATAL_FAILURE(InitState()); 8720 // VkDescriptorSetObj descriptorSet(m_device); 8721 VkDescriptorPoolSize ds_type_count = {}; 8722 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 8723 ds_type_count.descriptorCount = 1; 8724 8725 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 8726 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 8727 ds_pool_ci.pNext = NULL; 8728 ds_pool_ci.maxSets = 1; 8729 ds_pool_ci.poolSizeCount = 1; 8730 ds_pool_ci.pPoolSizes = &ds_type_count; 8731 8732 VkDescriptorPool ds_pool; 8733 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 8734 ASSERT_VK_SUCCESS(err); 8735 8736 VkDescriptorSetLayoutBinding dsl_binding = {}; 8737 dsl_binding.binding = 0; 8738 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 8739 dsl_binding.descriptorCount = 1; 8740 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 8741 dsl_binding.pImmutableSamplers = NULL; 8742 8743 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 8744 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 8745 ds_layout_ci.pNext = NULL; 8746 ds_layout_ci.bindingCount = 1; 8747 ds_layout_ci.pBindings = &dsl_binding; 8748 VkDescriptorSetLayout ds_layout; 8749 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 8750 ASSERT_VK_SUCCESS(err); 8751 8752 VkDescriptorSet descriptorSet; 8753 VkDescriptorSetAllocateInfo alloc_info = {}; 8754 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 8755 alloc_info.descriptorSetCount = 1; 8756 alloc_info.descriptorPool = ds_pool; 8757 alloc_info.pSetLayouts = &ds_layout; 8758 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 8759 ASSERT_VK_SUCCESS(err); 8760 8761 VkSamplerCreateInfo sampler_ci = {}; 8762 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; 8763 sampler_ci.pNext = NULL; 8764 sampler_ci.magFilter = VK_FILTER_NEAREST; 8765 sampler_ci.minFilter = VK_FILTER_NEAREST; 8766 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; 8767 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 8768 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 8769 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 8770 sampler_ci.mipLodBias = 1.0; 8771 sampler_ci.anisotropyEnable = VK_FALSE; 8772 sampler_ci.maxAnisotropy = 1; 8773 sampler_ci.compareEnable = VK_FALSE; 8774 sampler_ci.compareOp = VK_COMPARE_OP_NEVER; 8775 sampler_ci.minLod = 1.0; 8776 sampler_ci.maxLod = 1.0; 8777 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; 8778 sampler_ci.unnormalizedCoordinates = VK_FALSE; 8779 8780 VkSampler sampler; 8781 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 8782 ASSERT_VK_SUCCESS(err); 8783 8784 VkDescriptorImageInfo info = {}; 8785 info.sampler = sampler; 8786 8787 VkWriteDescriptorSet descriptor_write; 8788 memset(&descriptor_write, 0, sizeof(descriptor_write)); 8789 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 8790 descriptor_write.dstSet = descriptorSet; 8791 descriptor_write.dstBinding = 2; 8792 descriptor_write.descriptorCount = 1; 8793 // This is the wrong type, but out of bounds will be flagged first 8794 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 8795 descriptor_write.pImageInfo = &info; 8796 8797 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 8798 8799 m_errorMonitor->VerifyFound(); 8800 8801 vkDestroySampler(m_device->device(), sampler, NULL); 8802 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 8803 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 8804 } 8805 8806 TEST_F(VkLayerTest, InvalidDSUpdateStruct) { 8807 // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_* 8808 // types 8809 VkResult err; 8810 8811 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, ".sType must be VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET"); 8812 8813 ASSERT_NO_FATAL_FAILURE(InitState()); 8814 8815 VkDescriptorPoolSize ds_type_count = {}; 8816 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 8817 ds_type_count.descriptorCount = 1; 8818 8819 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 8820 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 8821 ds_pool_ci.pNext = NULL; 8822 ds_pool_ci.maxSets = 1; 8823 ds_pool_ci.poolSizeCount = 1; 8824 ds_pool_ci.pPoolSizes = &ds_type_count; 8825 8826 VkDescriptorPool ds_pool; 8827 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 8828 ASSERT_VK_SUCCESS(err); 8829 VkDescriptorSetLayoutBinding dsl_binding = {}; 8830 dsl_binding.binding = 0; 8831 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 8832 dsl_binding.descriptorCount = 1; 8833 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 8834 dsl_binding.pImmutableSamplers = NULL; 8835 8836 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 8837 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 8838 ds_layout_ci.pNext = NULL; 8839 ds_layout_ci.bindingCount = 1; 8840 ds_layout_ci.pBindings = &dsl_binding; 8841 8842 VkDescriptorSetLayout ds_layout; 8843 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 8844 ASSERT_VK_SUCCESS(err); 8845 8846 VkDescriptorSet descriptorSet; 8847 VkDescriptorSetAllocateInfo alloc_info = {}; 8848 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 8849 alloc_info.descriptorSetCount = 1; 8850 alloc_info.descriptorPool = ds_pool; 8851 alloc_info.pSetLayouts = &ds_layout; 8852 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 8853 ASSERT_VK_SUCCESS(err); 8854 8855 VkSamplerCreateInfo sampler_ci = {}; 8856 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; 8857 sampler_ci.pNext = NULL; 8858 sampler_ci.magFilter = VK_FILTER_NEAREST; 8859 sampler_ci.minFilter = VK_FILTER_NEAREST; 8860 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; 8861 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 8862 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 8863 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 8864 sampler_ci.mipLodBias = 1.0; 8865 sampler_ci.anisotropyEnable = VK_FALSE; 8866 sampler_ci.maxAnisotropy = 1; 8867 sampler_ci.compareEnable = VK_FALSE; 8868 sampler_ci.compareOp = VK_COMPARE_OP_NEVER; 8869 sampler_ci.minLod = 1.0; 8870 sampler_ci.maxLod = 1.0; 8871 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; 8872 sampler_ci.unnormalizedCoordinates = VK_FALSE; 8873 VkSampler sampler; 8874 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 8875 ASSERT_VK_SUCCESS(err); 8876 8877 VkDescriptorImageInfo info = {}; 8878 info.sampler = sampler; 8879 8880 VkWriteDescriptorSet descriptor_write; 8881 memset(&descriptor_write, 0, sizeof(descriptor_write)); 8882 descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */ 8883 descriptor_write.dstSet = descriptorSet; 8884 descriptor_write.descriptorCount = 1; 8885 // This is the wrong type, but out of bounds will be flagged first 8886 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 8887 descriptor_write.pImageInfo = &info; 8888 8889 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 8890 8891 m_errorMonitor->VerifyFound(); 8892 8893 vkDestroySampler(m_device->device(), sampler, NULL); 8894 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 8895 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 8896 } 8897 8898 TEST_F(VkLayerTest, SampleDescriptorUpdateError) { 8899 // Create a single Sampler descriptor and send it an invalid Sampler 8900 VkResult err; 8901 8902 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 8903 "Attempted write update to sampler descriptor with invalid sampler"); 8904 8905 ASSERT_NO_FATAL_FAILURE(InitState()); 8906 // TODO : Farm Descriptor setup code to helper function(s) to reduce copied 8907 // code 8908 VkDescriptorPoolSize ds_type_count = {}; 8909 ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER; 8910 ds_type_count.descriptorCount = 1; 8911 8912 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 8913 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 8914 ds_pool_ci.pNext = NULL; 8915 ds_pool_ci.maxSets = 1; 8916 ds_pool_ci.poolSizeCount = 1; 8917 ds_pool_ci.pPoolSizes = &ds_type_count; 8918 8919 VkDescriptorPool ds_pool; 8920 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 8921 ASSERT_VK_SUCCESS(err); 8922 8923 VkDescriptorSetLayoutBinding dsl_binding = {}; 8924 dsl_binding.binding = 0; 8925 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 8926 dsl_binding.descriptorCount = 1; 8927 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 8928 dsl_binding.pImmutableSamplers = NULL; 8929 8930 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 8931 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 8932 ds_layout_ci.pNext = NULL; 8933 ds_layout_ci.bindingCount = 1; 8934 ds_layout_ci.pBindings = &dsl_binding; 8935 VkDescriptorSetLayout ds_layout; 8936 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 8937 ASSERT_VK_SUCCESS(err); 8938 8939 VkDescriptorSet descriptorSet; 8940 VkDescriptorSetAllocateInfo alloc_info = {}; 8941 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 8942 alloc_info.descriptorSetCount = 1; 8943 alloc_info.descriptorPool = ds_pool; 8944 alloc_info.pSetLayouts = &ds_layout; 8945 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 8946 ASSERT_VK_SUCCESS(err); 8947 8948 VkSampler sampler = (VkSampler)((size_t)0xbaadbeef); // Sampler with invalid handle 8949 8950 VkDescriptorImageInfo descriptor_info; 8951 memset(&descriptor_info, 0, sizeof(VkDescriptorImageInfo)); 8952 descriptor_info.sampler = sampler; 8953 8954 VkWriteDescriptorSet descriptor_write; 8955 memset(&descriptor_write, 0, sizeof(descriptor_write)); 8956 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 8957 descriptor_write.dstSet = descriptorSet; 8958 descriptor_write.dstBinding = 0; 8959 descriptor_write.descriptorCount = 1; 8960 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 8961 descriptor_write.pImageInfo = &descriptor_info; 8962 8963 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 8964 8965 m_errorMonitor->VerifyFound(); 8966 8967 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 8968 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 8969 } 8970 8971 TEST_F(VkLayerTest, ImageViewDescriptorUpdateError) { 8972 // Create a single combined Image/Sampler descriptor and send it an invalid 8973 // imageView 8974 VkResult err; 8975 8976 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attempted write update to combined " 8977 "image sampler descriptor failed due " 8978 "to: Invalid VkImageView:"); 8979 8980 ASSERT_NO_FATAL_FAILURE(InitState()); 8981 VkDescriptorPoolSize ds_type_count = {}; 8982 ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 8983 ds_type_count.descriptorCount = 1; 8984 8985 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 8986 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 8987 ds_pool_ci.pNext = NULL; 8988 ds_pool_ci.maxSets = 1; 8989 ds_pool_ci.poolSizeCount = 1; 8990 ds_pool_ci.pPoolSizes = &ds_type_count; 8991 8992 VkDescriptorPool ds_pool; 8993 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 8994 ASSERT_VK_SUCCESS(err); 8995 8996 VkDescriptorSetLayoutBinding dsl_binding = {}; 8997 dsl_binding.binding = 0; 8998 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 8999 dsl_binding.descriptorCount = 1; 9000 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 9001 dsl_binding.pImmutableSamplers = NULL; 9002 9003 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 9004 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 9005 ds_layout_ci.pNext = NULL; 9006 ds_layout_ci.bindingCount = 1; 9007 ds_layout_ci.pBindings = &dsl_binding; 9008 VkDescriptorSetLayout ds_layout; 9009 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 9010 ASSERT_VK_SUCCESS(err); 9011 9012 VkDescriptorSet descriptorSet; 9013 VkDescriptorSetAllocateInfo alloc_info = {}; 9014 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 9015 alloc_info.descriptorSetCount = 1; 9016 alloc_info.descriptorPool = ds_pool; 9017 alloc_info.pSetLayouts = &ds_layout; 9018 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 9019 ASSERT_VK_SUCCESS(err); 9020 9021 VkSamplerCreateInfo sampler_ci = {}; 9022 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; 9023 sampler_ci.pNext = NULL; 9024 sampler_ci.magFilter = VK_FILTER_NEAREST; 9025 sampler_ci.minFilter = VK_FILTER_NEAREST; 9026 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; 9027 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 9028 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 9029 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 9030 sampler_ci.mipLodBias = 1.0; 9031 sampler_ci.anisotropyEnable = VK_FALSE; 9032 sampler_ci.maxAnisotropy = 1; 9033 sampler_ci.compareEnable = VK_FALSE; 9034 sampler_ci.compareOp = VK_COMPARE_OP_NEVER; 9035 sampler_ci.minLod = 1.0; 9036 sampler_ci.maxLod = 1.0; 9037 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; 9038 sampler_ci.unnormalizedCoordinates = VK_FALSE; 9039 9040 VkSampler sampler; 9041 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 9042 ASSERT_VK_SUCCESS(err); 9043 9044 VkImageView view = (VkImageView)((size_t)0xbaadbeef); // invalid imageView object 9045 9046 VkDescriptorImageInfo descriptor_info; 9047 memset(&descriptor_info, 0, sizeof(VkDescriptorImageInfo)); 9048 descriptor_info.sampler = sampler; 9049 descriptor_info.imageView = view; 9050 9051 VkWriteDescriptorSet descriptor_write; 9052 memset(&descriptor_write, 0, sizeof(descriptor_write)); 9053 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 9054 descriptor_write.dstSet = descriptorSet; 9055 descriptor_write.dstBinding = 0; 9056 descriptor_write.descriptorCount = 1; 9057 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 9058 descriptor_write.pImageInfo = &descriptor_info; 9059 9060 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 9061 9062 m_errorMonitor->VerifyFound(); 9063 9064 vkDestroySampler(m_device->device(), sampler, NULL); 9065 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 9066 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 9067 } 9068 9069 TEST_F(VkLayerTest, CopyDescriptorUpdateErrors) { 9070 // Create DS w/ layout of 2 types, write update 1 and attempt to copy-update 9071 // into the other 9072 VkResult err; 9073 9074 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " binding #1 with type " 9075 "VK_DESCRIPTOR_TYPE_SAMPLER. Types do " 9076 "not match."); 9077 9078 ASSERT_NO_FATAL_FAILURE(InitState()); 9079 // VkDescriptorSetObj descriptorSet(m_device); 9080 VkDescriptorPoolSize ds_type_count[2] = {}; 9081 ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 9082 ds_type_count[0].descriptorCount = 1; 9083 ds_type_count[1].type = VK_DESCRIPTOR_TYPE_SAMPLER; 9084 ds_type_count[1].descriptorCount = 1; 9085 9086 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 9087 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 9088 ds_pool_ci.pNext = NULL; 9089 ds_pool_ci.maxSets = 1; 9090 ds_pool_ci.poolSizeCount = 2; 9091 ds_pool_ci.pPoolSizes = ds_type_count; 9092 9093 VkDescriptorPool ds_pool; 9094 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 9095 ASSERT_VK_SUCCESS(err); 9096 VkDescriptorSetLayoutBinding dsl_binding[2] = {}; 9097 dsl_binding[0].binding = 0; 9098 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 9099 dsl_binding[0].descriptorCount = 1; 9100 dsl_binding[0].stageFlags = VK_SHADER_STAGE_ALL; 9101 dsl_binding[0].pImmutableSamplers = NULL; 9102 dsl_binding[1].binding = 1; 9103 dsl_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 9104 dsl_binding[1].descriptorCount = 1; 9105 dsl_binding[1].stageFlags = VK_SHADER_STAGE_ALL; 9106 dsl_binding[1].pImmutableSamplers = NULL; 9107 9108 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 9109 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 9110 ds_layout_ci.pNext = NULL; 9111 ds_layout_ci.bindingCount = 2; 9112 ds_layout_ci.pBindings = dsl_binding; 9113 9114 VkDescriptorSetLayout ds_layout; 9115 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 9116 ASSERT_VK_SUCCESS(err); 9117 9118 VkDescriptorSet descriptorSet; 9119 VkDescriptorSetAllocateInfo alloc_info = {}; 9120 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 9121 alloc_info.descriptorSetCount = 1; 9122 alloc_info.descriptorPool = ds_pool; 9123 alloc_info.pSetLayouts = &ds_layout; 9124 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 9125 ASSERT_VK_SUCCESS(err); 9126 9127 VkSamplerCreateInfo sampler_ci = {}; 9128 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; 9129 sampler_ci.pNext = NULL; 9130 sampler_ci.magFilter = VK_FILTER_NEAREST; 9131 sampler_ci.minFilter = VK_FILTER_NEAREST; 9132 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; 9133 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 9134 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 9135 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 9136 sampler_ci.mipLodBias = 1.0; 9137 sampler_ci.anisotropyEnable = VK_FALSE; 9138 sampler_ci.maxAnisotropy = 1; 9139 sampler_ci.compareEnable = VK_FALSE; 9140 sampler_ci.compareOp = VK_COMPARE_OP_NEVER; 9141 sampler_ci.minLod = 1.0; 9142 sampler_ci.maxLod = 1.0; 9143 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; 9144 sampler_ci.unnormalizedCoordinates = VK_FALSE; 9145 9146 VkSampler sampler; 9147 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 9148 ASSERT_VK_SUCCESS(err); 9149 9150 VkDescriptorImageInfo info = {}; 9151 info.sampler = sampler; 9152 9153 VkWriteDescriptorSet descriptor_write; 9154 memset(&descriptor_write, 0, sizeof(VkWriteDescriptorSet)); 9155 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 9156 descriptor_write.dstSet = descriptorSet; 9157 descriptor_write.dstBinding = 1; // SAMPLER binding from layout above 9158 descriptor_write.descriptorCount = 1; 9159 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 9160 descriptor_write.pImageInfo = &info; 9161 // This write update should succeed 9162 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 9163 // Now perform a copy update that fails due to type mismatch 9164 VkCopyDescriptorSet copy_ds_update; 9165 memset(©_ds_update, 0, sizeof(VkCopyDescriptorSet)); 9166 copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET; 9167 copy_ds_update.srcSet = descriptorSet; 9168 copy_ds_update.srcBinding = 1; // Copy from SAMPLER binding 9169 copy_ds_update.dstSet = descriptorSet; 9170 copy_ds_update.dstBinding = 0; // ERROR : copy to UNIFORM binding 9171 copy_ds_update.descriptorCount = 1; // copy 1 descriptor 9172 vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, ©_ds_update); 9173 9174 m_errorMonitor->VerifyFound(); 9175 // Now perform a copy update that fails due to binding out of bounds 9176 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " does not have copy update src binding of 3."); 9177 memset(©_ds_update, 0, sizeof(VkCopyDescriptorSet)); 9178 copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET; 9179 copy_ds_update.srcSet = descriptorSet; 9180 copy_ds_update.srcBinding = 3; // ERROR : Invalid binding for matching layout 9181 copy_ds_update.dstSet = descriptorSet; 9182 copy_ds_update.dstBinding = 0; 9183 copy_ds_update.descriptorCount = 1; // Copy 1 descriptor 9184 vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, ©_ds_update); 9185 9186 m_errorMonitor->VerifyFound(); 9187 9188 // Now perform a copy update that fails due to binding out of bounds 9189 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " binding#1 with offset index of 1 plus " 9190 "update array offset of 0 and update of " 9191 "5 descriptors oversteps total number " 9192 "of descriptors in set: 2."); 9193 9194 memset(©_ds_update, 0, sizeof(VkCopyDescriptorSet)); 9195 copy_ds_update.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET; 9196 copy_ds_update.srcSet = descriptorSet; 9197 copy_ds_update.srcBinding = 1; 9198 copy_ds_update.dstSet = descriptorSet; 9199 copy_ds_update.dstBinding = 0; 9200 copy_ds_update.descriptorCount = 5; // ERROR copy 5 descriptors (out of bounds for layout) 9201 vkUpdateDescriptorSets(m_device->device(), 0, NULL, 1, ©_ds_update); 9202 9203 m_errorMonitor->VerifyFound(); 9204 9205 vkDestroySampler(m_device->device(), sampler, NULL); 9206 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 9207 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 9208 } 9209 9210 TEST_F(VkLayerTest, NumSamplesMismatch) { 9211 // Create CommandBuffer where MSAA samples doesn't match RenderPass 9212 // sampleCount 9213 VkResult err; 9214 9215 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Num samples mismatch! "); 9216 9217 ASSERT_NO_FATAL_FAILURE(InitState()); 9218 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 9219 VkDescriptorPoolSize ds_type_count = {}; 9220 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 9221 ds_type_count.descriptorCount = 1; 9222 9223 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 9224 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 9225 ds_pool_ci.pNext = NULL; 9226 ds_pool_ci.maxSets = 1; 9227 ds_pool_ci.poolSizeCount = 1; 9228 ds_pool_ci.pPoolSizes = &ds_type_count; 9229 9230 VkDescriptorPool ds_pool; 9231 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 9232 ASSERT_VK_SUCCESS(err); 9233 9234 VkDescriptorSetLayoutBinding dsl_binding = {}; 9235 dsl_binding.binding = 0; 9236 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 9237 dsl_binding.descriptorCount = 1; 9238 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 9239 dsl_binding.pImmutableSamplers = NULL; 9240 9241 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 9242 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 9243 ds_layout_ci.pNext = NULL; 9244 ds_layout_ci.bindingCount = 1; 9245 ds_layout_ci.pBindings = &dsl_binding; 9246 9247 VkDescriptorSetLayout ds_layout; 9248 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 9249 ASSERT_VK_SUCCESS(err); 9250 9251 VkDescriptorSet descriptorSet; 9252 VkDescriptorSetAllocateInfo alloc_info = {}; 9253 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 9254 alloc_info.descriptorSetCount = 1; 9255 alloc_info.descriptorPool = ds_pool; 9256 alloc_info.pSetLayouts = &ds_layout; 9257 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 9258 ASSERT_VK_SUCCESS(err); 9259 9260 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {}; 9261 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 9262 pipe_ms_state_ci.pNext = NULL; 9263 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT; 9264 pipe_ms_state_ci.sampleShadingEnable = 0; 9265 pipe_ms_state_ci.minSampleShading = 1.0; 9266 pipe_ms_state_ci.pSampleMask = NULL; 9267 9268 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 9269 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 9270 pipeline_layout_ci.pNext = NULL; 9271 pipeline_layout_ci.setLayoutCount = 1; 9272 pipeline_layout_ci.pSetLayouts = &ds_layout; 9273 9274 VkPipelineLayout pipeline_layout; 9275 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 9276 ASSERT_VK_SUCCESS(err); 9277 9278 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 9279 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader 9280 // but add it to be able to run on more devices 9281 VkPipelineObj pipe(m_device); 9282 pipe.AddShader(&vs); 9283 pipe.AddShader(&fs); 9284 pipe.AddColorAttachment(); 9285 pipe.SetMSAA(&pipe_ms_state_ci); 9286 pipe.CreateVKPipeline(pipeline_layout, renderPass()); 9287 9288 BeginCommandBuffer(); 9289 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 9290 9291 // Render triangle (the error should trigger on the attempt to draw). 9292 Draw(3, 1, 0, 0); 9293 9294 // Finalize recording of the command buffer 9295 EndCommandBuffer(); 9296 9297 m_errorMonitor->VerifyFound(); 9298 9299 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 9300 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 9301 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 9302 } 9303 9304 TEST_F(VkLayerTest, RenderPassIncompatible) { 9305 TEST_DESCRIPTION("Hit RenderPass incompatible cases. " 9306 "Initial case is drawing with an active renderpass that's " 9307 "not compatible with the bound pipeline state object's creation renderpass"); 9308 VkResult err; 9309 9310 ASSERT_NO_FATAL_FAILURE(InitState()); 9311 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 9312 9313 VkDescriptorSetLayoutBinding dsl_binding = {}; 9314 dsl_binding.binding = 0; 9315 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 9316 dsl_binding.descriptorCount = 1; 9317 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 9318 dsl_binding.pImmutableSamplers = NULL; 9319 9320 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 9321 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 9322 ds_layout_ci.pNext = NULL; 9323 ds_layout_ci.bindingCount = 1; 9324 ds_layout_ci.pBindings = &dsl_binding; 9325 9326 VkDescriptorSetLayout ds_layout; 9327 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 9328 ASSERT_VK_SUCCESS(err); 9329 9330 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 9331 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 9332 pipeline_layout_ci.pNext = NULL; 9333 pipeline_layout_ci.setLayoutCount = 1; 9334 pipeline_layout_ci.pSetLayouts = &ds_layout; 9335 9336 VkPipelineLayout pipeline_layout; 9337 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 9338 ASSERT_VK_SUCCESS(err); 9339 9340 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 9341 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader 9342 // but add it to be able to run on more devices 9343 // Create a renderpass that will be incompatible with default renderpass 9344 VkAttachmentReference attach = {}; 9345 attach.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 9346 VkAttachmentReference color_att = {}; 9347 color_att.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 9348 VkSubpassDescription subpass = {}; 9349 subpass.inputAttachmentCount = 1; 9350 subpass.pInputAttachments = &attach; 9351 subpass.colorAttachmentCount = 1; 9352 subpass.pColorAttachments = &color_att; 9353 VkRenderPassCreateInfo rpci = {}; 9354 rpci.subpassCount = 1; 9355 rpci.pSubpasses = &subpass; 9356 rpci.attachmentCount = 1; 9357 VkAttachmentDescription attach_desc = {}; 9358 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; 9359 // Format incompatible with PSO RP color attach format B8G8R8A8_UNORM 9360 attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM; 9361 rpci.pAttachments = &attach_desc; 9362 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 9363 VkRenderPass rp; 9364 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 9365 VkPipelineObj pipe(m_device); 9366 pipe.AddShader(&vs); 9367 pipe.AddShader(&fs); 9368 pipe.AddColorAttachment(); 9369 VkViewport view_port = {}; 9370 m_viewports.push_back(view_port); 9371 pipe.SetViewport(m_viewports); 9372 VkRect2D rect = {}; 9373 m_scissors.push_back(rect); 9374 pipe.SetScissor(m_scissors); 9375 pipe.CreateVKPipeline(pipeline_layout, renderPass()); 9376 9377 VkCommandBufferInheritanceInfo cbii = {}; 9378 cbii.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; 9379 cbii.renderPass = rp; 9380 cbii.subpass = 0; 9381 VkCommandBufferBeginInfo cbbi = {}; 9382 cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 9383 cbbi.pInheritanceInfo = &cbii; 9384 vkBeginCommandBuffer(m_commandBuffer->handle(), &cbbi); 9385 VkRenderPassBeginInfo rpbi = {}; 9386 rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; 9387 rpbi.framebuffer = m_framebuffer; 9388 rpbi.renderPass = rp; 9389 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); 9390 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 9391 9392 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " is incompatible w/ gfx pipeline "); 9393 // Render triangle (the error should trigger on the attempt to draw). 9394 Draw(3, 1, 0, 0); 9395 9396 // Finalize recording of the command buffer 9397 EndCommandBuffer(); 9398 9399 m_errorMonitor->VerifyFound(); 9400 9401 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 9402 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 9403 vkDestroyRenderPass(m_device->device(), rp, NULL); 9404 } 9405 9406 TEST_F(VkLayerTest, NumBlendAttachMismatch) { 9407 // Create Pipeline where the number of blend attachments doesn't match the 9408 // number of color attachments. In this case, we don't add any color 9409 // blend attachments even though we have a color attachment. 9410 VkResult err; 9411 9412 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 9413 "Render pass subpass 0 mismatch with blending state defined and blend state attachment"); 9414 9415 ASSERT_NO_FATAL_FAILURE(InitState()); 9416 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 9417 VkDescriptorPoolSize ds_type_count = {}; 9418 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 9419 ds_type_count.descriptorCount = 1; 9420 9421 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 9422 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 9423 ds_pool_ci.pNext = NULL; 9424 ds_pool_ci.maxSets = 1; 9425 ds_pool_ci.poolSizeCount = 1; 9426 ds_pool_ci.pPoolSizes = &ds_type_count; 9427 9428 VkDescriptorPool ds_pool; 9429 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 9430 ASSERT_VK_SUCCESS(err); 9431 9432 VkDescriptorSetLayoutBinding dsl_binding = {}; 9433 dsl_binding.binding = 0; 9434 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 9435 dsl_binding.descriptorCount = 1; 9436 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 9437 dsl_binding.pImmutableSamplers = NULL; 9438 9439 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 9440 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 9441 ds_layout_ci.pNext = NULL; 9442 ds_layout_ci.bindingCount = 1; 9443 ds_layout_ci.pBindings = &dsl_binding; 9444 9445 VkDescriptorSetLayout ds_layout; 9446 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 9447 ASSERT_VK_SUCCESS(err); 9448 9449 VkDescriptorSet descriptorSet; 9450 VkDescriptorSetAllocateInfo alloc_info = {}; 9451 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 9452 alloc_info.descriptorSetCount = 1; 9453 alloc_info.descriptorPool = ds_pool; 9454 alloc_info.pSetLayouts = &ds_layout; 9455 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 9456 ASSERT_VK_SUCCESS(err); 9457 9458 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {}; 9459 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 9460 pipe_ms_state_ci.pNext = NULL; 9461 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; 9462 pipe_ms_state_ci.sampleShadingEnable = 0; 9463 pipe_ms_state_ci.minSampleShading = 1.0; 9464 pipe_ms_state_ci.pSampleMask = NULL; 9465 9466 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 9467 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 9468 pipeline_layout_ci.pNext = NULL; 9469 pipeline_layout_ci.setLayoutCount = 1; 9470 pipeline_layout_ci.pSetLayouts = &ds_layout; 9471 9472 VkPipelineLayout pipeline_layout; 9473 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 9474 ASSERT_VK_SUCCESS(err); 9475 9476 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 9477 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader 9478 // but add it to be able to run on more devices 9479 VkPipelineObj pipe(m_device); 9480 pipe.AddShader(&vs); 9481 pipe.AddShader(&fs); 9482 pipe.SetMSAA(&pipe_ms_state_ci); 9483 pipe.CreateVKPipeline(pipeline_layout, renderPass()); 9484 9485 BeginCommandBuffer(); 9486 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 9487 9488 // Render triangle (the error should trigger on the attempt to draw). 9489 Draw(3, 1, 0, 0); 9490 9491 // Finalize recording of the command buffer 9492 EndCommandBuffer(); 9493 9494 m_errorMonitor->VerifyFound(); 9495 9496 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 9497 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 9498 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 9499 } 9500 9501 TEST_F(VkLayerTest, MissingClearAttachment) { 9502 TEST_DESCRIPTION("Points to a wrong colorAttachment index in a VkClearAttachment " 9503 "structure passed to vkCmdClearAttachments"); 9504 ASSERT_NO_FATAL_FAILURE(InitState()); 9505 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 9506 "vkCmdClearAttachments() color attachment index 1 out of range for active subpass 0; ignored"); 9507 9508 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailCmdClearAttachments); 9509 m_errorMonitor->VerifyFound(); 9510 } 9511 9512 TEST_F(VkLayerTest, ClearCmdNoDraw) { 9513 // Create CommandBuffer where we add ClearCmd for FB Color attachment prior 9514 // to issuing a Draw 9515 VkResult err; 9516 9517 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 9518 "vkCmdClearAttachments() issued on command buffer object "); 9519 9520 ASSERT_NO_FATAL_FAILURE(InitState()); 9521 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 9522 9523 VkDescriptorPoolSize ds_type_count = {}; 9524 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 9525 ds_type_count.descriptorCount = 1; 9526 9527 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 9528 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 9529 ds_pool_ci.pNext = NULL; 9530 ds_pool_ci.maxSets = 1; 9531 ds_pool_ci.poolSizeCount = 1; 9532 ds_pool_ci.pPoolSizes = &ds_type_count; 9533 9534 VkDescriptorPool ds_pool; 9535 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 9536 ASSERT_VK_SUCCESS(err); 9537 9538 VkDescriptorSetLayoutBinding dsl_binding = {}; 9539 dsl_binding.binding = 0; 9540 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 9541 dsl_binding.descriptorCount = 1; 9542 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 9543 dsl_binding.pImmutableSamplers = NULL; 9544 9545 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 9546 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 9547 ds_layout_ci.pNext = NULL; 9548 ds_layout_ci.bindingCount = 1; 9549 ds_layout_ci.pBindings = &dsl_binding; 9550 9551 VkDescriptorSetLayout ds_layout; 9552 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 9553 ASSERT_VK_SUCCESS(err); 9554 9555 VkDescriptorSet descriptorSet; 9556 VkDescriptorSetAllocateInfo alloc_info = {}; 9557 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 9558 alloc_info.descriptorSetCount = 1; 9559 alloc_info.descriptorPool = ds_pool; 9560 alloc_info.pSetLayouts = &ds_layout; 9561 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 9562 ASSERT_VK_SUCCESS(err); 9563 9564 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {}; 9565 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 9566 pipe_ms_state_ci.pNext = NULL; 9567 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT; 9568 pipe_ms_state_ci.sampleShadingEnable = 0; 9569 pipe_ms_state_ci.minSampleShading = 1.0; 9570 pipe_ms_state_ci.pSampleMask = NULL; 9571 9572 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 9573 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 9574 pipeline_layout_ci.pNext = NULL; 9575 pipeline_layout_ci.setLayoutCount = 1; 9576 pipeline_layout_ci.pSetLayouts = &ds_layout; 9577 9578 VkPipelineLayout pipeline_layout; 9579 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 9580 ASSERT_VK_SUCCESS(err); 9581 9582 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 9583 // We shouldn't need a fragment shader but add it to be able to run 9584 // on more devices 9585 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 9586 9587 VkPipelineObj pipe(m_device); 9588 pipe.AddShader(&vs); 9589 pipe.AddShader(&fs); 9590 pipe.SetMSAA(&pipe_ms_state_ci); 9591 pipe.CreateVKPipeline(pipeline_layout, renderPass()); 9592 9593 BeginCommandBuffer(); 9594 9595 // Main thing we care about for this test is that the VkImage obj we're 9596 // clearing matches Color Attachment of FB 9597 // Also pass down other dummy params to keep driver and paramchecker happy 9598 VkClearAttachment color_attachment; 9599 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 9600 color_attachment.clearValue.color.float32[0] = 1.0; 9601 color_attachment.clearValue.color.float32[1] = 1.0; 9602 color_attachment.clearValue.color.float32[2] = 1.0; 9603 color_attachment.clearValue.color.float32[3] = 1.0; 9604 color_attachment.colorAttachment = 0; 9605 VkClearRect clear_rect = {{{0, 0}, {(uint32_t)m_width, (uint32_t)m_height}}}; 9606 9607 vkCmdClearAttachments(m_commandBuffer->GetBufferHandle(), 1, &color_attachment, 1, &clear_rect); 9608 9609 m_errorMonitor->VerifyFound(); 9610 9611 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 9612 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 9613 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 9614 } 9615 9616 TEST_F(VkLayerTest, VtxBufferBadIndex) { 9617 VkResult err; 9618 9619 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 9620 "but no vertex buffers are attached to this Pipeline State Object"); 9621 9622 ASSERT_NO_FATAL_FAILURE(InitState()); 9623 ASSERT_NO_FATAL_FAILURE(InitViewport()); 9624 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 9625 9626 VkDescriptorPoolSize ds_type_count = {}; 9627 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 9628 ds_type_count.descriptorCount = 1; 9629 9630 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 9631 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 9632 ds_pool_ci.pNext = NULL; 9633 ds_pool_ci.maxSets = 1; 9634 ds_pool_ci.poolSizeCount = 1; 9635 ds_pool_ci.pPoolSizes = &ds_type_count; 9636 9637 VkDescriptorPool ds_pool; 9638 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 9639 ASSERT_VK_SUCCESS(err); 9640 9641 VkDescriptorSetLayoutBinding dsl_binding = {}; 9642 dsl_binding.binding = 0; 9643 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 9644 dsl_binding.descriptorCount = 1; 9645 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 9646 dsl_binding.pImmutableSamplers = NULL; 9647 9648 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 9649 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 9650 ds_layout_ci.pNext = NULL; 9651 ds_layout_ci.bindingCount = 1; 9652 ds_layout_ci.pBindings = &dsl_binding; 9653 9654 VkDescriptorSetLayout ds_layout; 9655 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 9656 ASSERT_VK_SUCCESS(err); 9657 9658 VkDescriptorSet descriptorSet; 9659 VkDescriptorSetAllocateInfo alloc_info = {}; 9660 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 9661 alloc_info.descriptorSetCount = 1; 9662 alloc_info.descriptorPool = ds_pool; 9663 alloc_info.pSetLayouts = &ds_layout; 9664 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 9665 ASSERT_VK_SUCCESS(err); 9666 9667 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {}; 9668 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 9669 pipe_ms_state_ci.pNext = NULL; 9670 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; 9671 pipe_ms_state_ci.sampleShadingEnable = 0; 9672 pipe_ms_state_ci.minSampleShading = 1.0; 9673 pipe_ms_state_ci.pSampleMask = NULL; 9674 9675 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 9676 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 9677 pipeline_layout_ci.pNext = NULL; 9678 pipeline_layout_ci.setLayoutCount = 1; 9679 pipeline_layout_ci.pSetLayouts = &ds_layout; 9680 VkPipelineLayout pipeline_layout; 9681 9682 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 9683 ASSERT_VK_SUCCESS(err); 9684 9685 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 9686 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); // We shouldn't need a fragment shader 9687 // but add it to be able to run on more devices 9688 VkPipelineObj pipe(m_device); 9689 pipe.AddShader(&vs); 9690 pipe.AddShader(&fs); 9691 pipe.AddColorAttachment(); 9692 pipe.SetMSAA(&pipe_ms_state_ci); 9693 pipe.SetViewport(m_viewports); 9694 pipe.SetScissor(m_scissors); 9695 pipe.CreateVKPipeline(pipeline_layout, renderPass()); 9696 9697 BeginCommandBuffer(); 9698 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 9699 // Don't care about actual data, just need to get to draw to flag error 9700 static const float vbo_data[3] = {1.f, 0.f, 1.f}; 9701 VkConstantBufferObj vbo(m_device, sizeof(vbo_data), sizeof(float), (const void *)&vbo_data); 9702 BindVertexBuffer(&vbo, (VkDeviceSize)0, 1); // VBO idx 1, but no VBO in PSO 9703 Draw(1, 0, 0, 0); 9704 9705 m_errorMonitor->VerifyFound(); 9706 9707 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 9708 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 9709 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 9710 } 9711 9712 TEST_F(VkLayerTest, MismatchCountQueueCreateRequestedFeature) { 9713 TEST_DESCRIPTION("Use an invalid count in a vkEnumeratePhysicalDevices call." 9714 "Use invalid Queue Family Index in vkCreateDevice"); 9715 ASSERT_NO_FATAL_FAILURE(InitState()); 9716 9717 const char *mismatch_count_message = "Call to vkEnumeratePhysicalDevices() " 9718 "w/ pPhysicalDeviceCount value "; 9719 9720 const char *invalid_queueFamilyIndex_message = "Invalid queue create request in vkCreateDevice(). Invalid " 9721 "queueFamilyIndex "; 9722 9723 const char *unavailable_feature_message = "While calling vkCreateDevice(), requesting feature #"; 9724 9725 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, mismatch_count_message); 9726 // The following test fails with recent NVidia drivers. 9727 // By the time core_validation is reached, the NVidia 9728 // driver has sanitized the invalid condition and core_validation 9729 // is not introduced to the failure condition. This is not the case 9730 // with AMD and Mesa drivers. Futher investigation is required 9731 // uint32_t count = static_cast<uint32_t>(~0); 9732 // VkPhysicalDevice physical_device; 9733 // vkEnumeratePhysicalDevices(instance(), &count, &physical_device); 9734 // m_errorMonitor->VerifyFound(); 9735 9736 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_queueFamilyIndex_message); 9737 float queue_priority = 0.0; 9738 9739 VkDeviceQueueCreateInfo queue_create_info = {}; 9740 queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 9741 queue_create_info.queueCount = 1; 9742 queue_create_info.pQueuePriorities = &queue_priority; 9743 queue_create_info.queueFamilyIndex = static_cast<uint32_t>(~0); 9744 9745 VkPhysicalDeviceFeatures features = m_device->phy().features(); 9746 VkDevice testDevice; 9747 VkDeviceCreateInfo device_create_info = {}; 9748 device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; 9749 device_create_info.queueCreateInfoCount = 1; 9750 device_create_info.pQueueCreateInfos = &queue_create_info; 9751 device_create_info.pEnabledFeatures = &features; 9752 vkCreateDevice(gpu(), &device_create_info, nullptr, &testDevice); 9753 m_errorMonitor->VerifyFound(); 9754 9755 queue_create_info.queueFamilyIndex = 1; 9756 9757 unsigned feature_count = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32); 9758 VkBool32 *feature_array = reinterpret_cast<VkBool32 *>(&features); 9759 for (unsigned i = 0; i < feature_count; i++) { 9760 if (VK_FALSE == feature_array[i]) { 9761 feature_array[i] = VK_TRUE; 9762 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, unavailable_feature_message); 9763 device_create_info.pEnabledFeatures = &features; 9764 vkCreateDevice(gpu(), &device_create_info, nullptr, &testDevice); 9765 m_errorMonitor->VerifyFound(); 9766 break; 9767 } 9768 } 9769 } 9770 9771 TEST_F(VkLayerTest, InvalidQueueIndexInvalidQuery) { 9772 TEST_DESCRIPTION("Use an invalid queue index in a vkCmdWaitEvents call." 9773 "End a command buffer with a query still in progress."); 9774 9775 const char *invalid_queue_index = "was created with sharingMode of VK_SHARING_MODE_EXCLUSIVE. If one " 9776 "of src- or dstQueueFamilyIndex is VK_QUEUE_FAMILY_IGNORED, both " 9777 "must be."; 9778 9779 const char *invalid_query = "Ending command buffer with in progress query: queryPool 0x"; 9780 9781 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_queue_index); 9782 9783 ASSERT_NO_FATAL_FAILURE(InitState()); 9784 9785 VkEvent event; 9786 VkEventCreateInfo event_create_info{}; 9787 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 9788 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event); 9789 9790 VkQueue queue = VK_NULL_HANDLE; 9791 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue); 9792 9793 BeginCommandBuffer(); 9794 9795 VkImageObj image(m_device); 9796 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 9797 ASSERT_TRUE(image.initialized()); 9798 VkImageMemoryBarrier img_barrier = {}; 9799 img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 9800 img_barrier.pNext = NULL; 9801 img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; 9802 img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 9803 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 9804 img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 9805 img_barrier.image = image.handle(); 9806 img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 9807 9808 // QueueFamilyIndex must be VK_QUEUE_FAMILY_IGNORED, this verifies 9809 // that layer validation catches the case when it is not. 9810 img_barrier.dstQueueFamilyIndex = 0; 9811 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 9812 img_barrier.subresourceRange.baseArrayLayer = 0; 9813 img_barrier.subresourceRange.baseMipLevel = 0; 9814 img_barrier.subresourceRange.layerCount = 1; 9815 img_barrier.subresourceRange.levelCount = 1; 9816 vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 9817 nullptr, 0, nullptr, 1, &img_barrier); 9818 m_errorMonitor->VerifyFound(); 9819 9820 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_query); 9821 9822 VkQueryPool query_pool; 9823 VkQueryPoolCreateInfo query_pool_create_info = {}; 9824 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; 9825 query_pool_create_info.queryType = VK_QUERY_TYPE_OCCLUSION; 9826 query_pool_create_info.queryCount = 1; 9827 vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool); 9828 9829 vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0 /*startQuery*/, 1 /*queryCount*/); 9830 vkCmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0); 9831 9832 vkEndCommandBuffer(m_commandBuffer->handle()); 9833 m_errorMonitor->VerifyFound(); 9834 9835 vkDestroyQueryPool(m_device->device(), query_pool, nullptr); 9836 vkDestroyEvent(m_device->device(), event, nullptr); 9837 } 9838 9839 TEST_F(VkLayerTest, VertexBufferInvalid) { 9840 TEST_DESCRIPTION("Submit a command buffer using deleted vertex buffer, " 9841 "delete a buffer twice, use an invalid offset for each " 9842 "buffer type, and attempt to bind a null buffer"); 9843 9844 const char *deleted_buffer_in_command_buffer = "Cannot submit cmd buffer " 9845 "using deleted buffer "; 9846 const char *double_destroy_message = "Cannot free buffer 0x"; 9847 const char *invalid_offset_message = "vkBindBufferMemory(): " 9848 "memoryOffset is 0x"; 9849 const char *invalid_storage_buffer_offset_message = "vkBindBufferMemory(): " 9850 "storage memoryOffset " 9851 "is 0x"; 9852 const char *invalid_texel_buffer_offset_message = "vkBindBufferMemory(): " 9853 "texel memoryOffset " 9854 "is 0x"; 9855 const char *invalid_uniform_buffer_offset_message = "vkBindBufferMemory(): " 9856 "uniform memoryOffset " 9857 "is 0x"; 9858 const char *bind_null_buffer_message = "In vkBindBufferMemory, attempting" 9859 " to Bind Obj(0x"; 9860 const char *free_invalid_buffer_message = "Invalid Device Memory Object 0x"; 9861 9862 ASSERT_NO_FATAL_FAILURE(InitState()); 9863 ASSERT_NO_FATAL_FAILURE(InitViewport()); 9864 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 9865 9866 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {}; 9867 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 9868 pipe_ms_state_ci.pNext = NULL; 9869 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; 9870 pipe_ms_state_ci.sampleShadingEnable = 0; 9871 pipe_ms_state_ci.minSampleShading = 1.0; 9872 pipe_ms_state_ci.pSampleMask = nullptr; 9873 9874 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 9875 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 9876 VkPipelineLayout pipeline_layout; 9877 9878 VkResult err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, nullptr, &pipeline_layout); 9879 ASSERT_VK_SUCCESS(err); 9880 9881 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 9882 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 9883 VkPipelineObj pipe(m_device); 9884 pipe.AddShader(&vs); 9885 pipe.AddShader(&fs); 9886 pipe.AddColorAttachment(); 9887 pipe.SetMSAA(&pipe_ms_state_ci); 9888 pipe.SetViewport(m_viewports); 9889 pipe.SetScissor(m_scissors); 9890 pipe.CreateVKPipeline(pipeline_layout, renderPass()); 9891 9892 BeginCommandBuffer(); 9893 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 9894 9895 { 9896 // Create and bind a vertex buffer in a reduced scope, which will cause 9897 // it to be deleted upon leaving this scope 9898 const float vbo_data[3] = {1.f, 0.f, 1.f}; 9899 VkVerticesObj draw_verticies(m_device, 1, 1, sizeof(vbo_data), 3, vbo_data); 9900 draw_verticies.BindVertexBuffers(m_commandBuffer->handle()); 9901 draw_verticies.AddVertexInputToPipe(pipe); 9902 } 9903 9904 Draw(1, 0, 0, 0); 9905 9906 EndCommandBuffer(); 9907 9908 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, deleted_buffer_in_command_buffer); 9909 QueueCommandBuffer(false); 9910 m_errorMonitor->VerifyFound(); 9911 9912 { 9913 // Create and bind a vertex buffer in a reduced scope, and delete it 9914 // twice, the second through the destructor 9915 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eDoubleDelete); 9916 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, double_destroy_message); 9917 buffer_test.TestDoubleDestroy(); 9918 } 9919 m_errorMonitor->VerifyFound(); 9920 9921 if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidMemoryOffset)) { 9922 // Create and bind a memory buffer with an invalid offset. 9923 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_offset_message); 9924 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VkBufferTest::eInvalidMemoryOffset); 9925 (void)buffer_test; 9926 m_errorMonitor->VerifyFound(); 9927 } 9928 9929 if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset, 9930 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) { 9931 // Create and bind a memory buffer with an invalid offset again, 9932 // but look for a texel buffer message. 9933 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_texel_buffer_offset_message); 9934 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset); 9935 (void)buffer_test; 9936 m_errorMonitor->VerifyFound(); 9937 } 9938 9939 if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)) { 9940 // Create and bind a memory buffer with an invalid offset again, but 9941 // look for a uniform buffer message. 9942 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_uniform_buffer_offset_message); 9943 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset); 9944 (void)buffer_test; 9945 m_errorMonitor->VerifyFound(); 9946 } 9947 9948 if (VkBufferTest::GetTestConditionValid(m_device, VkBufferTest::eInvalidDeviceOffset, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) { 9949 // Create and bind a memory buffer with an invalid offset again, but 9950 // look for a storage buffer message. 9951 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_storage_buffer_offset_message); 9952 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eInvalidDeviceOffset); 9953 (void)buffer_test; 9954 m_errorMonitor->VerifyFound(); 9955 } 9956 9957 { 9958 // Attempt to bind a null buffer. 9959 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, bind_null_buffer_message); 9960 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eBindNullBuffer); 9961 (void)buffer_test; 9962 m_errorMonitor->VerifyFound(); 9963 } 9964 9965 { 9966 // Attempt to use an invalid handle to delete a buffer. 9967 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, free_invalid_buffer_message); 9968 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VkBufferTest::eFreeInvalidHandle); 9969 (void)buffer_test; 9970 } 9971 m_errorMonitor->VerifyFound(); 9972 9973 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 9974 } 9975 9976 // INVALID_IMAGE_LAYOUT tests (one other case is hit by MapMemWithoutHostVisibleBit and not here) 9977 TEST_F(VkLayerTest, InvalidImageLayout) { 9978 TEST_DESCRIPTION("Hit all possible validation checks associated with the " 9979 "DRAWSTATE_INVALID_IMAGE_LAYOUT enum. Generally these involve having" 9980 "images in the wrong layout when they're copied or transitioned."); 9981 // 3 in ValidateCmdBufImageLayouts 9982 // * -1 Attempt to submit cmd buf w/ deleted image 9983 // * -2 Cmd buf submit of image w/ layout not matching first use w/ subresource 9984 // * -3 Cmd buf submit of image w/ layout not matching first use w/o subresource 9985 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 9986 "Layout for input image should be TRANSFER_SRC_OPTIMAL instead of GENERAL."); 9987 9988 ASSERT_NO_FATAL_FAILURE(InitState()); 9989 // Create src & dst images to use for copy operations 9990 VkImage src_image; 9991 VkImage dst_image; 9992 9993 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 9994 const int32_t tex_width = 32; 9995 const int32_t tex_height = 32; 9996 9997 VkImageCreateInfo image_create_info = {}; 9998 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 9999 image_create_info.pNext = NULL; 10000 image_create_info.imageType = VK_IMAGE_TYPE_2D; 10001 image_create_info.format = tex_format; 10002 image_create_info.extent.width = tex_width; 10003 image_create_info.extent.height = tex_height; 10004 image_create_info.extent.depth = 1; 10005 image_create_info.mipLevels = 1; 10006 image_create_info.arrayLayers = 4; 10007 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 10008 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 10009 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 10010 image_create_info.flags = 0; 10011 10012 VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &src_image); 10013 ASSERT_VK_SUCCESS(err); 10014 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dst_image); 10015 ASSERT_VK_SUCCESS(err); 10016 10017 BeginCommandBuffer(); 10018 VkImageCopy copyRegion; 10019 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 10020 copyRegion.srcSubresource.mipLevel = 0; 10021 copyRegion.srcSubresource.baseArrayLayer = 0; 10022 copyRegion.srcSubresource.layerCount = 1; 10023 copyRegion.srcOffset.x = 0; 10024 copyRegion.srcOffset.y = 0; 10025 copyRegion.srcOffset.z = 0; 10026 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 10027 copyRegion.dstSubresource.mipLevel = 0; 10028 copyRegion.dstSubresource.baseArrayLayer = 0; 10029 copyRegion.dstSubresource.layerCount = 1; 10030 copyRegion.dstOffset.x = 0; 10031 copyRegion.dstOffset.y = 0; 10032 copyRegion.dstOffset.z = 0; 10033 copyRegion.extent.width = 1; 10034 copyRegion.extent.height = 1; 10035 copyRegion.extent.depth = 1; 10036 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region); 10037 m_errorMonitor->VerifyFound(); 10038 // Now cause error due to src image layout changing 10039 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot copy from an image whose source layout is " 10040 "VK_IMAGE_LAYOUT_UNDEFINED and doesn't match the current " 10041 "layout VK_IMAGE_LAYOUT_GENERAL."); 10042 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_UNDEFINED, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region); 10043 m_errorMonitor->VerifyFound(); 10044 // Final src error is due to bad layout type 10045 m_errorMonitor->SetDesiredFailureMsg( 10046 VK_DEBUG_REPORT_ERROR_BIT_EXT, 10047 "Layout for input image is VK_IMAGE_LAYOUT_UNDEFINED but can only be TRANSFER_SRC_OPTIMAL or GENERAL."); 10048 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_UNDEFINED, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region); 10049 m_errorMonitor->VerifyFound(); 10050 // Now verify same checks for dst 10051 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 10052 "Layout for output image should be TRANSFER_DST_OPTIMAL instead of GENERAL."); 10053 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region); 10054 m_errorMonitor->VerifyFound(); 10055 // Now cause error due to src image layout changing 10056 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot copy from an image whose dest layout is " 10057 "VK_IMAGE_LAYOUT_UNDEFINED and doesn't match the current " 10058 "layout VK_IMAGE_LAYOUT_GENERAL."); 10059 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_UNDEFINED, 1, ©Region); 10060 m_errorMonitor->VerifyFound(); 10061 m_errorMonitor->SetDesiredFailureMsg( 10062 VK_DEBUG_REPORT_ERROR_BIT_EXT, 10063 "Layout for output image is VK_IMAGE_LAYOUT_UNDEFINED but can only be TRANSFER_DST_OPTIMAL or GENERAL."); 10064 m_commandBuffer->CopyImage(src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_UNDEFINED, 1, ©Region); 10065 m_errorMonitor->VerifyFound(); 10066 // Now cause error due to bad image layout transition in PipelineBarrier 10067 VkImageMemoryBarrier image_barrier[1] = {}; 10068 image_barrier[0].oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; 10069 image_barrier[0].image = src_image; 10070 image_barrier[0].subresourceRange.layerCount = 2; 10071 image_barrier[0].subresourceRange.levelCount = 2; 10072 image_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 10073 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "You cannot transition the layout from " 10074 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL when " 10075 "current layout is VK_IMAGE_LAYOUT_GENERAL."); 10076 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 10077 NULL, 0, NULL, 1, image_barrier); 10078 m_errorMonitor->VerifyFound(); 10079 10080 // Finally some layout errors at RenderPass create time 10081 // Just hacking in specific state to get to the errors we want so don't copy this unless you know what you're doing. 10082 VkAttachmentReference attach = {}; 10083 // perf warning for GENERAL layout w/ non-DS input attachment 10084 attach.layout = VK_IMAGE_LAYOUT_GENERAL; 10085 VkSubpassDescription subpass = {}; 10086 subpass.inputAttachmentCount = 1; 10087 subpass.pInputAttachments = &attach; 10088 VkRenderPassCreateInfo rpci = {}; 10089 rpci.subpassCount = 1; 10090 rpci.pSubpasses = &subpass; 10091 rpci.attachmentCount = 1; 10092 VkAttachmentDescription attach_desc = {}; 10093 attach_desc.format = VK_FORMAT_UNDEFINED; 10094 rpci.pAttachments = &attach_desc; 10095 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 10096 VkRenderPass rp; 10097 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 10098 "Layout for input attachment is GENERAL but should be READ_ONLY_OPTIMAL."); 10099 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 10100 m_errorMonitor->VerifyFound(); 10101 // error w/ non-general layout 10102 attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 10103 10104 m_errorMonitor->SetDesiredFailureMsg( 10105 VK_DEBUG_REPORT_ERROR_BIT_EXT, 10106 "Layout for input attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be READ_ONLY_OPTIMAL or GENERAL."); 10107 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 10108 m_errorMonitor->VerifyFound(); 10109 subpass.inputAttachmentCount = 0; 10110 subpass.colorAttachmentCount = 1; 10111 subpass.pColorAttachments = &attach; 10112 attach.layout = VK_IMAGE_LAYOUT_GENERAL; 10113 // perf warning for GENERAL layout on color attachment 10114 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 10115 "Layout for color attachment is GENERAL but should be COLOR_ATTACHMENT_OPTIMAL."); 10116 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 10117 m_errorMonitor->VerifyFound(); 10118 // error w/ non-color opt or GENERAL layout for color attachment 10119 attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 10120 m_errorMonitor->SetDesiredFailureMsg( 10121 VK_DEBUG_REPORT_ERROR_BIT_EXT, 10122 "Layout for color attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be COLOR_ATTACHMENT_OPTIMAL or GENERAL."); 10123 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 10124 m_errorMonitor->VerifyFound(); 10125 subpass.colorAttachmentCount = 0; 10126 subpass.pDepthStencilAttachment = &attach; 10127 attach.layout = VK_IMAGE_LAYOUT_GENERAL; 10128 // perf warning for GENERAL layout on DS attachment 10129 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 10130 "GENERAL layout for depth attachment may not give optimal performance."); 10131 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 10132 m_errorMonitor->VerifyFound(); 10133 // error w/ non-ds opt or GENERAL layout for color attachment 10134 attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 10135 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 10136 "Layout for depth attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be " 10137 "DEPTH_STENCIL_ATTACHMENT_OPTIMAL, DEPTH_STENCIL_READ_ONLY_OPTIMAL or GENERAL."); 10138 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 10139 m_errorMonitor->VerifyFound(); 10140 // For this error we need a valid renderpass so create default one 10141 attach.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; 10142 attach.attachment = 0; 10143 attach_desc.format = VK_FORMAT_D24_UNORM_S8_UINT; 10144 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; 10145 attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; 10146 attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; 10147 attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; 10148 // Can't do a CLEAR load on READ_ONLY initialLayout 10149 attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 10150 attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; 10151 attach_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 10152 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " with invalid first layout " 10153 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_" 10154 "ONLY_OPTIMAL"); 10155 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 10156 m_errorMonitor->VerifyFound(); 10157 10158 vkDestroyImage(m_device->device(), src_image, NULL); 10159 vkDestroyImage(m_device->device(), dst_image, NULL); 10160 } 10161 10162 TEST_F(VkLayerTest, InvalidStorageImageLayout) { 10163 TEST_DESCRIPTION("Attempt to update a STORAGE_IMAGE descriptor w/o GENERAL layout."); 10164 VkResult err; 10165 10166 ASSERT_NO_FATAL_FAILURE(InitState()); 10167 10168 const VkFormat tex_format = VK_FORMAT_R8G8B8A8_UNORM; 10169 VkImageTiling tiling; 10170 VkFormatProperties format_properties; 10171 vkGetPhysicalDeviceFormatProperties(gpu(), tex_format, &format_properties); 10172 if (format_properties.linearTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) { 10173 tiling = VK_IMAGE_TILING_LINEAR; 10174 } else if (format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) { 10175 tiling = VK_IMAGE_TILING_OPTIMAL; 10176 } else { 10177 printf("Device does not support VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; " 10178 "skipped.\n"); 10179 return; 10180 } 10181 10182 VkDescriptorPoolSize ds_type = {}; 10183 ds_type.type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; 10184 ds_type.descriptorCount = 1; 10185 10186 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 10187 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 10188 ds_pool_ci.maxSets = 1; 10189 ds_pool_ci.poolSizeCount = 1; 10190 ds_pool_ci.pPoolSizes = &ds_type; 10191 ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; 10192 10193 VkDescriptorPool ds_pool; 10194 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 10195 ASSERT_VK_SUCCESS(err); 10196 10197 VkDescriptorSetLayoutBinding dsl_binding = {}; 10198 dsl_binding.binding = 0; 10199 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; 10200 dsl_binding.descriptorCount = 1; 10201 dsl_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 10202 dsl_binding.pImmutableSamplers = NULL; 10203 10204 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 10205 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 10206 ds_layout_ci.pNext = NULL; 10207 ds_layout_ci.bindingCount = 1; 10208 ds_layout_ci.pBindings = &dsl_binding; 10209 10210 VkDescriptorSetLayout ds_layout; 10211 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 10212 ASSERT_VK_SUCCESS(err); 10213 10214 VkDescriptorSetAllocateInfo alloc_info = {}; 10215 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 10216 alloc_info.descriptorSetCount = 1; 10217 alloc_info.descriptorPool = ds_pool; 10218 alloc_info.pSetLayouts = &ds_layout; 10219 VkDescriptorSet descriptor_set; 10220 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set); 10221 ASSERT_VK_SUCCESS(err); 10222 10223 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 10224 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 10225 pipeline_layout_ci.pNext = NULL; 10226 pipeline_layout_ci.setLayoutCount = 1; 10227 pipeline_layout_ci.pSetLayouts = &ds_layout; 10228 VkPipelineLayout pipeline_layout; 10229 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 10230 ASSERT_VK_SUCCESS(err); 10231 10232 VkImageObj image(m_device); 10233 image.init(32, 32, tex_format, VK_IMAGE_USAGE_STORAGE_BIT, tiling, 0); 10234 ASSERT_TRUE(image.initialized()); 10235 VkImageView view = image.targetView(tex_format); 10236 10237 VkDescriptorImageInfo image_info = {}; 10238 image_info.imageView = view; 10239 image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 10240 10241 VkWriteDescriptorSet descriptor_write = {}; 10242 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 10243 descriptor_write.dstSet = descriptor_set; 10244 descriptor_write.dstBinding = 0; 10245 descriptor_write.descriptorCount = 1; 10246 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; 10247 descriptor_write.pImageInfo = &image_info; 10248 10249 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 10250 " of VK_DESCRIPTOR_TYPE_STORAGE_IMAGE type is being updated with layout " 10251 "VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL but according to spec "); 10252 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 10253 m_errorMonitor->VerifyFound(); 10254 10255 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 10256 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 10257 vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set); 10258 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 10259 } 10260 10261 TEST_F(VkLayerTest, SimultaneousUse) { 10262 TEST_DESCRIPTION("Use vkCmdExecuteCommands with invalid state " 10263 "in primary and secondary command buffers."); 10264 10265 ASSERT_NO_FATAL_FAILURE(InitState()); 10266 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10267 10268 const char *simultaneous_use_message1 = "without VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set!"; 10269 const char *simultaneous_use_message2 = "does not have VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set and " 10270 "will cause primary command buffer"; 10271 10272 VkCommandBufferAllocateInfo command_buffer_allocate_info = {}; 10273 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 10274 command_buffer_allocate_info.commandPool = m_commandPool; 10275 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY; 10276 command_buffer_allocate_info.commandBufferCount = 1; 10277 10278 VkCommandBuffer secondary_command_buffer; 10279 ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer)); 10280 VkCommandBufferBeginInfo command_buffer_begin_info = {}; 10281 VkCommandBufferInheritanceInfo command_buffer_inheritance_info = {}; 10282 command_buffer_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; 10283 command_buffer_inheritance_info.renderPass = m_renderPass; 10284 command_buffer_inheritance_info.framebuffer = m_framebuffer; 10285 command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 10286 command_buffer_begin_info.flags = 10287 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; 10288 command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info; 10289 10290 vkBeginCommandBuffer(secondary_command_buffer, &command_buffer_begin_info); 10291 vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); 10292 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer); 10293 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); 10294 vkEndCommandBuffer(secondary_command_buffer); 10295 10296 VkSubmitInfo submit_info = {}; 10297 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 10298 submit_info.commandBufferCount = 1; 10299 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 10300 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 10301 10302 vkBeginCommandBuffer(m_commandBuffer->handle(), &command_buffer_begin_info); 10303 vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); 10304 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, simultaneous_use_message1); 10305 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer); 10306 m_errorMonitor->VerifyFound(); 10307 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); 10308 vkEndCommandBuffer(m_commandBuffer->handle()); 10309 10310 m_errorMonitor->SetDesiredFailureMsg(0, ""); 10311 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 10312 10313 command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; 10314 vkBeginCommandBuffer(m_commandBuffer->handle(), &command_buffer_begin_info); 10315 vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); 10316 10317 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, simultaneous_use_message2); 10318 vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer); 10319 m_errorMonitor->VerifyFound(); 10320 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); 10321 vkEndCommandBuffer(m_commandBuffer->handle()); 10322 } 10323 10324 TEST_F(VkLayerTest, InUseDestroyedSignaled) { 10325 TEST_DESCRIPTION("Use vkCmdExecuteCommands with invalid state " 10326 "in primary and secondary command buffers. " 10327 "Delete objects that are inuse. Call VkQueueSubmit " 10328 "with an event that has been deleted."); 10329 10330 ASSERT_NO_FATAL_FAILURE(InitState()); 10331 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10332 10333 const char *submit_with_deleted_event_message = "Cannot submit cmd buffer using deleted event 0x"; 10334 const char *cannot_delete_event_message = "Cannot delete event 0x"; 10335 const char *cannot_delete_semaphore_message = "Cannot delete semaphore 0x"; 10336 const char *cannot_destroy_fence_message = "Fence 0x"; 10337 10338 BeginCommandBuffer(); 10339 10340 VkEvent event; 10341 VkEventCreateInfo event_create_info = {}; 10342 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 10343 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event); 10344 vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); 10345 10346 EndCommandBuffer(); 10347 vkDestroyEvent(m_device->device(), event, nullptr); 10348 10349 VkSubmitInfo submit_info = {}; 10350 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 10351 submit_info.commandBufferCount = 1; 10352 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 10353 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, submit_with_deleted_event_message); 10354 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 10355 m_errorMonitor->VerifyFound(); 10356 10357 m_errorMonitor->SetDesiredFailureMsg(0, ""); 10358 vkResetCommandBuffer(m_commandBuffer->handle(), 0); 10359 10360 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event); 10361 10362 VkSemaphoreCreateInfo semaphore_create_info = {}; 10363 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 10364 VkSemaphore semaphore; 10365 ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore)); 10366 VkFenceCreateInfo fence_create_info = {}; 10367 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 10368 VkFence fence; 10369 ASSERT_VK_SUCCESS(vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence)); 10370 10371 VkDescriptorPoolSize descriptor_pool_type_count = {}; 10372 descriptor_pool_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 10373 descriptor_pool_type_count.descriptorCount = 1; 10374 10375 VkDescriptorPoolCreateInfo descriptor_pool_create_info = {}; 10376 descriptor_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 10377 descriptor_pool_create_info.maxSets = 1; 10378 descriptor_pool_create_info.poolSizeCount = 1; 10379 descriptor_pool_create_info.pPoolSizes = &descriptor_pool_type_count; 10380 descriptor_pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; 10381 10382 VkDescriptorPool descriptorset_pool; 10383 ASSERT_VK_SUCCESS(vkCreateDescriptorPool(m_device->device(), &descriptor_pool_create_info, nullptr, &descriptorset_pool)); 10384 10385 VkDescriptorSetLayoutBinding descriptorset_layout_binding = {}; 10386 descriptorset_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 10387 descriptorset_layout_binding.descriptorCount = 1; 10388 descriptorset_layout_binding.stageFlags = VK_SHADER_STAGE_ALL; 10389 10390 VkDescriptorSetLayoutCreateInfo descriptorset_layout_create_info = {}; 10391 descriptorset_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 10392 descriptorset_layout_create_info.bindingCount = 1; 10393 descriptorset_layout_create_info.pBindings = &descriptorset_layout_binding; 10394 10395 VkDescriptorSetLayout descriptorset_layout; 10396 ASSERT_VK_SUCCESS( 10397 vkCreateDescriptorSetLayout(m_device->device(), &descriptorset_layout_create_info, nullptr, &descriptorset_layout)); 10398 10399 VkDescriptorSet descriptorset; 10400 VkDescriptorSetAllocateInfo descriptorset_allocate_info = {}; 10401 descriptorset_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 10402 descriptorset_allocate_info.descriptorSetCount = 1; 10403 descriptorset_allocate_info.descriptorPool = descriptorset_pool; 10404 descriptorset_allocate_info.pSetLayouts = &descriptorset_layout; 10405 ASSERT_VK_SUCCESS(vkAllocateDescriptorSets(m_device->device(), &descriptorset_allocate_info, &descriptorset)); 10406 10407 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); 10408 10409 VkDescriptorBufferInfo buffer_info = {}; 10410 buffer_info.buffer = buffer_test.GetBuffer(); 10411 buffer_info.offset = 0; 10412 buffer_info.range = 1024; 10413 10414 VkWriteDescriptorSet write_descriptor_set = {}; 10415 write_descriptor_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 10416 write_descriptor_set.dstSet = descriptorset; 10417 write_descriptor_set.descriptorCount = 1; 10418 write_descriptor_set.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 10419 write_descriptor_set.pBufferInfo = &buffer_info; 10420 10421 vkUpdateDescriptorSets(m_device->device(), 1, &write_descriptor_set, 0, nullptr); 10422 10423 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 10424 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 10425 10426 VkPipelineObj pipe(m_device); 10427 pipe.AddColorAttachment(); 10428 pipe.AddShader(&vs); 10429 pipe.AddShader(&fs); 10430 10431 VkPipelineLayoutCreateInfo pipeline_layout_create_info = {}; 10432 pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 10433 pipeline_layout_create_info.setLayoutCount = 1; 10434 pipeline_layout_create_info.pSetLayouts = &descriptorset_layout; 10435 10436 VkPipelineLayout pipeline_layout; 10437 ASSERT_VK_SUCCESS(vkCreatePipelineLayout(m_device->device(), &pipeline_layout_create_info, nullptr, &pipeline_layout)); 10438 10439 pipe.CreateVKPipeline(pipeline_layout, m_renderPass); 10440 10441 BeginCommandBuffer(); 10442 vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); 10443 10444 vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 10445 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, 10446 &descriptorset, 0, NULL); 10447 10448 EndCommandBuffer(); 10449 10450 submit_info.signalSemaphoreCount = 1; 10451 submit_info.pSignalSemaphores = &semaphore; 10452 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence); 10453 10454 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, cannot_delete_event_message); 10455 vkDestroyEvent(m_device->device(), event, nullptr); 10456 m_errorMonitor->VerifyFound(); 10457 10458 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, cannot_delete_semaphore_message); 10459 vkDestroySemaphore(m_device->device(), semaphore, nullptr); 10460 m_errorMonitor->VerifyFound(); 10461 10462 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, cannot_destroy_fence_message); 10463 vkDestroyFence(m_device->device(), fence, nullptr); 10464 m_errorMonitor->VerifyFound(); 10465 10466 vkQueueWaitIdle(m_device->m_queue); 10467 vkDestroySemaphore(m_device->device(), semaphore, nullptr); 10468 vkDestroyFence(m_device->device(), fence, nullptr); 10469 vkDestroyEvent(m_device->device(), event, nullptr); 10470 vkDestroyDescriptorPool(m_device->device(), descriptorset_pool, nullptr); 10471 vkDestroyDescriptorSetLayout(m_device->device(), descriptorset_layout, nullptr); 10472 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, nullptr); 10473 } 10474 10475 TEST_F(VkLayerTest, QueryPoolInUseDestroyedSignaled) { 10476 TEST_DESCRIPTION("Delete in-use query pool."); 10477 10478 ASSERT_NO_FATAL_FAILURE(InitState()); 10479 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10480 10481 VkQueryPool query_pool; 10482 VkQueryPoolCreateInfo query_pool_ci{}; 10483 query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; 10484 query_pool_ci.queryType = VK_QUERY_TYPE_TIMESTAMP; 10485 query_pool_ci.queryCount = 1; 10486 vkCreateQueryPool(m_device->device(), &query_pool_ci, nullptr, &query_pool); 10487 BeginCommandBuffer(); 10488 // Reset query pool to create binding with cmd buffer 10489 vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1); 10490 10491 EndCommandBuffer(); 10492 10493 VkSubmitInfo submit_info = {}; 10494 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 10495 submit_info.commandBufferCount = 1; 10496 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 10497 // Submit cmd buffer and then destroy query pool while in-flight 10498 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 10499 10500 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete query pool 0x"); 10501 vkDestroyQueryPool(m_device->handle(), query_pool, NULL); 10502 m_errorMonitor->VerifyFound(); 10503 10504 vkQueueWaitIdle(m_device->m_queue); 10505 // Now that cmd buffer done we can safely destroy query_pool 10506 vkDestroyQueryPool(m_device->handle(), query_pool, NULL); 10507 } 10508 10509 TEST_F(VkLayerTest, PipelineInUseDestroyedSignaled) { 10510 TEST_DESCRIPTION("Delete in-use pipeline."); 10511 10512 ASSERT_NO_FATAL_FAILURE(InitState()); 10513 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10514 10515 // Empty pipeline layout used for binding PSO 10516 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 10517 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 10518 pipeline_layout_ci.setLayoutCount = 0; 10519 pipeline_layout_ci.pSetLayouts = NULL; 10520 10521 VkPipelineLayout pipeline_layout; 10522 VkResult err = vkCreatePipelineLayout(m_device->handle(), &pipeline_layout_ci, NULL, &pipeline_layout); 10523 ASSERT_VK_SUCCESS(err); 10524 10525 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete pipeline 0x"); 10526 // Create PSO to be used for draw-time errors below 10527 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 10528 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 10529 // Store pipeline handle so we can actually delete it before test finishes 10530 VkPipeline delete_this_pipeline; 10531 { // Scope pipeline so it will be auto-deleted 10532 VkPipelineObj pipe(m_device); 10533 pipe.AddShader(&vs); 10534 pipe.AddShader(&fs); 10535 pipe.AddColorAttachment(); 10536 pipe.CreateVKPipeline(pipeline_layout, renderPass()); 10537 delete_this_pipeline = pipe.handle(); 10538 10539 BeginCommandBuffer(); 10540 // Bind pipeline to cmd buffer 10541 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 10542 10543 EndCommandBuffer(); 10544 10545 VkSubmitInfo submit_info = {}; 10546 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 10547 submit_info.commandBufferCount = 1; 10548 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 10549 // Submit cmd buffer and then pipeline destroyed while in-flight 10550 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 10551 } // Pipeline deletion triggered here 10552 m_errorMonitor->VerifyFound(); 10553 // Make sure queue finished and then actually delete pipeline 10554 vkQueueWaitIdle(m_device->m_queue); 10555 vkDestroyPipeline(m_device->handle(), delete_this_pipeline, nullptr); 10556 vkDestroyPipelineLayout(m_device->handle(), pipeline_layout, nullptr); 10557 } 10558 10559 TEST_F(VkLayerTest, ImageViewInUseDestroyedSignaled) { 10560 TEST_DESCRIPTION("Delete in-use imageView."); 10561 10562 ASSERT_NO_FATAL_FAILURE(InitState()); 10563 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10564 10565 VkDescriptorPoolSize ds_type_count; 10566 ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 10567 ds_type_count.descriptorCount = 1; 10568 10569 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 10570 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 10571 ds_pool_ci.maxSets = 1; 10572 ds_pool_ci.poolSizeCount = 1; 10573 ds_pool_ci.pPoolSizes = &ds_type_count; 10574 10575 VkDescriptorPool ds_pool; 10576 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 10577 ASSERT_VK_SUCCESS(err); 10578 10579 VkSamplerCreateInfo sampler_ci = {}; 10580 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; 10581 sampler_ci.pNext = NULL; 10582 sampler_ci.magFilter = VK_FILTER_NEAREST; 10583 sampler_ci.minFilter = VK_FILTER_NEAREST; 10584 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; 10585 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 10586 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 10587 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 10588 sampler_ci.mipLodBias = 1.0; 10589 sampler_ci.anisotropyEnable = VK_FALSE; 10590 sampler_ci.maxAnisotropy = 1; 10591 sampler_ci.compareEnable = VK_FALSE; 10592 sampler_ci.compareOp = VK_COMPARE_OP_NEVER; 10593 sampler_ci.minLod = 1.0; 10594 sampler_ci.maxLod = 1.0; 10595 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; 10596 sampler_ci.unnormalizedCoordinates = VK_FALSE; 10597 VkSampler sampler; 10598 10599 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 10600 ASSERT_VK_SUCCESS(err); 10601 10602 VkDescriptorSetLayoutBinding layout_binding; 10603 layout_binding.binding = 0; 10604 layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 10605 layout_binding.descriptorCount = 1; 10606 layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 10607 layout_binding.pImmutableSamplers = NULL; 10608 10609 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 10610 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 10611 ds_layout_ci.bindingCount = 1; 10612 ds_layout_ci.pBindings = &layout_binding; 10613 VkDescriptorSetLayout ds_layout; 10614 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 10615 ASSERT_VK_SUCCESS(err); 10616 10617 VkDescriptorSetAllocateInfo alloc_info = {}; 10618 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 10619 alloc_info.descriptorSetCount = 1; 10620 alloc_info.descriptorPool = ds_pool; 10621 alloc_info.pSetLayouts = &ds_layout; 10622 VkDescriptorSet descriptor_set; 10623 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set); 10624 ASSERT_VK_SUCCESS(err); 10625 10626 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 10627 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 10628 pipeline_layout_ci.pNext = NULL; 10629 pipeline_layout_ci.setLayoutCount = 1; 10630 pipeline_layout_ci.pSetLayouts = &ds_layout; 10631 10632 VkPipelineLayout pipeline_layout; 10633 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 10634 ASSERT_VK_SUCCESS(err); 10635 10636 VkImageObj image(m_device); 10637 image.init(128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 10638 ASSERT_TRUE(image.initialized()); 10639 10640 VkImageView view; 10641 VkImageViewCreateInfo ivci = {}; 10642 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 10643 ivci.image = image.handle(); 10644 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; 10645 ivci.format = VK_FORMAT_R8G8B8A8_UNORM; 10646 ivci.subresourceRange.layerCount = 1; 10647 ivci.subresourceRange.baseMipLevel = 0; 10648 ivci.subresourceRange.levelCount = 1; 10649 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 10650 10651 err = vkCreateImageView(m_device->device(), &ivci, NULL, &view); 10652 ASSERT_VK_SUCCESS(err); 10653 10654 VkDescriptorImageInfo image_info{}; 10655 image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 10656 image_info.imageView = view; 10657 image_info.sampler = sampler; 10658 10659 VkWriteDescriptorSet descriptor_write = {}; 10660 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 10661 descriptor_write.dstSet = descriptor_set; 10662 descriptor_write.dstBinding = 0; 10663 descriptor_write.descriptorCount = 1; 10664 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 10665 descriptor_write.pImageInfo = &image_info; 10666 10667 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 10668 10669 // Create PSO to use the sampler 10670 char const *vsSource = "#version 450\n" 10671 "\n" 10672 "out gl_PerVertex { \n" 10673 " vec4 gl_Position;\n" 10674 "};\n" 10675 "void main(){\n" 10676 " gl_Position = vec4(1);\n" 10677 "}\n"; 10678 char const *fsSource = "#version 450\n" 10679 "\n" 10680 "layout(set=0, binding=0) uniform sampler2D s;\n" 10681 "layout(location=0) out vec4 x;\n" 10682 "void main(){\n" 10683 " x = texture(s, vec2(1));\n" 10684 "}\n"; 10685 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 10686 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 10687 VkPipelineObj pipe(m_device); 10688 pipe.AddShader(&vs); 10689 pipe.AddShader(&fs); 10690 pipe.AddColorAttachment(); 10691 pipe.CreateVKPipeline(pipeline_layout, renderPass()); 10692 10693 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete image view 0x"); 10694 10695 BeginCommandBuffer(); 10696 // Bind pipeline to cmd buffer 10697 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 10698 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, 10699 &descriptor_set, 0, nullptr); 10700 Draw(1, 0, 0, 0); 10701 EndCommandBuffer(); 10702 // Submit cmd buffer then destroy sampler 10703 VkSubmitInfo submit_info = {}; 10704 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 10705 submit_info.commandBufferCount = 1; 10706 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 10707 // Submit cmd buffer and then destroy imageView while in-flight 10708 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 10709 10710 vkDestroyImageView(m_device->device(), view, nullptr); 10711 m_errorMonitor->VerifyFound(); 10712 vkQueueWaitIdle(m_device->m_queue); 10713 // Now we can actually destroy imageView 10714 vkDestroyImageView(m_device->device(), view, NULL); 10715 vkDestroySampler(m_device->device(), sampler, nullptr); 10716 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 10717 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 10718 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 10719 } 10720 10721 TEST_F(VkLayerTest, BufferViewInUseDestroyedSignaled) { 10722 TEST_DESCRIPTION("Delete in-use bufferView."); 10723 10724 ASSERT_NO_FATAL_FAILURE(InitState()); 10725 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10726 10727 VkDescriptorPoolSize ds_type_count; 10728 ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 10729 ds_type_count.descriptorCount = 1; 10730 10731 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 10732 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 10733 ds_pool_ci.maxSets = 1; 10734 ds_pool_ci.poolSizeCount = 1; 10735 ds_pool_ci.pPoolSizes = &ds_type_count; 10736 10737 VkDescriptorPool ds_pool; 10738 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 10739 ASSERT_VK_SUCCESS(err); 10740 10741 VkDescriptorSetLayoutBinding layout_binding; 10742 layout_binding.binding = 0; 10743 layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 10744 layout_binding.descriptorCount = 1; 10745 layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 10746 layout_binding.pImmutableSamplers = NULL; 10747 10748 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 10749 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 10750 ds_layout_ci.bindingCount = 1; 10751 ds_layout_ci.pBindings = &layout_binding; 10752 VkDescriptorSetLayout ds_layout; 10753 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 10754 ASSERT_VK_SUCCESS(err); 10755 10756 VkDescriptorSetAllocateInfo alloc_info = {}; 10757 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 10758 alloc_info.descriptorSetCount = 1; 10759 alloc_info.descriptorPool = ds_pool; 10760 alloc_info.pSetLayouts = &ds_layout; 10761 VkDescriptorSet descriptor_set; 10762 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set); 10763 ASSERT_VK_SUCCESS(err); 10764 10765 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 10766 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 10767 pipeline_layout_ci.pNext = NULL; 10768 pipeline_layout_ci.setLayoutCount = 1; 10769 pipeline_layout_ci.pSetLayouts = &ds_layout; 10770 10771 VkPipelineLayout pipeline_layout; 10772 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 10773 ASSERT_VK_SUCCESS(err); 10774 10775 VkBuffer buffer; 10776 uint32_t queue_family_index = 0; 10777 VkBufferCreateInfo buffer_create_info = {}; 10778 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 10779 buffer_create_info.size = 1024; 10780 buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; 10781 buffer_create_info.queueFamilyIndexCount = 1; 10782 buffer_create_info.pQueueFamilyIndices = &queue_family_index; 10783 10784 err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer); 10785 ASSERT_VK_SUCCESS(err); 10786 10787 VkMemoryRequirements memory_reqs; 10788 VkDeviceMemory buffer_memory; 10789 10790 VkMemoryAllocateInfo memory_info = {}; 10791 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 10792 memory_info.allocationSize = 0; 10793 memory_info.memoryTypeIndex = 0; 10794 10795 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs); 10796 memory_info.allocationSize = memory_reqs.size; 10797 bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 10798 ASSERT_TRUE(pass); 10799 10800 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory); 10801 ASSERT_VK_SUCCESS(err); 10802 err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0); 10803 ASSERT_VK_SUCCESS(err); 10804 10805 VkBufferView view; 10806 VkBufferViewCreateInfo bvci = {}; 10807 bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; 10808 bvci.buffer = buffer; 10809 bvci.format = VK_FORMAT_R8_UNORM; 10810 bvci.range = VK_WHOLE_SIZE; 10811 10812 err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view); 10813 ASSERT_VK_SUCCESS(err); 10814 10815 VkWriteDescriptorSet descriptor_write = {}; 10816 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 10817 descriptor_write.dstSet = descriptor_set; 10818 descriptor_write.dstBinding = 0; 10819 descriptor_write.descriptorCount = 1; 10820 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 10821 descriptor_write.pTexelBufferView = &view; 10822 10823 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 10824 10825 char const *vsSource = "#version 450\n" 10826 "\n" 10827 "out gl_PerVertex { \n" 10828 " vec4 gl_Position;\n" 10829 "};\n" 10830 "void main(){\n" 10831 " gl_Position = vec4(1);\n" 10832 "}\n"; 10833 char const *fsSource = "#version 450\n" 10834 "\n" 10835 "layout(set=0, binding=0, r8) uniform imageBuffer s;\n" 10836 "layout(location=0) out vec4 x;\n" 10837 "void main(){\n" 10838 " x = imageLoad(s, 0);\n" 10839 "}\n"; 10840 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 10841 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 10842 VkPipelineObj pipe(m_device); 10843 pipe.AddShader(&vs); 10844 pipe.AddShader(&fs); 10845 pipe.AddColorAttachment(); 10846 pipe.CreateVKPipeline(pipeline_layout, renderPass()); 10847 10848 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete buffer view 0x"); 10849 10850 BeginCommandBuffer(); 10851 VkViewport viewport = {0, 0, 16, 16, 0, 1}; 10852 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 10853 VkRect2D scissor = {{0, 0}, {16, 16}}; 10854 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 10855 // Bind pipeline to cmd buffer 10856 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 10857 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, 10858 &descriptor_set, 0, nullptr); 10859 Draw(1, 0, 0, 0); 10860 EndCommandBuffer(); 10861 10862 VkSubmitInfo submit_info = {}; 10863 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 10864 submit_info.commandBufferCount = 1; 10865 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 10866 // Submit cmd buffer and then destroy bufferView while in-flight 10867 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 10868 10869 vkDestroyBufferView(m_device->device(), view, nullptr); 10870 m_errorMonitor->VerifyFound(); 10871 vkQueueWaitIdle(m_device->m_queue); 10872 // Now we can actually destroy bufferView 10873 vkDestroyBufferView(m_device->device(), view, NULL); 10874 vkDestroyBuffer(m_device->device(), buffer, NULL); 10875 vkFreeMemory(m_device->device(), buffer_memory, NULL); 10876 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 10877 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 10878 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 10879 } 10880 10881 TEST_F(VkLayerTest, SamplerInUseDestroyedSignaled) { 10882 TEST_DESCRIPTION("Delete in-use sampler."); 10883 10884 ASSERT_NO_FATAL_FAILURE(InitState()); 10885 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 10886 10887 VkDescriptorPoolSize ds_type_count; 10888 ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 10889 ds_type_count.descriptorCount = 1; 10890 10891 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 10892 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 10893 ds_pool_ci.maxSets = 1; 10894 ds_pool_ci.poolSizeCount = 1; 10895 ds_pool_ci.pPoolSizes = &ds_type_count; 10896 10897 VkDescriptorPool ds_pool; 10898 VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 10899 ASSERT_VK_SUCCESS(err); 10900 10901 VkSamplerCreateInfo sampler_ci = {}; 10902 sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; 10903 sampler_ci.pNext = NULL; 10904 sampler_ci.magFilter = VK_FILTER_NEAREST; 10905 sampler_ci.minFilter = VK_FILTER_NEAREST; 10906 sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; 10907 sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 10908 sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 10909 sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 10910 sampler_ci.mipLodBias = 1.0; 10911 sampler_ci.anisotropyEnable = VK_FALSE; 10912 sampler_ci.maxAnisotropy = 1; 10913 sampler_ci.compareEnable = VK_FALSE; 10914 sampler_ci.compareOp = VK_COMPARE_OP_NEVER; 10915 sampler_ci.minLod = 1.0; 10916 sampler_ci.maxLod = 1.0; 10917 sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; 10918 sampler_ci.unnormalizedCoordinates = VK_FALSE; 10919 VkSampler sampler; 10920 10921 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler); 10922 ASSERT_VK_SUCCESS(err); 10923 10924 VkDescriptorSetLayoutBinding layout_binding; 10925 layout_binding.binding = 0; 10926 layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 10927 layout_binding.descriptorCount = 1; 10928 layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 10929 layout_binding.pImmutableSamplers = NULL; 10930 10931 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 10932 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 10933 ds_layout_ci.bindingCount = 1; 10934 ds_layout_ci.pBindings = &layout_binding; 10935 VkDescriptorSetLayout ds_layout; 10936 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 10937 ASSERT_VK_SUCCESS(err); 10938 10939 VkDescriptorSetAllocateInfo alloc_info = {}; 10940 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 10941 alloc_info.descriptorSetCount = 1; 10942 alloc_info.descriptorPool = ds_pool; 10943 alloc_info.pSetLayouts = &ds_layout; 10944 VkDescriptorSet descriptor_set; 10945 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set); 10946 ASSERT_VK_SUCCESS(err); 10947 10948 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 10949 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 10950 pipeline_layout_ci.pNext = NULL; 10951 pipeline_layout_ci.setLayoutCount = 1; 10952 pipeline_layout_ci.pSetLayouts = &ds_layout; 10953 10954 VkPipelineLayout pipeline_layout; 10955 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 10956 ASSERT_VK_SUCCESS(err); 10957 10958 VkImageObj image(m_device); 10959 image.init(128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 10960 ASSERT_TRUE(image.initialized()); 10961 10962 VkImageView view; 10963 VkImageViewCreateInfo ivci = {}; 10964 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 10965 ivci.image = image.handle(); 10966 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; 10967 ivci.format = VK_FORMAT_R8G8B8A8_UNORM; 10968 ivci.subresourceRange.layerCount = 1; 10969 ivci.subresourceRange.baseMipLevel = 0; 10970 ivci.subresourceRange.levelCount = 1; 10971 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 10972 10973 err = vkCreateImageView(m_device->device(), &ivci, NULL, &view); 10974 ASSERT_VK_SUCCESS(err); 10975 10976 VkDescriptorImageInfo image_info{}; 10977 image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 10978 image_info.imageView = view; 10979 image_info.sampler = sampler; 10980 10981 VkWriteDescriptorSet descriptor_write = {}; 10982 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 10983 descriptor_write.dstSet = descriptor_set; 10984 descriptor_write.dstBinding = 0; 10985 descriptor_write.descriptorCount = 1; 10986 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 10987 descriptor_write.pImageInfo = &image_info; 10988 10989 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 10990 10991 // Create PSO to use the sampler 10992 char const *vsSource = "#version 450\n" 10993 "\n" 10994 "out gl_PerVertex { \n" 10995 " vec4 gl_Position;\n" 10996 "};\n" 10997 "void main(){\n" 10998 " gl_Position = vec4(1);\n" 10999 "}\n"; 11000 char const *fsSource = "#version 450\n" 11001 "\n" 11002 "layout(set=0, binding=0) uniform sampler2D s;\n" 11003 "layout(location=0) out vec4 x;\n" 11004 "void main(){\n" 11005 " x = texture(s, vec2(1));\n" 11006 "}\n"; 11007 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 11008 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 11009 VkPipelineObj pipe(m_device); 11010 pipe.AddShader(&vs); 11011 pipe.AddShader(&fs); 11012 pipe.AddColorAttachment(); 11013 pipe.CreateVKPipeline(pipeline_layout, renderPass()); 11014 11015 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete sampler 0x"); 11016 11017 BeginCommandBuffer(); 11018 // Bind pipeline to cmd buffer 11019 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle()); 11020 vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, 11021 &descriptor_set, 0, nullptr); 11022 Draw(1, 0, 0, 0); 11023 EndCommandBuffer(); 11024 // Submit cmd buffer then destroy sampler 11025 VkSubmitInfo submit_info = {}; 11026 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 11027 submit_info.commandBufferCount = 1; 11028 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 11029 // Submit cmd buffer and then destroy sampler while in-flight 11030 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 11031 11032 vkDestroySampler(m_device->device(), sampler, nullptr); 11033 m_errorMonitor->VerifyFound(); 11034 vkQueueWaitIdle(m_device->m_queue); 11035 // Now we can actually destroy sampler 11036 vkDestroySampler(m_device->device(), sampler, nullptr); 11037 vkDestroyImageView(m_device->device(), view, NULL); 11038 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 11039 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 11040 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 11041 } 11042 11043 TEST_F(VkLayerTest, QueueForwardProgressFenceWait) { 11044 TEST_DESCRIPTION("Call VkQueueSubmit with a semaphore that is already " 11045 "signaled but not waited on by the queue. Wait on a " 11046 "fence that has not yet been submitted to a queue."); 11047 11048 ASSERT_NO_FATAL_FAILURE(InitState()); 11049 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11050 11051 const char *queue_forward_progress_message = " that has already been signaled but not waited on by queue 0x"; 11052 const char *invalid_fence_wait_message = " which has not been submitted on a Queue or during " 11053 "acquire next image."; 11054 11055 BeginCommandBuffer(); 11056 EndCommandBuffer(); 11057 11058 VkSemaphoreCreateInfo semaphore_create_info = {}; 11059 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 11060 VkSemaphore semaphore; 11061 ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore)); 11062 VkSubmitInfo submit_info = {}; 11063 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 11064 submit_info.commandBufferCount = 1; 11065 submit_info.pCommandBuffers = &m_commandBuffer->handle(); 11066 submit_info.signalSemaphoreCount = 1; 11067 submit_info.pSignalSemaphores = &semaphore; 11068 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 11069 m_errorMonitor->SetDesiredFailureMsg(0, ""); 11070 vkResetCommandBuffer(m_commandBuffer->handle(), 0); 11071 BeginCommandBuffer(); 11072 EndCommandBuffer(); 11073 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, queue_forward_progress_message); 11074 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 11075 m_errorMonitor->VerifyFound(); 11076 11077 VkFenceCreateInfo fence_create_info = {}; 11078 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 11079 VkFence fence; 11080 ASSERT_VK_SUCCESS(vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence)); 11081 11082 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, invalid_fence_wait_message); 11083 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX); 11084 m_errorMonitor->VerifyFound(); 11085 11086 vkDeviceWaitIdle(m_device->device()); 11087 vkDestroyFence(m_device->device(), fence, nullptr); 11088 vkDestroySemaphore(m_device->device(), semaphore, nullptr); 11089 } 11090 11091 TEST_F(VkLayerTest, FramebufferIncompatible) { 11092 TEST_DESCRIPTION("Bind a secondary command buffer with with a framebuffer " 11093 "that does not match the framebuffer for the active " 11094 "renderpass."); 11095 ASSERT_NO_FATAL_FAILURE(InitState()); 11096 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11097 11098 // A renderpass with one color attachment. 11099 VkAttachmentDescription attachment = {0, 11100 VK_FORMAT_B8G8R8A8_UNORM, 11101 VK_SAMPLE_COUNT_1_BIT, 11102 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 11103 VK_ATTACHMENT_STORE_OP_STORE, 11104 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 11105 VK_ATTACHMENT_STORE_OP_DONT_CARE, 11106 VK_IMAGE_LAYOUT_UNDEFINED, 11107 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; 11108 11109 VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; 11110 11111 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr}; 11112 11113 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr}; 11114 11115 VkRenderPass rp; 11116 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 11117 ASSERT_VK_SUCCESS(err); 11118 11119 // A compatible framebuffer. 11120 VkImageObj image(m_device); 11121 image.init(32, 32, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 11122 ASSERT_TRUE(image.initialized()); 11123 11124 VkImageViewCreateInfo ivci = { 11125 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 11126 nullptr, 11127 0, 11128 image.handle(), 11129 VK_IMAGE_VIEW_TYPE_2D, 11130 VK_FORMAT_B8G8R8A8_UNORM, 11131 {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, 11132 VK_COMPONENT_SWIZZLE_IDENTITY}, 11133 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}, 11134 }; 11135 VkImageView view; 11136 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view); 11137 ASSERT_VK_SUCCESS(err); 11138 11139 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1}; 11140 VkFramebuffer fb; 11141 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); 11142 ASSERT_VK_SUCCESS(err); 11143 11144 VkCommandBufferAllocateInfo cbai = {}; 11145 cbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 11146 cbai.commandPool = m_commandPool; 11147 cbai.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY; 11148 cbai.commandBufferCount = 1; 11149 11150 VkCommandBuffer sec_cb; 11151 err = vkAllocateCommandBuffers(m_device->device(), &cbai, &sec_cb); 11152 ASSERT_VK_SUCCESS(err); 11153 VkCommandBufferBeginInfo cbbi = {}; 11154 VkCommandBufferInheritanceInfo cbii = {}; 11155 cbii.renderPass = renderPass(); 11156 cbii.framebuffer = fb; 11157 cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 11158 cbbi.pNext = NULL; 11159 cbbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; 11160 cbbi.pInheritanceInfo = &cbii; 11161 vkBeginCommandBuffer(sec_cb, &cbbi); 11162 vkEndCommandBuffer(sec_cb); 11163 11164 VkCommandBufferBeginInfo cbbi2 = { 11165 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 11166 0, nullptr 11167 }; 11168 vkBeginCommandBuffer(m_commandBuffer->GetBufferHandle(), &cbbi2); 11169 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); 11170 11171 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 11172 " that is not the same as the primary command buffer's current active framebuffer "); 11173 vkCmdExecuteCommands(m_commandBuffer->GetBufferHandle(), 1, &sec_cb); 11174 m_errorMonitor->VerifyFound(); 11175 // Cleanup 11176 vkDestroyImageView(m_device->device(), view, NULL); 11177 vkDestroyRenderPass(m_device->device(), rp, NULL); 11178 vkDestroyFramebuffer(m_device->device(), fb, NULL); 11179 } 11180 11181 TEST_F(VkLayerTest, ColorBlendLogicOpTests) { 11182 TEST_DESCRIPTION("If logicOp is available on the device, set it to an " 11183 "invalid value. If logicOp is not available, attempt to " 11184 "use it and verify that we see the correct error."); 11185 ASSERT_NO_FATAL_FAILURE(InitState()); 11186 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11187 11188 auto features = m_device->phy().features(); 11189 // Set the expected error depending on whether or not logicOp available 11190 if (VK_FALSE == features.logicOp) { 11191 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "If logic operations feature not " 11192 "enabled, logicOpEnable must be " 11193 "VK_FALSE"); 11194 } else { 11195 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "pColorBlendState->logicOp (16)"); 11196 } 11197 // Create a pipeline using logicOp 11198 VkResult err; 11199 11200 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 11201 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 11202 11203 VkPipelineLayout pipeline_layout; 11204 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 11205 ASSERT_VK_SUCCESS(err); 11206 11207 VkPipelineViewportStateCreateInfo vp_state_ci = {}; 11208 vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 11209 vp_state_ci.viewportCount = 1; 11210 VkViewport vp = {}; // Just need dummy vp to point to 11211 vp_state_ci.pViewports = &vp; 11212 vp_state_ci.scissorCount = 1; 11213 VkRect2D scissors = {}; // Dummy scissors to point to 11214 vp_state_ci.pScissors = &scissors; 11215 11216 VkPipelineShaderStageCreateInfo shaderStages[2]; 11217 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo)); 11218 11219 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 11220 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 11221 shaderStages[0] = vs.GetStageCreateInfo(); 11222 shaderStages[1] = fs.GetStageCreateInfo(); 11223 11224 VkPipelineVertexInputStateCreateInfo vi_ci = {}; 11225 vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 11226 11227 VkPipelineInputAssemblyStateCreateInfo ia_ci = {}; 11228 ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 11229 ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 11230 11231 VkPipelineRasterizationStateCreateInfo rs_ci = {}; 11232 rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 11233 rs_ci.lineWidth = 1.0f; 11234 11235 VkPipelineColorBlendAttachmentState att = {}; 11236 att.blendEnable = VK_FALSE; 11237 att.colorWriteMask = 0xf; 11238 11239 VkPipelineColorBlendStateCreateInfo cb_ci = {}; 11240 cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; 11241 // Enable logicOp & set logicOp to value 1 beyond allowed entries 11242 cb_ci.logicOpEnable = VK_TRUE; 11243 cb_ci.logicOp = VK_LOGIC_OP_RANGE_SIZE; // This should cause an error 11244 cb_ci.attachmentCount = 1; 11245 cb_ci.pAttachments = &att; 11246 11247 VkPipelineMultisampleStateCreateInfo ms_ci = {}; 11248 ms_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 11249 ms_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; 11250 11251 VkGraphicsPipelineCreateInfo gp_ci = {}; 11252 gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 11253 gp_ci.stageCount = 2; 11254 gp_ci.pStages = shaderStages; 11255 gp_ci.pVertexInputState = &vi_ci; 11256 gp_ci.pInputAssemblyState = &ia_ci; 11257 gp_ci.pViewportState = &vp_state_ci; 11258 gp_ci.pRasterizationState = &rs_ci; 11259 gp_ci.pColorBlendState = &cb_ci; 11260 gp_ci.pMultisampleState = &ms_ci; 11261 gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; 11262 gp_ci.layout = pipeline_layout; 11263 gp_ci.renderPass = renderPass(); 11264 11265 VkPipelineCacheCreateInfo pc_ci = {}; 11266 pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 11267 11268 VkPipeline pipeline; 11269 VkPipelineCache pipelineCache; 11270 err = vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache); 11271 ASSERT_VK_SUCCESS(err); 11272 11273 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, NULL, &pipeline); 11274 m_errorMonitor->VerifyFound(); 11275 if (VK_SUCCESS == err) { 11276 vkDestroyPipeline(m_device->device(), pipeline, NULL); 11277 } 11278 vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL); 11279 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 11280 } 11281 #endif // DRAW_STATE_TESTS 11282 11283 #if THREADING_TESTS 11284 #if GTEST_IS_THREADSAFE 11285 struct thread_data_struct { 11286 VkCommandBuffer commandBuffer; 11287 VkEvent event; 11288 bool bailout; 11289 }; 11290 11291 extern "C" void *AddToCommandBuffer(void *arg) { 11292 struct thread_data_struct *data = (struct thread_data_struct *)arg; 11293 11294 for (int i = 0; i < 80000; i++) { 11295 vkCmdSetEvent(data->commandBuffer, data->event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); 11296 if (data->bailout) { 11297 break; 11298 } 11299 } 11300 return NULL; 11301 } 11302 11303 TEST_F(VkLayerTest, ThreadCommandBufferCollision) { 11304 test_platform_thread thread; 11305 11306 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "THREADING ERROR"); 11307 11308 ASSERT_NO_FATAL_FAILURE(InitState()); 11309 ASSERT_NO_FATAL_FAILURE(InitViewport()); 11310 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11311 11312 // Calls AllocateCommandBuffers 11313 VkCommandBufferObj commandBuffer(m_device, m_commandPool); 11314 11315 // Avoid creating RenderPass 11316 commandBuffer.BeginCommandBuffer(); 11317 11318 VkEventCreateInfo event_info; 11319 VkEvent event; 11320 VkResult err; 11321 11322 memset(&event_info, 0, sizeof(event_info)); 11323 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 11324 11325 err = vkCreateEvent(device(), &event_info, NULL, &event); 11326 ASSERT_VK_SUCCESS(err); 11327 11328 err = vkResetEvent(device(), event); 11329 ASSERT_VK_SUCCESS(err); 11330 11331 struct thread_data_struct data; 11332 data.commandBuffer = commandBuffer.GetBufferHandle(); 11333 data.event = event; 11334 data.bailout = false; 11335 m_errorMonitor->SetBailout(&data.bailout); 11336 11337 // First do some correct operations using multiple threads. 11338 // Add many entries to command buffer from another thread. 11339 test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data); 11340 // Make non-conflicting calls from this thread at the same time. 11341 for (int i = 0; i < 80000; i++) { 11342 uint32_t count; 11343 vkEnumeratePhysicalDevices(instance(), &count, NULL); 11344 } 11345 test_platform_thread_join(thread, NULL); 11346 11347 // Then do some incorrect operations using multiple threads. 11348 // Add many entries to command buffer from another thread. 11349 test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data); 11350 // Add many entries to command buffer from this thread at the same time. 11351 AddToCommandBuffer(&data); 11352 11353 test_platform_thread_join(thread, NULL); 11354 commandBuffer.EndCommandBuffer(); 11355 11356 m_errorMonitor->SetBailout(NULL); 11357 11358 m_errorMonitor->VerifyFound(); 11359 11360 vkDestroyEvent(device(), event, NULL); 11361 } 11362 #endif // GTEST_IS_THREADSAFE 11363 #endif // THREADING_TESTS 11364 11365 #if SHADER_CHECKER_TESTS 11366 TEST_F(VkLayerTest, InvalidSPIRVCodeSize) { 11367 TEST_DESCRIPTION("Test that an error is produced for a spirv module " 11368 "with an impossible code size"); 11369 11370 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid SPIR-V header"); 11371 11372 ASSERT_NO_FATAL_FAILURE(InitState()); 11373 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11374 11375 VkShaderModule module; 11376 VkShaderModuleCreateInfo moduleCreateInfo; 11377 struct icd_spv_header spv; 11378 11379 spv.magic = ICD_SPV_MAGIC; 11380 spv.version = ICD_SPV_VERSION; 11381 spv.gen_magic = 0; 11382 11383 moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; 11384 moduleCreateInfo.pNext = NULL; 11385 moduleCreateInfo.pCode = (const uint32_t *)&spv; 11386 moduleCreateInfo.codeSize = 4; 11387 moduleCreateInfo.flags = 0; 11388 vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module); 11389 11390 m_errorMonitor->VerifyFound(); 11391 } 11392 11393 TEST_F(VkLayerTest, InvalidSPIRVMagic) { 11394 TEST_DESCRIPTION("Test that an error is produced for a spirv module " 11395 "with a bad magic number"); 11396 11397 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid SPIR-V magic number"); 11398 11399 ASSERT_NO_FATAL_FAILURE(InitState()); 11400 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11401 11402 VkShaderModule module; 11403 VkShaderModuleCreateInfo moduleCreateInfo; 11404 struct icd_spv_header spv; 11405 11406 spv.magic = ~ICD_SPV_MAGIC; 11407 spv.version = ICD_SPV_VERSION; 11408 spv.gen_magic = 0; 11409 11410 moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; 11411 moduleCreateInfo.pNext = NULL; 11412 moduleCreateInfo.pCode = (const uint32_t *)&spv; 11413 moduleCreateInfo.codeSize = sizeof(spv) + 10; 11414 moduleCreateInfo.flags = 0; 11415 vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module); 11416 11417 m_errorMonitor->VerifyFound(); 11418 } 11419 11420 #if 0 11421 // Not currently covered by SPIRV-Tools validator 11422 TEST_F(VkLayerTest, InvalidSPIRVVersion) { 11423 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 11424 "Invalid SPIR-V header"); 11425 11426 ASSERT_NO_FATAL_FAILURE(InitState()); 11427 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11428 11429 VkShaderModule module; 11430 VkShaderModuleCreateInfo moduleCreateInfo; 11431 struct icd_spv_header spv; 11432 11433 spv.magic = ICD_SPV_MAGIC; 11434 spv.version = ~ICD_SPV_VERSION; 11435 spv.gen_magic = 0; 11436 11437 moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; 11438 moduleCreateInfo.pNext = NULL; 11439 11440 moduleCreateInfo.pCode = (const uint32_t *)&spv; 11441 moduleCreateInfo.codeSize = sizeof(spv) + 10; 11442 moduleCreateInfo.flags = 0; 11443 vkCreateShaderModule(m_device->device(), &moduleCreateInfo, NULL, &module); 11444 11445 m_errorMonitor->VerifyFound(); 11446 } 11447 #endif 11448 11449 TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed) { 11450 TEST_DESCRIPTION("Test that a warning is produced for a vertex output that " 11451 "is not consumed by the fragment stage"); 11452 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "not consumed by fragment shader"); 11453 11454 ASSERT_NO_FATAL_FAILURE(InitState()); 11455 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11456 11457 char const *vsSource = "#version 450\n" 11458 "\n" 11459 "layout(location=0) out float x;\n" 11460 "out gl_PerVertex {\n" 11461 " vec4 gl_Position;\n" 11462 "};\n" 11463 "void main(){\n" 11464 " gl_Position = vec4(1);\n" 11465 " x = 0;\n" 11466 "}\n"; 11467 char const *fsSource = "#version 450\n" 11468 "\n" 11469 "layout(location=0) out vec4 color;\n" 11470 "void main(){\n" 11471 " color = vec4(1);\n" 11472 "}\n"; 11473 11474 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 11475 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 11476 11477 VkPipelineObj pipe(m_device); 11478 pipe.AddColorAttachment(); 11479 pipe.AddShader(&vs); 11480 pipe.AddShader(&fs); 11481 11482 VkDescriptorSetObj descriptorSet(m_device); 11483 descriptorSet.AppendDummy(); 11484 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 11485 11486 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 11487 11488 m_errorMonitor->VerifyFound(); 11489 } 11490 11491 TEST_F(VkLayerTest, CreatePipelineCheckShaderBadSpecialization) { 11492 TEST_DESCRIPTION("Challenge core_validation with shader validation issues related to vkCreateGraphicsPipelines."); 11493 11494 ASSERT_NO_FATAL_FAILURE(InitState()); 11495 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11496 11497 const char *bad_specialization_message = 11498 "Specialization entry 0 (for constant id 0) references memory outside provided specialization data "; 11499 11500 char const *vsSource = 11501 "#version 450\n" 11502 "\n" 11503 "out gl_PerVertex {\n" 11504 " vec4 gl_Position;\n" 11505 "};\n" 11506 "void main(){\n" 11507 " gl_Position = vec4(1);\n" 11508 "}\n"; 11509 11510 char const *fsSource = 11511 "#version 450\n" 11512 "\n" 11513 "layout (constant_id = 0) const float r = 0.0f;\n" 11514 "layout(location = 0) out vec4 uFragColor;\n" 11515 "void main(){\n" 11516 " uFragColor = vec4(r,1,0,1);\n" 11517 "}\n"; 11518 11519 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 11520 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 11521 11522 VkPipelineLayoutCreateInfo pipeline_layout_create_info = {}; 11523 pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 11524 11525 VkPipelineLayout pipeline_layout; 11526 ASSERT_VK_SUCCESS(vkCreatePipelineLayout(m_device->device(), &pipeline_layout_create_info, nullptr, &pipeline_layout)); 11527 11528 VkPipelineViewportStateCreateInfo vp_state_create_info = {}; 11529 vp_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 11530 vp_state_create_info.viewportCount = 1; 11531 VkViewport viewport = {}; 11532 vp_state_create_info.pViewports = &viewport; 11533 vp_state_create_info.scissorCount = 1; 11534 VkRect2D scissors = {}; 11535 vp_state_create_info.pScissors = &scissors; 11536 11537 VkDynamicState scissor_state = VK_DYNAMIC_STATE_SCISSOR; 11538 11539 VkPipelineDynamicStateCreateInfo pipeline_dynamic_state_create_info = {}; 11540 pipeline_dynamic_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; 11541 pipeline_dynamic_state_create_info.dynamicStateCount = 1; 11542 pipeline_dynamic_state_create_info.pDynamicStates = &scissor_state; 11543 11544 VkPipelineShaderStageCreateInfo shader_stage_create_info[2] = { 11545 vs.GetStageCreateInfo(), 11546 fs.GetStageCreateInfo() 11547 }; 11548 11549 VkPipelineVertexInputStateCreateInfo vertex_input_create_info = {}; 11550 vertex_input_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 11551 11552 VkPipelineInputAssemblyStateCreateInfo input_assembly_create_info = {}; 11553 input_assembly_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 11554 input_assembly_create_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 11555 11556 VkPipelineRasterizationStateCreateInfo rasterization_state_create_info = {}; 11557 rasterization_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 11558 rasterization_state_create_info.pNext = nullptr; 11559 rasterization_state_create_info.lineWidth = 1.0f; 11560 rasterization_state_create_info.rasterizerDiscardEnable = true; 11561 11562 VkPipelineColorBlendAttachmentState color_blend_attachment_state = {}; 11563 color_blend_attachment_state.blendEnable = VK_FALSE; 11564 color_blend_attachment_state.colorWriteMask = 0xf; 11565 11566 VkPipelineColorBlendStateCreateInfo color_blend_state_create_info = {}; 11567 color_blend_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; 11568 color_blend_state_create_info.attachmentCount = 1; 11569 color_blend_state_create_info.pAttachments = &color_blend_attachment_state; 11570 11571 VkGraphicsPipelineCreateInfo graphicspipe_create_info = {}; 11572 graphicspipe_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 11573 graphicspipe_create_info.stageCount = 2; 11574 graphicspipe_create_info.pStages = shader_stage_create_info; 11575 graphicspipe_create_info.pVertexInputState = &vertex_input_create_info; 11576 graphicspipe_create_info.pInputAssemblyState = &input_assembly_create_info; 11577 graphicspipe_create_info.pViewportState = &vp_state_create_info; 11578 graphicspipe_create_info.pRasterizationState = &rasterization_state_create_info; 11579 graphicspipe_create_info.pColorBlendState = &color_blend_state_create_info; 11580 graphicspipe_create_info.pDynamicState = &pipeline_dynamic_state_create_info; 11581 graphicspipe_create_info.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; 11582 graphicspipe_create_info.layout = pipeline_layout; 11583 graphicspipe_create_info.renderPass = renderPass(); 11584 11585 VkPipelineCacheCreateInfo pipeline_cache_create_info = {}; 11586 pipeline_cache_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 11587 11588 VkPipelineCache pipelineCache; 11589 ASSERT_VK_SUCCESS(vkCreatePipelineCache(m_device->device(), &pipeline_cache_create_info, nullptr, &pipelineCache)); 11590 11591 // This structure maps constant ids to data locations. 11592 const VkSpecializationMapEntry entry = 11593 // id, offset, size 11594 {0, 4, sizeof(uint32_t)}; // Challenge core validation by using a bogus offset. 11595 11596 uint32_t data = 1; 11597 11598 // Set up the info describing spec map and data 11599 const VkSpecializationInfo specialization_info = { 11600 1, 11601 &entry, 11602 1 * sizeof(float), 11603 &data, 11604 }; 11605 shader_stage_create_info[0].pSpecializationInfo = &specialization_info; 11606 11607 VkPipeline pipeline; 11608 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, bad_specialization_message); 11609 vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &graphicspipe_create_info, nullptr, &pipeline); 11610 m_errorMonitor->VerifyFound(); 11611 11612 vkDestroyPipelineCache(m_device->device(), pipelineCache, nullptr); 11613 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, nullptr); 11614 } 11615 11616 TEST_F(VkLayerTest, CreatePipelineCheckShaderDescriptorTypeMismatch) { 11617 TEST_DESCRIPTION("Challenge core_validation with shader validation issues related to vkCreateGraphicsPipelines."); 11618 11619 ASSERT_NO_FATAL_FAILURE(InitState()); 11620 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11621 11622 const char *descriptor_type_mismatch_message = "Type mismatch on descriptor slot 0.0 (used as type "; 11623 11624 VkDescriptorPoolSize descriptor_pool_type_count[2] = {}; 11625 descriptor_pool_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 11626 descriptor_pool_type_count[0].descriptorCount = 1; 11627 descriptor_pool_type_count[1].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; 11628 descriptor_pool_type_count[1].descriptorCount = 1; 11629 11630 VkDescriptorPoolCreateInfo descriptor_pool_create_info = {}; 11631 descriptor_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 11632 descriptor_pool_create_info.maxSets = 1; 11633 descriptor_pool_create_info.poolSizeCount = 2; 11634 descriptor_pool_create_info.pPoolSizes = descriptor_pool_type_count; 11635 descriptor_pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; 11636 11637 VkDescriptorPool descriptorset_pool; 11638 ASSERT_VK_SUCCESS(vkCreateDescriptorPool(m_device->device(), &descriptor_pool_create_info, nullptr, &descriptorset_pool)); 11639 11640 VkDescriptorSetLayoutBinding descriptorset_layout_binding = {}; 11641 descriptorset_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; 11642 descriptorset_layout_binding.descriptorCount = 1; 11643 descriptorset_layout_binding.stageFlags = VK_SHADER_STAGE_ALL; 11644 11645 VkDescriptorSetLayoutCreateInfo descriptorset_layout_create_info = {}; 11646 descriptorset_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 11647 descriptorset_layout_create_info.bindingCount = 1; 11648 descriptorset_layout_create_info.pBindings = &descriptorset_layout_binding; 11649 11650 VkDescriptorSetLayout descriptorset_layout; 11651 ASSERT_VK_SUCCESS(vkCreateDescriptorSetLayout(m_device->device(), &descriptorset_layout_create_info, nullptr, &descriptorset_layout)); 11652 11653 VkDescriptorSetAllocateInfo descriptorset_allocate_info = {}; 11654 descriptorset_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 11655 descriptorset_allocate_info.descriptorSetCount = 1; 11656 descriptorset_allocate_info.descriptorPool = descriptorset_pool; 11657 descriptorset_allocate_info.pSetLayouts = &descriptorset_layout; 11658 VkDescriptorSet descriptorset; 11659 ASSERT_VK_SUCCESS(vkAllocateDescriptorSets(m_device->device(), &descriptorset_allocate_info, &descriptorset)); 11660 11661 // Challenge core_validation with a non uniform buffer type. 11662 VkBufferTest storage_buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); 11663 11664 char const *vsSource = 11665 "#version 450\n" 11666 "\n" 11667 "layout (std140, set = 0, binding = 0) uniform buf {\n" 11668 " mat4 mvp;\n" 11669 "} ubuf;\n" 11670 "out gl_PerVertex {\n" 11671 " vec4 gl_Position;\n" 11672 "};\n" 11673 "void main(){\n" 11674 " gl_Position = ubuf.mvp * vec4(1);\n" 11675 "}\n"; 11676 11677 char const *fsSource = 11678 "#version 450\n" 11679 "\n" 11680 "layout(location = 0) out vec4 uFragColor;\n" 11681 "void main(){\n" 11682 " uFragColor = vec4(0,1,0,1);\n" 11683 "}\n"; 11684 11685 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 11686 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 11687 11688 VkPipelineLayoutCreateInfo pipeline_layout_create_info = {}; 11689 pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 11690 pipeline_layout_create_info.setLayoutCount = 1; 11691 pipeline_layout_create_info.pSetLayouts = &descriptorset_layout; 11692 11693 VkPipelineLayout pipeline_layout; 11694 ASSERT_VK_SUCCESS(vkCreatePipelineLayout(m_device->device(), &pipeline_layout_create_info, nullptr, &pipeline_layout)); 11695 11696 VkPipelineObj pipe(m_device); 11697 pipe.AddColorAttachment(); 11698 pipe.AddShader(&vs); 11699 pipe.AddShader(&fs); 11700 11701 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, descriptor_type_mismatch_message); 11702 pipe.CreateVKPipeline(pipeline_layout, renderPass()); 11703 m_errorMonitor->VerifyFound(); 11704 11705 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, nullptr); 11706 vkDestroyDescriptorPool(m_device->device(), descriptorset_pool, nullptr); 11707 vkDestroyDescriptorSetLayout(m_device->device(), descriptorset_layout, nullptr); 11708 } 11709 11710 TEST_F(VkLayerTest, CreatePipelineCheckShaderDescriptorNotAccessible) { 11711 TEST_DESCRIPTION( 11712 "Create a pipeline in which a descriptor used by a shader stage does not include that stage in its stageFlags."); 11713 11714 ASSERT_NO_FATAL_FAILURE(InitState()); 11715 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11716 11717 const char *descriptor_not_accessible_message = "Shader uses descriptor slot 0.0 (used as type "; 11718 11719 VkDescriptorPoolSize descriptor_pool_type_count = {}; 11720 descriptor_pool_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 11721 descriptor_pool_type_count.descriptorCount = 1; 11722 11723 VkDescriptorPoolCreateInfo descriptor_pool_create_info = {}; 11724 descriptor_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 11725 descriptor_pool_create_info.maxSets = 1; 11726 descriptor_pool_create_info.poolSizeCount = 1; 11727 descriptor_pool_create_info.pPoolSizes = &descriptor_pool_type_count; 11728 descriptor_pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; 11729 11730 VkDescriptorPool descriptorset_pool; 11731 ASSERT_VK_SUCCESS(vkCreateDescriptorPool(m_device->device(), &descriptor_pool_create_info, nullptr, &descriptorset_pool)); 11732 11733 VkDescriptorSetLayoutBinding descriptorset_layout_binding = {}; 11734 descriptorset_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 11735 descriptorset_layout_binding.descriptorCount = 1; 11736 // Intentionally make the uniform buffer inaccessible to the vertex shader to challenge core_validation 11737 descriptorset_layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 11738 11739 VkDescriptorSetLayoutCreateInfo descriptorset_layout_create_info = {}; 11740 descriptorset_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 11741 descriptorset_layout_create_info.bindingCount = 1; 11742 descriptorset_layout_create_info.pBindings = &descriptorset_layout_binding; 11743 11744 VkDescriptorSetLayout descriptorset_layout; 11745 ASSERT_VK_SUCCESS(vkCreateDescriptorSetLayout(m_device->device(), &descriptorset_layout_create_info, 11746 nullptr, &descriptorset_layout)); 11747 11748 VkDescriptorSetAllocateInfo descriptorset_allocate_info = {}; 11749 descriptorset_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 11750 descriptorset_allocate_info.descriptorSetCount = 1; 11751 descriptorset_allocate_info.descriptorPool = descriptorset_pool; 11752 descriptorset_allocate_info.pSetLayouts = &descriptorset_layout; 11753 VkDescriptorSet descriptorset; 11754 ASSERT_VK_SUCCESS(vkAllocateDescriptorSets(m_device->device(), &descriptorset_allocate_info, &descriptorset)); 11755 11756 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); 11757 11758 char const *vsSource = 11759 "#version 450\n" 11760 "\n" 11761 "layout (std140, set = 0, binding = 0) uniform buf {\n" 11762 " mat4 mvp;\n" 11763 "} ubuf;\n" 11764 "out gl_PerVertex {\n" 11765 " vec4 gl_Position;\n" 11766 "};\n" 11767 "void main(){\n" 11768 " gl_Position = ubuf.mvp * vec4(1);\n" 11769 "}\n"; 11770 11771 char const *fsSource = 11772 "#version 450\n" 11773 "\n" 11774 "layout(location = 0) out vec4 uFragColor;\n" 11775 "void main(){\n" 11776 " uFragColor = vec4(0,1,0,1);\n" 11777 "}\n"; 11778 11779 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 11780 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 11781 11782 VkPipelineLayoutCreateInfo pipeline_layout_create_info = {}; 11783 pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 11784 pipeline_layout_create_info.setLayoutCount = 1; 11785 pipeline_layout_create_info.pSetLayouts = &descriptorset_layout; 11786 11787 VkPipelineLayout pipeline_layout; 11788 ASSERT_VK_SUCCESS(vkCreatePipelineLayout(m_device->device(), &pipeline_layout_create_info, nullptr, &pipeline_layout)); 11789 11790 VkPipelineObj pipe(m_device); 11791 pipe.AddColorAttachment(); 11792 pipe.AddShader(&vs); 11793 pipe.AddShader(&fs); 11794 11795 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, descriptor_not_accessible_message); 11796 pipe.CreateVKPipeline(pipeline_layout, renderPass()); 11797 m_errorMonitor->VerifyFound(); 11798 11799 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, nullptr); 11800 vkDestroyDescriptorPool(m_device->device(), descriptorset_pool, nullptr); 11801 vkDestroyDescriptorSetLayout(m_device->device(), descriptorset_layout, nullptr); 11802 } 11803 11804 TEST_F(VkLayerTest, CreatePipelineCheckShaderPushConstantNotAccessible) { 11805 TEST_DESCRIPTION("Create a graphics pipleine in which a push constant range containing a push constant block member is not " 11806 "accessible from the current shader stage."); 11807 11808 ASSERT_NO_FATAL_FAILURE(InitState()); 11809 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11810 11811 const char *push_constant_not_accessible_message = 11812 "Push constant range covering variable starting at offset 0 not accessible from stage VK_SHADER_STAGE_VERTEX_BIT"; 11813 11814 char const *vsSource = 11815 "#version 450\n" 11816 "\n" 11817 "layout(push_constant, std430) uniform foo { float x; } consts;\n" 11818 "out gl_PerVertex {\n" 11819 " vec4 gl_Position;\n" 11820 "};\n" 11821 "void main(){\n" 11822 " gl_Position = vec4(consts.x);\n" 11823 "}\n"; 11824 11825 char const *fsSource = 11826 "#version 450\n" 11827 "\n" 11828 "layout(location = 0) out vec4 uFragColor;\n" 11829 "void main(){\n" 11830 " uFragColor = vec4(0,1,0,1);\n" 11831 "}\n"; 11832 11833 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 11834 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 11835 11836 VkPipelineLayoutCreateInfo pipeline_layout_create_info = {}; 11837 pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 11838 11839 // Set up a push constant range 11840 VkPushConstantRange push_constant_ranges = {}; 11841 // Set to the wrong stage to challenge core_validation 11842 push_constant_ranges.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 11843 push_constant_ranges.size = 4; 11844 11845 pipeline_layout_create_info.pPushConstantRanges = &push_constant_ranges; 11846 pipeline_layout_create_info.pushConstantRangeCount = 1; 11847 11848 VkPipelineLayout pipeline_layout; 11849 ASSERT_VK_SUCCESS(vkCreatePipelineLayout(m_device->device(), &pipeline_layout_create_info, nullptr, &pipeline_layout)); 11850 11851 VkPipelineObj pipe(m_device); 11852 pipe.AddColorAttachment(); 11853 pipe.AddShader(&vs); 11854 pipe.AddShader(&fs); 11855 11856 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, push_constant_not_accessible_message); 11857 pipe.CreateVKPipeline(pipeline_layout, renderPass()); 11858 m_errorMonitor->VerifyFound(); 11859 11860 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, nullptr); 11861 } 11862 11863 TEST_F(VkLayerTest, CreatePipelineCheckShaderNotEnabled) { 11864 TEST_DESCRIPTION( 11865 "Create a graphics pipeline in which a capability declared by the shader requires a feature not enabled on the device."); 11866 11867 ASSERT_NO_FATAL_FAILURE(InitState()); 11868 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11869 11870 const char *feature_not_enabled_message = 11871 "Shader requires VkPhysicalDeviceFeatures::shaderFloat64 but is not enabled on the device"; 11872 11873 // Some awkward steps are required to test with custom device features. 11874 std::vector<const char *> device_extension_names; 11875 auto features = m_device->phy().features(); 11876 // Disable support for 64 bit floats 11877 features.shaderFloat64 = false; 11878 // The sacrificial device object 11879 VkDeviceObj test_device(0, gpu(), device_extension_names, &features); 11880 11881 char const *vsSource = "#version 450\n" 11882 "\n" 11883 "out gl_PerVertex {\n" 11884 " vec4 gl_Position;\n" 11885 "};\n" 11886 "void main(){\n" 11887 " gl_Position = vec4(1);\n" 11888 "}\n"; 11889 char const *fsSource = "#version 450\n" 11890 "\n" 11891 "layout(location=0) out vec4 color;\n" 11892 "void main(){\n" 11893 " dvec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n" 11894 " color = vec4(green);\n" 11895 "}\n"; 11896 11897 VkShaderObj vs(&test_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 11898 VkShaderObj fs(&test_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 11899 11900 VkRenderpassObj render_pass(&test_device); 11901 11902 VkPipelineObj pipe(&test_device); 11903 pipe.AddColorAttachment(); 11904 pipe.AddShader(&vs); 11905 pipe.AddShader(&fs); 11906 11907 VkPipelineLayoutCreateInfo pipeline_layout_create_info = {}; 11908 pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 11909 VkPipelineLayout pipeline_layout; 11910 ASSERT_VK_SUCCESS(vkCreatePipelineLayout(test_device.device(), &pipeline_layout_create_info, nullptr, &pipeline_layout)); 11911 11912 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, feature_not_enabled_message); 11913 pipe.CreateVKPipeline(pipeline_layout, render_pass.handle()); 11914 m_errorMonitor->VerifyFound(); 11915 11916 vkDestroyPipelineLayout(test_device.device(), pipeline_layout, nullptr); 11917 } 11918 11919 TEST_F(VkLayerTest, CreatePipelineCheckShaderBadCapability) { 11920 TEST_DESCRIPTION("Create a graphics pipeline in which a capability declared by the shader is not supported by Vulkan shaders."); 11921 11922 ASSERT_NO_FATAL_FAILURE(InitState()); 11923 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11924 11925 const char *bad_capability_message = "Shader declares capability 53, not supported in Vulkan."; 11926 11927 char const *vsSource = "#version 450\n" 11928 "\n" 11929 "out gl_PerVertex {\n" 11930 " vec4 gl_Position;\n" 11931 "};\n" 11932 "layout(xfb_buffer = 1) out;" 11933 "void main(){\n" 11934 " gl_Position = vec4(1);\n" 11935 "}\n"; 11936 char const *fsSource = "#version 450\n" 11937 "\n" 11938 "layout(location=0) out vec4 color;\n" 11939 "void main(){\n" 11940 " dvec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n" 11941 " color = vec4(green);\n" 11942 "}\n"; 11943 11944 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 11945 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 11946 11947 VkPipelineObj pipe(m_device); 11948 pipe.AddColorAttachment(); 11949 pipe.AddShader(&vs); 11950 pipe.AddShader(&fs); 11951 11952 VkPipelineLayoutCreateInfo pipeline_layout_create_info = {}; 11953 pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 11954 VkPipelineLayout pipeline_layout; 11955 ASSERT_VK_SUCCESS(vkCreatePipelineLayout(m_device->device(), &pipeline_layout_create_info, nullptr, &pipeline_layout)); 11956 11957 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, bad_capability_message); 11958 pipe.CreateVKPipeline(pipeline_layout, renderPass()); 11959 m_errorMonitor->VerifyFound(); 11960 11961 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, nullptr); 11962 } 11963 11964 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided) { 11965 TEST_DESCRIPTION("Test that an error is produced for a fragment shader input " 11966 "which is not present in the outputs of the previous stage"); 11967 11968 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not written by vertex shader"); 11969 11970 ASSERT_NO_FATAL_FAILURE(InitState()); 11971 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 11972 11973 char const *vsSource = "#version 450\n" 11974 "\n" 11975 "out gl_PerVertex {\n" 11976 " vec4 gl_Position;\n" 11977 "};\n" 11978 "void main(){\n" 11979 " gl_Position = vec4(1);\n" 11980 "}\n"; 11981 char const *fsSource = "#version 450\n" 11982 "\n" 11983 "layout(location=0) in float x;\n" 11984 "layout(location=0) out vec4 color;\n" 11985 "void main(){\n" 11986 " color = vec4(x);\n" 11987 "}\n"; 11988 11989 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 11990 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 11991 11992 VkPipelineObj pipe(m_device); 11993 pipe.AddColorAttachment(); 11994 pipe.AddShader(&vs); 11995 pipe.AddShader(&fs); 11996 11997 VkDescriptorSetObj descriptorSet(m_device); 11998 descriptorSet.AppendDummy(); 11999 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 12000 12001 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 12002 12003 m_errorMonitor->VerifyFound(); 12004 } 12005 12006 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvidedInBlock) { 12007 TEST_DESCRIPTION("Test that an error is produced for a fragment shader input " 12008 "within an interace block, which is not present in the outputs " 12009 "of the previous stage."); 12010 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not written by vertex shader"); 12011 12012 ASSERT_NO_FATAL_FAILURE(InitState()); 12013 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12014 12015 char const *vsSource = "#version 450\n" 12016 "\n" 12017 "out gl_PerVertex {\n" 12018 " vec4 gl_Position;\n" 12019 "};\n" 12020 "void main(){\n" 12021 " gl_Position = vec4(1);\n" 12022 "}\n"; 12023 char const *fsSource = "#version 450\n" 12024 "\n" 12025 "in block { layout(location=0) float x; } ins;\n" 12026 "layout(location=0) out vec4 color;\n" 12027 "void main(){\n" 12028 " color = vec4(ins.x);\n" 12029 "}\n"; 12030 12031 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 12032 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 12033 12034 VkPipelineObj pipe(m_device); 12035 pipe.AddColorAttachment(); 12036 pipe.AddShader(&vs); 12037 pipe.AddShader(&fs); 12038 12039 VkDescriptorSetObj descriptorSet(m_device); 12040 descriptorSet.AppendDummy(); 12041 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 12042 12043 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 12044 12045 m_errorMonitor->VerifyFound(); 12046 } 12047 12048 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchArraySize) { 12049 TEST_DESCRIPTION("Test that an error is produced for mismatched array sizes " 12050 "across the vertex->fragment shader interface"); 12051 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0.0: 'ptr to " 12052 "output arr[2] of float32' vs 'ptr to " 12053 "input arr[3] of float32'"); 12054 12055 ASSERT_NO_FATAL_FAILURE(InitState()); 12056 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12057 12058 char const *vsSource = "#version 450\n" 12059 "\n" 12060 "layout(location=0) out float x[2];\n" 12061 "out gl_PerVertex {\n" 12062 " vec4 gl_Position;\n" 12063 "};\n" 12064 "void main(){\n" 12065 " x[0] = 0; x[1] = 0;\n" 12066 " gl_Position = vec4(1);\n" 12067 "}\n"; 12068 char const *fsSource = "#version 450\n" 12069 "\n" 12070 "layout(location=0) in float x[3];\n" 12071 "layout(location=0) out vec4 color;\n" 12072 "void main(){\n" 12073 " color = vec4(x[0] + x[1] + x[2]);\n" 12074 "}\n"; 12075 12076 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 12077 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 12078 12079 VkPipelineObj pipe(m_device); 12080 pipe.AddColorAttachment(); 12081 pipe.AddShader(&vs); 12082 pipe.AddShader(&fs); 12083 12084 VkDescriptorSetObj descriptorSet(m_device); 12085 descriptorSet.AppendDummy(); 12086 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 12087 12088 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 12089 12090 m_errorMonitor->VerifyFound(); 12091 } 12092 12093 12094 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch) { 12095 TEST_DESCRIPTION("Test that an error is produced for mismatched types across " 12096 "the vertex->fragment shader interface"); 12097 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0"); 12098 12099 ASSERT_NO_FATAL_FAILURE(InitState()); 12100 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12101 12102 char const *vsSource = "#version 450\n" 12103 "\n" 12104 "layout(location=0) out int x;\n" 12105 "out gl_PerVertex {\n" 12106 " vec4 gl_Position;\n" 12107 "};\n" 12108 "void main(){\n" 12109 " x = 0;\n" 12110 " gl_Position = vec4(1);\n" 12111 "}\n"; 12112 char const *fsSource = "#version 450\n" 12113 "\n" 12114 "layout(location=0) in float x;\n" /* VS writes int */ 12115 "layout(location=0) out vec4 color;\n" 12116 "void main(){\n" 12117 " color = vec4(x);\n" 12118 "}\n"; 12119 12120 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 12121 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 12122 12123 VkPipelineObj pipe(m_device); 12124 pipe.AddColorAttachment(); 12125 pipe.AddShader(&vs); 12126 pipe.AddShader(&fs); 12127 12128 VkDescriptorSetObj descriptorSet(m_device); 12129 descriptorSet.AppendDummy(); 12130 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 12131 12132 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 12133 12134 m_errorMonitor->VerifyFound(); 12135 } 12136 12137 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchInBlock) { 12138 TEST_DESCRIPTION("Test that an error is produced for mismatched types across " 12139 "the vertex->fragment shader interface, when the variable is contained within " 12140 "an interface block"); 12141 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0"); 12142 12143 ASSERT_NO_FATAL_FAILURE(InitState()); 12144 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12145 12146 char const *vsSource = "#version 450\n" 12147 "\n" 12148 "out block { layout(location=0) int x; } outs;\n" 12149 "out gl_PerVertex {\n" 12150 " vec4 gl_Position;\n" 12151 "};\n" 12152 "void main(){\n" 12153 " outs.x = 0;\n" 12154 " gl_Position = vec4(1);\n" 12155 "}\n"; 12156 char const *fsSource = "#version 450\n" 12157 "\n" 12158 "in block { layout(location=0) float x; } ins;\n" /* VS writes int */ 12159 "layout(location=0) out vec4 color;\n" 12160 "void main(){\n" 12161 " color = vec4(ins.x);\n" 12162 "}\n"; 12163 12164 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 12165 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 12166 12167 VkPipelineObj pipe(m_device); 12168 pipe.AddColorAttachment(); 12169 pipe.AddShader(&vs); 12170 pipe.AddShader(&fs); 12171 12172 VkDescriptorSetObj descriptorSet(m_device); 12173 descriptorSet.AppendDummy(); 12174 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 12175 12176 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 12177 12178 m_errorMonitor->VerifyFound(); 12179 } 12180 12181 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByLocation) { 12182 TEST_DESCRIPTION("Test that an error is produced for location mismatches across " 12183 "the vertex->fragment shader interface; This should manifest as a not-written/not-consumed " 12184 "pair, but flushes out broken walking of the interfaces"); 12185 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0.0 which is not written by vertex shader"); 12186 12187 ASSERT_NO_FATAL_FAILURE(InitState()); 12188 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12189 12190 char const *vsSource = "#version 450\n" 12191 "\n" 12192 "out block { layout(location=1) float x; } outs;\n" 12193 "out gl_PerVertex {\n" 12194 " vec4 gl_Position;\n" 12195 "};\n" 12196 "void main(){\n" 12197 " outs.x = 0;\n" 12198 " gl_Position = vec4(1);\n" 12199 "}\n"; 12200 char const *fsSource = "#version 450\n" 12201 "\n" 12202 "in block { layout(location=0) float x; } ins;\n" 12203 "layout(location=0) out vec4 color;\n" 12204 "void main(){\n" 12205 " color = vec4(ins.x);\n" 12206 "}\n"; 12207 12208 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 12209 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 12210 12211 VkPipelineObj pipe(m_device); 12212 pipe.AddColorAttachment(); 12213 pipe.AddShader(&vs); 12214 pipe.AddShader(&fs); 12215 12216 VkDescriptorSetObj descriptorSet(m_device); 12217 descriptorSet.AppendDummy(); 12218 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 12219 12220 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 12221 12222 m_errorMonitor->VerifyFound(); 12223 } 12224 12225 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByComponent) { 12226 TEST_DESCRIPTION("Test that an error is produced for component mismatches across the " 12227 "vertex->fragment shader interface. It's not enough to have the same set of locations in " 12228 "use; matching is defined in terms of spirv variables."); 12229 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0.1 which is not written by vertex shader"); 12230 12231 ASSERT_NO_FATAL_FAILURE(InitState()); 12232 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12233 12234 char const *vsSource = "#version 450\n" 12235 "\n" 12236 "out block { layout(location=0, component=0) float x; } outs;\n" 12237 "out gl_PerVertex {\n" 12238 " vec4 gl_Position;\n" 12239 "};\n" 12240 "void main(){\n" 12241 " outs.x = 0;\n" 12242 " gl_Position = vec4(1);\n" 12243 "}\n"; 12244 char const *fsSource = "#version 450\n" 12245 "\n" 12246 "in block { layout(location=0, component=1) float x; } ins;\n" 12247 "layout(location=0) out vec4 color;\n" 12248 "void main(){\n" 12249 " color = vec4(ins.x);\n" 12250 "}\n"; 12251 12252 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 12253 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 12254 12255 VkPipelineObj pipe(m_device); 12256 pipe.AddColorAttachment(); 12257 pipe.AddShader(&vs); 12258 pipe.AddShader(&fs); 12259 12260 VkDescriptorSetObj descriptorSet(m_device); 12261 descriptorSet.AppendDummy(); 12262 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 12263 12264 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 12265 12266 m_errorMonitor->VerifyFound(); 12267 } 12268 12269 TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed) { 12270 TEST_DESCRIPTION("Test that a warning is produced for a vertex attribute which is " 12271 "not consumed by the vertex shader"); 12272 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by vertex shader"); 12273 12274 ASSERT_NO_FATAL_FAILURE(InitState()); 12275 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12276 12277 VkVertexInputBindingDescription input_binding; 12278 memset(&input_binding, 0, sizeof(input_binding)); 12279 12280 VkVertexInputAttributeDescription input_attrib; 12281 memset(&input_attrib, 0, sizeof(input_attrib)); 12282 input_attrib.format = VK_FORMAT_R32_SFLOAT; 12283 12284 char const *vsSource = "#version 450\n" 12285 "\n" 12286 "out gl_PerVertex {\n" 12287 " vec4 gl_Position;\n" 12288 "};\n" 12289 "void main(){\n" 12290 " gl_Position = vec4(1);\n" 12291 "}\n"; 12292 char const *fsSource = "#version 450\n" 12293 "\n" 12294 "layout(location=0) out vec4 color;\n" 12295 "void main(){\n" 12296 " color = vec4(1);\n" 12297 "}\n"; 12298 12299 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 12300 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 12301 12302 VkPipelineObj pipe(m_device); 12303 pipe.AddColorAttachment(); 12304 pipe.AddShader(&vs); 12305 pipe.AddShader(&fs); 12306 12307 pipe.AddVertexInputBindings(&input_binding, 1); 12308 pipe.AddVertexInputAttribs(&input_attrib, 1); 12309 12310 VkDescriptorSetObj descriptorSet(m_device); 12311 descriptorSet.AppendDummy(); 12312 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 12313 12314 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 12315 12316 m_errorMonitor->VerifyFound(); 12317 } 12318 12319 TEST_F(VkLayerTest, CreatePipelineAttribLocationMismatch) { 12320 TEST_DESCRIPTION("Test that a warning is produced for a location mismatch on " 12321 "vertex attributes. This flushes out bad behavior in the interface walker"); 12322 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by vertex shader"); 12323 12324 ASSERT_NO_FATAL_FAILURE(InitState()); 12325 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12326 12327 VkVertexInputBindingDescription input_binding; 12328 memset(&input_binding, 0, sizeof(input_binding)); 12329 12330 VkVertexInputAttributeDescription input_attrib; 12331 memset(&input_attrib, 0, sizeof(input_attrib)); 12332 input_attrib.format = VK_FORMAT_R32_SFLOAT; 12333 12334 char const *vsSource = "#version 450\n" 12335 "\n" 12336 "layout(location=1) in float x;\n" 12337 "out gl_PerVertex {\n" 12338 " vec4 gl_Position;\n" 12339 "};\n" 12340 "void main(){\n" 12341 " gl_Position = vec4(x);\n" 12342 "}\n"; 12343 char const *fsSource = "#version 450\n" 12344 "\n" 12345 "layout(location=0) out vec4 color;\n" 12346 "void main(){\n" 12347 " color = vec4(1);\n" 12348 "}\n"; 12349 12350 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 12351 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 12352 12353 VkPipelineObj pipe(m_device); 12354 pipe.AddColorAttachment(); 12355 pipe.AddShader(&vs); 12356 pipe.AddShader(&fs); 12357 12358 pipe.AddVertexInputBindings(&input_binding, 1); 12359 pipe.AddVertexInputAttribs(&input_attrib, 1); 12360 12361 VkDescriptorSetObj descriptorSet(m_device); 12362 descriptorSet.AppendDummy(); 12363 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 12364 12365 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 12366 12367 m_errorMonitor->VerifyFound(); 12368 } 12369 12370 TEST_F(VkLayerTest, CreatePipelineAttribNotProvided) { 12371 TEST_DESCRIPTION("Test that an error is produced for a vertex shader input which is not " 12372 "provided by a vertex attribute"); 12373 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Vertex shader consumes input at location 0 but not provided"); 12374 12375 ASSERT_NO_FATAL_FAILURE(InitState()); 12376 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12377 12378 char const *vsSource = "#version 450\n" 12379 "\n" 12380 "layout(location=0) in vec4 x;\n" /* not provided */ 12381 "out gl_PerVertex {\n" 12382 " vec4 gl_Position;\n" 12383 "};\n" 12384 "void main(){\n" 12385 " gl_Position = x;\n" 12386 "}\n"; 12387 char const *fsSource = "#version 450\n" 12388 "\n" 12389 "layout(location=0) out vec4 color;\n" 12390 "void main(){\n" 12391 " color = vec4(1);\n" 12392 "}\n"; 12393 12394 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 12395 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 12396 12397 VkPipelineObj pipe(m_device); 12398 pipe.AddColorAttachment(); 12399 pipe.AddShader(&vs); 12400 pipe.AddShader(&fs); 12401 12402 VkDescriptorSetObj descriptorSet(m_device); 12403 descriptorSet.AppendDummy(); 12404 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 12405 12406 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 12407 12408 m_errorMonitor->VerifyFound(); 12409 } 12410 12411 TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch) { 12412 TEST_DESCRIPTION("Test that an error is produced for a mismatch between the " 12413 "fundamental type (float/int/uint) of an attribute and the " 12414 "vertex shader input that consumes it"); 12415 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0 does not match vertex shader input type"); 12416 12417 ASSERT_NO_FATAL_FAILURE(InitState()); 12418 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12419 12420 VkVertexInputBindingDescription input_binding; 12421 memset(&input_binding, 0, sizeof(input_binding)); 12422 12423 VkVertexInputAttributeDescription input_attrib; 12424 memset(&input_attrib, 0, sizeof(input_attrib)); 12425 input_attrib.format = VK_FORMAT_R32_SFLOAT; 12426 12427 char const *vsSource = "#version 450\n" 12428 "\n" 12429 "layout(location=0) in int x;\n" /* attrib provided float */ 12430 "out gl_PerVertex {\n" 12431 " vec4 gl_Position;\n" 12432 "};\n" 12433 "void main(){\n" 12434 " gl_Position = vec4(x);\n" 12435 "}\n"; 12436 char const *fsSource = "#version 450\n" 12437 "\n" 12438 "layout(location=0) out vec4 color;\n" 12439 "void main(){\n" 12440 " color = vec4(1);\n" 12441 "}\n"; 12442 12443 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 12444 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 12445 12446 VkPipelineObj pipe(m_device); 12447 pipe.AddColorAttachment(); 12448 pipe.AddShader(&vs); 12449 pipe.AddShader(&fs); 12450 12451 pipe.AddVertexInputBindings(&input_binding, 1); 12452 pipe.AddVertexInputAttribs(&input_attrib, 1); 12453 12454 VkDescriptorSetObj descriptorSet(m_device); 12455 descriptorSet.AppendDummy(); 12456 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 12457 12458 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 12459 12460 m_errorMonitor->VerifyFound(); 12461 } 12462 12463 TEST_F(VkLayerTest, CreatePipelineDuplicateStage) { 12464 TEST_DESCRIPTION("Test that an error is produced for a pipeline containing multiple " 12465 "shaders for the same stage"); 12466 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 12467 "Multiple shaders provided for stage VK_SHADER_STAGE_VERTEX_BIT"); 12468 12469 ASSERT_NO_FATAL_FAILURE(InitState()); 12470 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12471 12472 char const *vsSource = "#version 450\n" 12473 "\n" 12474 "out gl_PerVertex {\n" 12475 " vec4 gl_Position;\n" 12476 "};\n" 12477 "void main(){\n" 12478 " gl_Position = vec4(1);\n" 12479 "}\n"; 12480 char const *fsSource = "#version 450\n" 12481 "\n" 12482 "layout(location=0) out vec4 color;\n" 12483 "void main(){\n" 12484 " color = vec4(1);\n" 12485 "}\n"; 12486 12487 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 12488 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 12489 12490 VkPipelineObj pipe(m_device); 12491 pipe.AddColorAttachment(); 12492 pipe.AddShader(&vs); 12493 pipe.AddShader(&vs); // intentionally duplicate vertex shader attachment 12494 pipe.AddShader(&fs); 12495 12496 VkDescriptorSetObj descriptorSet(m_device); 12497 descriptorSet.AppendDummy(); 12498 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 12499 12500 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 12501 12502 m_errorMonitor->VerifyFound(); 12503 } 12504 12505 TEST_F(VkLayerTest, CreatePipelineMissingEntrypoint) { 12506 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 12507 "No entrypoint found named `foo`"); 12508 12509 ASSERT_NO_FATAL_FAILURE(InitState()); 12510 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12511 12512 char const *vsSource = "#version 450\n" 12513 "out gl_PerVertex {\n" 12514 " vec4 gl_Position;\n" 12515 "};\n" 12516 "void main(){\n" 12517 " gl_Position = vec4(0);\n" 12518 "}\n"; 12519 char const *fsSource = "#version 450\n" 12520 "\n" 12521 "layout(location=0) out vec4 color;\n" 12522 "void main(){\n" 12523 " color = vec4(1);\n" 12524 "}\n"; 12525 12526 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 12527 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this, "foo"); 12528 12529 VkPipelineObj pipe(m_device); 12530 pipe.AddColorAttachment(); 12531 pipe.AddShader(&vs); 12532 pipe.AddShader(&fs); 12533 12534 VkDescriptorSetObj descriptorSet(m_device); 12535 descriptorSet.AppendDummy(); 12536 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 12537 12538 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 12539 12540 m_errorMonitor->VerifyFound(); 12541 } 12542 12543 TEST_F(VkLayerTest, CreatePipelineDepthStencilRequired) { 12544 m_errorMonitor->SetDesiredFailureMsg( 12545 VK_DEBUG_REPORT_ERROR_BIT_EXT, 12546 "pDepthStencilState is NULL when rasterization is enabled and subpass " 12547 "uses a depth/stencil attachment"); 12548 12549 ASSERT_NO_FATAL_FAILURE(InitState()); 12550 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12551 12552 char const *vsSource = "#version 450\n" 12553 "void main(){ gl_Position = vec4(0); }\n"; 12554 char const *fsSource = "#version 450\n" 12555 "\n" 12556 "layout(location=0) out vec4 color;\n" 12557 "void main(){\n" 12558 " color = vec4(1);\n" 12559 "}\n"; 12560 12561 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 12562 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 12563 12564 VkPipelineObj pipe(m_device); 12565 pipe.AddColorAttachment(); 12566 pipe.AddShader(&vs); 12567 pipe.AddShader(&fs); 12568 12569 VkDescriptorSetObj descriptorSet(m_device); 12570 descriptorSet.AppendDummy(); 12571 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 12572 12573 VkAttachmentDescription attachments[] = { 12574 { 0, VK_FORMAT_B8G8R8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, 12575 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 12576 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 12577 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 12578 }, 12579 { 0, VK_FORMAT_D16_UNORM, VK_SAMPLE_COUNT_1_BIT, 12580 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 12581 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, 12582 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 12583 }, 12584 }; 12585 VkAttachmentReference refs[] = { 12586 { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }, 12587 { 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }, 12588 }; 12589 VkSubpassDescription subpass = { 12590 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 12591 1, &refs[0], nullptr, &refs[1], 12592 0, nullptr 12593 }; 12594 VkRenderPassCreateInfo rpci = { 12595 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 12596 0, 2, attachments, 1, &subpass, 0, nullptr 12597 }; 12598 VkRenderPass rp; 12599 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 12600 ASSERT_VK_SUCCESS(err); 12601 12602 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), rp); 12603 12604 m_errorMonitor->VerifyFound(); 12605 12606 vkDestroyRenderPass(m_device->device(), rp, nullptr); 12607 } 12608 12609 TEST_F(VkLayerTest, CreatePipelineTessPatchDecorationMismatch) { 12610 TEST_DESCRIPTION("Test that an error is produced for a variable output from " 12611 "the TCS without the patch decoration, but consumed in the TES " 12612 "with the decoration."); 12613 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is per-vertex in tessellation control shader stage " 12614 "but per-patch in tessellation evaluation shader stage"); 12615 12616 ASSERT_NO_FATAL_FAILURE(InitState()); 12617 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12618 12619 if (!m_device->phy().features().tessellationShader) { 12620 printf("Device does not support tessellation shaders; skipped.\n"); 12621 return; 12622 } 12623 12624 char const *vsSource = "#version 450\n" 12625 "void main(){}\n"; 12626 char const *tcsSource = "#version 450\n" 12627 "layout(location=0) out int x[];\n" 12628 "layout(vertices=3) out;\n" 12629 "void main(){\n" 12630 " gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n" 12631 " gl_TessLevelInner[0] = 1;\n" 12632 " x[gl_InvocationID] = gl_InvocationID;\n" 12633 "}\n"; 12634 char const *tesSource = "#version 450\n" 12635 "layout(triangles, equal_spacing, cw) in;\n" 12636 "layout(location=0) patch in int x;\n" 12637 "out gl_PerVertex { vec4 gl_Position; };\n" 12638 "void main(){\n" 12639 " gl_Position.xyz = gl_TessCoord;\n" 12640 " gl_Position.w = x;\n" 12641 "}\n"; 12642 char const *fsSource = "#version 450\n" 12643 "layout(location=0) out vec4 color;\n" 12644 "void main(){\n" 12645 " color = vec4(1);\n" 12646 "}\n"; 12647 12648 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 12649 VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this); 12650 VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this); 12651 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 12652 12653 VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0, 12654 VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE}; 12655 12656 VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3}; 12657 12658 VkPipelineObj pipe(m_device); 12659 pipe.SetInputAssembly(&iasci); 12660 pipe.SetTessellation(&tsci); 12661 pipe.AddColorAttachment(); 12662 pipe.AddShader(&vs); 12663 pipe.AddShader(&tcs); 12664 pipe.AddShader(&tes); 12665 pipe.AddShader(&fs); 12666 12667 VkDescriptorSetObj descriptorSet(m_device); 12668 descriptorSet.AppendDummy(); 12669 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 12670 12671 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 12672 12673 m_errorMonitor->VerifyFound(); 12674 } 12675 12676 TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict) { 12677 TEST_DESCRIPTION("Test that an error is produced for a vertex attribute setup where multiple " 12678 "bindings provide the same location"); 12679 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 12680 "Duplicate vertex input binding descriptions for binding 0"); 12681 12682 ASSERT_NO_FATAL_FAILURE(InitState()); 12683 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12684 12685 /* Two binding descriptions for binding 0 */ 12686 VkVertexInputBindingDescription input_bindings[2]; 12687 memset(input_bindings, 0, sizeof(input_bindings)); 12688 12689 VkVertexInputAttributeDescription input_attrib; 12690 memset(&input_attrib, 0, sizeof(input_attrib)); 12691 input_attrib.format = VK_FORMAT_R32_SFLOAT; 12692 12693 char const *vsSource = "#version 450\n" 12694 "\n" 12695 "layout(location=0) in float x;\n" /* attrib provided float */ 12696 "out gl_PerVertex {\n" 12697 " vec4 gl_Position;\n" 12698 "};\n" 12699 "void main(){\n" 12700 " gl_Position = vec4(x);\n" 12701 "}\n"; 12702 char const *fsSource = "#version 450\n" 12703 "\n" 12704 "layout(location=0) out vec4 color;\n" 12705 "void main(){\n" 12706 " color = vec4(1);\n" 12707 "}\n"; 12708 12709 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 12710 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 12711 12712 VkPipelineObj pipe(m_device); 12713 pipe.AddColorAttachment(); 12714 pipe.AddShader(&vs); 12715 pipe.AddShader(&fs); 12716 12717 pipe.AddVertexInputBindings(input_bindings, 2); 12718 pipe.AddVertexInputAttribs(&input_attrib, 1); 12719 12720 VkDescriptorSetObj descriptorSet(m_device); 12721 descriptorSet.AppendDummy(); 12722 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 12723 12724 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 12725 12726 m_errorMonitor->VerifyFound(); 12727 } 12728 12729 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten) { 12730 TEST_DESCRIPTION("Test that an error is produced for a fragment shader which does not " 12731 "provide an output for one of the pipeline's color attachments"); 12732 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attachment 0 not written by fragment shader"); 12733 12734 ASSERT_NO_FATAL_FAILURE(InitState()); 12735 12736 char const *vsSource = "#version 450\n" 12737 "\n" 12738 "out gl_PerVertex {\n" 12739 " vec4 gl_Position;\n" 12740 "};\n" 12741 "void main(){\n" 12742 " gl_Position = vec4(1);\n" 12743 "}\n"; 12744 char const *fsSource = "#version 450\n" 12745 "\n" 12746 "void main(){\n" 12747 "}\n"; 12748 12749 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 12750 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 12751 12752 VkPipelineObj pipe(m_device); 12753 pipe.AddShader(&vs); 12754 pipe.AddShader(&fs); 12755 12756 /* set up CB 0, not written */ 12757 pipe.AddColorAttachment(); 12758 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12759 12760 VkDescriptorSetObj descriptorSet(m_device); 12761 descriptorSet.AppendDummy(); 12762 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 12763 12764 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 12765 12766 m_errorMonitor->VerifyFound(); 12767 } 12768 12769 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed) { 12770 TEST_DESCRIPTION("Test that a warning is produced for a fragment shader which provides a spurious " 12771 "output with no matching attachment"); 12772 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, 12773 "fragment shader writes to output location 1 with no matching attachment"); 12774 12775 ASSERT_NO_FATAL_FAILURE(InitState()); 12776 12777 char const *vsSource = "#version 450\n" 12778 "\n" 12779 "out gl_PerVertex {\n" 12780 " vec4 gl_Position;\n" 12781 "};\n" 12782 "void main(){\n" 12783 " gl_Position = vec4(1);\n" 12784 "}\n"; 12785 char const *fsSource = "#version 450\n" 12786 "\n" 12787 "layout(location=0) out vec4 x;\n" 12788 "layout(location=1) out vec4 y;\n" /* no matching attachment for this */ 12789 "void main(){\n" 12790 " x = vec4(1);\n" 12791 " y = vec4(1);\n" 12792 "}\n"; 12793 12794 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 12795 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 12796 12797 VkPipelineObj pipe(m_device); 12798 pipe.AddShader(&vs); 12799 pipe.AddShader(&fs); 12800 12801 /* set up CB 0, not written */ 12802 pipe.AddColorAttachment(); 12803 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12804 /* FS writes CB 1, but we don't configure it */ 12805 12806 VkDescriptorSetObj descriptorSet(m_device); 12807 descriptorSet.AppendDummy(); 12808 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 12809 12810 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 12811 12812 m_errorMonitor->VerifyFound(); 12813 } 12814 12815 TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch) { 12816 TEST_DESCRIPTION("Test that an error is produced for a mismatch between the fundamental " 12817 "type of an fragment shader output variable, and the format of the corresponding attachment"); 12818 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "does not match fragment shader output type"); 12819 12820 ASSERT_NO_FATAL_FAILURE(InitState()); 12821 12822 char const *vsSource = "#version 450\n" 12823 "\n" 12824 "out gl_PerVertex {\n" 12825 " vec4 gl_Position;\n" 12826 "};\n" 12827 "void main(){\n" 12828 " gl_Position = vec4(1);\n" 12829 "}\n"; 12830 char const *fsSource = "#version 450\n" 12831 "\n" 12832 "layout(location=0) out ivec4 x;\n" /* not UNORM */ 12833 "void main(){\n" 12834 " x = ivec4(1);\n" 12835 "}\n"; 12836 12837 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 12838 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 12839 12840 VkPipelineObj pipe(m_device); 12841 pipe.AddShader(&vs); 12842 pipe.AddShader(&fs); 12843 12844 /* set up CB 0; type is UNORM by default */ 12845 pipe.AddColorAttachment(); 12846 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12847 12848 VkDescriptorSetObj descriptorSet(m_device); 12849 descriptorSet.AppendDummy(); 12850 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 12851 12852 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 12853 12854 m_errorMonitor->VerifyFound(); 12855 } 12856 12857 TEST_F(VkLayerTest, CreatePipelineUniformBlockNotProvided) { 12858 TEST_DESCRIPTION("Test that an error is produced for a shader consuming a uniform " 12859 "block which has no corresponding binding in the pipeline layout"); 12860 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not declared in pipeline layout"); 12861 12862 ASSERT_NO_FATAL_FAILURE(InitState()); 12863 12864 char const *vsSource = "#version 450\n" 12865 "\n" 12866 "out gl_PerVertex {\n" 12867 " vec4 gl_Position;\n" 12868 "};\n" 12869 "void main(){\n" 12870 " gl_Position = vec4(1);\n" 12871 "}\n"; 12872 char const *fsSource = "#version 450\n" 12873 "\n" 12874 "layout(location=0) out vec4 x;\n" 12875 "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n" 12876 "void main(){\n" 12877 " x = vec4(bar.y);\n" 12878 "}\n"; 12879 12880 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 12881 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 12882 12883 VkPipelineObj pipe(m_device); 12884 pipe.AddShader(&vs); 12885 pipe.AddShader(&fs); 12886 12887 /* set up CB 0; type is UNORM by default */ 12888 pipe.AddColorAttachment(); 12889 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12890 12891 VkDescriptorSetObj descriptorSet(m_device); 12892 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 12893 12894 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 12895 12896 m_errorMonitor->VerifyFound(); 12897 } 12898 12899 TEST_F(VkLayerTest, CreatePipelinePushConstantsNotInLayout) { 12900 TEST_DESCRIPTION("Test that an error is produced for a shader consuming push constants " 12901 "which are not provided in the pipeline layout"); 12902 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "not declared in layout"); 12903 12904 ASSERT_NO_FATAL_FAILURE(InitState()); 12905 12906 char const *vsSource = "#version 450\n" 12907 "\n" 12908 "layout(push_constant, std430) uniform foo { float x; } consts;\n" 12909 "out gl_PerVertex {\n" 12910 " vec4 gl_Position;\n" 12911 "};\n" 12912 "void main(){\n" 12913 " gl_Position = vec4(consts.x);\n" 12914 "}\n"; 12915 char const *fsSource = "#version 450\n" 12916 "\n" 12917 "layout(location=0) out vec4 x;\n" 12918 "void main(){\n" 12919 " x = vec4(1);\n" 12920 "}\n"; 12921 12922 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 12923 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 12924 12925 VkPipelineObj pipe(m_device); 12926 pipe.AddShader(&vs); 12927 pipe.AddShader(&fs); 12928 12929 /* set up CB 0; type is UNORM by default */ 12930 pipe.AddColorAttachment(); 12931 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12932 12933 VkDescriptorSetObj descriptorSet(m_device); 12934 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 12935 12936 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 12937 12938 /* should have generated an error -- no push constant ranges provided! */ 12939 m_errorMonitor->VerifyFound(); 12940 } 12941 12942 TEST_F(VkLayerTest, CreatePipelineInputAttachmentMissing) { 12943 TEST_DESCRIPTION("Test that an error is produced for a shader consuming an input attachment " 12944 "which is not included in the subpass description"); 12945 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 12946 "consumes input attachment index 0 but not provided in subpass"); 12947 12948 ASSERT_NO_FATAL_FAILURE(InitState()); 12949 12950 char const *vsSource = "#version 450\n" 12951 "\n" 12952 "out gl_PerVertex {\n" 12953 " vec4 gl_Position;\n" 12954 "};\n" 12955 "void main(){\n" 12956 " gl_Position = vec4(1);\n" 12957 "}\n"; 12958 char const *fsSource = "#version 450\n" 12959 "\n" 12960 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n" 12961 "layout(location=0) out vec4 color;\n" 12962 "void main() {\n" 12963 " color = subpassLoad(x);\n" 12964 "}\n"; 12965 12966 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 12967 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 12968 12969 VkPipelineObj pipe(m_device); 12970 pipe.AddShader(&vs); 12971 pipe.AddShader(&fs); 12972 pipe.AddColorAttachment(); 12973 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 12974 12975 VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}; 12976 VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb}; 12977 VkDescriptorSetLayout dsl; 12978 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl); 12979 ASSERT_VK_SUCCESS(err); 12980 12981 VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr}; 12982 VkPipelineLayout pl; 12983 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl); 12984 ASSERT_VK_SUCCESS(err); 12985 12986 // error here. 12987 pipe.CreateVKPipeline(pl, renderPass()); 12988 12989 m_errorMonitor->VerifyFound(); 12990 12991 vkDestroyPipelineLayout(m_device->device(), pl, nullptr); 12992 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr); 12993 } 12994 12995 TEST_F(VkLayerTest, CreatePipelineInputAttachmentTypeMismatch) { 12996 TEST_DESCRIPTION("Test that an error is produced for a shader consuming an input attachment " 12997 "with a format having a different fundamental type"); 12998 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 12999 "input attachment 0 format of VK_FORMAT_R8G8B8A8_UINT does not match"); 13000 13001 ASSERT_NO_FATAL_FAILURE(InitState()); 13002 13003 char const *vsSource = "#version 450\n" 13004 "\n" 13005 "out gl_PerVertex {\n" 13006 " vec4 gl_Position;\n" 13007 "};\n" 13008 "void main(){\n" 13009 " gl_Position = vec4(1);\n" 13010 "}\n"; 13011 char const *fsSource = "#version 450\n" 13012 "\n" 13013 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n" 13014 "layout(location=0) out vec4 color;\n" 13015 "void main() {\n" 13016 " color = subpassLoad(x);\n" 13017 "}\n"; 13018 13019 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 13020 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 13021 13022 VkPipelineObj pipe(m_device); 13023 pipe.AddShader(&vs); 13024 pipe.AddShader(&fs); 13025 pipe.AddColorAttachment(); 13026 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 13027 13028 VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}; 13029 VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb}; 13030 VkDescriptorSetLayout dsl; 13031 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl); 13032 ASSERT_VK_SUCCESS(err); 13033 13034 VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr}; 13035 VkPipelineLayout pl; 13036 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl); 13037 ASSERT_VK_SUCCESS(err); 13038 13039 VkAttachmentDescription descs[2] = { 13040 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, 13041 VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 13042 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, 13043 {0, VK_FORMAT_R8G8B8A8_UINT, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, 13044 VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL}, 13045 }; 13046 VkAttachmentReference color = { 13047 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 13048 }; 13049 VkAttachmentReference input = { 13050 1, VK_IMAGE_LAYOUT_GENERAL, 13051 }; 13052 13053 VkSubpassDescription sd = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr}; 13054 13055 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr}; 13056 VkRenderPass rp; 13057 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 13058 ASSERT_VK_SUCCESS(err); 13059 13060 // error here. 13061 pipe.CreateVKPipeline(pl, rp); 13062 13063 m_errorMonitor->VerifyFound(); 13064 13065 vkDestroyRenderPass(m_device->device(), rp, nullptr); 13066 vkDestroyPipelineLayout(m_device->device(), pl, nullptr); 13067 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr); 13068 } 13069 13070 TEST_F(VkLayerTest, CreatePipelineInputAttachmentMissingArray) { 13071 TEST_DESCRIPTION("Test that an error is produced for a shader consuming an input attachment " 13072 "which is not included in the subpass description -- array case"); 13073 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 13074 "consumes input attachment index 1 but not provided in subpass"); 13075 13076 ASSERT_NO_FATAL_FAILURE(InitState()); 13077 13078 char const *vsSource = "#version 450\n" 13079 "\n" 13080 "out gl_PerVertex {\n" 13081 " vec4 gl_Position;\n" 13082 "};\n" 13083 "void main(){\n" 13084 " gl_Position = vec4(1);\n" 13085 "}\n"; 13086 char const *fsSource = "#version 450\n" 13087 "\n" 13088 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput xs[2];\n" 13089 "layout(location=0) out vec4 color;\n" 13090 "void main() {\n" 13091 " color = subpassLoad(xs[1]);\n" 13092 "}\n"; 13093 13094 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 13095 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 13096 13097 VkPipelineObj pipe(m_device); 13098 pipe.AddShader(&vs); 13099 pipe.AddShader(&fs); 13100 pipe.AddColorAttachment(); 13101 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 13102 13103 VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}; 13104 VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb}; 13105 VkDescriptorSetLayout dsl; 13106 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl); 13107 ASSERT_VK_SUCCESS(err); 13108 13109 VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr}; 13110 VkPipelineLayout pl; 13111 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl); 13112 ASSERT_VK_SUCCESS(err); 13113 13114 // error here. 13115 pipe.CreateVKPipeline(pl, renderPass()); 13116 13117 m_errorMonitor->VerifyFound(); 13118 13119 vkDestroyPipelineLayout(m_device->device(), pl, nullptr); 13120 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr); 13121 } 13122 13123 TEST_F(VkLayerTest, CreateComputePipelineMissingDescriptor) { 13124 TEST_DESCRIPTION("Test that an error is produced for a compute pipeline consuming a " 13125 "descriptor which is not provided in the pipeline layout"); 13126 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Shader uses descriptor slot 0.0"); 13127 13128 ASSERT_NO_FATAL_FAILURE(InitState()); 13129 13130 char const *csSource = "#version 450\n" 13131 "\n" 13132 "layout(local_size_x=1) in;\n" 13133 "layout(set=0, binding=0) buffer block { vec4 x; };\n" 13134 "void main(){\n" 13135 " x = vec4(1);\n" 13136 "}\n"; 13137 13138 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this); 13139 13140 VkDescriptorSetObj descriptorSet(m_device); 13141 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 13142 13143 VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, 13144 nullptr, 13145 0, 13146 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, 13147 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr}, 13148 descriptorSet.GetPipelineLayout(), 13149 VK_NULL_HANDLE, 13150 -1}; 13151 13152 VkPipeline pipe; 13153 VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe); 13154 13155 m_errorMonitor->VerifyFound(); 13156 13157 if (err == VK_SUCCESS) { 13158 vkDestroyPipeline(m_device->device(), pipe, nullptr); 13159 } 13160 } 13161 13162 TEST_F(VkLayerTest, CreateComputePipelineDescriptorTypeMismatch) { 13163 TEST_DESCRIPTION("Test that an error is produced for a pipeline consuming a " 13164 "descriptor-backed resource of a mismatched type"); 13165 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 13166 "but descriptor of type VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER"); 13167 13168 ASSERT_NO_FATAL_FAILURE(InitState()); 13169 13170 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}; 13171 VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &binding}; 13172 VkDescriptorSetLayout dsl; 13173 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl); 13174 ASSERT_VK_SUCCESS(err); 13175 13176 VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr}; 13177 VkPipelineLayout pl; 13178 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl); 13179 ASSERT_VK_SUCCESS(err); 13180 13181 char const *csSource = "#version 450\n" 13182 "\n" 13183 "layout(local_size_x=1) in;\n" 13184 "layout(set=0, binding=0) buffer block { vec4 x; };\n" 13185 "void main() {\n" 13186 " x.x = 1.0f;\n" 13187 "}\n"; 13188 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this); 13189 13190 VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, 13191 nullptr, 13192 0, 13193 {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, 13194 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr}, 13195 pl, 13196 VK_NULL_HANDLE, 13197 -1}; 13198 13199 VkPipeline pipe; 13200 err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe); 13201 13202 m_errorMonitor->VerifyFound(); 13203 13204 if (err == VK_SUCCESS) { 13205 vkDestroyPipeline(m_device->device(), pipe, nullptr); 13206 } 13207 13208 vkDestroyPipelineLayout(m_device->device(), pl, nullptr); 13209 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr); 13210 } 13211 13212 TEST_F(VkLayerTest, DrawTimeImageViewTypeMismatchWithPipeline) { 13213 TEST_DESCRIPTION("Test that an error is produced when an image view type " 13214 "does not match the dimensionality declared in the shader"); 13215 13216 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "requires an image view of type VK_IMAGE_VIEW_TYPE_3D"); 13217 13218 ASSERT_NO_FATAL_FAILURE(InitState()); 13219 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 13220 13221 char const *vsSource = "#version 450\n" 13222 "\n" 13223 "out gl_PerVertex { vec4 gl_Position; };\n" 13224 "void main() { gl_Position = vec4(0); }\n"; 13225 char const *fsSource = "#version 450\n" 13226 "\n" 13227 "layout(set=0, binding=0) uniform sampler3D s;\n" 13228 "layout(location=0) out vec4 color;\n" 13229 "void main() {\n" 13230 " color = texture(s, vec3(0));\n" 13231 "}\n"; 13232 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 13233 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 13234 13235 VkPipelineObj pipe(m_device); 13236 pipe.AddShader(&vs); 13237 pipe.AddShader(&fs); 13238 pipe.AddColorAttachment(); 13239 13240 VkTextureObj texture(m_device, nullptr); 13241 VkSamplerObj sampler(m_device); 13242 13243 VkDescriptorSetObj descriptorSet(m_device); 13244 descriptorSet.AppendSamplerTexture(&sampler, &texture); 13245 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 13246 13247 VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 13248 ASSERT_VK_SUCCESS(err); 13249 13250 BeginCommandBuffer(); 13251 13252 m_commandBuffer->BindPipeline(pipe); 13253 m_commandBuffer->BindDescriptorSet(descriptorSet); 13254 13255 VkViewport viewport = {0, 0, 16, 16, 0, 1}; 13256 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 13257 VkRect2D scissor = {{0, 0}, {16, 16}}; 13258 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 13259 13260 // error produced here. 13261 vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); 13262 13263 m_errorMonitor->VerifyFound(); 13264 13265 EndCommandBuffer(); 13266 } 13267 13268 TEST_F(VkLayerTest, DrawTimeImageMultisampleMismatchWithPipeline) { 13269 TEST_DESCRIPTION("Test that an error is produced when a multisampled images " 13270 "are consumed via singlesample images types in the shader, or vice versa."); 13271 13272 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "requires bound image to have multiple samples"); 13273 13274 ASSERT_NO_FATAL_FAILURE(InitState()); 13275 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 13276 13277 char const *vsSource = "#version 450\n" 13278 "\n" 13279 "out gl_PerVertex { vec4 gl_Position; };\n" 13280 "void main() { gl_Position = vec4(0); }\n"; 13281 char const *fsSource = "#version 450\n" 13282 "\n" 13283 "layout(set=0, binding=0) uniform sampler2DMS s;\n" 13284 "layout(location=0) out vec4 color;\n" 13285 "void main() {\n" 13286 " color = texelFetch(s, ivec2(0), 0);\n" 13287 "}\n"; 13288 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 13289 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 13290 13291 VkPipelineObj pipe(m_device); 13292 pipe.AddShader(&vs); 13293 pipe.AddShader(&fs); 13294 pipe.AddColorAttachment(); 13295 13296 VkTextureObj texture(m_device, nullptr); 13297 VkSamplerObj sampler(m_device); 13298 13299 VkDescriptorSetObj descriptorSet(m_device); 13300 descriptorSet.AppendSamplerTexture(&sampler, &texture); 13301 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 13302 13303 VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 13304 ASSERT_VK_SUCCESS(err); 13305 13306 BeginCommandBuffer(); 13307 13308 m_commandBuffer->BindPipeline(pipe); 13309 m_commandBuffer->BindDescriptorSet(descriptorSet); 13310 13311 VkViewport viewport = {0, 0, 16, 16, 0, 1}; 13312 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport); 13313 VkRect2D scissor = {{0, 0}, {16, 16}}; 13314 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor); 13315 13316 // error produced here. 13317 vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0); 13318 13319 m_errorMonitor->VerifyFound(); 13320 13321 EndCommandBuffer(); 13322 } 13323 13324 #endif // SHADER_CHECKER_TESTS 13325 13326 #if DEVICE_LIMITS_TESTS 13327 TEST_F(VkLayerTest, CreateImageLimitsViolationMaxWidth) { 13328 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "CreateImage extents exceed allowable limits for format"); 13329 13330 ASSERT_NO_FATAL_FAILURE(InitState()); 13331 13332 // Create an image 13333 VkImage image; 13334 13335 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 13336 const int32_t tex_width = 32; 13337 const int32_t tex_height = 32; 13338 13339 VkImageCreateInfo image_create_info = {}; 13340 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 13341 image_create_info.pNext = NULL; 13342 image_create_info.imageType = VK_IMAGE_TYPE_2D; 13343 image_create_info.format = tex_format; 13344 image_create_info.extent.width = tex_width; 13345 image_create_info.extent.height = tex_height; 13346 image_create_info.extent.depth = 1; 13347 image_create_info.mipLevels = 1; 13348 image_create_info.arrayLayers = 1; 13349 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 13350 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 13351 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 13352 image_create_info.flags = 0; 13353 13354 // Introduce error by sending down a bogus width extent 13355 image_create_info.extent.width = 65536; 13356 vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 13357 13358 m_errorMonitor->VerifyFound(); 13359 } 13360 13361 TEST_F(VkLayerTest, CreateImageLimitsViolationMinWidth) { 13362 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 13363 "CreateImage extents is 0 for at least one required dimension"); 13364 13365 ASSERT_NO_FATAL_FAILURE(InitState()); 13366 13367 // Create an image 13368 VkImage image; 13369 13370 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 13371 const int32_t tex_width = 32; 13372 const int32_t tex_height = 32; 13373 13374 VkImageCreateInfo image_create_info = {}; 13375 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 13376 image_create_info.pNext = NULL; 13377 image_create_info.imageType = VK_IMAGE_TYPE_2D; 13378 image_create_info.format = tex_format; 13379 image_create_info.extent.width = tex_width; 13380 image_create_info.extent.height = tex_height; 13381 image_create_info.extent.depth = 1; 13382 image_create_info.mipLevels = 1; 13383 image_create_info.arrayLayers = 1; 13384 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 13385 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 13386 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 13387 image_create_info.flags = 0; 13388 13389 // Introduce error by sending down a bogus width extent 13390 image_create_info.extent.width = 0; 13391 vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 13392 13393 m_errorMonitor->VerifyFound(); 13394 } 13395 #endif // DEVICE_LIMITS_TESTS 13396 13397 #if IMAGE_TESTS 13398 TEST_F(VkLayerTest, AttachmentDescriptionUndefinedFormat) { 13399 TEST_DESCRIPTION("Create a render pass with an attachment description " 13400 "format set to VK_FORMAT_UNDEFINED"); 13401 13402 ASSERT_NO_FATAL_FAILURE(InitState()); 13403 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 13404 13405 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "format is VK_FORMAT_UNDEFINED"); 13406 13407 VkAttachmentReference color_attach = {}; 13408 color_attach.layout = VK_IMAGE_LAYOUT_GENERAL; 13409 color_attach.attachment = 0; 13410 VkSubpassDescription subpass = {}; 13411 subpass.colorAttachmentCount = 1; 13412 subpass.pColorAttachments = &color_attach; 13413 13414 VkRenderPassCreateInfo rpci = {}; 13415 rpci.subpassCount = 1; 13416 rpci.pSubpasses = &subpass; 13417 rpci.attachmentCount = 1; 13418 VkAttachmentDescription attach_desc = {}; 13419 attach_desc.format = VK_FORMAT_UNDEFINED; 13420 rpci.pAttachments = &attach_desc; 13421 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 13422 VkRenderPass rp; 13423 VkResult result = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 13424 13425 m_errorMonitor->VerifyFound(); 13426 13427 if (result == VK_SUCCESS) { 13428 vkDestroyRenderPass(m_device->device(), rp, NULL); 13429 } 13430 } 13431 13432 TEST_F(VkLayerTest, InvalidImageView) { 13433 VkResult err; 13434 13435 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with baseMipLevel 10 "); 13436 13437 ASSERT_NO_FATAL_FAILURE(InitState()); 13438 13439 // Create an image and try to create a view with bad baseMipLevel 13440 VkImage image; 13441 13442 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 13443 const int32_t tex_width = 32; 13444 const int32_t tex_height = 32; 13445 13446 VkImageCreateInfo image_create_info = {}; 13447 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 13448 image_create_info.pNext = NULL; 13449 image_create_info.imageType = VK_IMAGE_TYPE_2D; 13450 image_create_info.format = tex_format; 13451 image_create_info.extent.width = tex_width; 13452 image_create_info.extent.height = tex_height; 13453 image_create_info.extent.depth = 1; 13454 image_create_info.mipLevels = 1; 13455 image_create_info.arrayLayers = 1; 13456 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 13457 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 13458 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 13459 image_create_info.flags = 0; 13460 13461 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 13462 ASSERT_VK_SUCCESS(err); 13463 13464 VkImageViewCreateInfo image_view_create_info = {}; 13465 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 13466 image_view_create_info.image = image; 13467 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; 13468 image_view_create_info.format = tex_format; 13469 image_view_create_info.subresourceRange.layerCount = 1; 13470 image_view_create_info.subresourceRange.baseMipLevel = 10; // cause an error 13471 image_view_create_info.subresourceRange.levelCount = 1; 13472 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 13473 13474 VkImageView view; 13475 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view); 13476 13477 m_errorMonitor->VerifyFound(); 13478 vkDestroyImage(m_device->device(), image, NULL); 13479 } 13480 13481 TEST_F(VkLayerTest, CreateImageViewNoMemoryBoundToImage) { 13482 VkResult err; 13483 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 13484 " used with no memory bound. Memory should be bound by calling vkBindImageMemory()."); 13485 13486 ASSERT_NO_FATAL_FAILURE(InitState()); 13487 13488 // Create an image and try to create a view with no memory backing the image 13489 VkImage image; 13490 13491 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 13492 const int32_t tex_width = 32; 13493 const int32_t tex_height = 32; 13494 13495 VkImageCreateInfo image_create_info = {}; 13496 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 13497 image_create_info.pNext = NULL; 13498 image_create_info.imageType = VK_IMAGE_TYPE_2D; 13499 image_create_info.format = tex_format; 13500 image_create_info.extent.width = tex_width; 13501 image_create_info.extent.height = tex_height; 13502 image_create_info.extent.depth = 1; 13503 image_create_info.mipLevels = 1; 13504 image_create_info.arrayLayers = 1; 13505 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 13506 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 13507 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 13508 image_create_info.flags = 0; 13509 13510 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 13511 ASSERT_VK_SUCCESS(err); 13512 13513 VkImageViewCreateInfo image_view_create_info = {}; 13514 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 13515 image_view_create_info.image = image; 13516 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; 13517 image_view_create_info.format = tex_format; 13518 image_view_create_info.subresourceRange.layerCount = 1; 13519 image_view_create_info.subresourceRange.baseMipLevel = 0; 13520 image_view_create_info.subresourceRange.levelCount = 1; 13521 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 13522 13523 VkImageView view; 13524 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view); 13525 13526 m_errorMonitor->VerifyFound(); 13527 vkDestroyImage(m_device->device(), image, NULL); 13528 // If last error is success, it still created the view, so delete it. 13529 if (err == VK_SUCCESS) { 13530 vkDestroyImageView(m_device->device(), view, NULL); 13531 } 13532 } 13533 13534 TEST_F(VkLayerTest, InvalidImageViewAspect) { 13535 TEST_DESCRIPTION("Create an image and try to create a view with an invalid aspectMask"); 13536 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView: Color image " 13537 "formats must have ONLY the " 13538 "VK_IMAGE_ASPECT_COLOR_BIT set"); 13539 13540 ASSERT_NO_FATAL_FAILURE(InitState()); 13541 13542 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 13543 VkImageObj image(m_device); 13544 image.init(32, 32, tex_format, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_LINEAR, 0); 13545 ASSERT_TRUE(image.initialized()); 13546 13547 VkImageViewCreateInfo image_view_create_info = {}; 13548 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 13549 image_view_create_info.image = image.handle(); 13550 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; 13551 image_view_create_info.format = tex_format; 13552 image_view_create_info.subresourceRange.baseMipLevel = 0; 13553 image_view_create_info.subresourceRange.levelCount = 1; 13554 // Cause an error by setting an invalid image aspect 13555 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT; 13556 13557 VkImageView view; 13558 vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view); 13559 13560 m_errorMonitor->VerifyFound(); 13561 } 13562 13563 TEST_F(VkLayerTest, CopyImageLayerCountMismatch) { 13564 VkResult err; 13565 bool pass; 13566 13567 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 13568 "vkCmdCopyImage: number of layers in source and destination subresources for pRegions"); 13569 13570 ASSERT_NO_FATAL_FAILURE(InitState()); 13571 13572 // Create two images of different types and try to copy between them 13573 VkImage srcImage; 13574 VkImage dstImage; 13575 VkDeviceMemory srcMem; 13576 VkDeviceMemory destMem; 13577 VkMemoryRequirements memReqs; 13578 13579 VkImageCreateInfo image_create_info = {}; 13580 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 13581 image_create_info.pNext = NULL; 13582 image_create_info.imageType = VK_IMAGE_TYPE_2D; 13583 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; 13584 image_create_info.extent.width = 32; 13585 image_create_info.extent.height = 32; 13586 image_create_info.extent.depth = 1; 13587 image_create_info.mipLevels = 1; 13588 image_create_info.arrayLayers = 4; 13589 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 13590 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 13591 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 13592 image_create_info.flags = 0; 13593 13594 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage); 13595 ASSERT_VK_SUCCESS(err); 13596 13597 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; 13598 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage); 13599 ASSERT_VK_SUCCESS(err); 13600 13601 // Allocate memory 13602 VkMemoryAllocateInfo memAlloc = {}; 13603 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 13604 memAlloc.pNext = NULL; 13605 memAlloc.allocationSize = 0; 13606 memAlloc.memoryTypeIndex = 0; 13607 13608 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs); 13609 memAlloc.allocationSize = memReqs.size; 13610 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 13611 ASSERT_TRUE(pass); 13612 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem); 13613 ASSERT_VK_SUCCESS(err); 13614 13615 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs); 13616 memAlloc.allocationSize = memReqs.size; 13617 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 13618 ASSERT_VK_SUCCESS(err); 13619 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem); 13620 ASSERT_VK_SUCCESS(err); 13621 13622 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0); 13623 ASSERT_VK_SUCCESS(err); 13624 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0); 13625 ASSERT_VK_SUCCESS(err); 13626 13627 BeginCommandBuffer(); 13628 VkImageCopy copyRegion; 13629 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 13630 copyRegion.srcSubresource.mipLevel = 0; 13631 copyRegion.srcSubresource.baseArrayLayer = 0; 13632 copyRegion.srcSubresource.layerCount = 1; 13633 copyRegion.srcOffset.x = 0; 13634 copyRegion.srcOffset.y = 0; 13635 copyRegion.srcOffset.z = 0; 13636 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 13637 copyRegion.dstSubresource.mipLevel = 0; 13638 copyRegion.dstSubresource.baseArrayLayer = 0; 13639 // Introduce failure by forcing the dst layerCount to differ from src 13640 copyRegion.dstSubresource.layerCount = 3; 13641 copyRegion.dstOffset.x = 0; 13642 copyRegion.dstOffset.y = 0; 13643 copyRegion.dstOffset.z = 0; 13644 copyRegion.extent.width = 1; 13645 copyRegion.extent.height = 1; 13646 copyRegion.extent.depth = 1; 13647 m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region); 13648 EndCommandBuffer(); 13649 13650 m_errorMonitor->VerifyFound(); 13651 13652 vkDestroyImage(m_device->device(), srcImage, NULL); 13653 vkDestroyImage(m_device->device(), dstImage, NULL); 13654 vkFreeMemory(m_device->device(), srcMem, NULL); 13655 vkFreeMemory(m_device->device(), destMem, NULL); 13656 } 13657 13658 TEST_F(VkLayerTest, ImageLayerUnsupportedFormat) { 13659 13660 TEST_DESCRIPTION("Creating images with unsuported formats "); 13661 13662 ASSERT_NO_FATAL_FAILURE(InitState()); 13663 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 13664 VkImageObj image(m_device); 13665 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 13666 VK_IMAGE_TILING_OPTIMAL, 0); 13667 ASSERT_TRUE(image.initialized()); 13668 13669 // Create image with unsupported format - Expect FORMAT_UNSUPPORTED 13670 VkImageCreateInfo image_create_info; 13671 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 13672 image_create_info.pNext = NULL; 13673 image_create_info.imageType = VK_IMAGE_TYPE_2D; 13674 image_create_info.format = VK_FORMAT_UNDEFINED; 13675 image_create_info.extent.width = 32; 13676 image_create_info.extent.height = 32; 13677 image_create_info.extent.depth = 1; 13678 image_create_info.mipLevels = 1; 13679 image_create_info.arrayLayers = 1; 13680 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 13681 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 13682 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 13683 image_create_info.flags = 0; 13684 13685 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 13686 "vkCreateImage: VkFormat for image must not be VK_FORMAT_UNDEFINED"); 13687 13688 VkImage localImage; 13689 vkCreateImage(m_device->handle(), &image_create_info, NULL, &localImage); 13690 m_errorMonitor->VerifyFound(); 13691 13692 VkFormat unsupported = VK_FORMAT_UNDEFINED; 13693 // Look for a format that is COMPLETELY unsupported with this hardware 13694 for (int f = VK_FORMAT_BEGIN_RANGE; f <= VK_FORMAT_END_RANGE; f++) { 13695 VkFormat format = static_cast<VkFormat>(f); 13696 VkFormatProperties fProps = m_device->format_properties(format); 13697 if (format != VK_FORMAT_UNDEFINED && fProps.linearTilingFeatures == 0 && fProps.optimalTilingFeatures == 0) { 13698 unsupported = format; 13699 break; 13700 } 13701 } 13702 13703 if (unsupported != VK_FORMAT_UNDEFINED) { 13704 image_create_info.format = unsupported; 13705 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is an unsupported format"); 13706 13707 vkCreateImage(m_device->handle(), &image_create_info, NULL, &localImage); 13708 m_errorMonitor->VerifyFound(); 13709 } 13710 } 13711 13712 TEST_F(VkLayerTest, ImageLayerViewTests) { 13713 VkResult ret; 13714 TEST_DESCRIPTION("Passing bad parameters to CreateImageView"); 13715 13716 ASSERT_NO_FATAL_FAILURE(InitState()); 13717 13718 VkImageObj image(m_device); 13719 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 13720 VK_IMAGE_TILING_OPTIMAL, 0); 13721 ASSERT_TRUE(image.initialized()); 13722 13723 VkImageView imgView; 13724 VkImageViewCreateInfo imgViewInfo = {}; 13725 imgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 13726 imgViewInfo.image = image.handle(); 13727 imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; 13728 imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM; 13729 imgViewInfo.subresourceRange.layerCount = 1; 13730 imgViewInfo.subresourceRange.baseMipLevel = 0; 13731 imgViewInfo.subresourceRange.levelCount = 1; 13732 imgViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 13733 13734 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with baseMipLevel"); 13735 // View can't have baseMipLevel >= image's mipLevels - Expect 13736 // VIEW_CREATE_ERROR 13737 imgViewInfo.subresourceRange.baseMipLevel = 1; 13738 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView); 13739 m_errorMonitor->VerifyFound(); 13740 imgViewInfo.subresourceRange.baseMipLevel = 0; 13741 13742 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with baseArrayLayer"); 13743 // View can't have baseArrayLayer >= image's arraySize - Expect 13744 // VIEW_CREATE_ERROR 13745 imgViewInfo.subresourceRange.baseArrayLayer = 1; 13746 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView); 13747 m_errorMonitor->VerifyFound(); 13748 imgViewInfo.subresourceRange.baseArrayLayer = 0; 13749 13750 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with 0 in " 13751 "pCreateInfo->subresourceRange." 13752 "levelCount"); 13753 // View's levelCount can't be 0 - Expect VIEW_CREATE_ERROR 13754 imgViewInfo.subresourceRange.levelCount = 0; 13755 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView); 13756 m_errorMonitor->VerifyFound(); 13757 imgViewInfo.subresourceRange.levelCount = 1; 13758 13759 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreateImageView called with 0 in " 13760 "pCreateInfo->subresourceRange." 13761 "layerCount"); 13762 // View's layerCount can't be 0 - Expect VIEW_CREATE_ERROR 13763 imgViewInfo.subresourceRange.layerCount = 0; 13764 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView); 13765 m_errorMonitor->VerifyFound(); 13766 imgViewInfo.subresourceRange.layerCount = 1; 13767 13768 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "but both must be color formats"); 13769 // Can't use depth format for view into color image - Expect INVALID_FORMAT 13770 imgViewInfo.format = VK_FORMAT_D24_UNORM_S8_UINT; 13771 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView); 13772 m_errorMonitor->VerifyFound(); 13773 imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM; 13774 13775 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Formats MUST be IDENTICAL unless " 13776 "VK_IMAGE_CREATE_MUTABLE_FORMAT BIT " 13777 "was set on image creation."); 13778 // Same compatibility class but no MUTABLE_FORMAT bit - Expect 13779 // VIEW_CREATE_ERROR 13780 imgViewInfo.format = VK_FORMAT_B8G8R8A8_UINT; 13781 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView); 13782 m_errorMonitor->VerifyFound(); 13783 imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM; 13784 13785 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "can support ImageViews with " 13786 "differing formats but they must be " 13787 "in the same compatibility class."); 13788 // Have MUTABLE_FORMAT bit but not in same compatibility class - Expect 13789 // VIEW_CREATE_ERROR 13790 VkImageCreateInfo mutImgInfo = image.create_info(); 13791 VkImage mutImage; 13792 mutImgInfo.format = VK_FORMAT_R8_UINT; 13793 assert(m_device->format_properties(VK_FORMAT_R8_UINT).optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); 13794 mutImgInfo.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; 13795 mutImgInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 13796 ret = vkCreateImage(m_device->handle(), &mutImgInfo, NULL, &mutImage); 13797 ASSERT_VK_SUCCESS(ret); 13798 imgViewInfo.image = mutImage; 13799 vkCreateImageView(m_device->handle(), &imgViewInfo, NULL, &imgView); 13800 m_errorMonitor->VerifyFound(); 13801 imgViewInfo.image = image.handle(); 13802 vkDestroyImage(m_device->handle(), mutImage, NULL); 13803 } 13804 13805 TEST_F(VkLayerTest, MiscImageLayerTests) { 13806 13807 TEST_DESCRIPTION("Image layer tests that don't belong elsewhare"); 13808 13809 ASSERT_NO_FATAL_FAILURE(InitState()); 13810 13811 VkImageObj image(m_device); 13812 image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 13813 VK_IMAGE_TILING_OPTIMAL, 0); 13814 ASSERT_TRUE(image.initialized()); 13815 13816 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "number of layers in image subresource is zero"); 13817 vk_testing::Buffer buffer; 13818 VkMemoryPropertyFlags reqs = 0; 13819 buffer.init_as_src(*m_device, 128 * 128 * 4, reqs); 13820 VkBufferImageCopy region = {}; 13821 region.bufferRowLength = 128; 13822 region.bufferImageHeight = 128; 13823 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 13824 // layerCount can't be 0 - Expect MISMATCHED_IMAGE_ASPECT 13825 region.imageSubresource.layerCount = 0; 13826 region.imageExtent.height = 4; 13827 region.imageExtent.width = 4; 13828 region.imageExtent.depth = 1; 13829 m_commandBuffer->BeginCommandBuffer(); 13830 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(), 13831 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); 13832 m_errorMonitor->VerifyFound(); 13833 region.imageSubresource.layerCount = 1; 13834 13835 // BufferOffset must be a multiple of the calling command's VkImage parameter's texel size 13836 // Introduce failure by setting bufferOffset to 1 and 1/2 texels 13837 region.bufferOffset = 6; 13838 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must be a multiple of this format's texel size"); 13839 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(), 13840 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); 13841 m_errorMonitor->VerifyFound(); 13842 13843 // BufferOffset must be a multiple of 4 13844 // Introduce failure by setting bufferOffset to a value not divisible by 4 13845 region.bufferOffset = 6; 13846 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "must be a multiple of 4"); 13847 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(), 13848 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); 13849 m_errorMonitor->VerifyFound(); 13850 13851 // BufferRowLength must be 0, or greater than or equal to the width member of imageExtent 13852 region.bufferOffset = 0; 13853 region.imageExtent.height = 128; 13854 region.imageExtent.width = 128; 13855 // Introduce failure by setting bufferRowLength > 0 but less than width 13856 region.bufferRowLength = 64; 13857 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 13858 "must be zero or greater-than-or-equal-to imageExtent.width"); 13859 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(), 13860 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); 13861 m_errorMonitor->VerifyFound(); 13862 13863 // BufferImageHeight must be 0, or greater than or equal to the height member of imageExtent 13864 region.bufferRowLength = 128; 13865 // Introduce failure by setting bufferRowHeight > 0 but less than height 13866 region.bufferImageHeight = 64; 13867 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 13868 "must be zero or greater-than-or-equal-to imageExtent.height"); 13869 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(), 13870 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); 13871 m_errorMonitor->VerifyFound(); 13872 13873 region.bufferImageHeight = 128; 13874 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "aspectMasks for each region must " 13875 "specify only COLOR or DEPTH or " 13876 "STENCIL"); 13877 // Expect MISMATCHED_IMAGE_ASPECT 13878 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT; 13879 vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(), 13880 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); 13881 m_errorMonitor->VerifyFound(); 13882 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 13883 13884 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 13885 "If the format of srcImage is a depth, stencil, depth stencil or " 13886 "integer-based format then filter must be VK_FILTER_NEAREST"); 13887 // Expect INVALID_FILTER 13888 VkImageObj intImage1(m_device); 13889 intImage1.init(128, 128, VK_FORMAT_R8_UINT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 13890 VkImageObj intImage2(m_device); 13891 intImage2.init(128, 128, VK_FORMAT_R8_UINT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 13892 VkImageBlit blitRegion = {}; 13893 blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 13894 blitRegion.srcSubresource.baseArrayLayer = 0; 13895 blitRegion.srcSubresource.layerCount = 1; 13896 blitRegion.srcSubresource.mipLevel = 0; 13897 blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 13898 blitRegion.dstSubresource.baseArrayLayer = 0; 13899 blitRegion.dstSubresource.layerCount = 1; 13900 blitRegion.dstSubresource.mipLevel = 0; 13901 13902 vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), intImage1.handle(), intImage1.layout(), intImage2.handle(), 13903 intImage2.layout(), 16, &blitRegion, VK_FILTER_LINEAR); 13904 m_errorMonitor->VerifyFound(); 13905 13906 // Look for NULL-blit warning 13907 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "Offsets specify a zero-volume area."); 13908 vkCmdBlitImage(m_commandBuffer->GetBufferHandle(), intImage1.handle(), intImage1.layout(), intImage2.handle(), 13909 intImage2.layout(), 1, &blitRegion, VK_FILTER_LINEAR); 13910 m_errorMonitor->VerifyFound(); 13911 13912 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "called with 0 in ppMemoryBarriers"); 13913 VkImageMemoryBarrier img_barrier; 13914 img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 13915 img_barrier.pNext = NULL; 13916 img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; 13917 img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 13918 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 13919 img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 13920 img_barrier.image = image.handle(); 13921 img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 13922 img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 13923 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 13924 img_barrier.subresourceRange.baseArrayLayer = 0; 13925 img_barrier.subresourceRange.baseMipLevel = 0; 13926 // layerCount should not be 0 - Expect INVALID_IMAGE_RESOURCE 13927 img_barrier.subresourceRange.layerCount = 0; 13928 img_barrier.subresourceRange.levelCount = 1; 13929 vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, 13930 nullptr, 0, nullptr, 1, &img_barrier); 13931 m_errorMonitor->VerifyFound(); 13932 img_barrier.subresourceRange.layerCount = 1; 13933 } 13934 13935 TEST_F(VkLayerTest, ImageFormatLimits) { 13936 13937 TEST_DESCRIPTION("Exceed the limits of image format "); 13938 13939 ASSERT_NO_FATAL_FAILURE(InitState()); 13940 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "CreateImage extents exceed allowable limits for format"); 13941 VkImageCreateInfo image_create_info = {}; 13942 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 13943 image_create_info.pNext = NULL; 13944 image_create_info.imageType = VK_IMAGE_TYPE_2D; 13945 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; 13946 image_create_info.extent.width = 32; 13947 image_create_info.extent.height = 32; 13948 image_create_info.extent.depth = 1; 13949 image_create_info.mipLevels = 1; 13950 image_create_info.arrayLayers = 1; 13951 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 13952 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 13953 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 13954 image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 13955 image_create_info.flags = 0; 13956 13957 VkImage nullImg; 13958 VkImageFormatProperties imgFmtProps; 13959 vkGetPhysicalDeviceImageFormatProperties(gpu(), image_create_info.format, image_create_info.imageType, image_create_info.tiling, 13960 image_create_info.usage, image_create_info.flags, &imgFmtProps); 13961 image_create_info.extent.depth = imgFmtProps.maxExtent.depth + 1; 13962 // Expect INVALID_FORMAT_LIMITS_VIOLATION 13963 vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg); 13964 m_errorMonitor->VerifyFound(); 13965 image_create_info.extent.depth = 1; 13966 13967 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "exceeds allowable maximum supported by format of"); 13968 image_create_info.mipLevels = imgFmtProps.maxMipLevels + 1; 13969 // Expect INVALID_FORMAT_LIMITS_VIOLATION 13970 vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg); 13971 m_errorMonitor->VerifyFound(); 13972 image_create_info.mipLevels = 1; 13973 13974 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "exceeds allowable maximum supported by format of"); 13975 image_create_info.arrayLayers = imgFmtProps.maxArrayLayers + 1; 13976 // Expect INVALID_FORMAT_LIMITS_VIOLATION 13977 vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg); 13978 m_errorMonitor->VerifyFound(); 13979 image_create_info.arrayLayers = 1; 13980 13981 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is not supported by format"); 13982 int samples = imgFmtProps.sampleCounts >> 1; 13983 image_create_info.samples = (VkSampleCountFlagBits)samples; 13984 // Expect INVALID_FORMAT_LIMITS_VIOLATION 13985 vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg); 13986 m_errorMonitor->VerifyFound(); 13987 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 13988 13989 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "pCreateInfo->initialLayout, must be " 13990 "VK_IMAGE_LAYOUT_UNDEFINED or " 13991 "VK_IMAGE_LAYOUT_PREINITIALIZED"); 13992 image_create_info.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 13993 // Expect INVALID_LAYOUT 13994 vkCreateImage(m_device->handle(), &image_create_info, NULL, &nullImg); 13995 m_errorMonitor->VerifyFound(); 13996 image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 13997 } 13998 13999 TEST_F(VkLayerTest, CopyImageSrcSizeExceeded) { 14000 14001 // Image copy with source region specified greater than src image size 14002 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01175); 14003 14004 ASSERT_NO_FATAL_FAILURE(InitState()); 14005 14006 VkImageObj src_image(m_device); 14007 src_image.init(32, 32, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_LINEAR, 0); 14008 VkImageObj dst_image(m_device); 14009 dst_image.init(64, 64, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_LINEAR, 0); 14010 14011 BeginCommandBuffer(); 14012 VkImageCopy copy_region; 14013 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14014 copy_region.srcSubresource.mipLevel = 0; 14015 copy_region.srcSubresource.baseArrayLayer = 0; 14016 copy_region.srcSubresource.layerCount = 0; 14017 copy_region.srcOffset.x = 0; 14018 copy_region.srcOffset.y = 0; 14019 copy_region.srcOffset.z = 0; 14020 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14021 copy_region.dstSubresource.mipLevel = 0; 14022 copy_region.dstSubresource.baseArrayLayer = 0; 14023 copy_region.dstSubresource.layerCount = 0; 14024 copy_region.dstOffset.x = 0; 14025 copy_region.dstOffset.y = 0; 14026 copy_region.dstOffset.z = 0; 14027 copy_region.extent.width = 64; 14028 copy_region.extent.height = 64; 14029 copy_region.extent.depth = 1; 14030 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 14031 ©_region); 14032 EndCommandBuffer(); 14033 14034 m_errorMonitor->VerifyFound(); 14035 } 14036 14037 TEST_F(VkLayerTest, CopyImageDstSizeExceeded) { 14038 14039 // Image copy with dest region specified greater than dest image size 14040 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01176); 14041 14042 ASSERT_NO_FATAL_FAILURE(InitState()); 14043 14044 VkImageObj src_image(m_device); 14045 src_image.init(64, 64, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_LINEAR, 0); 14046 VkImageObj dst_image(m_device); 14047 dst_image.init(32, 32, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_LINEAR, 0); 14048 14049 BeginCommandBuffer(); 14050 VkImageCopy copy_region; 14051 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14052 copy_region.srcSubresource.mipLevel = 0; 14053 copy_region.srcSubresource.baseArrayLayer = 0; 14054 copy_region.srcSubresource.layerCount = 0; 14055 copy_region.srcOffset.x = 0; 14056 copy_region.srcOffset.y = 0; 14057 copy_region.srcOffset.z = 0; 14058 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14059 copy_region.dstSubresource.mipLevel = 0; 14060 copy_region.dstSubresource.baseArrayLayer = 0; 14061 copy_region.dstSubresource.layerCount = 0; 14062 copy_region.dstOffset.x = 0; 14063 copy_region.dstOffset.y = 0; 14064 copy_region.dstOffset.z = 0; 14065 copy_region.extent.width = 64; 14066 copy_region.extent.height = 64; 14067 copy_region.extent.depth = 1; 14068 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1, 14069 ©_region); 14070 EndCommandBuffer(); 14071 14072 m_errorMonitor->VerifyFound(); 14073 } 14074 14075 TEST_F(VkLayerTest, CopyImageFormatSizeMismatch) { 14076 VkResult err; 14077 bool pass; 14078 14079 // Create color images with different format sizes and try to copy between them 14080 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 14081 "vkCmdCopyImage called with unmatched source and dest image format sizes"); 14082 14083 ASSERT_NO_FATAL_FAILURE(InitState()); 14084 14085 // Create two images of different types and try to copy between them 14086 VkImage srcImage; 14087 VkImage dstImage; 14088 VkDeviceMemory srcMem; 14089 VkDeviceMemory destMem; 14090 VkMemoryRequirements memReqs; 14091 14092 VkImageCreateInfo image_create_info = {}; 14093 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 14094 image_create_info.pNext = NULL; 14095 image_create_info.imageType = VK_IMAGE_TYPE_2D; 14096 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; 14097 image_create_info.extent.width = 32; 14098 image_create_info.extent.height = 32; 14099 image_create_info.extent.depth = 1; 14100 image_create_info.mipLevels = 1; 14101 image_create_info.arrayLayers = 1; 14102 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 14103 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 14104 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 14105 image_create_info.flags = 0; 14106 14107 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage); 14108 ASSERT_VK_SUCCESS(err); 14109 14110 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; 14111 // Introduce failure by creating second image with a different-sized format. 14112 image_create_info.format = VK_FORMAT_R5G5B5A1_UNORM_PACK16; 14113 14114 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage); 14115 ASSERT_VK_SUCCESS(err); 14116 14117 // Allocate memory 14118 VkMemoryAllocateInfo memAlloc = {}; 14119 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 14120 memAlloc.pNext = NULL; 14121 memAlloc.allocationSize = 0; 14122 memAlloc.memoryTypeIndex = 0; 14123 14124 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs); 14125 memAlloc.allocationSize = memReqs.size; 14126 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 14127 ASSERT_TRUE(pass); 14128 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem); 14129 ASSERT_VK_SUCCESS(err); 14130 14131 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs); 14132 memAlloc.allocationSize = memReqs.size; 14133 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 14134 ASSERT_TRUE(pass); 14135 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem); 14136 ASSERT_VK_SUCCESS(err); 14137 14138 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0); 14139 ASSERT_VK_SUCCESS(err); 14140 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0); 14141 ASSERT_VK_SUCCESS(err); 14142 14143 BeginCommandBuffer(); 14144 VkImageCopy copyRegion; 14145 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14146 copyRegion.srcSubresource.mipLevel = 0; 14147 copyRegion.srcSubresource.baseArrayLayer = 0; 14148 copyRegion.srcSubresource.layerCount = 0; 14149 copyRegion.srcOffset.x = 0; 14150 copyRegion.srcOffset.y = 0; 14151 copyRegion.srcOffset.z = 0; 14152 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14153 copyRegion.dstSubresource.mipLevel = 0; 14154 copyRegion.dstSubresource.baseArrayLayer = 0; 14155 copyRegion.dstSubresource.layerCount = 0; 14156 copyRegion.dstOffset.x = 0; 14157 copyRegion.dstOffset.y = 0; 14158 copyRegion.dstOffset.z = 0; 14159 copyRegion.extent.width = 1; 14160 copyRegion.extent.height = 1; 14161 copyRegion.extent.depth = 1; 14162 m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region); 14163 EndCommandBuffer(); 14164 14165 m_errorMonitor->VerifyFound(); 14166 14167 vkDestroyImage(m_device->device(), srcImage, NULL); 14168 vkDestroyImage(m_device->device(), dstImage, NULL); 14169 vkFreeMemory(m_device->device(), srcMem, NULL); 14170 vkFreeMemory(m_device->device(), destMem, NULL); 14171 } 14172 14173 TEST_F(VkLayerTest, CopyImageDepthStencilFormatMismatch) { 14174 VkResult err; 14175 bool pass; 14176 14177 // Create a color image and a depth/stencil image and try to copy between them 14178 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 14179 "vkCmdCopyImage called with unmatched source and dest image depth"); 14180 14181 ASSERT_NO_FATAL_FAILURE(InitState()); 14182 14183 // Create two images of different types and try to copy between them 14184 VkImage srcImage; 14185 VkImage dstImage; 14186 VkDeviceMemory srcMem; 14187 VkDeviceMemory destMem; 14188 VkMemoryRequirements memReqs; 14189 14190 VkImageCreateInfo image_create_info = {}; 14191 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 14192 image_create_info.pNext = NULL; 14193 image_create_info.imageType = VK_IMAGE_TYPE_2D; 14194 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; 14195 image_create_info.extent.width = 32; 14196 image_create_info.extent.height = 32; 14197 image_create_info.extent.depth = 1; 14198 image_create_info.mipLevels = 1; 14199 image_create_info.arrayLayers = 1; 14200 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 14201 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 14202 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 14203 image_create_info.flags = 0; 14204 14205 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage); 14206 ASSERT_VK_SUCCESS(err); 14207 14208 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; 14209 14210 // Introduce failure by creating second image with a depth/stencil format 14211 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 14212 image_create_info.format = VK_FORMAT_D24_UNORM_S8_UINT; 14213 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; 14214 14215 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage); 14216 ASSERT_VK_SUCCESS(err); 14217 14218 // Allocate memory 14219 VkMemoryAllocateInfo memAlloc = {}; 14220 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 14221 memAlloc.pNext = NULL; 14222 memAlloc.allocationSize = 0; 14223 memAlloc.memoryTypeIndex = 0; 14224 14225 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs); 14226 memAlloc.allocationSize = memReqs.size; 14227 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 14228 ASSERT_TRUE(pass); 14229 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem); 14230 ASSERT_VK_SUCCESS(err); 14231 14232 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs); 14233 memAlloc.allocationSize = memReqs.size; 14234 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 14235 ASSERT_TRUE(pass); 14236 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem); 14237 ASSERT_VK_SUCCESS(err); 14238 14239 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0); 14240 ASSERT_VK_SUCCESS(err); 14241 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0); 14242 ASSERT_VK_SUCCESS(err); 14243 14244 BeginCommandBuffer(); 14245 VkImageCopy copyRegion; 14246 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14247 copyRegion.srcSubresource.mipLevel = 0; 14248 copyRegion.srcSubresource.baseArrayLayer = 0; 14249 copyRegion.srcSubresource.layerCount = 0; 14250 copyRegion.srcOffset.x = 0; 14251 copyRegion.srcOffset.y = 0; 14252 copyRegion.srcOffset.z = 0; 14253 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14254 copyRegion.dstSubresource.mipLevel = 0; 14255 copyRegion.dstSubresource.baseArrayLayer = 0; 14256 copyRegion.dstSubresource.layerCount = 0; 14257 copyRegion.dstOffset.x = 0; 14258 copyRegion.dstOffset.y = 0; 14259 copyRegion.dstOffset.z = 0; 14260 copyRegion.extent.width = 1; 14261 copyRegion.extent.height = 1; 14262 copyRegion.extent.depth = 1; 14263 m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region); 14264 EndCommandBuffer(); 14265 14266 m_errorMonitor->VerifyFound(); 14267 14268 vkDestroyImage(m_device->device(), srcImage, NULL); 14269 vkDestroyImage(m_device->device(), dstImage, NULL); 14270 vkFreeMemory(m_device->device(), srcMem, NULL); 14271 vkFreeMemory(m_device->device(), destMem, NULL); 14272 } 14273 14274 TEST_F(VkLayerTest, ResolveImageLowSampleCount) { 14275 VkResult err; 14276 bool pass; 14277 14278 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 14279 "vkCmdResolveImage called with source sample count less than 2."); 14280 14281 ASSERT_NO_FATAL_FAILURE(InitState()); 14282 14283 // Create two images of sample count 1 and try to Resolve between them 14284 VkImage srcImage; 14285 VkImage dstImage; 14286 VkDeviceMemory srcMem; 14287 VkDeviceMemory destMem; 14288 VkMemoryRequirements memReqs; 14289 14290 VkImageCreateInfo image_create_info = {}; 14291 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 14292 image_create_info.pNext = NULL; 14293 image_create_info.imageType = VK_IMAGE_TYPE_2D; 14294 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; 14295 image_create_info.extent.width = 32; 14296 image_create_info.extent.height = 1; 14297 image_create_info.extent.depth = 1; 14298 image_create_info.mipLevels = 1; 14299 image_create_info.arrayLayers = 1; 14300 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 14301 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 14302 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 14303 image_create_info.flags = 0; 14304 14305 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage); 14306 ASSERT_VK_SUCCESS(err); 14307 14308 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; 14309 14310 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage); 14311 ASSERT_VK_SUCCESS(err); 14312 14313 // Allocate memory 14314 VkMemoryAllocateInfo memAlloc = {}; 14315 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 14316 memAlloc.pNext = NULL; 14317 memAlloc.allocationSize = 0; 14318 memAlloc.memoryTypeIndex = 0; 14319 14320 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs); 14321 memAlloc.allocationSize = memReqs.size; 14322 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 14323 ASSERT_TRUE(pass); 14324 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem); 14325 ASSERT_VK_SUCCESS(err); 14326 14327 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs); 14328 memAlloc.allocationSize = memReqs.size; 14329 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 14330 ASSERT_TRUE(pass); 14331 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem); 14332 ASSERT_VK_SUCCESS(err); 14333 14334 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0); 14335 ASSERT_VK_SUCCESS(err); 14336 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0); 14337 ASSERT_VK_SUCCESS(err); 14338 14339 BeginCommandBuffer(); 14340 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest? 14341 // VK_IMAGE_LAYOUT_UNDEFINED = 0, 14342 // VK_IMAGE_LAYOUT_GENERAL = 1, 14343 VkImageResolve resolveRegion; 14344 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14345 resolveRegion.srcSubresource.mipLevel = 0; 14346 resolveRegion.srcSubresource.baseArrayLayer = 0; 14347 resolveRegion.srcSubresource.layerCount = 1; 14348 resolveRegion.srcOffset.x = 0; 14349 resolveRegion.srcOffset.y = 0; 14350 resolveRegion.srcOffset.z = 0; 14351 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14352 resolveRegion.dstSubresource.mipLevel = 0; 14353 resolveRegion.dstSubresource.baseArrayLayer = 0; 14354 resolveRegion.dstSubresource.layerCount = 1; 14355 resolveRegion.dstOffset.x = 0; 14356 resolveRegion.dstOffset.y = 0; 14357 resolveRegion.dstOffset.z = 0; 14358 resolveRegion.extent.width = 1; 14359 resolveRegion.extent.height = 1; 14360 resolveRegion.extent.depth = 1; 14361 m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion); 14362 EndCommandBuffer(); 14363 14364 m_errorMonitor->VerifyFound(); 14365 14366 vkDestroyImage(m_device->device(), srcImage, NULL); 14367 vkDestroyImage(m_device->device(), dstImage, NULL); 14368 vkFreeMemory(m_device->device(), srcMem, NULL); 14369 vkFreeMemory(m_device->device(), destMem, NULL); 14370 } 14371 14372 TEST_F(VkLayerTest, ResolveImageHighSampleCount) { 14373 VkResult err; 14374 bool pass; 14375 14376 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 14377 "vkCmdResolveImage called with dest sample count greater than 1."); 14378 14379 ASSERT_NO_FATAL_FAILURE(InitState()); 14380 14381 // Create two images of sample count 4 and try to Resolve between them 14382 VkImage srcImage; 14383 VkImage dstImage; 14384 VkDeviceMemory srcMem; 14385 VkDeviceMemory destMem; 14386 VkMemoryRequirements memReqs; 14387 14388 VkImageCreateInfo image_create_info = {}; 14389 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 14390 image_create_info.pNext = NULL; 14391 image_create_info.imageType = VK_IMAGE_TYPE_2D; 14392 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; 14393 image_create_info.extent.width = 32; 14394 image_create_info.extent.height = 1; 14395 image_create_info.extent.depth = 1; 14396 image_create_info.mipLevels = 1; 14397 image_create_info.arrayLayers = 1; 14398 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; 14399 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 14400 // Note: Some implementations expect color attachment usage for any 14401 // multisample surface 14402 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 14403 image_create_info.flags = 0; 14404 14405 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage); 14406 ASSERT_VK_SUCCESS(err); 14407 14408 // Note: Some implementations expect color attachment usage for any 14409 // multisample surface 14410 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 14411 14412 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage); 14413 ASSERT_VK_SUCCESS(err); 14414 14415 // Allocate memory 14416 VkMemoryAllocateInfo memAlloc = {}; 14417 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 14418 memAlloc.pNext = NULL; 14419 memAlloc.allocationSize = 0; 14420 memAlloc.memoryTypeIndex = 0; 14421 14422 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs); 14423 memAlloc.allocationSize = memReqs.size; 14424 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 14425 ASSERT_TRUE(pass); 14426 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem); 14427 ASSERT_VK_SUCCESS(err); 14428 14429 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs); 14430 memAlloc.allocationSize = memReqs.size; 14431 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 14432 ASSERT_TRUE(pass); 14433 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem); 14434 ASSERT_VK_SUCCESS(err); 14435 14436 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0); 14437 ASSERT_VK_SUCCESS(err); 14438 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0); 14439 ASSERT_VK_SUCCESS(err); 14440 14441 BeginCommandBuffer(); 14442 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest? 14443 // VK_IMAGE_LAYOUT_UNDEFINED = 0, 14444 // VK_IMAGE_LAYOUT_GENERAL = 1, 14445 VkImageResolve resolveRegion; 14446 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14447 resolveRegion.srcSubresource.mipLevel = 0; 14448 resolveRegion.srcSubresource.baseArrayLayer = 0; 14449 resolveRegion.srcSubresource.layerCount = 1; 14450 resolveRegion.srcOffset.x = 0; 14451 resolveRegion.srcOffset.y = 0; 14452 resolveRegion.srcOffset.z = 0; 14453 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14454 resolveRegion.dstSubresource.mipLevel = 0; 14455 resolveRegion.dstSubresource.baseArrayLayer = 0; 14456 resolveRegion.dstSubresource.layerCount = 1; 14457 resolveRegion.dstOffset.x = 0; 14458 resolveRegion.dstOffset.y = 0; 14459 resolveRegion.dstOffset.z = 0; 14460 resolveRegion.extent.width = 1; 14461 resolveRegion.extent.height = 1; 14462 resolveRegion.extent.depth = 1; 14463 m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion); 14464 EndCommandBuffer(); 14465 14466 m_errorMonitor->VerifyFound(); 14467 14468 vkDestroyImage(m_device->device(), srcImage, NULL); 14469 vkDestroyImage(m_device->device(), dstImage, NULL); 14470 vkFreeMemory(m_device->device(), srcMem, NULL); 14471 vkFreeMemory(m_device->device(), destMem, NULL); 14472 } 14473 14474 TEST_F(VkLayerTest, ResolveImageFormatMismatch) { 14475 VkResult err; 14476 bool pass; 14477 14478 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 14479 "vkCmdResolveImage called with unmatched source and dest formats."); 14480 14481 ASSERT_NO_FATAL_FAILURE(InitState()); 14482 14483 // Create two images of different types and try to copy between them 14484 VkImage srcImage; 14485 VkImage dstImage; 14486 VkDeviceMemory srcMem; 14487 VkDeviceMemory destMem; 14488 VkMemoryRequirements memReqs; 14489 14490 VkImageCreateInfo image_create_info = {}; 14491 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 14492 image_create_info.pNext = NULL; 14493 image_create_info.imageType = VK_IMAGE_TYPE_2D; 14494 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; 14495 image_create_info.extent.width = 32; 14496 image_create_info.extent.height = 1; 14497 image_create_info.extent.depth = 1; 14498 image_create_info.mipLevels = 1; 14499 image_create_info.arrayLayers = 1; 14500 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT; 14501 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 14502 // Note: Some implementations expect color attachment usage for any 14503 // multisample surface 14504 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 14505 image_create_info.flags = 0; 14506 14507 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage); 14508 ASSERT_VK_SUCCESS(err); 14509 14510 // Set format to something other than source image 14511 image_create_info.format = VK_FORMAT_R32_SFLOAT; 14512 // Note: Some implementations expect color attachment usage for any 14513 // multisample surface 14514 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 14515 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 14516 14517 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage); 14518 ASSERT_VK_SUCCESS(err); 14519 14520 // Allocate memory 14521 VkMemoryAllocateInfo memAlloc = {}; 14522 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 14523 memAlloc.pNext = NULL; 14524 memAlloc.allocationSize = 0; 14525 memAlloc.memoryTypeIndex = 0; 14526 14527 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs); 14528 memAlloc.allocationSize = memReqs.size; 14529 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 14530 ASSERT_TRUE(pass); 14531 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem); 14532 ASSERT_VK_SUCCESS(err); 14533 14534 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs); 14535 memAlloc.allocationSize = memReqs.size; 14536 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 14537 ASSERT_TRUE(pass); 14538 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem); 14539 ASSERT_VK_SUCCESS(err); 14540 14541 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0); 14542 ASSERT_VK_SUCCESS(err); 14543 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0); 14544 ASSERT_VK_SUCCESS(err); 14545 14546 BeginCommandBuffer(); 14547 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest? 14548 // VK_IMAGE_LAYOUT_UNDEFINED = 0, 14549 // VK_IMAGE_LAYOUT_GENERAL = 1, 14550 VkImageResolve resolveRegion; 14551 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14552 resolveRegion.srcSubresource.mipLevel = 0; 14553 resolveRegion.srcSubresource.baseArrayLayer = 0; 14554 resolveRegion.srcSubresource.layerCount = 1; 14555 resolveRegion.srcOffset.x = 0; 14556 resolveRegion.srcOffset.y = 0; 14557 resolveRegion.srcOffset.z = 0; 14558 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14559 resolveRegion.dstSubresource.mipLevel = 0; 14560 resolveRegion.dstSubresource.baseArrayLayer = 0; 14561 resolveRegion.dstSubresource.layerCount = 1; 14562 resolveRegion.dstOffset.x = 0; 14563 resolveRegion.dstOffset.y = 0; 14564 resolveRegion.dstOffset.z = 0; 14565 resolveRegion.extent.width = 1; 14566 resolveRegion.extent.height = 1; 14567 resolveRegion.extent.depth = 1; 14568 m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion); 14569 EndCommandBuffer(); 14570 14571 m_errorMonitor->VerifyFound(); 14572 14573 vkDestroyImage(m_device->device(), srcImage, NULL); 14574 vkDestroyImage(m_device->device(), dstImage, NULL); 14575 vkFreeMemory(m_device->device(), srcMem, NULL); 14576 vkFreeMemory(m_device->device(), destMem, NULL); 14577 } 14578 14579 TEST_F(VkLayerTest, ResolveImageTypeMismatch) { 14580 VkResult err; 14581 bool pass; 14582 14583 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 14584 "vkCmdResolveImage called with unmatched source and dest image types."); 14585 14586 ASSERT_NO_FATAL_FAILURE(InitState()); 14587 14588 // Create two images of different types and try to copy between them 14589 VkImage srcImage; 14590 VkImage dstImage; 14591 VkDeviceMemory srcMem; 14592 VkDeviceMemory destMem; 14593 VkMemoryRequirements memReqs; 14594 14595 VkImageCreateInfo image_create_info = {}; 14596 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 14597 image_create_info.pNext = NULL; 14598 image_create_info.imageType = VK_IMAGE_TYPE_2D; 14599 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; 14600 image_create_info.extent.width = 32; 14601 image_create_info.extent.height = 1; 14602 image_create_info.extent.depth = 1; 14603 image_create_info.mipLevels = 1; 14604 image_create_info.arrayLayers = 1; 14605 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT; 14606 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 14607 // Note: Some implementations expect color attachment usage for any 14608 // multisample surface 14609 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 14610 image_create_info.flags = 0; 14611 14612 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage); 14613 ASSERT_VK_SUCCESS(err); 14614 14615 image_create_info.imageType = VK_IMAGE_TYPE_1D; 14616 // Note: Some implementations expect color attachment usage for any 14617 // multisample surface 14618 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 14619 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 14620 14621 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage); 14622 ASSERT_VK_SUCCESS(err); 14623 14624 // Allocate memory 14625 VkMemoryAllocateInfo memAlloc = {}; 14626 memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 14627 memAlloc.pNext = NULL; 14628 memAlloc.allocationSize = 0; 14629 memAlloc.memoryTypeIndex = 0; 14630 14631 vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs); 14632 memAlloc.allocationSize = memReqs.size; 14633 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 14634 ASSERT_TRUE(pass); 14635 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem); 14636 ASSERT_VK_SUCCESS(err); 14637 14638 vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs); 14639 memAlloc.allocationSize = memReqs.size; 14640 pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0); 14641 ASSERT_TRUE(pass); 14642 err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem); 14643 ASSERT_VK_SUCCESS(err); 14644 14645 err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0); 14646 ASSERT_VK_SUCCESS(err); 14647 err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0); 14648 ASSERT_VK_SUCCESS(err); 14649 14650 BeginCommandBuffer(); 14651 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest? 14652 // VK_IMAGE_LAYOUT_UNDEFINED = 0, 14653 // VK_IMAGE_LAYOUT_GENERAL = 1, 14654 VkImageResolve resolveRegion; 14655 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14656 resolveRegion.srcSubresource.mipLevel = 0; 14657 resolveRegion.srcSubresource.baseArrayLayer = 0; 14658 resolveRegion.srcSubresource.layerCount = 1; 14659 resolveRegion.srcOffset.x = 0; 14660 resolveRegion.srcOffset.y = 0; 14661 resolveRegion.srcOffset.z = 0; 14662 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14663 resolveRegion.dstSubresource.mipLevel = 0; 14664 resolveRegion.dstSubresource.baseArrayLayer = 0; 14665 resolveRegion.dstSubresource.layerCount = 1; 14666 resolveRegion.dstOffset.x = 0; 14667 resolveRegion.dstOffset.y = 0; 14668 resolveRegion.dstOffset.z = 0; 14669 resolveRegion.extent.width = 1; 14670 resolveRegion.extent.height = 1; 14671 resolveRegion.extent.depth = 1; 14672 m_commandBuffer->ResolveImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion); 14673 EndCommandBuffer(); 14674 14675 m_errorMonitor->VerifyFound(); 14676 14677 vkDestroyImage(m_device->device(), srcImage, NULL); 14678 vkDestroyImage(m_device->device(), dstImage, NULL); 14679 vkFreeMemory(m_device->device(), srcMem, NULL); 14680 vkFreeMemory(m_device->device(), destMem, NULL); 14681 } 14682 14683 TEST_F(VkLayerTest, DepthStencilImageViewWithColorAspectBitError) { 14684 // Create a single Image descriptor and cause it to first hit an error due 14685 // to using a DS format, then cause it to hit error due to COLOR_BIT not 14686 // set in aspect 14687 // The image format check comes 2nd in validation so we trigger it first, 14688 // then when we cause aspect fail next, bad format check will be preempted 14689 VkResult err; 14690 14691 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 14692 "Combination depth/stencil image formats can have only the "); 14693 14694 ASSERT_NO_FATAL_FAILURE(InitState()); 14695 14696 VkDescriptorPoolSize ds_type_count = {}; 14697 ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; 14698 ds_type_count.descriptorCount = 1; 14699 14700 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 14701 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 14702 ds_pool_ci.pNext = NULL; 14703 ds_pool_ci.maxSets = 1; 14704 ds_pool_ci.poolSizeCount = 1; 14705 ds_pool_ci.pPoolSizes = &ds_type_count; 14706 14707 VkDescriptorPool ds_pool; 14708 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 14709 ASSERT_VK_SUCCESS(err); 14710 14711 VkDescriptorSetLayoutBinding dsl_binding = {}; 14712 dsl_binding.binding = 0; 14713 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; 14714 dsl_binding.descriptorCount = 1; 14715 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 14716 dsl_binding.pImmutableSamplers = NULL; 14717 14718 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 14719 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 14720 ds_layout_ci.pNext = NULL; 14721 ds_layout_ci.bindingCount = 1; 14722 ds_layout_ci.pBindings = &dsl_binding; 14723 VkDescriptorSetLayout ds_layout; 14724 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 14725 ASSERT_VK_SUCCESS(err); 14726 14727 VkDescriptorSet descriptorSet; 14728 VkDescriptorSetAllocateInfo alloc_info = {}; 14729 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 14730 alloc_info.descriptorSetCount = 1; 14731 alloc_info.descriptorPool = ds_pool; 14732 alloc_info.pSetLayouts = &ds_layout; 14733 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet); 14734 ASSERT_VK_SUCCESS(err); 14735 14736 VkImage image_bad; 14737 VkImage image_good; 14738 // One bad format and one good format for Color attachment 14739 const VkFormat tex_format_bad = VK_FORMAT_D24_UNORM_S8_UINT; 14740 const VkFormat tex_format_good = VK_FORMAT_B8G8R8A8_UNORM; 14741 const int32_t tex_width = 32; 14742 const int32_t tex_height = 32; 14743 14744 VkImageCreateInfo image_create_info = {}; 14745 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 14746 image_create_info.pNext = NULL; 14747 image_create_info.imageType = VK_IMAGE_TYPE_2D; 14748 image_create_info.format = tex_format_bad; 14749 image_create_info.extent.width = tex_width; 14750 image_create_info.extent.height = tex_height; 14751 image_create_info.extent.depth = 1; 14752 image_create_info.mipLevels = 1; 14753 image_create_info.arrayLayers = 1; 14754 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 14755 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 14756 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; 14757 image_create_info.flags = 0; 14758 14759 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image_bad); 14760 ASSERT_VK_SUCCESS(err); 14761 image_create_info.format = tex_format_good; 14762 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 14763 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image_good); 14764 ASSERT_VK_SUCCESS(err); 14765 14766 VkImageViewCreateInfo image_view_create_info = {}; 14767 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 14768 image_view_create_info.image = image_bad; 14769 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; 14770 image_view_create_info.format = tex_format_bad; 14771 image_view_create_info.subresourceRange.baseArrayLayer = 0; 14772 image_view_create_info.subresourceRange.baseMipLevel = 0; 14773 image_view_create_info.subresourceRange.layerCount = 1; 14774 image_view_create_info.subresourceRange.levelCount = 1; 14775 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 14776 14777 VkImageView view; 14778 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view); 14779 14780 m_errorMonitor->VerifyFound(); 14781 14782 vkDestroyImage(m_device->device(), image_bad, NULL); 14783 vkDestroyImage(m_device->device(), image_good, NULL); 14784 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 14785 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 14786 } 14787 14788 TEST_F(VkLayerTest, ClearImageErrors) { 14789 TEST_DESCRIPTION("Call ClearColorImage w/ a depth|stencil image and " 14790 "ClearDepthStencilImage with a color image."); 14791 14792 ASSERT_NO_FATAL_FAILURE(InitState()); 14793 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 14794 14795 // Renderpass is started here so end it as Clear cmds can't be in renderpass 14796 BeginCommandBuffer(); 14797 m_commandBuffer->EndRenderPass(); 14798 14799 // Color image 14800 VkClearColorValue clear_color; 14801 memset(clear_color.uint32, 0, sizeof(uint32_t) * 4); 14802 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; 14803 const VkFormat color_format = VK_FORMAT_B8G8R8A8_UNORM; 14804 const int32_t img_width = 32; 14805 const int32_t img_height = 32; 14806 VkImageCreateInfo image_create_info = {}; 14807 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 14808 image_create_info.pNext = NULL; 14809 image_create_info.imageType = VK_IMAGE_TYPE_2D; 14810 image_create_info.format = color_format; 14811 image_create_info.extent.width = img_width; 14812 image_create_info.extent.height = img_height; 14813 image_create_info.extent.depth = 1; 14814 image_create_info.mipLevels = 1; 14815 image_create_info.arrayLayers = 1; 14816 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 14817 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 14818 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 14819 14820 vk_testing::Image color_image; 14821 color_image.init(*m_device, (const VkImageCreateInfo &)image_create_info, reqs); 14822 14823 const VkImageSubresourceRange color_range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT); 14824 14825 // Depth/Stencil image 14826 VkClearDepthStencilValue clear_value = {0}; 14827 reqs = 0; // don't need HOST_VISIBLE DS image 14828 VkImageCreateInfo ds_image_create_info = vk_testing::Image::create_info(); 14829 ds_image_create_info.imageType = VK_IMAGE_TYPE_2D; 14830 ds_image_create_info.format = VK_FORMAT_D24_UNORM_S8_UINT; 14831 ds_image_create_info.extent.width = 64; 14832 ds_image_create_info.extent.height = 64; 14833 ds_image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 14834 ds_image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; 14835 14836 vk_testing::Image ds_image; 14837 ds_image.init(*m_device, (const VkImageCreateInfo &)ds_image_create_info, reqs); 14838 14839 const VkImageSubresourceRange ds_range = vk_testing::Image::subresource_range(ds_image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT); 14840 14841 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearColorImage called with depth/stencil image."); 14842 14843 vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, 14844 &color_range); 14845 14846 m_errorMonitor->VerifyFound(); 14847 14848 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearColorImage called with " 14849 "image created without " 14850 "VK_IMAGE_USAGE_TRANSFER_DST_BIT"); 14851 14852 vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, 14853 &color_range); 14854 14855 m_errorMonitor->VerifyFound(); 14856 14857 // Call CmdClearDepthStencilImage with color image 14858 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 14859 "vkCmdClearDepthStencilImage called without a depth/stencil image."); 14860 14861 vkCmdClearDepthStencilImage(m_commandBuffer->GetBufferHandle(), color_image.handle(), 14862 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, &clear_value, 1, &ds_range); 14863 14864 m_errorMonitor->VerifyFound(); 14865 } 14866 #endif // IMAGE_TESTS 14867 14868 14869 // WSI Enabled Tests 14870 // 14871 TEST_F(VkWsiEnabledLayerTest, TestEnabledWsi) { 14872 14873 #if defined(VK_USE_PLATFORM_XCB_KHR) 14874 VkSurfaceKHR surface = VK_NULL_HANDLE; 14875 14876 VkResult err; 14877 bool pass; 14878 VkSwapchainKHR swapchain = VK_NULL_HANDLE; 14879 VkSwapchainCreateInfoKHR swapchain_create_info = {}; 14880 // uint32_t swapchain_image_count = 0; 14881 // VkImage swapchain_images[1] = {VK_NULL_HANDLE}; 14882 // uint32_t image_index = 0; 14883 // VkPresentInfoKHR present_info = {}; 14884 14885 ASSERT_NO_FATAL_FAILURE(InitState()); 14886 14887 // Use the create function from one of the VK_KHR_*_surface extension in 14888 // order to create a surface, testing all known errors in the process, 14889 // before successfully creating a surface: 14890 // First, try to create a surface without a VkXcbSurfaceCreateInfoKHR: 14891 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pCreateInfo specified as NULL"); 14892 err = vkCreateXcbSurfaceKHR(instance(), NULL, NULL, &surface); 14893 pass = (err != VK_SUCCESS); 14894 ASSERT_TRUE(pass); 14895 m_errorMonitor->VerifyFound(); 14896 14897 // Next, try to create a surface with the wrong 14898 // VkXcbSurfaceCreateInfoKHR::sType: 14899 VkXcbSurfaceCreateInfoKHR xcb_create_info = {}; 14900 xcb_create_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; 14901 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pCreateInfo->sType must be"); 14902 err = vkCreateXcbSurfaceKHR(instance(), &xcb_create_info, NULL, &surface); 14903 pass = (err != VK_SUCCESS); 14904 ASSERT_TRUE(pass); 14905 m_errorMonitor->VerifyFound(); 14906 14907 // Create a native window, and then correctly create a surface: 14908 xcb_connection_t *connection; 14909 xcb_screen_t *screen; 14910 xcb_window_t xcb_window; 14911 xcb_intern_atom_reply_t *atom_wm_delete_window; 14912 14913 const xcb_setup_t *setup; 14914 xcb_screen_iterator_t iter; 14915 int scr; 14916 uint32_t value_mask, value_list[32]; 14917 int width = 1; 14918 int height = 1; 14919 14920 connection = xcb_connect(NULL, &scr); 14921 ASSERT_TRUE(connection != NULL); 14922 setup = xcb_get_setup(connection); 14923 iter = xcb_setup_roots_iterator(setup); 14924 while (scr-- > 0) 14925 xcb_screen_next(&iter); 14926 screen = iter.data; 14927 14928 xcb_window = xcb_generate_id(connection); 14929 14930 value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; 14931 value_list[0] = screen->black_pixel; 14932 value_list[1] = XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY; 14933 14934 xcb_create_window(connection, XCB_COPY_FROM_PARENT, xcb_window, screen->root, 0, 0, width, height, 0, 14935 XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, value_mask, value_list); 14936 14937 /* Magic code that will send notification when window is destroyed */ 14938 xcb_intern_atom_cookie_t cookie = xcb_intern_atom(connection, 1, 12, "WM_PROTOCOLS"); 14939 xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(connection, cookie, 0); 14940 14941 xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(connection, 0, 16, "WM_DELETE_WINDOW"); 14942 atom_wm_delete_window = xcb_intern_atom_reply(connection, cookie2, 0); 14943 xcb_change_property(connection, XCB_PROP_MODE_REPLACE, xcb_window, (*reply).atom, 4, 32, 1, &(*atom_wm_delete_window).atom); 14944 free(reply); 14945 14946 xcb_map_window(connection, xcb_window); 14947 14948 // Force the x/y coordinates to 100,100 results are identical in consecutive 14949 // runs 14950 const uint32_t coords[] = { 100, 100 }; 14951 xcb_configure_window(connection, xcb_window, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, coords); 14952 14953 // Finally, try to correctly create a surface: 14954 xcb_create_info.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; 14955 xcb_create_info.pNext = NULL; 14956 xcb_create_info.flags = 0; 14957 xcb_create_info.connection = connection; 14958 xcb_create_info.window = xcb_window; 14959 err = vkCreateXcbSurfaceKHR(instance(), &xcb_create_info, NULL, &surface); 14960 pass = (err == VK_SUCCESS); 14961 ASSERT_TRUE(pass); 14962 14963 // Check if surface supports presentation: 14964 14965 // 1st, do so without having queried the queue families: 14966 VkBool32 supported = false; 14967 // TODO: Get the following error to come out: 14968 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 14969 "called before calling the vkGetPhysicalDeviceQueueFamilyProperties " 14970 "function"); 14971 err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu(), 0, surface, &supported); 14972 pass = (err != VK_SUCCESS); 14973 // ASSERT_TRUE(pass); 14974 // m_errorMonitor->VerifyFound(); 14975 14976 // Next, query a queue family index that's too large: 14977 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "called with a queueFamilyIndex that is too large"); 14978 err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu(), 100000, surface, &supported); 14979 pass = (err != VK_SUCCESS); 14980 ASSERT_TRUE(pass); 14981 m_errorMonitor->VerifyFound(); 14982 14983 // Finally, do so correctly: 14984 // FIXME: THIS ISN'T CORRECT--MUST QUERY UNTIL WE FIND A QUEUE FAMILY THAT'S 14985 // SUPPORTED 14986 err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu(), 0, surface, &supported); 14987 pass = (err == VK_SUCCESS); 14988 ASSERT_TRUE(pass); 14989 14990 // Before proceeding, try to create a swapchain without having called 14991 // vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): 14992 swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; 14993 swapchain_create_info.pNext = NULL; 14994 swapchain_create_info.flags = 0; 14995 swapchain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 14996 swapchain_create_info.surface = surface; 14997 swapchain_create_info.imageArrayLayers = 1; 14998 swapchain_create_info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; 14999 swapchain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; 15000 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 15001 "called before calling vkGetPhysicalDeviceSurfaceCapabilitiesKHR()."); 15002 err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain); 15003 pass = (err != VK_SUCCESS); 15004 ASSERT_TRUE(pass); 15005 m_errorMonitor->VerifyFound(); 15006 15007 // Get the surface capabilities: 15008 VkSurfaceCapabilitiesKHR surface_capabilities; 15009 15010 // Do so correctly (only error logged by this entrypoint is if the 15011 // extension isn't enabled): 15012 err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu(), surface, &surface_capabilities); 15013 pass = (err == VK_SUCCESS); 15014 ASSERT_TRUE(pass); 15015 15016 // Get the surface formats: 15017 uint32_t surface_format_count; 15018 15019 // First, try without a pointer to surface_format_count: 15020 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pSurfaceFormatCount " 15021 "specified as NULL"); 15022 vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, NULL, NULL); 15023 pass = (err == VK_SUCCESS); 15024 ASSERT_TRUE(pass); 15025 m_errorMonitor->VerifyFound(); 15026 15027 // Next, call with a non-NULL pSurfaceFormats, even though we haven't 15028 // correctly done a 1st try (to get the count): 15029 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "but no prior positive value has been seen for"); 15030 surface_format_count = 0; 15031 vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, (VkSurfaceFormatKHR *)&surface_format_count); 15032 pass = (err == VK_SUCCESS); 15033 ASSERT_TRUE(pass); 15034 m_errorMonitor->VerifyFound(); 15035 15036 // Next, correctly do a 1st try (with a NULL pointer to surface_formats): 15037 vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, NULL); 15038 pass = (err == VK_SUCCESS); 15039 ASSERT_TRUE(pass); 15040 15041 // Allocate memory for the correct number of VkSurfaceFormatKHR's: 15042 VkSurfaceFormatKHR *surface_formats = (VkSurfaceFormatKHR *)malloc(surface_format_count * sizeof(VkSurfaceFormatKHR)); 15043 15044 // Next, do a 2nd try with surface_format_count being set too high: 15045 surface_format_count += 5; 15046 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is greater than the value"); 15047 vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, surface_formats); 15048 pass = (err == VK_SUCCESS); 15049 ASSERT_TRUE(pass); 15050 m_errorMonitor->VerifyFound(); 15051 15052 // Finally, do a correct 1st and 2nd try: 15053 vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, NULL); 15054 pass = (err == VK_SUCCESS); 15055 ASSERT_TRUE(pass); 15056 vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, surface_formats); 15057 pass = (err == VK_SUCCESS); 15058 ASSERT_TRUE(pass); 15059 15060 // Get the surface present modes: 15061 uint32_t surface_present_mode_count; 15062 15063 // First, try without a pointer to surface_format_count: 15064 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pPresentModeCount " 15065 "specified as NULL"); 15066 15067 vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, NULL, NULL); 15068 pass = (err == VK_SUCCESS); 15069 ASSERT_TRUE(pass); 15070 m_errorMonitor->VerifyFound(); 15071 15072 // Next, call with a non-NULL VkPresentModeKHR, even though we haven't 15073 // correctly done a 1st try (to get the count): 15074 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "but no prior positive value has been seen for"); 15075 surface_present_mode_count = 0; 15076 vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, 15077 (VkPresentModeKHR *)&surface_present_mode_count); 15078 pass = (err == VK_SUCCESS); 15079 ASSERT_TRUE(pass); 15080 m_errorMonitor->VerifyFound(); 15081 15082 // Next, correctly do a 1st try (with a NULL pointer to surface_formats): 15083 vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, NULL); 15084 pass = (err == VK_SUCCESS); 15085 ASSERT_TRUE(pass); 15086 15087 // Allocate memory for the correct number of VkSurfaceFormatKHR's: 15088 VkPresentModeKHR *surface_present_modes = (VkPresentModeKHR *)malloc(surface_present_mode_count * sizeof(VkPresentModeKHR)); 15089 15090 // Next, do a 2nd try with surface_format_count being set too high: 15091 surface_present_mode_count += 5; 15092 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is greater than the value"); 15093 vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, surface_present_modes); 15094 pass = (err == VK_SUCCESS); 15095 ASSERT_TRUE(pass); 15096 m_errorMonitor->VerifyFound(); 15097 15098 // Finally, do a correct 1st and 2nd try: 15099 vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, NULL); 15100 pass = (err == VK_SUCCESS); 15101 ASSERT_TRUE(pass); 15102 vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, surface_present_modes); 15103 pass = (err == VK_SUCCESS); 15104 ASSERT_TRUE(pass); 15105 15106 // Create a swapchain: 15107 15108 // First, try without a pointer to swapchain_create_info: 15109 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pCreateInfo " 15110 "specified as NULL"); 15111 15112 err = vkCreateSwapchainKHR(m_device->device(), NULL, NULL, &swapchain); 15113 pass = (err != VK_SUCCESS); 15114 ASSERT_TRUE(pass); 15115 m_errorMonitor->VerifyFound(); 15116 15117 // Next, call with a non-NULL swapchain_create_info, that has the wrong 15118 // sType: 15119 swapchain_create_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; 15120 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pCreateInfo->sType must be"); 15121 15122 err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain); 15123 pass = (err != VK_SUCCESS); 15124 ASSERT_TRUE(pass); 15125 m_errorMonitor->VerifyFound(); 15126 15127 // Next, call with a NULL swapchain pointer: 15128 swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; 15129 swapchain_create_info.pNext = NULL; 15130 swapchain_create_info.flags = 0; 15131 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pSwapchain " 15132 "specified as NULL"); 15133 15134 err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, NULL); 15135 pass = (err != VK_SUCCESS); 15136 ASSERT_TRUE(pass); 15137 m_errorMonitor->VerifyFound(); 15138 15139 // TODO: Enhance swapchain layer so that 15140 // swapchain_create_info.queueFamilyIndexCount is checked against something? 15141 15142 // Next, call with a queue family index that's too large: 15143 uint32_t queueFamilyIndex[2] = { 100000, 0 }; 15144 swapchain_create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT; 15145 swapchain_create_info.queueFamilyIndexCount = 2; 15146 swapchain_create_info.pQueueFamilyIndices = queueFamilyIndex; 15147 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "called with a queueFamilyIndex that is too large"); 15148 err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain); 15149 pass = (err != VK_SUCCESS); 15150 ASSERT_TRUE(pass); 15151 m_errorMonitor->VerifyFound(); 15152 15153 // Next, call a queueFamilyIndexCount that's too small for CONCURRENT: 15154 swapchain_create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT; 15155 swapchain_create_info.queueFamilyIndexCount = 1; 15156 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 15157 "but with a bad value(s) for pCreateInfo->queueFamilyIndexCount or " 15158 "pCreateInfo->pQueueFamilyIndices)."); 15159 err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain); 15160 pass = (err != VK_SUCCESS); 15161 ASSERT_TRUE(pass); 15162 m_errorMonitor->VerifyFound(); 15163 15164 // Next, call with an invalid imageSharingMode: 15165 swapchain_create_info.imageSharingMode = VK_SHARING_MODE_MAX_ENUM; 15166 swapchain_create_info.queueFamilyIndexCount = 1; 15167 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, 15168 "called with a non-supported pCreateInfo->imageSharingMode (i.e."); 15169 err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain); 15170 pass = (err != VK_SUCCESS); 15171 ASSERT_TRUE(pass); 15172 m_errorMonitor->VerifyFound(); 15173 // Fix for the future: 15174 // FIXME: THIS ISN'T CORRECT--MUST QUERY UNTIL WE FIND A QUEUE FAMILY THAT'S 15175 // SUPPORTED 15176 swapchain_create_info.queueFamilyIndexCount = 0; 15177 queueFamilyIndex[0] = 0; 15178 swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; 15179 15180 // TODO: CONTINUE TESTING VALIDATION OF vkCreateSwapchainKHR() ... 15181 // Get the images from a swapchain: 15182 // Acquire an image from a swapchain: 15183 // Present an image to a swapchain: 15184 // Destroy the swapchain: 15185 15186 // TODOs: 15187 // 15188 // - Try destroying the device without first destroying the swapchain 15189 // 15190 // - Try destroying the device without first destroying the surface 15191 // 15192 // - Try destroying the surface without first destroying the swapchain 15193 15194 // Destroy the surface: 15195 vkDestroySurfaceKHR(instance(), surface, NULL); 15196 15197 // Tear down the window: 15198 xcb_destroy_window(connection, xcb_window); 15199 xcb_disconnect(connection); 15200 15201 #else // VK_USE_PLATFORM_XCB_KHR 15202 return; 15203 #endif // VK_USE_PLATFORM_XCB_KHR 15204 } 15205 15206 // 15207 // POSITIVE VALIDATION TESTS 15208 // 15209 // These tests do not expect to encounter ANY validation errors pass only if this is true 15210 15211 // This is a positive test. No failures are expected. 15212 TEST_F(VkPositiveLayerTest, IgnoreUnrelatedDescriptor) { 15213 TEST_DESCRIPTION("Ensure that the vkUpdateDescriptorSets validation code " 15214 "is ignoring VkWriteDescriptorSet members that are not " 15215 "related to the descriptor type specified by " 15216 "VkWriteDescriptorSet::descriptorType. Correct " 15217 "validation behavior will result in the test running to " 15218 "completion without validation errors."); 15219 15220 const uintptr_t invalid_ptr = 0xcdcdcdcd; 15221 15222 ASSERT_NO_FATAL_FAILURE(InitState()); 15223 15224 // Image Case 15225 { 15226 m_errorMonitor->ExpectSuccess(); 15227 15228 VkImage image; 15229 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 15230 const int32_t tex_width = 32; 15231 const int32_t tex_height = 32; 15232 VkImageCreateInfo image_create_info = {}; 15233 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 15234 image_create_info.pNext = NULL; 15235 image_create_info.imageType = VK_IMAGE_TYPE_2D; 15236 image_create_info.format = tex_format; 15237 image_create_info.extent.width = tex_width; 15238 image_create_info.extent.height = tex_height; 15239 image_create_info.extent.depth = 1; 15240 image_create_info.mipLevels = 1; 15241 image_create_info.arrayLayers = 1; 15242 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 15243 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 15244 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; 15245 image_create_info.flags = 0; 15246 VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 15247 ASSERT_VK_SUCCESS(err); 15248 15249 VkMemoryRequirements memory_reqs; 15250 VkDeviceMemory image_memory; 15251 bool pass; 15252 VkMemoryAllocateInfo memory_info = {}; 15253 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 15254 memory_info.pNext = NULL; 15255 memory_info.allocationSize = 0; 15256 memory_info.memoryTypeIndex = 0; 15257 vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs); 15258 memory_info.allocationSize = memory_reqs.size; 15259 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 15260 ASSERT_TRUE(pass); 15261 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory); 15262 ASSERT_VK_SUCCESS(err); 15263 err = vkBindImageMemory(m_device->device(), image, image_memory, 0); 15264 ASSERT_VK_SUCCESS(err); 15265 15266 VkImageViewCreateInfo image_view_create_info = {}; 15267 image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 15268 image_view_create_info.image = image; 15269 image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; 15270 image_view_create_info.format = tex_format; 15271 image_view_create_info.subresourceRange.layerCount = 1; 15272 image_view_create_info.subresourceRange.baseMipLevel = 0; 15273 image_view_create_info.subresourceRange.levelCount = 1; 15274 image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 15275 15276 VkImageView view; 15277 err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view); 15278 ASSERT_VK_SUCCESS(err); 15279 15280 VkDescriptorPoolSize ds_type_count = {}; 15281 ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; 15282 ds_type_count.descriptorCount = 1; 15283 15284 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 15285 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 15286 ds_pool_ci.pNext = NULL; 15287 ds_pool_ci.maxSets = 1; 15288 ds_pool_ci.poolSizeCount = 1; 15289 ds_pool_ci.pPoolSizes = &ds_type_count; 15290 15291 VkDescriptorPool ds_pool; 15292 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 15293 ASSERT_VK_SUCCESS(err); 15294 15295 VkDescriptorSetLayoutBinding dsl_binding = {}; 15296 dsl_binding.binding = 0; 15297 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; 15298 dsl_binding.descriptorCount = 1; 15299 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 15300 dsl_binding.pImmutableSamplers = NULL; 15301 15302 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 15303 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 15304 ds_layout_ci.pNext = NULL; 15305 ds_layout_ci.bindingCount = 1; 15306 ds_layout_ci.pBindings = &dsl_binding; 15307 VkDescriptorSetLayout ds_layout; 15308 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 15309 ASSERT_VK_SUCCESS(err); 15310 15311 VkDescriptorSet descriptor_set; 15312 VkDescriptorSetAllocateInfo alloc_info = {}; 15313 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 15314 alloc_info.descriptorSetCount = 1; 15315 alloc_info.descriptorPool = ds_pool; 15316 alloc_info.pSetLayouts = &ds_layout; 15317 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set); 15318 ASSERT_VK_SUCCESS(err); 15319 15320 VkDescriptorImageInfo image_info = {}; 15321 image_info.imageView = view; 15322 image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 15323 15324 VkWriteDescriptorSet descriptor_write; 15325 memset(&descriptor_write, 0, sizeof(descriptor_write)); 15326 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 15327 descriptor_write.dstSet = descriptor_set; 15328 descriptor_write.dstBinding = 0; 15329 descriptor_write.descriptorCount = 1; 15330 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; 15331 descriptor_write.pImageInfo = &image_info; 15332 15333 // Set pBufferInfo and pTexelBufferView to invalid values, which should 15334 // be 15335 // ignored for descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE. 15336 // This will most likely produce a crash if the parameter_validation 15337 // layer 15338 // does not correctly ignore pBufferInfo. 15339 descriptor_write.pBufferInfo = reinterpret_cast<const VkDescriptorBufferInfo *>(invalid_ptr); 15340 descriptor_write.pTexelBufferView = reinterpret_cast<const VkBufferView *>(invalid_ptr); 15341 15342 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 15343 15344 m_errorMonitor->VerifyNotFound(); 15345 15346 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 15347 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 15348 vkDestroyImageView(m_device->device(), view, NULL); 15349 vkDestroyImage(m_device->device(), image, NULL); 15350 vkFreeMemory(m_device->device(), image_memory, NULL); 15351 } 15352 15353 // Buffer Case 15354 { 15355 m_errorMonitor->ExpectSuccess(); 15356 15357 VkBuffer buffer; 15358 uint32_t queue_family_index = 0; 15359 VkBufferCreateInfo buffer_create_info = {}; 15360 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 15361 buffer_create_info.size = 1024; 15362 buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 15363 buffer_create_info.queueFamilyIndexCount = 1; 15364 buffer_create_info.pQueueFamilyIndices = &queue_family_index; 15365 15366 VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer); 15367 ASSERT_VK_SUCCESS(err); 15368 15369 VkMemoryRequirements memory_reqs; 15370 VkDeviceMemory buffer_memory; 15371 bool pass; 15372 VkMemoryAllocateInfo memory_info = {}; 15373 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 15374 memory_info.pNext = NULL; 15375 memory_info.allocationSize = 0; 15376 memory_info.memoryTypeIndex = 0; 15377 15378 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs); 15379 memory_info.allocationSize = memory_reqs.size; 15380 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 15381 ASSERT_TRUE(pass); 15382 15383 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory); 15384 ASSERT_VK_SUCCESS(err); 15385 err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0); 15386 ASSERT_VK_SUCCESS(err); 15387 15388 VkDescriptorPoolSize ds_type_count = {}; 15389 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 15390 ds_type_count.descriptorCount = 1; 15391 15392 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 15393 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 15394 ds_pool_ci.pNext = NULL; 15395 ds_pool_ci.maxSets = 1; 15396 ds_pool_ci.poolSizeCount = 1; 15397 ds_pool_ci.pPoolSizes = &ds_type_count; 15398 15399 VkDescriptorPool ds_pool; 15400 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 15401 ASSERT_VK_SUCCESS(err); 15402 15403 VkDescriptorSetLayoutBinding dsl_binding = {}; 15404 dsl_binding.binding = 0; 15405 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 15406 dsl_binding.descriptorCount = 1; 15407 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 15408 dsl_binding.pImmutableSamplers = NULL; 15409 15410 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 15411 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 15412 ds_layout_ci.pNext = NULL; 15413 ds_layout_ci.bindingCount = 1; 15414 ds_layout_ci.pBindings = &dsl_binding; 15415 VkDescriptorSetLayout ds_layout; 15416 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 15417 ASSERT_VK_SUCCESS(err); 15418 15419 VkDescriptorSet descriptor_set; 15420 VkDescriptorSetAllocateInfo alloc_info = {}; 15421 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 15422 alloc_info.descriptorSetCount = 1; 15423 alloc_info.descriptorPool = ds_pool; 15424 alloc_info.pSetLayouts = &ds_layout; 15425 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set); 15426 ASSERT_VK_SUCCESS(err); 15427 15428 VkDescriptorBufferInfo buffer_info = {}; 15429 buffer_info.buffer = buffer; 15430 buffer_info.offset = 0; 15431 buffer_info.range = 1024; 15432 15433 VkWriteDescriptorSet descriptor_write; 15434 memset(&descriptor_write, 0, sizeof(descriptor_write)); 15435 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 15436 descriptor_write.dstSet = descriptor_set; 15437 descriptor_write.dstBinding = 0; 15438 descriptor_write.descriptorCount = 1; 15439 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 15440 descriptor_write.pBufferInfo = &buffer_info; 15441 15442 // Set pImageInfo and pTexelBufferView to invalid values, which should 15443 // be 15444 // ignored for descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER. 15445 // This will most likely produce a crash if the parameter_validation 15446 // layer 15447 // does not correctly ignore pImageInfo. 15448 descriptor_write.pImageInfo = reinterpret_cast<const VkDescriptorImageInfo *>(invalid_ptr); 15449 descriptor_write.pTexelBufferView = reinterpret_cast<const VkBufferView *>(invalid_ptr); 15450 15451 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 15452 15453 m_errorMonitor->VerifyNotFound(); 15454 15455 vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set); 15456 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 15457 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 15458 vkDestroyBuffer(m_device->device(), buffer, NULL); 15459 vkFreeMemory(m_device->device(), buffer_memory, NULL); 15460 } 15461 15462 // Texel Buffer Case 15463 { 15464 m_errorMonitor->ExpectSuccess(); 15465 15466 VkBuffer buffer; 15467 uint32_t queue_family_index = 0; 15468 VkBufferCreateInfo buffer_create_info = {}; 15469 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 15470 buffer_create_info.size = 1024; 15471 buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; 15472 buffer_create_info.queueFamilyIndexCount = 1; 15473 buffer_create_info.pQueueFamilyIndices = &queue_family_index; 15474 15475 VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer); 15476 ASSERT_VK_SUCCESS(err); 15477 15478 VkMemoryRequirements memory_reqs; 15479 VkDeviceMemory buffer_memory; 15480 bool pass; 15481 VkMemoryAllocateInfo memory_info = {}; 15482 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 15483 memory_info.pNext = NULL; 15484 memory_info.allocationSize = 0; 15485 memory_info.memoryTypeIndex = 0; 15486 15487 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs); 15488 memory_info.allocationSize = memory_reqs.size; 15489 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 15490 ASSERT_TRUE(pass); 15491 15492 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory); 15493 ASSERT_VK_SUCCESS(err); 15494 err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0); 15495 ASSERT_VK_SUCCESS(err); 15496 15497 VkBufferViewCreateInfo buff_view_ci = {}; 15498 buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; 15499 buff_view_ci.buffer = buffer; 15500 buff_view_ci.format = VK_FORMAT_R8_UNORM; 15501 buff_view_ci.range = VK_WHOLE_SIZE; 15502 VkBufferView buffer_view; 15503 err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buffer_view); 15504 15505 VkDescriptorPoolSize ds_type_count = {}; 15506 ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 15507 ds_type_count.descriptorCount = 1; 15508 15509 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 15510 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 15511 ds_pool_ci.pNext = NULL; 15512 ds_pool_ci.maxSets = 1; 15513 ds_pool_ci.poolSizeCount = 1; 15514 ds_pool_ci.pPoolSizes = &ds_type_count; 15515 15516 VkDescriptorPool ds_pool; 15517 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 15518 ASSERT_VK_SUCCESS(err); 15519 15520 VkDescriptorSetLayoutBinding dsl_binding = {}; 15521 dsl_binding.binding = 0; 15522 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 15523 dsl_binding.descriptorCount = 1; 15524 dsl_binding.stageFlags = VK_SHADER_STAGE_ALL; 15525 dsl_binding.pImmutableSamplers = NULL; 15526 15527 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 15528 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 15529 ds_layout_ci.pNext = NULL; 15530 ds_layout_ci.bindingCount = 1; 15531 ds_layout_ci.pBindings = &dsl_binding; 15532 VkDescriptorSetLayout ds_layout; 15533 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 15534 ASSERT_VK_SUCCESS(err); 15535 15536 VkDescriptorSet descriptor_set; 15537 VkDescriptorSetAllocateInfo alloc_info = {}; 15538 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 15539 alloc_info.descriptorSetCount = 1; 15540 alloc_info.descriptorPool = ds_pool; 15541 alloc_info.pSetLayouts = &ds_layout; 15542 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set); 15543 ASSERT_VK_SUCCESS(err); 15544 15545 VkWriteDescriptorSet descriptor_write; 15546 memset(&descriptor_write, 0, sizeof(descriptor_write)); 15547 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 15548 descriptor_write.dstSet = descriptor_set; 15549 descriptor_write.dstBinding = 0; 15550 descriptor_write.descriptorCount = 1; 15551 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 15552 descriptor_write.pTexelBufferView = &buffer_view; 15553 15554 // Set pImageInfo and pBufferInfo to invalid values, which should be 15555 // ignored for descriptorType == 15556 // VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER. 15557 // This will most likely produce a crash if the parameter_validation 15558 // layer 15559 // does not correctly ignore pImageInfo and pBufferInfo. 15560 descriptor_write.pImageInfo = reinterpret_cast<const VkDescriptorImageInfo *>(invalid_ptr); 15561 descriptor_write.pBufferInfo = reinterpret_cast<const VkDescriptorBufferInfo *>(invalid_ptr); 15562 15563 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 15564 15565 m_errorMonitor->VerifyNotFound(); 15566 15567 vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set); 15568 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 15569 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 15570 vkDestroyBufferView(m_device->device(), buffer_view, NULL); 15571 vkDestroyBuffer(m_device->device(), buffer, NULL); 15572 vkFreeMemory(m_device->device(), buffer_memory, NULL); 15573 } 15574 } 15575 15576 TEST_F(VkLayerTest, DuplicateDescriptorBinding) { 15577 TEST_DESCRIPTION("Create a descriptor set layout with a duplicate binding number."); 15578 15579 ASSERT_NO_FATAL_FAILURE(InitState()); 15580 // Create layout where two binding #s are "1" 15581 static const uint32_t NUM_BINDINGS = 3; 15582 VkDescriptorSetLayoutBinding dsl_binding[NUM_BINDINGS] = {}; 15583 dsl_binding[0].binding = 1; 15584 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 15585 dsl_binding[0].descriptorCount = 1; 15586 dsl_binding[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 15587 dsl_binding[0].pImmutableSamplers = NULL; 15588 dsl_binding[1].binding = 0; 15589 dsl_binding[1].descriptorCount = 1; 15590 dsl_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 15591 dsl_binding[1].descriptorCount = 1; 15592 dsl_binding[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 15593 dsl_binding[1].pImmutableSamplers = NULL; 15594 dsl_binding[2].binding = 1; // Duplicate binding should cause error 15595 dsl_binding[2].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 15596 dsl_binding[2].descriptorCount = 1; 15597 dsl_binding[2].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 15598 dsl_binding[2].pImmutableSamplers = NULL; 15599 15600 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 15601 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 15602 ds_layout_ci.pNext = NULL; 15603 ds_layout_ci.bindingCount = NUM_BINDINGS; 15604 ds_layout_ci.pBindings = dsl_binding; 15605 VkDescriptorSetLayout ds_layout; 15606 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_02345); 15607 vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 15608 m_errorMonitor->VerifyFound(); 15609 } 15610 15611 // This is a positive test. No failures are expected. 15612 TEST_F(VkPositiveLayerTest, EmptyDescriptorUpdateTest) { 15613 TEST_DESCRIPTION("Update last descriptor in a set that includes an empty binding"); 15614 VkResult err; 15615 15616 ASSERT_NO_FATAL_FAILURE(InitState()); 15617 m_errorMonitor->ExpectSuccess(); 15618 VkDescriptorPoolSize ds_type_count = {}; 15619 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 15620 ds_type_count.descriptorCount = 2; 15621 15622 VkDescriptorPoolCreateInfo ds_pool_ci = {}; 15623 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 15624 ds_pool_ci.pNext = NULL; 15625 ds_pool_ci.maxSets = 1; 15626 ds_pool_ci.poolSizeCount = 1; 15627 ds_pool_ci.pPoolSizes = &ds_type_count; 15628 15629 VkDescriptorPool ds_pool; 15630 err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool); 15631 ASSERT_VK_SUCCESS(err); 15632 15633 // Create layout with two uniform buffer descriptors w/ empty binding between them 15634 static const uint32_t NUM_BINDINGS = 3; 15635 VkDescriptorSetLayoutBinding dsl_binding[NUM_BINDINGS] = {}; 15636 dsl_binding[0].binding = 0; 15637 dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 15638 dsl_binding[0].descriptorCount = 1; 15639 dsl_binding[0].stageFlags = VK_SHADER_STAGE_ALL; 15640 dsl_binding[0].pImmutableSamplers = NULL; 15641 dsl_binding[1].binding = 1; 15642 dsl_binding[1].descriptorCount = 0; // empty binding 15643 dsl_binding[2].binding = 2; 15644 dsl_binding[2].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 15645 dsl_binding[2].descriptorCount = 1; 15646 dsl_binding[2].stageFlags = VK_SHADER_STAGE_ALL; 15647 dsl_binding[2].pImmutableSamplers = NULL; 15648 15649 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {}; 15650 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 15651 ds_layout_ci.pNext = NULL; 15652 ds_layout_ci.bindingCount = NUM_BINDINGS; 15653 ds_layout_ci.pBindings = dsl_binding; 15654 VkDescriptorSetLayout ds_layout; 15655 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout); 15656 ASSERT_VK_SUCCESS(err); 15657 15658 VkDescriptorSet descriptor_set = {}; 15659 VkDescriptorSetAllocateInfo alloc_info = {}; 15660 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 15661 alloc_info.descriptorSetCount = 1; 15662 alloc_info.descriptorPool = ds_pool; 15663 alloc_info.pSetLayouts = &ds_layout; 15664 err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set); 15665 ASSERT_VK_SUCCESS(err); 15666 15667 // Create a buffer to be used for update 15668 VkBufferCreateInfo buff_ci = {}; 15669 buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 15670 buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 15671 buff_ci.size = 256; 15672 buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 15673 VkBuffer buffer; 15674 err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer); 15675 ASSERT_VK_SUCCESS(err); 15676 // Have to bind memory to buffer before descriptor update 15677 VkMemoryAllocateInfo mem_alloc = {}; 15678 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 15679 mem_alloc.pNext = NULL; 15680 mem_alloc.allocationSize = 512; // one allocation for both buffers 15681 mem_alloc.memoryTypeIndex = 0; 15682 15683 VkMemoryRequirements mem_reqs; 15684 vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs); 15685 bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0); 15686 if (!pass) { 15687 vkDestroyBuffer(m_device->device(), buffer, NULL); 15688 return; 15689 } 15690 15691 VkDeviceMemory mem; 15692 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem); 15693 ASSERT_VK_SUCCESS(err); 15694 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0); 15695 ASSERT_VK_SUCCESS(err); 15696 15697 // Only update the descriptor at binding 2 15698 VkDescriptorBufferInfo buff_info = {}; 15699 buff_info.buffer = buffer; 15700 buff_info.offset = 0; 15701 buff_info.range = VK_WHOLE_SIZE; 15702 VkWriteDescriptorSet descriptor_write = {}; 15703 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 15704 descriptor_write.dstBinding = 2; 15705 descriptor_write.descriptorCount = 1; 15706 descriptor_write.pTexelBufferView = nullptr; 15707 descriptor_write.pBufferInfo = &buff_info; 15708 descriptor_write.pImageInfo = nullptr; 15709 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 15710 descriptor_write.dstSet = descriptor_set; 15711 15712 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL); 15713 15714 m_errorMonitor->VerifyNotFound(); 15715 // Cleanup 15716 vkFreeMemory(m_device->device(), mem, NULL); 15717 vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL); 15718 vkDestroyBuffer(m_device->device(), buffer, NULL); 15719 vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL); 15720 } 15721 15722 // This is a positive test. No failures are expected. 15723 TEST_F(VkPositiveLayerTest, TestAliasedMemoryTracking) { 15724 VkResult err; 15725 bool pass; 15726 15727 TEST_DESCRIPTION("Create a buffer, allocate memory, bind memory, destroy " 15728 "the buffer, create an image, and bind the same memory to " 15729 "it"); 15730 15731 m_errorMonitor->ExpectSuccess(); 15732 15733 ASSERT_NO_FATAL_FAILURE(InitState()); 15734 15735 VkBuffer buffer; 15736 VkImage image; 15737 VkDeviceMemory mem; 15738 VkMemoryRequirements mem_reqs; 15739 15740 VkBufferCreateInfo buf_info = {}; 15741 buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 15742 buf_info.pNext = NULL; 15743 buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 15744 buf_info.size = 256; 15745 buf_info.queueFamilyIndexCount = 0; 15746 buf_info.pQueueFamilyIndices = NULL; 15747 buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 15748 buf_info.flags = 0; 15749 err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer); 15750 ASSERT_VK_SUCCESS(err); 15751 15752 vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs); 15753 15754 VkMemoryAllocateInfo alloc_info = {}; 15755 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 15756 alloc_info.pNext = NULL; 15757 alloc_info.memoryTypeIndex = 0; 15758 15759 // Ensure memory is big enough for both bindings 15760 alloc_info.allocationSize = 0x10000; 15761 15762 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); 15763 if (!pass) { 15764 vkDestroyBuffer(m_device->device(), buffer, NULL); 15765 return; 15766 } 15767 15768 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem); 15769 ASSERT_VK_SUCCESS(err); 15770 15771 uint8_t *pData; 15772 err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData); 15773 ASSERT_VK_SUCCESS(err); 15774 15775 memset(pData, 0xCADECADE, static_cast<size_t>(mem_reqs.size)); 15776 15777 vkUnmapMemory(m_device->device(), mem); 15778 15779 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0); 15780 ASSERT_VK_SUCCESS(err); 15781 15782 // NOW, destroy the buffer. Obviously, the resource no longer occupies this 15783 // memory. In fact, it was never used by the GPU. 15784 // Just be be sure, wait for idle. 15785 vkDestroyBuffer(m_device->device(), buffer, NULL); 15786 vkDeviceWaitIdle(m_device->device()); 15787 15788 VkImageCreateInfo image_create_info = {}; 15789 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 15790 image_create_info.pNext = NULL; 15791 image_create_info.imageType = VK_IMAGE_TYPE_2D; 15792 image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM; 15793 image_create_info.extent.width = 64; 15794 image_create_info.extent.height = 64; 15795 image_create_info.extent.depth = 1; 15796 image_create_info.mipLevels = 1; 15797 image_create_info.arrayLayers = 1; 15798 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 15799 image_create_info.tiling = VK_IMAGE_TILING_LINEAR; 15800 image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; 15801 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 15802 image_create_info.queueFamilyIndexCount = 0; 15803 image_create_info.pQueueFamilyIndices = NULL; 15804 image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 15805 image_create_info.flags = 0; 15806 15807 VkMemoryAllocateInfo mem_alloc = {}; 15808 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 15809 mem_alloc.pNext = NULL; 15810 mem_alloc.allocationSize = 0; 15811 mem_alloc.memoryTypeIndex = 0; 15812 15813 /* Create a mappable image. It will be the texture if linear images are ok 15814 * to be textures or it will be the staging image if they are not. 15815 */ 15816 err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 15817 ASSERT_VK_SUCCESS(err); 15818 15819 vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs); 15820 15821 mem_alloc.allocationSize = mem_reqs.size; 15822 15823 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); 15824 if (!pass) { 15825 vkDestroyImage(m_device->device(), image, NULL); 15826 return; 15827 } 15828 15829 // VALIDATION FAILURE: 15830 err = vkBindImageMemory(m_device->device(), image, mem, 0); 15831 ASSERT_VK_SUCCESS(err); 15832 15833 m_errorMonitor->VerifyNotFound(); 15834 15835 vkFreeMemory(m_device->device(), mem, NULL); 15836 vkDestroyBuffer(m_device->device(), buffer, NULL); 15837 vkDestroyImage(m_device->device(), image, NULL); 15838 } 15839 15840 TEST_F(VkPositiveLayerTest, NonCoherentMemoryMapping) { 15841 15842 TEST_DESCRIPTION("Ensure that validations handling of non-coherent memory " 15843 "mapping while using VK_WHOLE_SIZE does not cause access " 15844 "violations"); 15845 VkResult err; 15846 uint8_t *pData; 15847 ASSERT_NO_FATAL_FAILURE(InitState()); 15848 15849 VkDeviceMemory mem; 15850 VkMemoryRequirements mem_reqs; 15851 mem_reqs.memoryTypeBits = 0xFFFFFFFF; 15852 VkMemoryAllocateInfo alloc_info = {}; 15853 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 15854 alloc_info.pNext = NULL; 15855 alloc_info.memoryTypeIndex = 0; 15856 15857 static const VkDeviceSize allocation_size = 0x1000; 15858 alloc_info.allocationSize = allocation_size; 15859 15860 // Find a memory configurations WITHOUT a COHERENT bit, otherwise exit 15861 bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 15862 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); 15863 if (!pass) { 15864 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, 15865 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 15866 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); 15867 if (!pass) { 15868 pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, 15869 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | 15870 VK_MEMORY_PROPERTY_HOST_CACHED_BIT, 15871 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); 15872 if (!pass) { 15873 return; 15874 } 15875 } 15876 } 15877 15878 err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem); 15879 ASSERT_VK_SUCCESS(err); 15880 15881 // Map/Flush/Invalidate using WHOLE_SIZE and zero offsets and entire 15882 // mapped range 15883 m_errorMonitor->ExpectSuccess(); 15884 err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, (void **)&pData); 15885 ASSERT_VK_SUCCESS(err); 15886 VkMappedMemoryRange mmr = {}; 15887 mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; 15888 mmr.memory = mem; 15889 mmr.offset = 0; 15890 mmr.size = VK_WHOLE_SIZE; 15891 err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr); 15892 ASSERT_VK_SUCCESS(err); 15893 err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr); 15894 ASSERT_VK_SUCCESS(err); 15895 m_errorMonitor->VerifyNotFound(); 15896 vkUnmapMemory(m_device->device(), mem); 15897 15898 // Map/Flush/Invalidate using WHOLE_SIZE and a prime offset and entire 15899 // mapped range 15900 m_errorMonitor->ExpectSuccess(); 15901 err = vkMapMemory(m_device->device(), mem, 13, VK_WHOLE_SIZE, 0, (void **)&pData); 15902 ASSERT_VK_SUCCESS(err); 15903 mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; 15904 mmr.memory = mem; 15905 mmr.offset = 13; 15906 mmr.size = VK_WHOLE_SIZE; 15907 err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr); 15908 ASSERT_VK_SUCCESS(err); 15909 err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr); 15910 ASSERT_VK_SUCCESS(err); 15911 m_errorMonitor->VerifyNotFound(); 15912 vkUnmapMemory(m_device->device(), mem); 15913 15914 // Map with prime offset and size 15915 // Flush/Invalidate subrange of mapped area with prime offset and size 15916 m_errorMonitor->ExpectSuccess(); 15917 err = vkMapMemory(m_device->device(), mem, allocation_size - 137, 109, 0, (void **)&pData); 15918 ASSERT_VK_SUCCESS(err); 15919 mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; 15920 mmr.memory = mem; 15921 mmr.offset = allocation_size - 107; 15922 mmr.size = 61; 15923 err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr); 15924 ASSERT_VK_SUCCESS(err); 15925 err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr); 15926 ASSERT_VK_SUCCESS(err); 15927 m_errorMonitor->VerifyNotFound(); 15928 vkUnmapMemory(m_device->device(), mem); 15929 15930 // Map without offset and flush WHOLE_SIZE with two separate offsets 15931 m_errorMonitor->ExpectSuccess(); 15932 err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, (void **)&pData); 15933 ASSERT_VK_SUCCESS(err); 15934 mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; 15935 mmr.memory = mem; 15936 mmr.offset = allocation_size - 100; 15937 mmr.size = VK_WHOLE_SIZE; 15938 err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr); 15939 ASSERT_VK_SUCCESS(err); 15940 mmr.offset = allocation_size - 200; 15941 mmr.size = VK_WHOLE_SIZE; 15942 err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr); 15943 ASSERT_VK_SUCCESS(err); 15944 m_errorMonitor->VerifyNotFound(); 15945 vkUnmapMemory(m_device->device(), mem); 15946 15947 vkFreeMemory(m_device->device(), mem, NULL); 15948 } 15949 15950 // This is a positive test. We used to expect error in this case but spec now allows it 15951 TEST_F(VkPositiveLayerTest, ResetUnsignaledFence) { 15952 m_errorMonitor->ExpectSuccess(); 15953 vk_testing::Fence testFence; 15954 VkFenceCreateInfo fenceInfo = {}; 15955 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 15956 fenceInfo.pNext = NULL; 15957 15958 ASSERT_NO_FATAL_FAILURE(InitState()); 15959 testFence.init(*m_device, fenceInfo); 15960 VkFence fences[1] = { testFence.handle() }; 15961 VkResult result = vkResetFences(m_device->device(), 1, fences); 15962 ASSERT_VK_SUCCESS(result); 15963 15964 m_errorMonitor->VerifyNotFound(); 15965 } 15966 15967 TEST_F(VkPositiveLayerTest, CommandBufferSimultaneousUseSync) { 15968 m_errorMonitor->ExpectSuccess(); 15969 15970 ASSERT_NO_FATAL_FAILURE(InitState()); 15971 VkResult err; 15972 15973 // Record (empty!) command buffer that can be submitted multiple times 15974 // simultaneously. 15975 VkCommandBufferBeginInfo cbbi = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 15976 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, nullptr }; 15977 m_commandBuffer->BeginCommandBuffer(&cbbi); 15978 m_commandBuffer->EndCommandBuffer(); 15979 15980 VkFenceCreateInfo fci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 }; 15981 VkFence fence; 15982 err = vkCreateFence(m_device->device(), &fci, nullptr, &fence); 15983 ASSERT_VK_SUCCESS(err); 15984 15985 VkSemaphoreCreateInfo sci = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0 }; 15986 VkSemaphore s1, s2; 15987 err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s1); 15988 ASSERT_VK_SUCCESS(err); 15989 err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s2); 15990 ASSERT_VK_SUCCESS(err); 15991 15992 // Submit CB once signaling s1, with fence so we can roll forward to its retirement. 15993 VkSubmitInfo si = { VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &m_commandBuffer->handle(), 1, &s1 }; 15994 err = vkQueueSubmit(m_device->m_queue, 1, &si, fence); 15995 ASSERT_VK_SUCCESS(err); 15996 15997 // Submit CB again, signaling s2. 15998 si.pSignalSemaphores = &s2; 15999 err = vkQueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE); 16000 ASSERT_VK_SUCCESS(err); 16001 16002 // Wait for fence. 16003 err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX); 16004 ASSERT_VK_SUCCESS(err); 16005 16006 // CB is still in flight from second submission, but semaphore s1 is no 16007 // longer in flight. delete it. 16008 vkDestroySemaphore(m_device->device(), s1, nullptr); 16009 16010 m_errorMonitor->VerifyNotFound(); 16011 16012 // Force device idle and clean up remaining objects 16013 vkDeviceWaitIdle(m_device->device()); 16014 vkDestroySemaphore(m_device->device(), s2, nullptr); 16015 vkDestroyFence(m_device->device(), fence, nullptr); 16016 } 16017 16018 TEST_F(VkPositiveLayerTest, FenceCreateSignaledWaitHandling) { 16019 m_errorMonitor->ExpectSuccess(); 16020 16021 ASSERT_NO_FATAL_FAILURE(InitState()); 16022 VkResult err; 16023 16024 // A fence created signaled 16025 VkFenceCreateInfo fci1 = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, VK_FENCE_CREATE_SIGNALED_BIT }; 16026 VkFence f1; 16027 err = vkCreateFence(m_device->device(), &fci1, nullptr, &f1); 16028 ASSERT_VK_SUCCESS(err); 16029 16030 // A fence created not 16031 VkFenceCreateInfo fci2 = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 }; 16032 VkFence f2; 16033 err = vkCreateFence(m_device->device(), &fci2, nullptr, &f2); 16034 ASSERT_VK_SUCCESS(err); 16035 16036 // Submit the unsignaled fence 16037 VkSubmitInfo si = { VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 0, nullptr, 0, nullptr }; 16038 err = vkQueueSubmit(m_device->m_queue, 1, &si, f2); 16039 16040 // Wait on both fences, with signaled first. 16041 VkFence fences[] = { f1, f2 }; 16042 vkWaitForFences(m_device->device(), 2, fences, VK_TRUE, UINT64_MAX); 16043 16044 // Should have both retired! 16045 vkDestroyFence(m_device->device(), f1, nullptr); 16046 vkDestroyFence(m_device->device(), f2, nullptr); 16047 16048 m_errorMonitor->VerifyNotFound(); 16049 } 16050 16051 TEST_F(VkPositiveLayerTest, ValidUsage) { 16052 TEST_DESCRIPTION("Verify that creating an image view from an image with valid usage " 16053 "doesn't generate validation errors"); 16054 16055 ASSERT_NO_FATAL_FAILURE(InitState()); 16056 16057 m_errorMonitor->ExpectSuccess(); 16058 // Verify that we can create a view with usage INPUT_ATTACHMENT 16059 VkImageObj image(m_device); 16060 image.init(128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 16061 ASSERT_TRUE(image.initialized()); 16062 VkImageView imageView; 16063 VkImageViewCreateInfo ivci = {}; 16064 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 16065 ivci.image = image.handle(); 16066 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; 16067 ivci.format = VK_FORMAT_R8G8B8A8_UNORM; 16068 ivci.subresourceRange.layerCount = 1; 16069 ivci.subresourceRange.baseMipLevel = 0; 16070 ivci.subresourceRange.levelCount = 1; 16071 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 16072 16073 vkCreateImageView(m_device->device(), &ivci, NULL, &imageView); 16074 m_errorMonitor->VerifyNotFound(); 16075 vkDestroyImageView(m_device->device(), imageView, NULL); 16076 } 16077 16078 // This is a positive test. No failures are expected. 16079 TEST_F(VkPositiveLayerTest, BindSparse) { 16080 TEST_DESCRIPTION("Bind 2 memory ranges to one image using vkQueueBindSparse, destroy the image" 16081 "and then free the memory"); 16082 16083 ASSERT_NO_FATAL_FAILURE(InitState()); 16084 16085 auto index = m_device->graphics_queue_node_index_; 16086 if (!(m_device->queue_props[index].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT)) 16087 return; 16088 16089 m_errorMonitor->ExpectSuccess(); 16090 16091 VkImage image; 16092 VkImageCreateInfo image_create_info = {}; 16093 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 16094 image_create_info.pNext = NULL; 16095 image_create_info.imageType = VK_IMAGE_TYPE_2D; 16096 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; 16097 image_create_info.extent.width = 64; 16098 image_create_info.extent.height = 64; 16099 image_create_info.extent.depth = 1; 16100 image_create_info.mipLevels = 1; 16101 image_create_info.arrayLayers = 1; 16102 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 16103 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 16104 image_create_info.usage = VK_IMAGE_USAGE_STORAGE_BIT; 16105 image_create_info.flags = VK_IMAGE_CREATE_SPARSE_BINDING_BIT; 16106 VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image); 16107 ASSERT_VK_SUCCESS(err); 16108 16109 VkMemoryRequirements memory_reqs; 16110 VkDeviceMemory memory_one, memory_two; 16111 bool pass; 16112 VkMemoryAllocateInfo memory_info = {}; 16113 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 16114 memory_info.pNext = NULL; 16115 memory_info.allocationSize = 0; 16116 memory_info.memoryTypeIndex = 0; 16117 vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs); 16118 // Find an image big enough to allow sparse mapping of 2 memory regions 16119 // Increase the image size until it is at least twice the 16120 // size of the required alignment, to ensure we can bind both 16121 // allocated memory blocks to the image on aligned offsets. 16122 while (memory_reqs.size < (memory_reqs.alignment * 2)) { 16123 vkDestroyImage(m_device->device(), image, nullptr); 16124 image_create_info.extent.width *= 2; 16125 image_create_info.extent.height *= 2; 16126 err = vkCreateImage(m_device->device(), &image_create_info, nullptr, &image); 16127 ASSERT_VK_SUCCESS(err); 16128 vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs); 16129 } 16130 // Allocate 2 memory regions of minimum alignment size, bind one at 0, the other 16131 // at the end of the first 16132 memory_info.allocationSize = memory_reqs.alignment; 16133 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 16134 ASSERT_TRUE(pass); 16135 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &memory_one); 16136 ASSERT_VK_SUCCESS(err); 16137 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &memory_two); 16138 ASSERT_VK_SUCCESS(err); 16139 VkSparseMemoryBind binds[2]; 16140 binds[0].flags = 0; 16141 binds[0].memory = memory_one; 16142 binds[0].memoryOffset = 0; 16143 binds[0].resourceOffset = 0; 16144 binds[0].size = memory_info.allocationSize; 16145 binds[1].flags = 0; 16146 binds[1].memory = memory_two; 16147 binds[1].memoryOffset = 0; 16148 binds[1].resourceOffset = memory_info.allocationSize; 16149 binds[1].size = memory_info.allocationSize; 16150 16151 VkSparseImageOpaqueMemoryBindInfo opaqueBindInfo; 16152 opaqueBindInfo.image = image; 16153 opaqueBindInfo.bindCount = 2; 16154 opaqueBindInfo.pBinds = binds; 16155 16156 VkFence fence = VK_NULL_HANDLE; 16157 VkBindSparseInfo bindSparseInfo = {}; 16158 bindSparseInfo.sType = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO; 16159 bindSparseInfo.imageOpaqueBindCount = 1; 16160 bindSparseInfo.pImageOpaqueBinds = &opaqueBindInfo; 16161 16162 vkQueueBindSparse(m_device->m_queue, 1, &bindSparseInfo, fence); 16163 vkQueueWaitIdle(m_device->m_queue); 16164 vkDestroyImage(m_device->device(), image, NULL); 16165 vkFreeMemory(m_device->device(), memory_one, NULL); 16166 vkFreeMemory(m_device->device(), memory_two, NULL); 16167 m_errorMonitor->VerifyNotFound(); 16168 } 16169 16170 TEST_F(VkPositiveLayerTest, RenderPassInitialLayoutUndefined) { 16171 TEST_DESCRIPTION("Ensure that CmdBeginRenderPass with an attachment's " 16172 "initialLayout of VK_IMAGE_LAYOUT_UNDEFINED works when " 16173 "the command buffer has prior knowledge of that " 16174 "attachment's layout."); 16175 16176 m_errorMonitor->ExpectSuccess(); 16177 16178 ASSERT_NO_FATAL_FAILURE(InitState()); 16179 16180 // A renderpass with one color attachment. 16181 VkAttachmentDescription attachment = { 0, 16182 VK_FORMAT_R8G8B8A8_UNORM, 16183 VK_SAMPLE_COUNT_1_BIT, 16184 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 16185 VK_ATTACHMENT_STORE_OP_STORE, 16186 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 16187 VK_ATTACHMENT_STORE_OP_DONT_CARE, 16188 VK_IMAGE_LAYOUT_UNDEFINED, 16189 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; 16190 16191 VkAttachmentReference att_ref = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; 16192 16193 VkSubpassDescription subpass = { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr }; 16194 16195 VkRenderPassCreateInfo rpci = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr }; 16196 16197 VkRenderPass rp; 16198 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 16199 ASSERT_VK_SUCCESS(err); 16200 16201 // A compatible framebuffer. 16202 VkImageObj image(m_device); 16203 image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 16204 ASSERT_TRUE(image.initialized()); 16205 16206 VkImageViewCreateInfo ivci = { 16207 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 16208 nullptr, 16209 0, 16210 image.handle(), 16211 VK_IMAGE_VIEW_TYPE_2D, 16212 VK_FORMAT_R8G8B8A8_UNORM, 16213 { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, 16214 VK_COMPONENT_SWIZZLE_IDENTITY }, 16215 { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }, 16216 }; 16217 VkImageView view; 16218 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view); 16219 ASSERT_VK_SUCCESS(err); 16220 16221 VkFramebufferCreateInfo fci = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1 }; 16222 VkFramebuffer fb; 16223 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); 16224 ASSERT_VK_SUCCESS(err); 16225 16226 // Record a single command buffer which uses this renderpass twice. The 16227 // bug is triggered at the beginning of the second renderpass, when the 16228 // command buffer already has a layout recorded for the attachment. 16229 VkRenderPassBeginInfo rpbi = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb,{ { 0, 0 },{ 32, 32 } }, 0, nullptr }; 16230 BeginCommandBuffer(); 16231 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); 16232 vkCmdEndRenderPass(m_commandBuffer->handle()); 16233 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); 16234 16235 m_errorMonitor->VerifyNotFound(); 16236 16237 vkCmdEndRenderPass(m_commandBuffer->handle()); 16238 EndCommandBuffer(); 16239 16240 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 16241 vkDestroyRenderPass(m_device->device(), rp, nullptr); 16242 vkDestroyImageView(m_device->device(), view, nullptr); 16243 } 16244 16245 TEST_F(VkPositiveLayerTest, FramebufferBindingDestroyCommandPool) { 16246 TEST_DESCRIPTION("This test should pass. Create a Framebuffer and " 16247 "command buffer, bind them together, then destroy " 16248 "command pool and framebuffer and verify there are no " 16249 "errors."); 16250 16251 m_errorMonitor->ExpectSuccess(); 16252 16253 ASSERT_NO_FATAL_FAILURE(InitState()); 16254 16255 // A renderpass with one color attachment. 16256 VkAttachmentDescription attachment = { 0, 16257 VK_FORMAT_R8G8B8A8_UNORM, 16258 VK_SAMPLE_COUNT_1_BIT, 16259 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 16260 VK_ATTACHMENT_STORE_OP_STORE, 16261 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 16262 VK_ATTACHMENT_STORE_OP_DONT_CARE, 16263 VK_IMAGE_LAYOUT_UNDEFINED, 16264 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; 16265 16266 VkAttachmentReference att_ref = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; 16267 16268 VkSubpassDescription subpass = { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr }; 16269 16270 VkRenderPassCreateInfo rpci = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr }; 16271 16272 VkRenderPass rp; 16273 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 16274 ASSERT_VK_SUCCESS(err); 16275 16276 // A compatible framebuffer. 16277 VkImageObj image(m_device); 16278 image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 16279 ASSERT_TRUE(image.initialized()); 16280 16281 VkImageViewCreateInfo ivci = { 16282 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 16283 nullptr, 16284 0, 16285 image.handle(), 16286 VK_IMAGE_VIEW_TYPE_2D, 16287 VK_FORMAT_R8G8B8A8_UNORM, 16288 { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, 16289 VK_COMPONENT_SWIZZLE_IDENTITY }, 16290 { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }, 16291 }; 16292 VkImageView view; 16293 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view); 16294 ASSERT_VK_SUCCESS(err); 16295 16296 VkFramebufferCreateInfo fci = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1 }; 16297 VkFramebuffer fb; 16298 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); 16299 ASSERT_VK_SUCCESS(err); 16300 16301 // Explicitly create a command buffer to bind the FB to so that we can then 16302 // destroy the command pool in order to implicitly free command buffer 16303 VkCommandPool command_pool; 16304 VkCommandPoolCreateInfo pool_create_info{}; 16305 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 16306 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 16307 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 16308 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 16309 16310 VkCommandBuffer command_buffer; 16311 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 16312 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 16313 command_buffer_allocate_info.commandPool = command_pool; 16314 command_buffer_allocate_info.commandBufferCount = 1; 16315 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 16316 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer); 16317 16318 // Begin our cmd buffer with renderpass using our framebuffer 16319 VkRenderPassBeginInfo rpbi = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb,{ { 0, 0 },{ 32, 32 } }, 0, nullptr }; 16320 VkCommandBufferBeginInfo begin_info{}; 16321 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 16322 vkBeginCommandBuffer(command_buffer, &begin_info); 16323 16324 vkCmdBeginRenderPass(command_buffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE); 16325 vkCmdEndRenderPass(command_buffer); 16326 vkEndCommandBuffer(command_buffer); 16327 vkDestroyImageView(m_device->device(), view, nullptr); 16328 // Destroy command pool to implicitly free command buffer 16329 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 16330 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 16331 vkDestroyRenderPass(m_device->device(), rp, nullptr); 16332 m_errorMonitor->VerifyNotFound(); 16333 } 16334 16335 TEST_F(VkPositiveLayerTest, RenderPassSubpassZeroTransitionsApplied) { 16336 TEST_DESCRIPTION("Ensure that CmdBeginRenderPass applies the layout " 16337 "transitions for the first subpass"); 16338 16339 m_errorMonitor->ExpectSuccess(); 16340 16341 ASSERT_NO_FATAL_FAILURE(InitState()); 16342 16343 // A renderpass with one color attachment. 16344 VkAttachmentDescription attachment = { 0, 16345 VK_FORMAT_R8G8B8A8_UNORM, 16346 VK_SAMPLE_COUNT_1_BIT, 16347 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 16348 VK_ATTACHMENT_STORE_OP_STORE, 16349 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 16350 VK_ATTACHMENT_STORE_OP_DONT_CARE, 16351 VK_IMAGE_LAYOUT_UNDEFINED, 16352 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; 16353 16354 VkAttachmentReference att_ref = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; 16355 16356 VkSubpassDescription subpass = { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr }; 16357 16358 VkSubpassDependency dep = { 0, 16359 0, 16360 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 16361 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 16362 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 16363 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 16364 VK_DEPENDENCY_BY_REGION_BIT }; 16365 16366 VkRenderPassCreateInfo rpci = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep }; 16367 16368 VkResult err; 16369 VkRenderPass rp; 16370 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 16371 ASSERT_VK_SUCCESS(err); 16372 16373 // A compatible framebuffer. 16374 VkImageObj image(m_device); 16375 image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0); 16376 ASSERT_TRUE(image.initialized()); 16377 16378 VkImageViewCreateInfo ivci = { 16379 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 16380 nullptr, 16381 0, 16382 image.handle(), 16383 VK_IMAGE_VIEW_TYPE_2D, 16384 VK_FORMAT_R8G8B8A8_UNORM, 16385 { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, 16386 VK_COMPONENT_SWIZZLE_IDENTITY }, 16387 { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }, 16388 }; 16389 VkImageView view; 16390 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view); 16391 ASSERT_VK_SUCCESS(err); 16392 16393 VkFramebufferCreateInfo fci = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1 }; 16394 VkFramebuffer fb; 16395 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); 16396 ASSERT_VK_SUCCESS(err); 16397 16398 // Record a single command buffer which issues a pipeline barrier w/ 16399 // image memory barrier for the attachment. This detects the previously 16400 // missing tracking of the subpass layout by throwing a validation error 16401 // if it doesn't occur. 16402 VkRenderPassBeginInfo rpbi = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb,{ { 0, 0 },{ 32, 32 } }, 0, nullptr }; 16403 BeginCommandBuffer(); 16404 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); 16405 16406 VkImageMemoryBarrier imb = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 16407 nullptr, 16408 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 16409 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 16410 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 16411 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 16412 VK_QUEUE_FAMILY_IGNORED, 16413 VK_QUEUE_FAMILY_IGNORED, 16414 image.handle(), 16415 { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } }; 16416 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 16417 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 16418 &imb); 16419 16420 vkCmdEndRenderPass(m_commandBuffer->handle()); 16421 m_errorMonitor->VerifyNotFound(); 16422 EndCommandBuffer(); 16423 16424 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 16425 vkDestroyRenderPass(m_device->device(), rp, nullptr); 16426 vkDestroyImageView(m_device->device(), view, nullptr); 16427 } 16428 16429 TEST_F(VkPositiveLayerTest, DepthStencilLayoutTransitionForDepthOnlyImageview) { 16430 TEST_DESCRIPTION("Validate that when an imageView of a depth/stencil image " 16431 "is used as a depth/stencil framebuffer attachment, the " 16432 "aspectMask is ignored and both depth and stencil image " 16433 "subresources are used."); 16434 16435 VkFormatProperties format_properties; 16436 vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_D32_SFLOAT_S8_UINT, &format_properties); 16437 if (!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { 16438 return; 16439 } 16440 16441 m_errorMonitor->ExpectSuccess(); 16442 16443 ASSERT_NO_FATAL_FAILURE(InitState()); 16444 16445 VkAttachmentDescription attachment = { 0, 16446 VK_FORMAT_D32_SFLOAT_S8_UINT, 16447 VK_SAMPLE_COUNT_1_BIT, 16448 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 16449 VK_ATTACHMENT_STORE_OP_STORE, 16450 VK_ATTACHMENT_LOAD_OP_DONT_CARE, 16451 VK_ATTACHMENT_STORE_OP_DONT_CARE, 16452 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 16453 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; 16454 16455 VkAttachmentReference att_ref = { 0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; 16456 16457 VkSubpassDescription subpass = { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &att_ref, 0, nullptr }; 16458 16459 VkSubpassDependency dep = { 0, 16460 0, 16461 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 16462 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 16463 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 16464 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 16465 VK_DEPENDENCY_BY_REGION_BIT}; 16466 16467 VkRenderPassCreateInfo rpci = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep }; 16468 16469 VkResult err; 16470 VkRenderPass rp; 16471 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 16472 ASSERT_VK_SUCCESS(err); 16473 16474 VkImageObj image(m_device); 16475 image.init_no_layout(32, 32, VK_FORMAT_D32_SFLOAT_S8_UINT, 16476 0x26, // usage 16477 VK_IMAGE_TILING_OPTIMAL, 0); 16478 ASSERT_TRUE(image.initialized()); 16479 image.SetLayout(0x6, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); 16480 16481 VkImageViewCreateInfo ivci = { 16482 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 16483 nullptr, 16484 0, 16485 image.handle(), 16486 VK_IMAGE_VIEW_TYPE_2D, 16487 VK_FORMAT_D32_SFLOAT_S8_UINT, 16488 { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }, 16489 { 0x2, 0, 1, 0, 1 }, 16490 }; 16491 VkImageView view; 16492 err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view); 16493 ASSERT_VK_SUCCESS(err); 16494 16495 VkFramebufferCreateInfo fci = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1 }; 16496 VkFramebuffer fb; 16497 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); 16498 ASSERT_VK_SUCCESS(err); 16499 16500 VkRenderPassBeginInfo rpbi = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb,{ { 0, 0 },{ 32, 32 } }, 0, nullptr }; 16501 BeginCommandBuffer(); 16502 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); 16503 16504 VkImageMemoryBarrier imb = {}; 16505 imb.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 16506 imb.pNext = nullptr; 16507 imb.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 16508 imb.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 16509 imb.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 16510 imb.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 16511 imb.srcQueueFamilyIndex = 0; 16512 imb.dstQueueFamilyIndex = 0; 16513 imb.image = image.handle(); 16514 imb.subresourceRange.aspectMask = 0x6; 16515 imb.subresourceRange.baseMipLevel = 0; 16516 imb.subresourceRange.levelCount = 0x1; 16517 imb.subresourceRange.baseArrayLayer = 0; 16518 imb.subresourceRange.layerCount = 0x1; 16519 16520 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 16521 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, 16522 &imb); 16523 16524 vkCmdEndRenderPass(m_commandBuffer->handle()); 16525 EndCommandBuffer(); 16526 QueueCommandBuffer(false); 16527 m_errorMonitor->VerifyNotFound(); 16528 16529 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 16530 vkDestroyRenderPass(m_device->device(), rp, nullptr); 16531 vkDestroyImageView(m_device->device(), view, nullptr); 16532 } 16533 16534 TEST_F(VkPositiveLayerTest, RenderPassTransitionsAttachmentUnused) { 16535 TEST_DESCRIPTION("Ensure that layout transitions work correctly without " 16536 "errors, when an attachment reference is " 16537 "VK_ATTACHMENT_UNUSED"); 16538 16539 m_errorMonitor->ExpectSuccess(); 16540 16541 ASSERT_NO_FATAL_FAILURE(InitState()); 16542 16543 // A renderpass with no attachments 16544 VkAttachmentReference att_ref = { VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; 16545 16546 VkSubpassDescription subpass = { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr }; 16547 16548 VkRenderPassCreateInfo rpci = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, &subpass, 0, nullptr }; 16549 16550 VkRenderPass rp; 16551 VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 16552 ASSERT_VK_SUCCESS(err); 16553 16554 // A compatible framebuffer. 16555 VkFramebufferCreateInfo fci = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 32, 32, 1 }; 16556 VkFramebuffer fb; 16557 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb); 16558 ASSERT_VK_SUCCESS(err); 16559 16560 // Record a command buffer which just begins and ends the renderpass. The 16561 // bug manifests in BeginRenderPass. 16562 VkRenderPassBeginInfo rpbi = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb,{ { 0, 0 },{ 32, 32 } }, 0, nullptr }; 16563 BeginCommandBuffer(); 16564 vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE); 16565 vkCmdEndRenderPass(m_commandBuffer->handle()); 16566 m_errorMonitor->VerifyNotFound(); 16567 EndCommandBuffer(); 16568 16569 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 16570 vkDestroyRenderPass(m_device->device(), rp, nullptr); 16571 } 16572 16573 // This is a positive test. No errors are expected. 16574 TEST_F(VkPositiveLayerTest, StencilLoadOp) { 16575 TEST_DESCRIPTION("Create a stencil-only attachment with a LOAD_OP set to " 16576 "CLEAR. stencil[Load|Store]Op used to be ignored."); 16577 VkResult result = VK_SUCCESS; 16578 VkImageFormatProperties formatProps; 16579 vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, 16580 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0, 16581 &formatProps); 16582 if (formatProps.maxExtent.width < 100 || formatProps.maxExtent.height < 100) { 16583 return; 16584 } 16585 16586 ASSERT_NO_FATAL_FAILURE(InitState()); 16587 VkFormat depth_stencil_fmt = VK_FORMAT_D24_UNORM_S8_UINT; 16588 m_depthStencil->Init(m_device, 100, 100, depth_stencil_fmt, 16589 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT); 16590 VkAttachmentDescription att = {}; 16591 VkAttachmentReference ref = {}; 16592 att.format = depth_stencil_fmt; 16593 att.samples = VK_SAMPLE_COUNT_1_BIT; 16594 att.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; 16595 att.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; 16596 att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 16597 att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; 16598 att.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 16599 att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 16600 16601 VkClearValue clear; 16602 clear.depthStencil.depth = 1.0; 16603 clear.depthStencil.stencil = 0; 16604 ref.attachment = 0; 16605 ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 16606 16607 VkSubpassDescription subpass = {}; 16608 subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; 16609 subpass.flags = 0; 16610 subpass.inputAttachmentCount = 0; 16611 subpass.pInputAttachments = NULL; 16612 subpass.colorAttachmentCount = 0; 16613 subpass.pColorAttachments = NULL; 16614 subpass.pResolveAttachments = NULL; 16615 subpass.pDepthStencilAttachment = &ref; 16616 subpass.preserveAttachmentCount = 0; 16617 subpass.pPreserveAttachments = NULL; 16618 16619 VkRenderPass rp; 16620 VkRenderPassCreateInfo rp_info = {}; 16621 rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 16622 rp_info.attachmentCount = 1; 16623 rp_info.pAttachments = &att; 16624 rp_info.subpassCount = 1; 16625 rp_info.pSubpasses = &subpass; 16626 result = vkCreateRenderPass(device(), &rp_info, NULL, &rp); 16627 ASSERT_VK_SUCCESS(result); 16628 16629 VkImageView *depthView = m_depthStencil->BindInfo(); 16630 VkFramebufferCreateInfo fb_info = {}; 16631 fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; 16632 fb_info.pNext = NULL; 16633 fb_info.renderPass = rp; 16634 fb_info.attachmentCount = 1; 16635 fb_info.pAttachments = depthView; 16636 fb_info.width = 100; 16637 fb_info.height = 100; 16638 fb_info.layers = 1; 16639 VkFramebuffer fb; 16640 result = vkCreateFramebuffer(device(), &fb_info, NULL, &fb); 16641 ASSERT_VK_SUCCESS(result); 16642 16643 VkRenderPassBeginInfo rpbinfo = {}; 16644 rpbinfo.clearValueCount = 1; 16645 rpbinfo.pClearValues = &clear; 16646 rpbinfo.pNext = NULL; 16647 rpbinfo.renderPass = rp; 16648 rpbinfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; 16649 rpbinfo.renderArea.extent.width = 100; 16650 rpbinfo.renderArea.extent.height = 100; 16651 rpbinfo.renderArea.offset.x = 0; 16652 rpbinfo.renderArea.offset.y = 0; 16653 rpbinfo.framebuffer = fb; 16654 16655 VkFence fence = {}; 16656 VkFenceCreateInfo fence_ci = {}; 16657 fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 16658 fence_ci.pNext = nullptr; 16659 fence_ci.flags = 0; 16660 result = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fence); 16661 ASSERT_VK_SUCCESS(result); 16662 16663 m_commandBuffer->BeginCommandBuffer(); 16664 m_commandBuffer->BeginRenderPass(rpbinfo); 16665 m_commandBuffer->EndRenderPass(); 16666 m_commandBuffer->EndCommandBuffer(); 16667 m_commandBuffer->QueueCommandBuffer(fence); 16668 16669 VkImageObj destImage(m_device); 16670 destImage.init(100, 100, depth_stencil_fmt, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 16671 VK_IMAGE_TILING_OPTIMAL, 0); 16672 VkImageMemoryBarrier barrier = {}; 16673 VkImageSubresourceRange range; 16674 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 16675 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 16676 barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; 16677 barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 16678 barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 16679 barrier.image = m_depthStencil->handle(); 16680 range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 16681 range.baseMipLevel = 0; 16682 range.levelCount = 1; 16683 range.baseArrayLayer = 0; 16684 range.layerCount = 1; 16685 barrier.subresourceRange = range; 16686 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX); 16687 VkCommandBufferObj cmdbuf(m_device, m_commandPool); 16688 cmdbuf.BeginCommandBuffer(); 16689 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, 16690 &barrier); 16691 barrier.srcAccessMask = 0; 16692 barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; 16693 barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 16694 barrier.image = destImage.handle(); 16695 barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 16696 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, 16697 &barrier); 16698 VkImageCopy cregion; 16699 cregion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 16700 cregion.srcSubresource.mipLevel = 0; 16701 cregion.srcSubresource.baseArrayLayer = 0; 16702 cregion.srcSubresource.layerCount = 1; 16703 cregion.srcOffset.x = 0; 16704 cregion.srcOffset.y = 0; 16705 cregion.srcOffset.z = 0; 16706 cregion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 16707 cregion.dstSubresource.mipLevel = 0; 16708 cregion.dstSubresource.baseArrayLayer = 0; 16709 cregion.dstSubresource.layerCount = 1; 16710 cregion.dstOffset.x = 0; 16711 cregion.dstOffset.y = 0; 16712 cregion.dstOffset.z = 0; 16713 cregion.extent.width = 100; 16714 cregion.extent.height = 100; 16715 cregion.extent.depth = 1; 16716 cmdbuf.CopyImage(m_depthStencil->handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, destImage.handle(), 16717 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cregion); 16718 cmdbuf.EndCommandBuffer(); 16719 16720 VkSubmitInfo submit_info; 16721 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 16722 submit_info.pNext = NULL; 16723 submit_info.waitSemaphoreCount = 0; 16724 submit_info.pWaitSemaphores = NULL; 16725 submit_info.pWaitDstStageMask = NULL; 16726 submit_info.commandBufferCount = 1; 16727 submit_info.pCommandBuffers = &cmdbuf.handle(); 16728 submit_info.signalSemaphoreCount = 0; 16729 submit_info.pSignalSemaphores = NULL; 16730 16731 m_errorMonitor->ExpectSuccess(); 16732 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 16733 m_errorMonitor->VerifyNotFound(); 16734 16735 vkQueueWaitIdle(m_device->m_queue); 16736 vkDestroyFence(m_device->device(), fence, nullptr); 16737 vkDestroyRenderPass(m_device->device(), rp, nullptr); 16738 vkDestroyFramebuffer(m_device->device(), fb, nullptr); 16739 } 16740 16741 // This is a positive test. No errors should be generated. 16742 TEST_F(VkPositiveLayerTest, WaitEventThenSet) { 16743 TEST_DESCRIPTION("Wait on a event then set it after the wait has been submitted."); 16744 16745 m_errorMonitor->ExpectSuccess(); 16746 ASSERT_NO_FATAL_FAILURE(InitState()); 16747 16748 VkEvent event; 16749 VkEventCreateInfo event_create_info{}; 16750 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 16751 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event); 16752 16753 VkCommandPool command_pool; 16754 VkCommandPoolCreateInfo pool_create_info{}; 16755 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 16756 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 16757 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 16758 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 16759 16760 VkCommandBuffer command_buffer; 16761 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 16762 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 16763 command_buffer_allocate_info.commandPool = command_pool; 16764 command_buffer_allocate_info.commandBufferCount = 1; 16765 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 16766 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer); 16767 16768 VkQueue queue = VK_NULL_HANDLE; 16769 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue); 16770 16771 { 16772 VkCommandBufferBeginInfo begin_info{}; 16773 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 16774 vkBeginCommandBuffer(command_buffer, &begin_info); 16775 16776 vkCmdWaitEvents(command_buffer, 1, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0, 16777 nullptr, 0, nullptr); 16778 vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); 16779 vkEndCommandBuffer(command_buffer); 16780 } 16781 { 16782 VkSubmitInfo submit_info{}; 16783 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 16784 submit_info.commandBufferCount = 1; 16785 submit_info.pCommandBuffers = &command_buffer; 16786 submit_info.signalSemaphoreCount = 0; 16787 submit_info.pSignalSemaphores = nullptr; 16788 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE); 16789 } 16790 { vkSetEvent(m_device->device(), event); } 16791 16792 vkQueueWaitIdle(queue); 16793 16794 vkDestroyEvent(m_device->device(), event, nullptr); 16795 vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer); 16796 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 16797 16798 m_errorMonitor->VerifyNotFound(); 16799 } 16800 // This is a positive test. No errors should be generated. 16801 TEST_F(VkPositiveLayerTest, QueryAndCopySecondaryCommandBuffers) { 16802 TEST_DESCRIPTION("Issue a query on a secondary command buffery and copy it on a primary."); 16803 16804 ASSERT_NO_FATAL_FAILURE(InitState()); 16805 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) 16806 return; 16807 16808 m_errorMonitor->ExpectSuccess(); 16809 16810 VkQueryPool query_pool; 16811 VkQueryPoolCreateInfo query_pool_create_info{}; 16812 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; 16813 query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP; 16814 query_pool_create_info.queryCount = 1; 16815 vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool); 16816 16817 VkCommandPool command_pool; 16818 VkCommandPoolCreateInfo pool_create_info{}; 16819 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 16820 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 16821 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 16822 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 16823 16824 VkCommandBuffer command_buffer; 16825 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 16826 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 16827 command_buffer_allocate_info.commandPool = command_pool; 16828 command_buffer_allocate_info.commandBufferCount = 1; 16829 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 16830 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer); 16831 16832 VkCommandBuffer secondary_command_buffer; 16833 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY; 16834 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer); 16835 16836 VkQueue queue = VK_NULL_HANDLE; 16837 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue); 16838 16839 uint32_t qfi = 0; 16840 VkBufferCreateInfo buff_create_info = {}; 16841 buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 16842 buff_create_info.size = 1024; 16843 buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT; 16844 buff_create_info.queueFamilyIndexCount = 1; 16845 buff_create_info.pQueueFamilyIndices = &qfi; 16846 16847 VkResult err; 16848 VkBuffer buffer; 16849 err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer); 16850 ASSERT_VK_SUCCESS(err); 16851 VkMemoryAllocateInfo mem_alloc = {}; 16852 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 16853 mem_alloc.pNext = NULL; 16854 mem_alloc.allocationSize = 1024; 16855 mem_alloc.memoryTypeIndex = 0; 16856 16857 VkMemoryRequirements memReqs; 16858 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs); 16859 bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0); 16860 if (!pass) { 16861 vkDestroyBuffer(m_device->device(), buffer, NULL); 16862 return; 16863 } 16864 16865 VkDeviceMemory mem; 16866 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem); 16867 ASSERT_VK_SUCCESS(err); 16868 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0); 16869 ASSERT_VK_SUCCESS(err); 16870 16871 VkCommandBufferInheritanceInfo hinfo = {}; 16872 hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; 16873 hinfo.renderPass = VK_NULL_HANDLE; 16874 hinfo.subpass = 0; 16875 hinfo.framebuffer = VK_NULL_HANDLE; 16876 hinfo.occlusionQueryEnable = VK_FALSE; 16877 hinfo.queryFlags = 0; 16878 hinfo.pipelineStatistics = 0; 16879 16880 { 16881 VkCommandBufferBeginInfo begin_info{}; 16882 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 16883 begin_info.pInheritanceInfo = &hinfo; 16884 vkBeginCommandBuffer(secondary_command_buffer, &begin_info); 16885 16886 vkCmdResetQueryPool(secondary_command_buffer, query_pool, 0, 1); 16887 vkCmdWriteTimestamp(secondary_command_buffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0); 16888 16889 vkEndCommandBuffer(secondary_command_buffer); 16890 16891 begin_info.pInheritanceInfo = nullptr; 16892 vkBeginCommandBuffer(command_buffer, &begin_info); 16893 16894 vkCmdExecuteCommands(command_buffer, 1, &secondary_command_buffer); 16895 vkCmdCopyQueryPoolResults(command_buffer, query_pool, 0, 1, buffer, 0, 0, 0); 16896 16897 vkEndCommandBuffer(command_buffer); 16898 } 16899 { 16900 VkSubmitInfo submit_info{}; 16901 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 16902 submit_info.commandBufferCount = 1; 16903 submit_info.pCommandBuffers = &command_buffer; 16904 submit_info.signalSemaphoreCount = 0; 16905 submit_info.pSignalSemaphores = nullptr; 16906 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE); 16907 } 16908 16909 vkQueueWaitIdle(queue); 16910 16911 vkDestroyQueryPool(m_device->device(), query_pool, nullptr); 16912 vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer); 16913 vkFreeCommandBuffers(m_device->device(), command_pool, 1, &secondary_command_buffer); 16914 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 16915 vkDestroyBuffer(m_device->device(), buffer, NULL); 16916 vkFreeMemory(m_device->device(), mem, NULL); 16917 16918 m_errorMonitor->VerifyNotFound(); 16919 } 16920 16921 // This is a positive test. No errors should be generated. 16922 TEST_F(VkPositiveLayerTest, QueryAndCopyMultipleCommandBuffers) { 16923 TEST_DESCRIPTION("Issue a query and copy from it on a second command buffer."); 16924 16925 ASSERT_NO_FATAL_FAILURE(InitState()); 16926 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) 16927 return; 16928 16929 m_errorMonitor->ExpectSuccess(); 16930 16931 VkQueryPool query_pool; 16932 VkQueryPoolCreateInfo query_pool_create_info{}; 16933 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; 16934 query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP; 16935 query_pool_create_info.queryCount = 1; 16936 vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool); 16937 16938 VkCommandPool command_pool; 16939 VkCommandPoolCreateInfo pool_create_info{}; 16940 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 16941 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 16942 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 16943 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 16944 16945 VkCommandBuffer command_buffer[2]; 16946 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 16947 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 16948 command_buffer_allocate_info.commandPool = command_pool; 16949 command_buffer_allocate_info.commandBufferCount = 2; 16950 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 16951 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer); 16952 16953 VkQueue queue = VK_NULL_HANDLE; 16954 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue); 16955 16956 uint32_t qfi = 0; 16957 VkBufferCreateInfo buff_create_info = {}; 16958 buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 16959 buff_create_info.size = 1024; 16960 buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT; 16961 buff_create_info.queueFamilyIndexCount = 1; 16962 buff_create_info.pQueueFamilyIndices = &qfi; 16963 16964 VkResult err; 16965 VkBuffer buffer; 16966 err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer); 16967 ASSERT_VK_SUCCESS(err); 16968 VkMemoryAllocateInfo mem_alloc = {}; 16969 mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 16970 mem_alloc.pNext = NULL; 16971 mem_alloc.allocationSize = 1024; 16972 mem_alloc.memoryTypeIndex = 0; 16973 16974 VkMemoryRequirements memReqs; 16975 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs); 16976 bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0); 16977 if (!pass) { 16978 vkDestroyBuffer(m_device->device(), buffer, NULL); 16979 return; 16980 } 16981 16982 VkDeviceMemory mem; 16983 err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem); 16984 ASSERT_VK_SUCCESS(err); 16985 err = vkBindBufferMemory(m_device->device(), buffer, mem, 0); 16986 ASSERT_VK_SUCCESS(err); 16987 16988 { 16989 VkCommandBufferBeginInfo begin_info{}; 16990 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 16991 vkBeginCommandBuffer(command_buffer[0], &begin_info); 16992 16993 vkCmdResetQueryPool(command_buffer[0], query_pool, 0, 1); 16994 vkCmdWriteTimestamp(command_buffer[0], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0); 16995 16996 vkEndCommandBuffer(command_buffer[0]); 16997 16998 vkBeginCommandBuffer(command_buffer[1], &begin_info); 16999 17000 vkCmdCopyQueryPoolResults(command_buffer[1], query_pool, 0, 1, buffer, 0, 0, 0); 17001 17002 vkEndCommandBuffer(command_buffer[1]); 17003 } 17004 { 17005 VkSubmitInfo submit_info{}; 17006 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 17007 submit_info.commandBufferCount = 2; 17008 submit_info.pCommandBuffers = command_buffer; 17009 submit_info.signalSemaphoreCount = 0; 17010 submit_info.pSignalSemaphores = nullptr; 17011 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE); 17012 } 17013 17014 vkQueueWaitIdle(queue); 17015 17016 vkDestroyQueryPool(m_device->device(), query_pool, nullptr); 17017 vkFreeCommandBuffers(m_device->device(), command_pool, 2, command_buffer); 17018 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 17019 vkDestroyBuffer(m_device->device(), buffer, NULL); 17020 vkFreeMemory(m_device->device(), mem, NULL); 17021 17022 m_errorMonitor->VerifyNotFound(); 17023 } 17024 17025 TEST_F(VkPositiveLayerTest, ResetEventThenSet) { 17026 TEST_DESCRIPTION("Reset an event then set it after the reset has been submitted."); 17027 17028 m_errorMonitor->ExpectSuccess(); 17029 17030 ASSERT_NO_FATAL_FAILURE(InitState()); 17031 VkEvent event; 17032 VkEventCreateInfo event_create_info{}; 17033 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 17034 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event); 17035 17036 VkCommandPool command_pool; 17037 VkCommandPoolCreateInfo pool_create_info{}; 17038 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 17039 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 17040 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 17041 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 17042 17043 VkCommandBuffer command_buffer; 17044 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 17045 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 17046 command_buffer_allocate_info.commandPool = command_pool; 17047 command_buffer_allocate_info.commandBufferCount = 1; 17048 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 17049 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer); 17050 17051 VkQueue queue = VK_NULL_HANDLE; 17052 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue); 17053 17054 { 17055 VkCommandBufferBeginInfo begin_info{}; 17056 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 17057 vkBeginCommandBuffer(command_buffer, &begin_info); 17058 17059 vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); 17060 vkCmdWaitEvents(command_buffer, 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 17061 nullptr, 0, nullptr, 0, nullptr); 17062 vkEndCommandBuffer(command_buffer); 17063 } 17064 { 17065 VkSubmitInfo submit_info{}; 17066 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 17067 submit_info.commandBufferCount = 1; 17068 submit_info.pCommandBuffers = &command_buffer; 17069 submit_info.signalSemaphoreCount = 0; 17070 submit_info.pSignalSemaphores = nullptr; 17071 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE); 17072 } 17073 { 17074 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is already in use by a " 17075 "command buffer."); 17076 vkSetEvent(m_device->device(), event); 17077 m_errorMonitor->VerifyFound(); 17078 } 17079 17080 vkQueueWaitIdle(queue); 17081 17082 vkDestroyEvent(m_device->device(), event, nullptr); 17083 vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer); 17084 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 17085 } 17086 17087 // This is a positive test. No errors should be generated. 17088 TEST_F(VkPositiveLayerTest, TwoFencesThreeFrames) { 17089 TEST_DESCRIPTION("Two command buffers with two separate fences are each " 17090 "run through a Submit & WaitForFences cycle 3 times. This " 17091 "previously revealed a bug so running this positive test " 17092 "to prevent a regression."); 17093 m_errorMonitor->ExpectSuccess(); 17094 17095 ASSERT_NO_FATAL_FAILURE(InitState()); 17096 VkQueue queue = VK_NULL_HANDLE; 17097 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue); 17098 17099 static const uint32_t NUM_OBJECTS = 2; 17100 static const uint32_t NUM_FRAMES = 3; 17101 VkCommandBuffer cmd_buffers[NUM_OBJECTS] = {}; 17102 VkFence fences[NUM_OBJECTS] = {}; 17103 17104 VkCommandPool cmd_pool; 17105 VkCommandPoolCreateInfo cmd_pool_ci = {}; 17106 cmd_pool_ci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 17107 cmd_pool_ci.queueFamilyIndex = m_device->graphics_queue_node_index_; 17108 cmd_pool_ci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 17109 VkResult err = vkCreateCommandPool(m_device->device(), &cmd_pool_ci, nullptr, &cmd_pool); 17110 ASSERT_VK_SUCCESS(err); 17111 17112 VkCommandBufferAllocateInfo cmd_buf_info = {}; 17113 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 17114 cmd_buf_info.commandPool = cmd_pool; 17115 cmd_buf_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 17116 cmd_buf_info.commandBufferCount = 1; 17117 17118 VkFenceCreateInfo fence_ci = {}; 17119 fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 17120 fence_ci.pNext = nullptr; 17121 fence_ci.flags = 0; 17122 17123 for (uint32_t i = 0; i < NUM_OBJECTS; ++i) { 17124 err = vkAllocateCommandBuffers(m_device->device(), &cmd_buf_info, &cmd_buffers[i]); 17125 ASSERT_VK_SUCCESS(err); 17126 err = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fences[i]); 17127 ASSERT_VK_SUCCESS(err); 17128 } 17129 17130 for (uint32_t frame = 0; frame < NUM_FRAMES; ++frame) { 17131 for (uint32_t obj = 0; obj < NUM_OBJECTS; ++obj) { 17132 // Create empty cmd buffer 17133 VkCommandBufferBeginInfo cmdBufBeginDesc = {}; 17134 cmdBufBeginDesc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 17135 17136 err = vkBeginCommandBuffer(cmd_buffers[obj], &cmdBufBeginDesc); 17137 ASSERT_VK_SUCCESS(err); 17138 err = vkEndCommandBuffer(cmd_buffers[obj]); 17139 ASSERT_VK_SUCCESS(err); 17140 17141 VkSubmitInfo submit_info = {}; 17142 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 17143 submit_info.commandBufferCount = 1; 17144 submit_info.pCommandBuffers = &cmd_buffers[obj]; 17145 // Submit cmd buffer and wait for fence 17146 err = vkQueueSubmit(queue, 1, &submit_info, fences[obj]); 17147 ASSERT_VK_SUCCESS(err); 17148 err = vkWaitForFences(m_device->device(), 1, &fences[obj], VK_TRUE, UINT64_MAX); 17149 ASSERT_VK_SUCCESS(err); 17150 err = vkResetFences(m_device->device(), 1, &fences[obj]); 17151 ASSERT_VK_SUCCESS(err); 17152 } 17153 } 17154 m_errorMonitor->VerifyNotFound(); 17155 vkDestroyCommandPool(m_device->device(), cmd_pool, NULL); 17156 for (uint32_t i = 0; i < NUM_OBJECTS; ++i) { 17157 vkDestroyFence(m_device->device(), fences[i], nullptr); 17158 } 17159 } 17160 // This is a positive test. No errors should be generated. 17161 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWI) { 17162 17163 TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call " 17164 "submitted on separate queues followed by a QueueWaitIdle."); 17165 17166 ASSERT_NO_FATAL_FAILURE(InitState()); 17167 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) 17168 return; 17169 17170 m_errorMonitor->ExpectSuccess(); 17171 17172 VkSemaphore semaphore; 17173 VkSemaphoreCreateInfo semaphore_create_info{}; 17174 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 17175 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore); 17176 17177 VkCommandPool command_pool; 17178 VkCommandPoolCreateInfo pool_create_info{}; 17179 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 17180 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 17181 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 17182 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 17183 17184 VkCommandBuffer command_buffer[2]; 17185 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 17186 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 17187 command_buffer_allocate_info.commandPool = command_pool; 17188 command_buffer_allocate_info.commandBufferCount = 2; 17189 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 17190 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer); 17191 17192 VkQueue queue = VK_NULL_HANDLE; 17193 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue); 17194 17195 { 17196 VkCommandBufferBeginInfo begin_info{}; 17197 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 17198 vkBeginCommandBuffer(command_buffer[0], &begin_info); 17199 17200 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 17201 nullptr, 0, nullptr, 0, nullptr); 17202 17203 VkViewport viewport{}; 17204 viewport.maxDepth = 1.0f; 17205 viewport.minDepth = 0.0f; 17206 viewport.width = 512; 17207 viewport.height = 512; 17208 viewport.x = 0; 17209 viewport.y = 0; 17210 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport); 17211 vkEndCommandBuffer(command_buffer[0]); 17212 } 17213 { 17214 VkCommandBufferBeginInfo begin_info{}; 17215 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 17216 vkBeginCommandBuffer(command_buffer[1], &begin_info); 17217 17218 VkViewport viewport{}; 17219 viewport.maxDepth = 1.0f; 17220 viewport.minDepth = 0.0f; 17221 viewport.width = 512; 17222 viewport.height = 512; 17223 viewport.x = 0; 17224 viewport.y = 0; 17225 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport); 17226 vkEndCommandBuffer(command_buffer[1]); 17227 } 17228 { 17229 VkSubmitInfo submit_info{}; 17230 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 17231 submit_info.commandBufferCount = 1; 17232 submit_info.pCommandBuffers = &command_buffer[0]; 17233 submit_info.signalSemaphoreCount = 1; 17234 submit_info.pSignalSemaphores = &semaphore; 17235 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE); 17236 } 17237 { 17238 VkPipelineStageFlags flags[]{ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT }; 17239 VkSubmitInfo submit_info{}; 17240 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 17241 submit_info.commandBufferCount = 1; 17242 submit_info.pCommandBuffers = &command_buffer[1]; 17243 submit_info.waitSemaphoreCount = 1; 17244 submit_info.pWaitSemaphores = &semaphore; 17245 submit_info.pWaitDstStageMask = flags; 17246 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 17247 } 17248 17249 vkQueueWaitIdle(m_device->m_queue); 17250 17251 vkDestroySemaphore(m_device->device(), semaphore, nullptr); 17252 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]); 17253 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 17254 17255 m_errorMonitor->VerifyNotFound(); 17256 } 17257 17258 // This is a positive test. No errors should be generated. 17259 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWIFence) { 17260 17261 TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call " 17262 "submitted on separate queues, the second having a fence" 17263 "followed by a QueueWaitIdle."); 17264 17265 ASSERT_NO_FATAL_FAILURE(InitState()); 17266 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) 17267 return; 17268 17269 m_errorMonitor->ExpectSuccess(); 17270 17271 VkFence fence; 17272 VkFenceCreateInfo fence_create_info{}; 17273 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 17274 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence); 17275 17276 VkSemaphore semaphore; 17277 VkSemaphoreCreateInfo semaphore_create_info{}; 17278 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 17279 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore); 17280 17281 VkCommandPool command_pool; 17282 VkCommandPoolCreateInfo pool_create_info{}; 17283 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 17284 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 17285 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 17286 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 17287 17288 VkCommandBuffer command_buffer[2]; 17289 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 17290 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 17291 command_buffer_allocate_info.commandPool = command_pool; 17292 command_buffer_allocate_info.commandBufferCount = 2; 17293 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 17294 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer); 17295 17296 VkQueue queue = VK_NULL_HANDLE; 17297 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue); 17298 17299 { 17300 VkCommandBufferBeginInfo begin_info{}; 17301 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 17302 vkBeginCommandBuffer(command_buffer[0], &begin_info); 17303 17304 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 17305 nullptr, 0, nullptr, 0, nullptr); 17306 17307 VkViewport viewport{}; 17308 viewport.maxDepth = 1.0f; 17309 viewport.minDepth = 0.0f; 17310 viewport.width = 512; 17311 viewport.height = 512; 17312 viewport.x = 0; 17313 viewport.y = 0; 17314 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport); 17315 vkEndCommandBuffer(command_buffer[0]); 17316 } 17317 { 17318 VkCommandBufferBeginInfo begin_info{}; 17319 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 17320 vkBeginCommandBuffer(command_buffer[1], &begin_info); 17321 17322 VkViewport viewport{}; 17323 viewport.maxDepth = 1.0f; 17324 viewport.minDepth = 0.0f; 17325 viewport.width = 512; 17326 viewport.height = 512; 17327 viewport.x = 0; 17328 viewport.y = 0; 17329 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport); 17330 vkEndCommandBuffer(command_buffer[1]); 17331 } 17332 { 17333 VkSubmitInfo submit_info{}; 17334 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 17335 submit_info.commandBufferCount = 1; 17336 submit_info.pCommandBuffers = &command_buffer[0]; 17337 submit_info.signalSemaphoreCount = 1; 17338 submit_info.pSignalSemaphores = &semaphore; 17339 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE); 17340 } 17341 { 17342 VkPipelineStageFlags flags[]{ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT }; 17343 VkSubmitInfo submit_info{}; 17344 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 17345 submit_info.commandBufferCount = 1; 17346 submit_info.pCommandBuffers = &command_buffer[1]; 17347 submit_info.waitSemaphoreCount = 1; 17348 submit_info.pWaitSemaphores = &semaphore; 17349 submit_info.pWaitDstStageMask = flags; 17350 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence); 17351 } 17352 17353 vkQueueWaitIdle(m_device->m_queue); 17354 17355 vkDestroyFence(m_device->device(), fence, nullptr); 17356 vkDestroySemaphore(m_device->device(), semaphore, nullptr); 17357 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]); 17358 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 17359 17360 m_errorMonitor->VerifyNotFound(); 17361 } 17362 17363 // This is a positive test. No errors should be generated. 17364 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceTwoWFF) { 17365 17366 TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call " 17367 "submitted on separate queues, the second having a fence" 17368 "followed by two consecutive WaitForFences calls on the same fence."); 17369 17370 ASSERT_NO_FATAL_FAILURE(InitState()); 17371 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) 17372 return; 17373 17374 m_errorMonitor->ExpectSuccess(); 17375 17376 VkFence fence; 17377 VkFenceCreateInfo fence_create_info{}; 17378 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 17379 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence); 17380 17381 VkSemaphore semaphore; 17382 VkSemaphoreCreateInfo semaphore_create_info{}; 17383 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 17384 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore); 17385 17386 VkCommandPool command_pool; 17387 VkCommandPoolCreateInfo pool_create_info{}; 17388 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 17389 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 17390 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 17391 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 17392 17393 VkCommandBuffer command_buffer[2]; 17394 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 17395 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 17396 command_buffer_allocate_info.commandPool = command_pool; 17397 command_buffer_allocate_info.commandBufferCount = 2; 17398 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 17399 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer); 17400 17401 VkQueue queue = VK_NULL_HANDLE; 17402 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue); 17403 17404 { 17405 VkCommandBufferBeginInfo begin_info{}; 17406 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 17407 vkBeginCommandBuffer(command_buffer[0], &begin_info); 17408 17409 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 17410 nullptr, 0, nullptr, 0, nullptr); 17411 17412 VkViewport viewport{}; 17413 viewport.maxDepth = 1.0f; 17414 viewport.minDepth = 0.0f; 17415 viewport.width = 512; 17416 viewport.height = 512; 17417 viewport.x = 0; 17418 viewport.y = 0; 17419 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport); 17420 vkEndCommandBuffer(command_buffer[0]); 17421 } 17422 { 17423 VkCommandBufferBeginInfo begin_info{}; 17424 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 17425 vkBeginCommandBuffer(command_buffer[1], &begin_info); 17426 17427 VkViewport viewport{}; 17428 viewport.maxDepth = 1.0f; 17429 viewport.minDepth = 0.0f; 17430 viewport.width = 512; 17431 viewport.height = 512; 17432 viewport.x = 0; 17433 viewport.y = 0; 17434 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport); 17435 vkEndCommandBuffer(command_buffer[1]); 17436 } 17437 { 17438 VkSubmitInfo submit_info{}; 17439 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 17440 submit_info.commandBufferCount = 1; 17441 submit_info.pCommandBuffers = &command_buffer[0]; 17442 submit_info.signalSemaphoreCount = 1; 17443 submit_info.pSignalSemaphores = &semaphore; 17444 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE); 17445 } 17446 { 17447 VkPipelineStageFlags flags[]{ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT }; 17448 VkSubmitInfo submit_info{}; 17449 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 17450 submit_info.commandBufferCount = 1; 17451 submit_info.pCommandBuffers = &command_buffer[1]; 17452 submit_info.waitSemaphoreCount = 1; 17453 submit_info.pWaitSemaphores = &semaphore; 17454 submit_info.pWaitDstStageMask = flags; 17455 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence); 17456 } 17457 17458 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX); 17459 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX); 17460 17461 vkDestroyFence(m_device->device(), fence, nullptr); 17462 vkDestroySemaphore(m_device->device(), semaphore, nullptr); 17463 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]); 17464 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 17465 17466 m_errorMonitor->VerifyNotFound(); 17467 } 17468 17469 TEST_F(VkPositiveLayerTest, TwoQueuesEnsureCorrectRetirementWithWorkStolen) { 17470 17471 ASSERT_NO_FATAL_FAILURE(InitState()); 17472 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) { 17473 printf("Test requires two queues, skipping\n"); 17474 return; 17475 } 17476 17477 VkResult err; 17478 17479 m_errorMonitor->ExpectSuccess(); 17480 17481 VkQueue q0 = m_device->m_queue; 17482 VkQueue q1 = nullptr; 17483 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &q1); 17484 ASSERT_NE(q1, nullptr); 17485 17486 // An (empty) command buffer. We must have work in the first submission -- 17487 // the layer treats unfenced work differently from fenced work. 17488 VkCommandPoolCreateInfo cpci = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, nullptr, 0, 0 }; 17489 VkCommandPool pool; 17490 err = vkCreateCommandPool(m_device->device(), &cpci, nullptr, &pool); 17491 ASSERT_VK_SUCCESS(err); 17492 VkCommandBufferAllocateInfo cbai = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, nullptr, pool, 17493 VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1 }; 17494 VkCommandBuffer cb; 17495 err = vkAllocateCommandBuffers(m_device->device(), &cbai, &cb); 17496 ASSERT_VK_SUCCESS(err); 17497 VkCommandBufferBeginInfo cbbi = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, nullptr }; 17498 err = vkBeginCommandBuffer(cb, &cbbi); 17499 ASSERT_VK_SUCCESS(err); 17500 err = vkEndCommandBuffer(cb); 17501 ASSERT_VK_SUCCESS(err); 17502 17503 // A semaphore 17504 VkSemaphoreCreateInfo sci = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0 }; 17505 VkSemaphore s; 17506 err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s); 17507 ASSERT_VK_SUCCESS(err); 17508 17509 // First submission, to q0 17510 VkSubmitInfo s0 = { VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &cb, 1, &s }; 17511 17512 err = vkQueueSubmit(q0, 1, &s0, VK_NULL_HANDLE); 17513 ASSERT_VK_SUCCESS(err); 17514 17515 // Second submission, to q1, waiting on s 17516 VkFlags waitmask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; // doesn't really matter what this value is. 17517 VkSubmitInfo s1 = { VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &s, &waitmask, 0, nullptr, 0, nullptr }; 17518 17519 err = vkQueueSubmit(q1, 1, &s1, VK_NULL_HANDLE); 17520 ASSERT_VK_SUCCESS(err); 17521 17522 // Wait for q0 idle 17523 err = vkQueueWaitIdle(q0); 17524 ASSERT_VK_SUCCESS(err); 17525 17526 // Command buffer should have been completed (it was on q0); reset the pool. 17527 vkFreeCommandBuffers(m_device->device(), pool, 1, &cb); 17528 17529 m_errorMonitor->VerifyNotFound(); 17530 17531 // Force device completely idle and clean up resources 17532 vkDeviceWaitIdle(m_device->device()); 17533 vkDestroyCommandPool(m_device->device(), pool, nullptr); 17534 vkDestroySemaphore(m_device->device(), s, nullptr); 17535 } 17536 17537 // This is a positive test. No errors should be generated. 17538 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFence) { 17539 17540 TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call " 17541 "submitted on separate queues, the second having a fence, " 17542 "followed by a WaitForFences call."); 17543 17544 ASSERT_NO_FATAL_FAILURE(InitState()); 17545 if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) 17546 return; 17547 17548 m_errorMonitor->ExpectSuccess(); 17549 17550 ASSERT_NO_FATAL_FAILURE(InitState()); 17551 VkFence fence; 17552 VkFenceCreateInfo fence_create_info{}; 17553 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 17554 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence); 17555 17556 VkSemaphore semaphore; 17557 VkSemaphoreCreateInfo semaphore_create_info{}; 17558 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 17559 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore); 17560 17561 VkCommandPool command_pool; 17562 VkCommandPoolCreateInfo pool_create_info{}; 17563 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 17564 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 17565 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 17566 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 17567 17568 VkCommandBuffer command_buffer[2]; 17569 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 17570 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 17571 command_buffer_allocate_info.commandPool = command_pool; 17572 command_buffer_allocate_info.commandBufferCount = 2; 17573 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 17574 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer); 17575 17576 VkQueue queue = VK_NULL_HANDLE; 17577 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue); 17578 17579 { 17580 VkCommandBufferBeginInfo begin_info{}; 17581 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 17582 vkBeginCommandBuffer(command_buffer[0], &begin_info); 17583 17584 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 17585 nullptr, 0, nullptr, 0, nullptr); 17586 17587 VkViewport viewport{}; 17588 viewport.maxDepth = 1.0f; 17589 viewport.minDepth = 0.0f; 17590 viewport.width = 512; 17591 viewport.height = 512; 17592 viewport.x = 0; 17593 viewport.y = 0; 17594 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport); 17595 vkEndCommandBuffer(command_buffer[0]); 17596 } 17597 { 17598 VkCommandBufferBeginInfo begin_info{}; 17599 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 17600 vkBeginCommandBuffer(command_buffer[1], &begin_info); 17601 17602 VkViewport viewport{}; 17603 viewport.maxDepth = 1.0f; 17604 viewport.minDepth = 0.0f; 17605 viewport.width = 512; 17606 viewport.height = 512; 17607 viewport.x = 0; 17608 viewport.y = 0; 17609 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport); 17610 vkEndCommandBuffer(command_buffer[1]); 17611 } 17612 { 17613 VkSubmitInfo submit_info{}; 17614 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 17615 submit_info.commandBufferCount = 1; 17616 submit_info.pCommandBuffers = &command_buffer[0]; 17617 submit_info.signalSemaphoreCount = 1; 17618 submit_info.pSignalSemaphores = &semaphore; 17619 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE); 17620 } 17621 { 17622 VkPipelineStageFlags flags[]{ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT }; 17623 VkSubmitInfo submit_info{}; 17624 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 17625 submit_info.commandBufferCount = 1; 17626 submit_info.pCommandBuffers = &command_buffer[1]; 17627 submit_info.waitSemaphoreCount = 1; 17628 submit_info.pWaitSemaphores = &semaphore; 17629 submit_info.pWaitDstStageMask = flags; 17630 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence); 17631 } 17632 17633 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX); 17634 17635 vkDestroyFence(m_device->device(), fence, nullptr); 17636 vkDestroySemaphore(m_device->device(), semaphore, nullptr); 17637 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]); 17638 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 17639 17640 m_errorMonitor->VerifyNotFound(); 17641 } 17642 17643 // This is a positive test. No errors should be generated. 17644 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsOneQueueWithSemaphoreAndOneFence) { 17645 17646 TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call " 17647 "on the same queue, sharing a signal/wait semaphore, the " 17648 "second having a fence, " 17649 "followed by a WaitForFences call."); 17650 17651 m_errorMonitor->ExpectSuccess(); 17652 17653 ASSERT_NO_FATAL_FAILURE(InitState()); 17654 VkFence fence; 17655 VkFenceCreateInfo fence_create_info{}; 17656 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 17657 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence); 17658 17659 VkSemaphore semaphore; 17660 VkSemaphoreCreateInfo semaphore_create_info{}; 17661 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 17662 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore); 17663 17664 VkCommandPool command_pool; 17665 VkCommandPoolCreateInfo pool_create_info{}; 17666 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 17667 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 17668 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 17669 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 17670 17671 VkCommandBuffer command_buffer[2]; 17672 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 17673 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 17674 command_buffer_allocate_info.commandPool = command_pool; 17675 command_buffer_allocate_info.commandBufferCount = 2; 17676 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 17677 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer); 17678 17679 { 17680 VkCommandBufferBeginInfo begin_info{}; 17681 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 17682 vkBeginCommandBuffer(command_buffer[0], &begin_info); 17683 17684 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 17685 nullptr, 0, nullptr, 0, nullptr); 17686 17687 VkViewport viewport{}; 17688 viewport.maxDepth = 1.0f; 17689 viewport.minDepth = 0.0f; 17690 viewport.width = 512; 17691 viewport.height = 512; 17692 viewport.x = 0; 17693 viewport.y = 0; 17694 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport); 17695 vkEndCommandBuffer(command_buffer[0]); 17696 } 17697 { 17698 VkCommandBufferBeginInfo begin_info{}; 17699 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 17700 vkBeginCommandBuffer(command_buffer[1], &begin_info); 17701 17702 VkViewport viewport{}; 17703 viewport.maxDepth = 1.0f; 17704 viewport.minDepth = 0.0f; 17705 viewport.width = 512; 17706 viewport.height = 512; 17707 viewport.x = 0; 17708 viewport.y = 0; 17709 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport); 17710 vkEndCommandBuffer(command_buffer[1]); 17711 } 17712 { 17713 VkSubmitInfo submit_info{}; 17714 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 17715 submit_info.commandBufferCount = 1; 17716 submit_info.pCommandBuffers = &command_buffer[0]; 17717 submit_info.signalSemaphoreCount = 1; 17718 submit_info.pSignalSemaphores = &semaphore; 17719 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 17720 } 17721 { 17722 VkPipelineStageFlags flags[]{ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT }; 17723 VkSubmitInfo submit_info{}; 17724 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 17725 submit_info.commandBufferCount = 1; 17726 submit_info.pCommandBuffers = &command_buffer[1]; 17727 submit_info.waitSemaphoreCount = 1; 17728 submit_info.pWaitSemaphores = &semaphore; 17729 submit_info.pWaitDstStageMask = flags; 17730 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence); 17731 } 17732 17733 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX); 17734 17735 vkDestroyFence(m_device->device(), fence, nullptr); 17736 vkDestroySemaphore(m_device->device(), semaphore, nullptr); 17737 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]); 17738 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 17739 17740 m_errorMonitor->VerifyNotFound(); 17741 } 17742 17743 // This is a positive test. No errors should be generated. 17744 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsOneQueueNullQueueSubmitWithFence) { 17745 17746 TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call " 17747 "on the same queue, no fences, followed by a third QueueSubmit with NO " 17748 "SubmitInfos but with a fence, followed by a WaitForFences call."); 17749 17750 m_errorMonitor->ExpectSuccess(); 17751 17752 ASSERT_NO_FATAL_FAILURE(InitState()); 17753 VkFence fence; 17754 VkFenceCreateInfo fence_create_info{}; 17755 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 17756 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence); 17757 17758 VkCommandPool command_pool; 17759 VkCommandPoolCreateInfo pool_create_info{}; 17760 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 17761 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 17762 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 17763 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 17764 17765 VkCommandBuffer command_buffer[2]; 17766 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 17767 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 17768 command_buffer_allocate_info.commandPool = command_pool; 17769 command_buffer_allocate_info.commandBufferCount = 2; 17770 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 17771 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer); 17772 17773 { 17774 VkCommandBufferBeginInfo begin_info{}; 17775 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 17776 vkBeginCommandBuffer(command_buffer[0], &begin_info); 17777 17778 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 17779 nullptr, 0, nullptr, 0, nullptr); 17780 17781 VkViewport viewport{}; 17782 viewport.maxDepth = 1.0f; 17783 viewport.minDepth = 0.0f; 17784 viewport.width = 512; 17785 viewport.height = 512; 17786 viewport.x = 0; 17787 viewport.y = 0; 17788 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport); 17789 vkEndCommandBuffer(command_buffer[0]); 17790 } 17791 { 17792 VkCommandBufferBeginInfo begin_info{}; 17793 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 17794 vkBeginCommandBuffer(command_buffer[1], &begin_info); 17795 17796 VkViewport viewport{}; 17797 viewport.maxDepth = 1.0f; 17798 viewport.minDepth = 0.0f; 17799 viewport.width = 512; 17800 viewport.height = 512; 17801 viewport.x = 0; 17802 viewport.y = 0; 17803 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport); 17804 vkEndCommandBuffer(command_buffer[1]); 17805 } 17806 { 17807 VkSubmitInfo submit_info{}; 17808 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 17809 submit_info.commandBufferCount = 1; 17810 submit_info.pCommandBuffers = &command_buffer[0]; 17811 submit_info.signalSemaphoreCount = 0; 17812 submit_info.pSignalSemaphores = VK_NULL_HANDLE; 17813 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 17814 } 17815 { 17816 VkPipelineStageFlags flags[]{ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT }; 17817 VkSubmitInfo submit_info{}; 17818 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 17819 submit_info.commandBufferCount = 1; 17820 submit_info.pCommandBuffers = &command_buffer[1]; 17821 submit_info.waitSemaphoreCount = 0; 17822 submit_info.pWaitSemaphores = VK_NULL_HANDLE; 17823 submit_info.pWaitDstStageMask = flags; 17824 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 17825 } 17826 17827 vkQueueSubmit(m_device->m_queue, 0, NULL, fence); 17828 17829 VkResult err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX); 17830 ASSERT_VK_SUCCESS(err); 17831 17832 vkDestroyFence(m_device->device(), fence, nullptr); 17833 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]); 17834 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 17835 17836 m_errorMonitor->VerifyNotFound(); 17837 } 17838 17839 // This is a positive test. No errors should be generated. 17840 TEST_F(VkPositiveLayerTest, TwoQueueSubmitsOneQueueOneFence) { 17841 17842 TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call " 17843 "on the same queue, the second having a fence, followed " 17844 "by a WaitForFences call."); 17845 17846 m_errorMonitor->ExpectSuccess(); 17847 17848 ASSERT_NO_FATAL_FAILURE(InitState()); 17849 VkFence fence; 17850 VkFenceCreateInfo fence_create_info{}; 17851 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 17852 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence); 17853 17854 VkCommandPool command_pool; 17855 VkCommandPoolCreateInfo pool_create_info{}; 17856 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 17857 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 17858 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 17859 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 17860 17861 VkCommandBuffer command_buffer[2]; 17862 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 17863 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 17864 command_buffer_allocate_info.commandPool = command_pool; 17865 command_buffer_allocate_info.commandBufferCount = 2; 17866 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 17867 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer); 17868 17869 { 17870 VkCommandBufferBeginInfo begin_info{}; 17871 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 17872 vkBeginCommandBuffer(command_buffer[0], &begin_info); 17873 17874 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 17875 nullptr, 0, nullptr, 0, nullptr); 17876 17877 VkViewport viewport{}; 17878 viewport.maxDepth = 1.0f; 17879 viewport.minDepth = 0.0f; 17880 viewport.width = 512; 17881 viewport.height = 512; 17882 viewport.x = 0; 17883 viewport.y = 0; 17884 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport); 17885 vkEndCommandBuffer(command_buffer[0]); 17886 } 17887 { 17888 VkCommandBufferBeginInfo begin_info{}; 17889 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 17890 vkBeginCommandBuffer(command_buffer[1], &begin_info); 17891 17892 VkViewport viewport{}; 17893 viewport.maxDepth = 1.0f; 17894 viewport.minDepth = 0.0f; 17895 viewport.width = 512; 17896 viewport.height = 512; 17897 viewport.x = 0; 17898 viewport.y = 0; 17899 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport); 17900 vkEndCommandBuffer(command_buffer[1]); 17901 } 17902 { 17903 VkSubmitInfo submit_info{}; 17904 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 17905 submit_info.commandBufferCount = 1; 17906 submit_info.pCommandBuffers = &command_buffer[0]; 17907 submit_info.signalSemaphoreCount = 0; 17908 submit_info.pSignalSemaphores = VK_NULL_HANDLE; 17909 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE); 17910 } 17911 { 17912 VkPipelineStageFlags flags[]{ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT }; 17913 VkSubmitInfo submit_info{}; 17914 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 17915 submit_info.commandBufferCount = 1; 17916 submit_info.pCommandBuffers = &command_buffer[1]; 17917 submit_info.waitSemaphoreCount = 0; 17918 submit_info.pWaitSemaphores = VK_NULL_HANDLE; 17919 submit_info.pWaitDstStageMask = flags; 17920 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence); 17921 } 17922 17923 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX); 17924 17925 vkDestroyFence(m_device->device(), fence, nullptr); 17926 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]); 17927 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 17928 17929 m_errorMonitor->VerifyNotFound(); 17930 } 17931 17932 // This is a positive test. No errors should be generated. 17933 TEST_F(VkPositiveLayerTest, TwoSubmitInfosWithSemaphoreOneQueueSubmitsOneFence) { 17934 17935 TEST_DESCRIPTION("Two command buffers each in a separate SubmitInfo sent in a single " 17936 "QueueSubmit call followed by a WaitForFences call."); 17937 ASSERT_NO_FATAL_FAILURE(InitState()); 17938 17939 m_errorMonitor->ExpectSuccess(); 17940 17941 VkFence fence; 17942 VkFenceCreateInfo fence_create_info{}; 17943 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 17944 vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence); 17945 17946 VkSemaphore semaphore; 17947 VkSemaphoreCreateInfo semaphore_create_info{}; 17948 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 17949 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore); 17950 17951 VkCommandPool command_pool; 17952 VkCommandPoolCreateInfo pool_create_info{}; 17953 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 17954 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 17955 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 17956 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool); 17957 17958 VkCommandBuffer command_buffer[2]; 17959 VkCommandBufferAllocateInfo command_buffer_allocate_info{}; 17960 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 17961 command_buffer_allocate_info.commandPool = command_pool; 17962 command_buffer_allocate_info.commandBufferCount = 2; 17963 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 17964 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer); 17965 17966 { 17967 VkCommandBufferBeginInfo begin_info{}; 17968 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 17969 vkBeginCommandBuffer(command_buffer[0], &begin_info); 17970 17971 vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, 17972 nullptr, 0, nullptr, 0, nullptr); 17973 17974 VkViewport viewport{}; 17975 viewport.maxDepth = 1.0f; 17976 viewport.minDepth = 0.0f; 17977 viewport.width = 512; 17978 viewport.height = 512; 17979 viewport.x = 0; 17980 viewport.y = 0; 17981 vkCmdSetViewport(command_buffer[0], 0, 1, &viewport); 17982 vkEndCommandBuffer(command_buffer[0]); 17983 } 17984 { 17985 VkCommandBufferBeginInfo begin_info{}; 17986 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 17987 vkBeginCommandBuffer(command_buffer[1], &begin_info); 17988 17989 VkViewport viewport{}; 17990 viewport.maxDepth = 1.0f; 17991 viewport.minDepth = 0.0f; 17992 viewport.width = 512; 17993 viewport.height = 512; 17994 viewport.x = 0; 17995 viewport.y = 0; 17996 vkCmdSetViewport(command_buffer[1], 0, 1, &viewport); 17997 vkEndCommandBuffer(command_buffer[1]); 17998 } 17999 { 18000 VkSubmitInfo submit_info[2]; 18001 VkPipelineStageFlags flags[]{ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT }; 18002 18003 submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 18004 submit_info[0].pNext = NULL; 18005 submit_info[0].commandBufferCount = 1; 18006 submit_info[0].pCommandBuffers = &command_buffer[0]; 18007 submit_info[0].signalSemaphoreCount = 1; 18008 submit_info[0].pSignalSemaphores = &semaphore; 18009 submit_info[0].waitSemaphoreCount = 0; 18010 submit_info[0].pWaitSemaphores = NULL; 18011 submit_info[0].pWaitDstStageMask = 0; 18012 18013 submit_info[1].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 18014 submit_info[1].pNext = NULL; 18015 submit_info[1].commandBufferCount = 1; 18016 submit_info[1].pCommandBuffers = &command_buffer[1]; 18017 submit_info[1].waitSemaphoreCount = 1; 18018 submit_info[1].pWaitSemaphores = &semaphore; 18019 submit_info[1].pWaitDstStageMask = flags; 18020 submit_info[1].signalSemaphoreCount = 0; 18021 submit_info[1].pSignalSemaphores = NULL; 18022 vkQueueSubmit(m_device->m_queue, 2, &submit_info[0], fence); 18023 } 18024 18025 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX); 18026 18027 vkDestroyFence(m_device->device(), fence, nullptr); 18028 vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]); 18029 vkDestroyCommandPool(m_device->device(), command_pool, NULL); 18030 vkDestroySemaphore(m_device->device(), semaphore, nullptr); 18031 18032 m_errorMonitor->VerifyNotFound(); 18033 } 18034 18035 TEST_F(VkPositiveLayerTest, RenderPassSecondaryCommandBuffersMultipleTimes) { 18036 m_errorMonitor->ExpectSuccess(); 18037 18038 ASSERT_NO_FATAL_FAILURE(InitState()); 18039 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 18040 18041 BeginCommandBuffer(); // Framework implicitly begins the renderpass. 18042 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); // End implicit. 18043 18044 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); 18045 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); 18046 m_errorMonitor->VerifyNotFound(); 18047 vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 18048 m_errorMonitor->VerifyNotFound(); 18049 vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); 18050 m_errorMonitor->VerifyNotFound(); 18051 18052 m_commandBuffer->EndCommandBuffer(); 18053 m_errorMonitor->VerifyNotFound(); 18054 } 18055 18056 TEST_F(VkPositiveLayerTest, ValidRenderPassAttachmentLayoutWithLoadOp) { 18057 TEST_DESCRIPTION("Positive test where we create a renderpass with an " 18058 "attachment that uses LOAD_OP_CLEAR, the first subpass " 18059 "has a valid layout, and a second subpass then uses a " 18060 "valid *READ_ONLY* layout."); 18061 m_errorMonitor->ExpectSuccess(); 18062 ASSERT_NO_FATAL_FAILURE(InitState()); 18063 18064 VkAttachmentReference attach[2] = {}; 18065 attach[0].attachment = 0; 18066 attach[0].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 18067 attach[1].attachment = 0; 18068 attach[1].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; 18069 VkSubpassDescription subpasses[2] = {}; 18070 // First subpass clears DS attach on load 18071 subpasses[0].pDepthStencilAttachment = &attach[0]; 18072 // 2nd subpass reads in DS as input attachment 18073 subpasses[1].inputAttachmentCount = 1; 18074 subpasses[1].pInputAttachments = &attach[1]; 18075 VkAttachmentDescription attach_desc = {}; 18076 attach_desc.format = VK_FORMAT_D24_UNORM_S8_UINT; 18077 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; 18078 attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; 18079 attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; 18080 attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 18081 attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 18082 attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 18083 attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; 18084 VkRenderPassCreateInfo rpci = {}; 18085 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 18086 rpci.attachmentCount = 1; 18087 rpci.pAttachments = &attach_desc; 18088 rpci.subpassCount = 2; 18089 rpci.pSubpasses = subpasses; 18090 18091 // Now create RenderPass and verify no errors 18092 VkRenderPass rp; 18093 vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp); 18094 m_errorMonitor->VerifyNotFound(); 18095 18096 vkDestroyRenderPass(m_device->device(), rp, NULL); 18097 } 18098 18099 TEST_F(VkPositiveLayerTest, CreatePipelineAttribMatrixType) { 18100 TEST_DESCRIPTION("Test that pipeline validation accepts matrices passed " 18101 "as vertex attributes"); 18102 m_errorMonitor->ExpectSuccess(); 18103 18104 ASSERT_NO_FATAL_FAILURE(InitState()); 18105 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 18106 18107 VkVertexInputBindingDescription input_binding; 18108 memset(&input_binding, 0, sizeof(input_binding)); 18109 18110 VkVertexInputAttributeDescription input_attribs[2]; 18111 memset(input_attribs, 0, sizeof(input_attribs)); 18112 18113 for (int i = 0; i < 2; i++) { 18114 input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT; 18115 input_attribs[i].location = i; 18116 } 18117 18118 char const *vsSource = "#version 450\n" 18119 "\n" 18120 "layout(location=0) in mat2x4 x;\n" 18121 "out gl_PerVertex {\n" 18122 " vec4 gl_Position;\n" 18123 "};\n" 18124 "void main(){\n" 18125 " gl_Position = x[0] + x[1];\n" 18126 "}\n"; 18127 char const *fsSource = "#version 450\n" 18128 "\n" 18129 "layout(location=0) out vec4 color;\n" 18130 "void main(){\n" 18131 " color = vec4(1);\n" 18132 "}\n"; 18133 18134 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 18135 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 18136 18137 VkPipelineObj pipe(m_device); 18138 pipe.AddColorAttachment(); 18139 pipe.AddShader(&vs); 18140 pipe.AddShader(&fs); 18141 18142 pipe.AddVertexInputBindings(&input_binding, 1); 18143 pipe.AddVertexInputAttribs(input_attribs, 2); 18144 18145 VkDescriptorSetObj descriptorSet(m_device); 18146 descriptorSet.AppendDummy(); 18147 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 18148 18149 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 18150 18151 /* expect success */ 18152 m_errorMonitor->VerifyNotFound(); 18153 } 18154 18155 TEST_F(VkPositiveLayerTest, CreatePipelineAttribArrayType) { 18156 m_errorMonitor->ExpectSuccess(); 18157 18158 ASSERT_NO_FATAL_FAILURE(InitState()); 18159 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 18160 18161 VkVertexInputBindingDescription input_binding; 18162 memset(&input_binding, 0, sizeof(input_binding)); 18163 18164 VkVertexInputAttributeDescription input_attribs[2]; 18165 memset(input_attribs, 0, sizeof(input_attribs)); 18166 18167 for (int i = 0; i < 2; i++) { 18168 input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT; 18169 input_attribs[i].location = i; 18170 } 18171 18172 char const *vsSource = "#version 450\n" 18173 "\n" 18174 "layout(location=0) in vec4 x[2];\n" 18175 "out gl_PerVertex {\n" 18176 " vec4 gl_Position;\n" 18177 "};\n" 18178 "void main(){\n" 18179 " gl_Position = x[0] + x[1];\n" 18180 "}\n"; 18181 char const *fsSource = "#version 450\n" 18182 "\n" 18183 "layout(location=0) out vec4 color;\n" 18184 "void main(){\n" 18185 " color = vec4(1);\n" 18186 "}\n"; 18187 18188 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 18189 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 18190 18191 VkPipelineObj pipe(m_device); 18192 pipe.AddColorAttachment(); 18193 pipe.AddShader(&vs); 18194 pipe.AddShader(&fs); 18195 18196 pipe.AddVertexInputBindings(&input_binding, 1); 18197 pipe.AddVertexInputAttribs(input_attribs, 2); 18198 18199 VkDescriptorSetObj descriptorSet(m_device); 18200 descriptorSet.AppendDummy(); 18201 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 18202 18203 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 18204 18205 m_errorMonitor->VerifyNotFound(); 18206 } 18207 18208 TEST_F(VkPositiveLayerTest, CreatePipelineAttribComponents) { 18209 TEST_DESCRIPTION("Test that pipeline validation accepts consuming a vertex attribute " 18210 "through multiple vertex shader inputs, each consuming a different " 18211 "subset of the components."); 18212 m_errorMonitor->ExpectSuccess(); 18213 18214 ASSERT_NO_FATAL_FAILURE(InitState()); 18215 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 18216 18217 VkVertexInputBindingDescription input_binding; 18218 memset(&input_binding, 0, sizeof(input_binding)); 18219 18220 VkVertexInputAttributeDescription input_attribs[3]; 18221 memset(input_attribs, 0, sizeof(input_attribs)); 18222 18223 for (int i = 0; i < 3; i++) { 18224 input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT; 18225 input_attribs[i].location = i; 18226 } 18227 18228 char const *vsSource = "#version 450\n" 18229 "\n" 18230 "layout(location=0) in vec4 x;\n" 18231 "layout(location=1) in vec3 y1;\n" 18232 "layout(location=1, component=3) in float y2;\n" 18233 "layout(location=2) in vec4 z;\n" 18234 "out gl_PerVertex {\n" 18235 " vec4 gl_Position;\n" 18236 "};\n" 18237 "void main(){\n" 18238 " gl_Position = x + vec4(y1, y2) + z;\n" 18239 "}\n"; 18240 char const *fsSource = "#version 450\n" 18241 "\n" 18242 "layout(location=0) out vec4 color;\n" 18243 "void main(){\n" 18244 " color = vec4(1);\n" 18245 "}\n"; 18246 18247 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 18248 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 18249 18250 VkPipelineObj pipe(m_device); 18251 pipe.AddColorAttachment(); 18252 pipe.AddShader(&vs); 18253 pipe.AddShader(&fs); 18254 18255 pipe.AddVertexInputBindings(&input_binding, 1); 18256 pipe.AddVertexInputAttribs(input_attribs, 3); 18257 18258 VkDescriptorSetObj descriptorSet(m_device); 18259 descriptorSet.AppendDummy(); 18260 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 18261 18262 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 18263 18264 m_errorMonitor->VerifyNotFound(); 18265 } 18266 18267 TEST_F(VkPositiveLayerTest, CreatePipelineSimplePositive) { 18268 m_errorMonitor->ExpectSuccess(); 18269 18270 ASSERT_NO_FATAL_FAILURE(InitState()); 18271 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 18272 18273 char const *vsSource = "#version 450\n" 18274 "out gl_PerVertex {\n" 18275 " vec4 gl_Position;\n" 18276 "};\n" 18277 "void main(){\n" 18278 " gl_Position = vec4(0);\n" 18279 "}\n"; 18280 char const *fsSource = "#version 450\n" 18281 "\n" 18282 "layout(location=0) out vec4 color;\n" 18283 "void main(){\n" 18284 " color = vec4(1);\n" 18285 "}\n"; 18286 18287 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 18288 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 18289 18290 VkPipelineObj pipe(m_device); 18291 pipe.AddColorAttachment(); 18292 pipe.AddShader(&vs); 18293 pipe.AddShader(&fs); 18294 18295 VkDescriptorSetObj descriptorSet(m_device); 18296 descriptorSet.AppendDummy(); 18297 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 18298 18299 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 18300 18301 m_errorMonitor->VerifyNotFound(); 18302 } 18303 18304 TEST_F(VkPositiveLayerTest, CreatePipelineRelaxedTypeMatch) { 18305 TEST_DESCRIPTION("Test that pipeline validation accepts the relaxed type matching rules " 18306 "set out in 14.1.3: fundamental type must match, and producer side must " 18307 "have at least as many components"); 18308 m_errorMonitor->ExpectSuccess(); 18309 18310 // VK 1.0.8 Specification, 14.1.3 "Additionally,..." block 18311 18312 ASSERT_NO_FATAL_FAILURE(InitState()); 18313 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 18314 18315 char const *vsSource = "#version 450\n" 18316 "out gl_PerVertex {\n" 18317 " vec4 gl_Position;\n" 18318 "};\n" 18319 "layout(location=0) out vec3 x;\n" 18320 "layout(location=1) out ivec3 y;\n" 18321 "layout(location=2) out vec3 z;\n" 18322 "void main(){\n" 18323 " gl_Position = vec4(0);\n" 18324 " x = vec3(0); y = ivec3(0); z = vec3(0);\n" 18325 "}\n"; 18326 char const *fsSource = "#version 450\n" 18327 "\n" 18328 "layout(location=0) out vec4 color;\n" 18329 "layout(location=0) in float x;\n" 18330 "layout(location=1) flat in int y;\n" 18331 "layout(location=2) in vec2 z;\n" 18332 "void main(){\n" 18333 " color = vec4(1 + x + y + z.x);\n" 18334 "}\n"; 18335 18336 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 18337 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 18338 18339 VkPipelineObj pipe(m_device); 18340 pipe.AddColorAttachment(); 18341 pipe.AddShader(&vs); 18342 pipe.AddShader(&fs); 18343 18344 VkDescriptorSetObj descriptorSet(m_device); 18345 descriptorSet.AppendDummy(); 18346 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 18347 18348 VkResult err = VK_SUCCESS; 18349 err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 18350 ASSERT_VK_SUCCESS(err); 18351 18352 m_errorMonitor->VerifyNotFound(); 18353 } 18354 18355 TEST_F(VkPositiveLayerTest, CreatePipelineTessPerVertex) { 18356 TEST_DESCRIPTION("Test that pipeline validation accepts per-vertex variables " 18357 "passed between the TCS and TES stages"); 18358 m_errorMonitor->ExpectSuccess(); 18359 18360 ASSERT_NO_FATAL_FAILURE(InitState()); 18361 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 18362 18363 if (!m_device->phy().features().tessellationShader) { 18364 printf("Device does not support tessellation shaders; skipped.\n"); 18365 return; 18366 } 18367 18368 char const *vsSource = "#version 450\n" 18369 "void main(){}\n"; 18370 char const *tcsSource = "#version 450\n" 18371 "layout(location=0) out int x[];\n" 18372 "layout(vertices=3) out;\n" 18373 "void main(){\n" 18374 " gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n" 18375 " gl_TessLevelInner[0] = 1;\n" 18376 " x[gl_InvocationID] = gl_InvocationID;\n" 18377 "}\n"; 18378 char const *tesSource = "#version 450\n" 18379 "layout(triangles, equal_spacing, cw) in;\n" 18380 "layout(location=0) in int x[];\n" 18381 "out gl_PerVertex { vec4 gl_Position; };\n" 18382 "void main(){\n" 18383 " gl_Position.xyz = gl_TessCoord;\n" 18384 " gl_Position.w = x[0] + x[1] + x[2];\n" 18385 "}\n"; 18386 char const *fsSource = "#version 450\n" 18387 "layout(location=0) out vec4 color;\n" 18388 "void main(){\n" 18389 " color = vec4(1);\n" 18390 "}\n"; 18391 18392 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 18393 VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this); 18394 VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this); 18395 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 18396 18397 VkPipelineInputAssemblyStateCreateInfo iasci{ VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0, 18398 VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE }; 18399 18400 VkPipelineTessellationStateCreateInfo tsci{ VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3 }; 18401 18402 VkPipelineObj pipe(m_device); 18403 pipe.SetInputAssembly(&iasci); 18404 pipe.SetTessellation(&tsci); 18405 pipe.AddColorAttachment(); 18406 pipe.AddShader(&vs); 18407 pipe.AddShader(&tcs); 18408 pipe.AddShader(&tes); 18409 pipe.AddShader(&fs); 18410 18411 VkDescriptorSetObj descriptorSet(m_device); 18412 descriptorSet.AppendDummy(); 18413 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 18414 18415 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 18416 18417 m_errorMonitor->VerifyNotFound(); 18418 } 18419 18420 TEST_F(VkPositiveLayerTest, CreatePipelineGeometryInputBlockPositive) { 18421 TEST_DESCRIPTION("Test that pipeline validation accepts a user-defined " 18422 "interface block passed into the geometry shader. This " 18423 "is interesting because the 'extra' array level is not " 18424 "present on the member type, but on the block instance."); 18425 m_errorMonitor->ExpectSuccess(); 18426 18427 ASSERT_NO_FATAL_FAILURE(InitState()); 18428 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 18429 18430 if (!m_device->phy().features().geometryShader) { 18431 printf("Device does not support geometry shaders; skipped.\n"); 18432 return; 18433 } 18434 18435 char const *vsSource = "#version 450\n" 18436 "layout(location=0) out VertexData { vec4 x; } vs_out;\n" 18437 "void main(){\n" 18438 " vs_out.x = vec4(1);\n" 18439 "}\n"; 18440 char const *gsSource = "#version 450\n" 18441 "layout(triangles) in;\n" 18442 "layout(triangle_strip, max_vertices=3) out;\n" 18443 "layout(location=0) in VertexData { vec4 x; } gs_in[];\n" 18444 "out gl_PerVertex { vec4 gl_Position; };\n" 18445 "void main() {\n" 18446 " gl_Position = gs_in[0].x;\n" 18447 " EmitVertex();\n" 18448 "}\n"; 18449 char const *fsSource = "#version 450\n" 18450 "layout(location=0) out vec4 color;\n" 18451 "void main(){\n" 18452 " color = vec4(1);\n" 18453 "}\n"; 18454 18455 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 18456 VkShaderObj gs(m_device, gsSource, VK_SHADER_STAGE_GEOMETRY_BIT, this); 18457 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 18458 18459 VkPipelineObj pipe(m_device); 18460 pipe.AddColorAttachment(); 18461 pipe.AddShader(&vs); 18462 pipe.AddShader(&gs); 18463 pipe.AddShader(&fs); 18464 18465 VkDescriptorSetObj descriptorSet(m_device); 18466 descriptorSet.AppendDummy(); 18467 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 18468 18469 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 18470 18471 m_errorMonitor->VerifyNotFound(); 18472 } 18473 18474 TEST_F(VkPositiveLayerTest, CreatePipeline64BitAttributesPositive) { 18475 TEST_DESCRIPTION("Test that pipeline validation accepts basic use of 64bit vertex " 18476 "attributes. This is interesting because they consume multiple " 18477 "locations."); 18478 m_errorMonitor->ExpectSuccess(); 18479 18480 ASSERT_NO_FATAL_FAILURE(InitState()); 18481 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 18482 18483 if (!m_device->phy().features().shaderFloat64) { 18484 printf("Device does not support 64bit vertex attributes; skipped.\n"); 18485 return; 18486 } 18487 18488 VkVertexInputBindingDescription input_bindings[1]; 18489 memset(input_bindings, 0, sizeof(input_bindings)); 18490 18491 VkVertexInputAttributeDescription input_attribs[4]; 18492 memset(input_attribs, 0, sizeof(input_attribs)); 18493 input_attribs[0].location = 0; 18494 input_attribs[0].offset = 0; 18495 input_attribs[0].format = VK_FORMAT_R64G64B64A64_SFLOAT; 18496 input_attribs[1].location = 2; 18497 input_attribs[1].offset = 32; 18498 input_attribs[1].format = VK_FORMAT_R64G64B64A64_SFLOAT; 18499 input_attribs[2].location = 4; 18500 input_attribs[2].offset = 64; 18501 input_attribs[2].format = VK_FORMAT_R64G64B64A64_SFLOAT; 18502 input_attribs[3].location = 6; 18503 input_attribs[3].offset = 96; 18504 input_attribs[3].format = VK_FORMAT_R64G64B64A64_SFLOAT; 18505 18506 char const *vsSource = "#version 450\n" 18507 "\n" 18508 "layout(location=0) in dmat4 x;\n" 18509 "out gl_PerVertex {\n" 18510 " vec4 gl_Position;\n" 18511 "};\n" 18512 "void main(){\n" 18513 " gl_Position = vec4(x[0][0]);\n" 18514 "}\n"; 18515 char const *fsSource = "#version 450\n" 18516 "\n" 18517 "layout(location=0) out vec4 color;\n" 18518 "void main(){\n" 18519 " color = vec4(1);\n" 18520 "}\n"; 18521 18522 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 18523 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 18524 18525 VkPipelineObj pipe(m_device); 18526 pipe.AddColorAttachment(); 18527 pipe.AddShader(&vs); 18528 pipe.AddShader(&fs); 18529 18530 pipe.AddVertexInputBindings(input_bindings, 1); 18531 pipe.AddVertexInputAttribs(input_attribs, 4); 18532 18533 VkDescriptorSetObj descriptorSet(m_device); 18534 descriptorSet.AppendDummy(); 18535 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 18536 18537 pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass()); 18538 18539 m_errorMonitor->VerifyNotFound(); 18540 } 18541 18542 TEST_F(VkPositiveLayerTest, CreatePipelineInputAttachmentPositive) { 18543 TEST_DESCRIPTION("Positive test for a correctly matched input attachment"); 18544 m_errorMonitor->ExpectSuccess(); 18545 18546 ASSERT_NO_FATAL_FAILURE(InitState()); 18547 18548 char const *vsSource = "#version 450\n" 18549 "\n" 18550 "out gl_PerVertex {\n" 18551 " vec4 gl_Position;\n" 18552 "};\n" 18553 "void main(){\n" 18554 " gl_Position = vec4(1);\n" 18555 "}\n"; 18556 char const *fsSource = "#version 450\n" 18557 "\n" 18558 "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n" 18559 "layout(location=0) out vec4 color;\n" 18560 "void main() {\n" 18561 " color = subpassLoad(x);\n" 18562 "}\n"; 18563 18564 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this); 18565 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this); 18566 18567 VkPipelineObj pipe(m_device); 18568 pipe.AddShader(&vs); 18569 pipe.AddShader(&fs); 18570 pipe.AddColorAttachment(); 18571 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 18572 18573 VkDescriptorSetLayoutBinding dslb = { 0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr }; 18574 VkDescriptorSetLayoutCreateInfo dslci = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb }; 18575 VkDescriptorSetLayout dsl; 18576 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl); 18577 ASSERT_VK_SUCCESS(err); 18578 18579 VkPipelineLayoutCreateInfo plci = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr }; 18580 VkPipelineLayout pl; 18581 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl); 18582 ASSERT_VK_SUCCESS(err); 18583 18584 VkAttachmentDescription descs[2] = { 18585 { 0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, 18586 VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 18587 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }, 18588 { 0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, 18589 VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL }, 18590 }; 18591 VkAttachmentReference color = { 18592 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 18593 }; 18594 VkAttachmentReference input = { 18595 1, VK_IMAGE_LAYOUT_GENERAL, 18596 }; 18597 18598 VkSubpassDescription sd = { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr }; 18599 18600 VkRenderPassCreateInfo rpci = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr }; 18601 VkRenderPass rp; 18602 err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp); 18603 ASSERT_VK_SUCCESS(err); 18604 18605 // should be OK. would go wrong here if it's going to... 18606 pipe.CreateVKPipeline(pl, rp); 18607 18608 m_errorMonitor->VerifyNotFound(); 18609 18610 vkDestroyRenderPass(m_device->device(), rp, nullptr); 18611 vkDestroyPipelineLayout(m_device->device(), pl, nullptr); 18612 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr); 18613 } 18614 18615 TEST_F(VkPositiveLayerTest, CreateComputePipelineMissingDescriptorUnusedPositive) { 18616 TEST_DESCRIPTION("Test that pipeline validation accepts a compute pipeline which declares a " 18617 "descriptor-backed resource which is not provided, but the shader does not " 18618 "statically use it. This is interesting because it requires compute pipelines " 18619 "to have a proper descriptor use walk, which they didn't for some time."); 18620 m_errorMonitor->ExpectSuccess(); 18621 18622 ASSERT_NO_FATAL_FAILURE(InitState()); 18623 18624 char const *csSource = "#version 450\n" 18625 "\n" 18626 "layout(local_size_x=1) in;\n" 18627 "layout(set=0, binding=0) buffer block { vec4 x; };\n" 18628 "void main(){\n" 18629 " // x is not used.\n" 18630 "}\n"; 18631 18632 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this); 18633 18634 VkDescriptorSetObj descriptorSet(m_device); 18635 descriptorSet.CreateVKDescriptorSet(m_commandBuffer); 18636 18637 VkComputePipelineCreateInfo cpci = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, 18638 nullptr, 18639 0, 18640 { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, 18641 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr }, 18642 descriptorSet.GetPipelineLayout(), 18643 VK_NULL_HANDLE, 18644 -1 }; 18645 18646 VkPipeline pipe; 18647 VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe); 18648 18649 m_errorMonitor->VerifyNotFound(); 18650 18651 if (err == VK_SUCCESS) { 18652 vkDestroyPipeline(m_device->device(), pipe, nullptr); 18653 } 18654 } 18655 18656 TEST_F(VkPositiveLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsSampler) { 18657 TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming only the " 18658 "sampler portion of a combined image + sampler"); 18659 m_errorMonitor->ExpectSuccess(); 18660 18661 ASSERT_NO_FATAL_FAILURE(InitState()); 18662 18663 VkDescriptorSetLayoutBinding bindings[] = { 18664 { 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr }, 18665 { 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr }, 18666 { 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr }, 18667 }; 18668 VkDescriptorSetLayoutCreateInfo dslci = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 3, bindings }; 18669 VkDescriptorSetLayout dsl; 18670 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl); 18671 ASSERT_VK_SUCCESS(err); 18672 18673 VkPipelineLayoutCreateInfo plci = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr }; 18674 VkPipelineLayout pl; 18675 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl); 18676 ASSERT_VK_SUCCESS(err); 18677 18678 char const *csSource = "#version 450\n" 18679 "\n" 18680 "layout(local_size_x=1) in;\n" 18681 "layout(set=0, binding=0) uniform sampler s;\n" 18682 "layout(set=0, binding=1) uniform texture2D t;\n" 18683 "layout(set=0, binding=2) buffer block { vec4 x; };\n" 18684 "void main() {\n" 18685 " x = texture(sampler2D(t, s), vec2(0));\n" 18686 "}\n"; 18687 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this); 18688 18689 VkComputePipelineCreateInfo cpci = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, 18690 nullptr, 18691 0, 18692 { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, 18693 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr }, 18694 pl, 18695 VK_NULL_HANDLE, 18696 -1 }; 18697 18698 VkPipeline pipe; 18699 err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe); 18700 18701 m_errorMonitor->VerifyNotFound(); 18702 18703 if (err == VK_SUCCESS) { 18704 vkDestroyPipeline(m_device->device(), pipe, nullptr); 18705 } 18706 18707 vkDestroyPipelineLayout(m_device->device(), pl, nullptr); 18708 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr); 18709 } 18710 18711 TEST_F(VkPositiveLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsImage) { 18712 TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming only the " 18713 "image portion of a combined image + sampler"); 18714 m_errorMonitor->ExpectSuccess(); 18715 18716 ASSERT_NO_FATAL_FAILURE(InitState()); 18717 18718 VkDescriptorSetLayoutBinding bindings[] = { 18719 { 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr }, 18720 { 1, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr }, 18721 { 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr }, 18722 }; 18723 VkDescriptorSetLayoutCreateInfo dslci = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 3, bindings }; 18724 VkDescriptorSetLayout dsl; 18725 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl); 18726 ASSERT_VK_SUCCESS(err); 18727 18728 VkPipelineLayoutCreateInfo plci = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr }; 18729 VkPipelineLayout pl; 18730 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl); 18731 ASSERT_VK_SUCCESS(err); 18732 18733 char const *csSource = "#version 450\n" 18734 "\n" 18735 "layout(local_size_x=1) in;\n" 18736 "layout(set=0, binding=0) uniform texture2D t;\n" 18737 "layout(set=0, binding=1) uniform sampler s;\n" 18738 "layout(set=0, binding=2) buffer block { vec4 x; };\n" 18739 "void main() {\n" 18740 " x = texture(sampler2D(t, s), vec2(0));\n" 18741 "}\n"; 18742 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this); 18743 18744 VkComputePipelineCreateInfo cpci = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, 18745 nullptr, 18746 0, 18747 { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, 18748 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr }, 18749 pl, 18750 VK_NULL_HANDLE, 18751 -1 }; 18752 18753 VkPipeline pipe; 18754 err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe); 18755 18756 m_errorMonitor->VerifyNotFound(); 18757 18758 if (err == VK_SUCCESS) { 18759 vkDestroyPipeline(m_device->device(), pipe, nullptr); 18760 } 18761 18762 vkDestroyPipelineLayout(m_device->device(), pl, nullptr); 18763 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr); 18764 } 18765 18766 TEST_F(VkPositiveLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsBoth) { 18767 TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming " 18768 "both the sampler and the image of a combined image+sampler " 18769 "but via separate variables"); 18770 m_errorMonitor->ExpectSuccess(); 18771 18772 ASSERT_NO_FATAL_FAILURE(InitState()); 18773 18774 VkDescriptorSetLayoutBinding bindings[] = { 18775 { 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr }, 18776 { 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr }, 18777 }; 18778 VkDescriptorSetLayoutCreateInfo dslci = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 2, bindings }; 18779 VkDescriptorSetLayout dsl; 18780 VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl); 18781 ASSERT_VK_SUCCESS(err); 18782 18783 VkPipelineLayoutCreateInfo plci = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr }; 18784 VkPipelineLayout pl; 18785 err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl); 18786 ASSERT_VK_SUCCESS(err); 18787 18788 char const *csSource = "#version 450\n" 18789 "\n" 18790 "layout(local_size_x=1) in;\n" 18791 "layout(set=0, binding=0) uniform texture2D t;\n" 18792 "layout(set=0, binding=0) uniform sampler s; // both binding 0!\n" 18793 "layout(set=0, binding=1) buffer block { vec4 x; };\n" 18794 "void main() {\n" 18795 " x = texture(sampler2D(t, s), vec2(0));\n" 18796 "}\n"; 18797 VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this); 18798 18799 VkComputePipelineCreateInfo cpci = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, 18800 nullptr, 18801 0, 18802 { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, 18803 VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr }, 18804 pl, 18805 VK_NULL_HANDLE, 18806 -1 }; 18807 18808 VkPipeline pipe; 18809 err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe); 18810 18811 m_errorMonitor->VerifyNotFound(); 18812 18813 if (err == VK_SUCCESS) { 18814 vkDestroyPipeline(m_device->device(), pipe, nullptr); 18815 } 18816 18817 vkDestroyPipelineLayout(m_device->device(), pl, nullptr); 18818 vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr); 18819 } 18820 18821 TEST_F(VkPositiveLayerTest, ValidStructPNext) { 18822 TEST_DESCRIPTION("Verify that a valid pNext value is handled correctly"); 18823 18824 ASSERT_NO_FATAL_FAILURE(InitState()); 18825 18826 // Positive test to check parameter_validation and unique_objects support 18827 // for NV_dedicated_allocation 18828 uint32_t extension_count = 0; 18829 bool supports_nv_dedicated_allocation = false; 18830 VkResult err = vkEnumerateDeviceExtensionProperties(gpu(), nullptr, &extension_count, nullptr); 18831 ASSERT_VK_SUCCESS(err); 18832 18833 if (extension_count > 0) { 18834 std::vector<VkExtensionProperties> available_extensions(extension_count); 18835 18836 err = vkEnumerateDeviceExtensionProperties(gpu(), nullptr, &extension_count, &available_extensions[0]); 18837 ASSERT_VK_SUCCESS(err); 18838 18839 for (const auto &extension_props : available_extensions) { 18840 if (strcmp(extension_props.extensionName, VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME) == 0) { 18841 supports_nv_dedicated_allocation = true; 18842 } 18843 } 18844 } 18845 18846 if (supports_nv_dedicated_allocation) { 18847 m_errorMonitor->ExpectSuccess(); 18848 18849 VkDedicatedAllocationBufferCreateInfoNV dedicated_buffer_create_info = {}; 18850 dedicated_buffer_create_info.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV; 18851 dedicated_buffer_create_info.pNext = nullptr; 18852 dedicated_buffer_create_info.dedicatedAllocation = VK_TRUE; 18853 18854 uint32_t queue_family_index = 0; 18855 VkBufferCreateInfo buffer_create_info = {}; 18856 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 18857 buffer_create_info.pNext = &dedicated_buffer_create_info; 18858 buffer_create_info.size = 1024; 18859 buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 18860 buffer_create_info.queueFamilyIndexCount = 1; 18861 buffer_create_info.pQueueFamilyIndices = &queue_family_index; 18862 18863 VkBuffer buffer; 18864 VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer); 18865 ASSERT_VK_SUCCESS(err); 18866 18867 VkMemoryRequirements memory_reqs; 18868 vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs); 18869 18870 VkDedicatedAllocationMemoryAllocateInfoNV dedicated_memory_info = {}; 18871 dedicated_memory_info.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV; 18872 dedicated_memory_info.pNext = nullptr; 18873 dedicated_memory_info.buffer = buffer; 18874 dedicated_memory_info.image = VK_NULL_HANDLE; 18875 18876 VkMemoryAllocateInfo memory_info = {}; 18877 memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 18878 memory_info.pNext = &dedicated_memory_info; 18879 memory_info.allocationSize = memory_reqs.size; 18880 18881 bool pass; 18882 pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0); 18883 ASSERT_TRUE(pass); 18884 18885 VkDeviceMemory buffer_memory; 18886 err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory); 18887 ASSERT_VK_SUCCESS(err); 18888 18889 err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0); 18890 ASSERT_VK_SUCCESS(err); 18891 18892 vkDestroyBuffer(m_device->device(), buffer, NULL); 18893 vkFreeMemory(m_device->device(), buffer_memory, NULL); 18894 18895 m_errorMonitor->VerifyNotFound(); 18896 } 18897 } 18898 18899 TEST_F(VkPositiveLayerTest, PSOPolygonModeValid) { 18900 VkResult err; 18901 18902 TEST_DESCRIPTION("Verify that using a solid polygon fill mode works correctly."); 18903 18904 ASSERT_NO_FATAL_FAILURE(InitState()); 18905 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 18906 18907 std::vector<const char *> device_extension_names; 18908 auto features = m_device->phy().features(); 18909 // Artificially disable support for non-solid fill modes 18910 features.fillModeNonSolid = false; 18911 // The sacrificial device object 18912 VkDeviceObj test_device(0, gpu(), device_extension_names, &features); 18913 18914 VkRenderpassObj render_pass(&test_device); 18915 18916 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 18917 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 18918 pipeline_layout_ci.setLayoutCount = 0; 18919 pipeline_layout_ci.pSetLayouts = NULL; 18920 18921 VkPipelineLayout pipeline_layout; 18922 err = vkCreatePipelineLayout(test_device.device(), &pipeline_layout_ci, NULL, &pipeline_layout); 18923 ASSERT_VK_SUCCESS(err); 18924 18925 VkPipelineRasterizationStateCreateInfo rs_ci = {}; 18926 rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 18927 rs_ci.pNext = nullptr; 18928 rs_ci.lineWidth = 1.0f; 18929 rs_ci.rasterizerDiscardEnable = true; 18930 18931 VkShaderObj vs(&test_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this); 18932 VkShaderObj fs(&test_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this); 18933 18934 // Set polygonMode=FILL. No error is expected 18935 m_errorMonitor->ExpectSuccess(); 18936 { 18937 VkPipelineObj pipe(&test_device); 18938 pipe.AddShader(&vs); 18939 pipe.AddShader(&fs); 18940 pipe.AddColorAttachment(); 18941 // Set polygonMode to a good value 18942 rs_ci.polygonMode = VK_POLYGON_MODE_FILL; 18943 pipe.SetRasterization(&rs_ci); 18944 pipe.CreateVKPipeline(pipeline_layout, render_pass.handle()); 18945 } 18946 m_errorMonitor->VerifyNotFound(); 18947 18948 vkDestroyPipelineLayout(test_device.device(), pipeline_layout, NULL); 18949 } 18950 18951 TEST_F(VkPositiveLayerTest, ValidPushConstants) { 18952 VkResult err; 18953 ASSERT_NO_FATAL_FAILURE(InitState()); 18954 ASSERT_NO_FATAL_FAILURE(InitViewport()); 18955 ASSERT_NO_FATAL_FAILURE(InitRenderTarget()); 18956 18957 VkPipelineLayout pipeline_layout; 18958 VkPushConstantRange pc_range = {}; 18959 VkPipelineLayoutCreateInfo pipeline_layout_ci = {}; 18960 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 18961 pipeline_layout_ci.pushConstantRangeCount = 1; 18962 pipeline_layout_ci.pPushConstantRanges = &pc_range; 18963 18964 // 18965 // Check for invalid push constant ranges in pipeline layouts. 18966 // 18967 struct PipelineLayoutTestCase { 18968 VkPushConstantRange const range; 18969 char const *msg; 18970 }; 18971 18972 // Check for overlapping ranges 18973 const uint32_t ranges_per_test = 5; 18974 struct OverlappingRangeTestCase { 18975 VkPushConstantRange const ranges[ranges_per_test]; 18976 char const *msg; 18977 }; 18978 18979 // Run some positive tests to make sure overlap checking in the layer is OK 18980 const std::array<OverlappingRangeTestCase, 2> overlapping_range_tests_pos = { { { { { VK_SHADER_STAGE_VERTEX_BIT, 0, 4 }, 18981 { VK_SHADER_STAGE_VERTEX_BIT, 4, 4 }, 18982 { VK_SHADER_STAGE_VERTEX_BIT, 8, 4 }, 18983 { VK_SHADER_STAGE_VERTEX_BIT, 12, 4 }, 18984 { VK_SHADER_STAGE_VERTEX_BIT, 16, 4 } }, 18985 "" }, 18986 { { { VK_SHADER_STAGE_VERTEX_BIT, 92, 24 }, 18987 { VK_SHADER_STAGE_VERTEX_BIT, 80, 4 }, 18988 { VK_SHADER_STAGE_VERTEX_BIT, 64, 8 }, 18989 { VK_SHADER_STAGE_VERTEX_BIT, 4, 16 }, 18990 { VK_SHADER_STAGE_VERTEX_BIT, 0, 4 } }, 18991 "" } } }; 18992 for (const auto &iter : overlapping_range_tests_pos) { 18993 pipeline_layout_ci.pPushConstantRanges = iter.ranges; 18994 m_errorMonitor->ExpectSuccess(); 18995 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 18996 m_errorMonitor->VerifyNotFound(); 18997 if (VK_SUCCESS == err) { 18998 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 18999 } 19000 } 19001 19002 // 19003 // CmdPushConstants tests 19004 // 19005 const uint8_t dummy_values[100] = {}; 19006 19007 BeginCommandBuffer(); 19008 19009 // positive overlapping range tests with cmd 19010 const std::array<PipelineLayoutTestCase, 4> cmd_overlap_tests_pos = { { 19011 { { VK_SHADER_STAGE_VERTEX_BIT, 0, 16 }, "" }, 19012 { { VK_SHADER_STAGE_VERTEX_BIT, 0, 4 }, "" }, 19013 { { VK_SHADER_STAGE_VERTEX_BIT, 20, 12 }, "" }, 19014 { { VK_SHADER_STAGE_VERTEX_BIT, 56, 36 }, "" }, 19015 } }; 19016 19017 // Setup ranges: [0,16) [20,36) [36,44) [44,52) [56,80) [80,92) 19018 const VkPushConstantRange pc_range4[] = { 19019 { VK_SHADER_STAGE_VERTEX_BIT, 20, 16 },{ VK_SHADER_STAGE_VERTEX_BIT, 0, 16 },{ VK_SHADER_STAGE_VERTEX_BIT, 44, 8 }, 19020 { VK_SHADER_STAGE_VERTEX_BIT, 80, 12 },{ VK_SHADER_STAGE_VERTEX_BIT, 36, 8 },{ VK_SHADER_STAGE_VERTEX_BIT, 56, 24 }, 19021 }; 19022 19023 pipeline_layout_ci.pushConstantRangeCount = sizeof(pc_range4) / sizeof(VkPushConstantRange); 19024 pipeline_layout_ci.pPushConstantRanges = pc_range4; 19025 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout); 19026 ASSERT_VK_SUCCESS(err); 19027 for (const auto &iter : cmd_overlap_tests_pos) { 19028 m_errorMonitor->ExpectSuccess(); 19029 vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset, 19030 iter.range.size, dummy_values); 19031 m_errorMonitor->VerifyNotFound(); 19032 } 19033 vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL); 19034 19035 EndCommandBuffer(); 19036 } 19037 19038 19039 19040 19041 19042 19043 19044 #if 0 // A few devices have issues with this test so disabling for now 19045 TEST_F(VkPositiveLayerTest, LongFenceChain) 19046 { 19047 m_errorMonitor->ExpectSuccess(); 19048 19049 ASSERT_NO_FATAL_FAILURE(InitState()); 19050 VkResult err; 19051 19052 std::vector<VkFence> fences; 19053 19054 const int chainLength = 32768; 19055 19056 for (int i = 0; i < chainLength; i++) { 19057 VkFenceCreateInfo fci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 }; 19058 VkFence fence; 19059 err = vkCreateFence(m_device->device(), &fci, nullptr, &fence); 19060 ASSERT_VK_SUCCESS(err); 19061 19062 fences.push_back(fence); 19063 19064 VkSubmitInfo si = { VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 19065 0, nullptr, 0, nullptr }; 19066 err = vkQueueSubmit(m_device->m_queue, 1, &si, fence); 19067 ASSERT_VK_SUCCESS(err); 19068 19069 } 19070 19071 // BOOM, stack overflow. 19072 vkWaitForFences(m_device->device(), 1, &fences.back(), VK_TRUE, UINT64_MAX); 19073 19074 for (auto fence : fences) 19075 vkDestroyFence(m_device->device(), fence, nullptr); 19076 19077 m_errorMonitor->VerifyNotFound(); 19078 } 19079 #endif 19080 19081 19082 #if defined(ANDROID) && defined(VALIDATION_APK) 19083 static bool initialized = false; 19084 static bool active = false; 19085 19086 // Convert Intents to argv 19087 // Ported from Hologram sample, only difference is flexible key 19088 std::vector<std::string> get_args(android_app &app, const char *intent_extra_data_key) { 19089 std::vector<std::string> args; 19090 JavaVM &vm = *app.activity->vm; 19091 JNIEnv *p_env; 19092 if (vm.AttachCurrentThread(&p_env, nullptr) != JNI_OK) 19093 return args; 19094 19095 JNIEnv &env = *p_env; 19096 jobject activity = app.activity->clazz; 19097 jmethodID get_intent_method = env.GetMethodID(env.GetObjectClass(activity), "getIntent", "()Landroid/content/Intent;"); 19098 jobject intent = env.CallObjectMethod(activity, get_intent_method); 19099 jmethodID get_string_extra_method = 19100 env.GetMethodID(env.GetObjectClass(intent), "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;"); 19101 jvalue get_string_extra_args; 19102 get_string_extra_args.l = env.NewStringUTF(intent_extra_data_key); 19103 jstring extra_str = static_cast<jstring>(env.CallObjectMethodA(intent, get_string_extra_method, &get_string_extra_args)); 19104 19105 std::string args_str; 19106 if (extra_str) { 19107 const char *extra_utf = env.GetStringUTFChars(extra_str, nullptr); 19108 args_str = extra_utf; 19109 env.ReleaseStringUTFChars(extra_str, extra_utf); 19110 env.DeleteLocalRef(extra_str); 19111 } 19112 19113 env.DeleteLocalRef(get_string_extra_args.l); 19114 env.DeleteLocalRef(intent); 19115 vm.DetachCurrentThread(); 19116 19117 // split args_str 19118 std::stringstream ss(args_str); 19119 std::string arg; 19120 while (std::getline(ss, arg, ' ')) { 19121 if (!arg.empty()) 19122 args.push_back(arg); 19123 } 19124 19125 return args; 19126 } 19127 19128 static int32_t processInput(struct android_app *app, AInputEvent *event) { return 0; } 19129 19130 static void processCommand(struct android_app *app, int32_t cmd) { 19131 switch (cmd) { 19132 case APP_CMD_INIT_WINDOW: { 19133 if (app->window) { 19134 initialized = true; 19135 } 19136 break; 19137 } 19138 case APP_CMD_GAINED_FOCUS: { 19139 active = true; 19140 break; 19141 } 19142 case APP_CMD_LOST_FOCUS: { 19143 active = false; 19144 break; 19145 } 19146 } 19147 } 19148 19149 void android_main(struct android_app *app) { 19150 app_dummy(); 19151 19152 const char *appTag = "VulkanLayerValidationTests"; 19153 19154 int vulkanSupport = InitVulkan(); 19155 if (vulkanSupport == 0) { 19156 __android_log_print(ANDROID_LOG_INFO, appTag, "==== FAILED ==== No Vulkan support found"); 19157 return; 19158 } 19159 19160 app->onAppCmd = processCommand; 19161 app->onInputEvent = processInput; 19162 19163 while (1) { 19164 int events; 19165 struct android_poll_source *source; 19166 while (ALooper_pollAll(active ? 0 : -1, NULL, &events, (void **)&source) >= 0) { 19167 if (source) { 19168 source->process(app, source); 19169 } 19170 19171 if (app->destroyRequested != 0) { 19172 VkTestFramework::Finish(); 19173 return; 19174 } 19175 } 19176 19177 if (initialized && active) { 19178 // Use the following key to send arguments to gtest, i.e. 19179 // --es args "--gtest_filter=-VkLayerTest.foo" 19180 const char key[] = "args"; 19181 std::vector<std::string> args = get_args(*app, key); 19182 19183 std::string filter = ""; 19184 if (args.size() > 0) { 19185 __android_log_print(ANDROID_LOG_INFO, appTag, "Intent args = %s", args[0].c_str()); 19186 filter += args[0]; 19187 } else { 19188 __android_log_print(ANDROID_LOG_INFO, appTag, "No Intent args detected"); 19189 } 19190 19191 int argc = 2; 19192 char *argv[] = {(char *)"foo", (char *)filter.c_str()}; 19193 __android_log_print(ANDROID_LOG_DEBUG, appTag, "filter = %s", argv[1]); 19194 19195 // Route output to files until we can override the gtest output 19196 freopen("/sdcard/Android/data/com.example.VulkanLayerValidationTests/files/out.txt", "w", stdout); 19197 freopen("/sdcard/Android/data/com.example.VulkanLayerValidationTests/files/err.txt", "w", stderr); 19198 19199 ::testing::InitGoogleTest(&argc, argv); 19200 VkTestFramework::InitArgs(&argc, argv); 19201 ::testing::AddGlobalTestEnvironment(new TestEnvironment); 19202 19203 int result = RUN_ALL_TESTS(); 19204 19205 if (result != 0) { 19206 __android_log_print(ANDROID_LOG_INFO, appTag, "==== Tests FAILED ===="); 19207 } else { 19208 __android_log_print(ANDROID_LOG_INFO, appTag, "==== Tests PASSED ===="); 19209 } 19210 19211 VkTestFramework::Finish(); 19212 19213 fclose(stdout); 19214 fclose(stderr); 19215 19216 ANativeActivity_finish(app->activity); 19217 19218 return; 19219 } 19220 } 19221 } 19222 #endif 19223 19224 int main(int argc, char **argv) { 19225 int result; 19226 19227 #ifdef ANDROID 19228 int vulkanSupport = InitVulkan(); 19229 if (vulkanSupport == 0) 19230 return 1; 19231 #endif 19232 19233 ::testing::InitGoogleTest(&argc, argv); 19234 VkTestFramework::InitArgs(&argc, argv); 19235 19236 ::testing::AddGlobalTestEnvironment(new TestEnvironment); 19237 19238 result = RUN_ALL_TESTS(); 19239 19240 VkTestFramework::Finish(); 19241 return result; 19242 } 19243